
Dear all, I'm going to change the ADL lookup hook of range functions. instead of the irritating void foo() { using namespace boost; begin(r); } we simply now say void foo() { boost::begin(r); } and get full ADL lookup. This changes the extension protocol to overiding these three functions: range_adl_begin() range_adl_end() range_adl_size() Any comments before I commit? -Thorsten -- Thorsten Ottosen ---------------------------- www.dezide.com www.cs.aau.dk/index2.php?content=Research/bss www.boost.org www.open-std.org/JTC1/SC22/WG21/

Thorsten Ottosen wrote:
Dear all,
I'm going to change the ADL lookup hook of range functions.
instead of the irritating
void foo() { using namespace boost; begin(r); }
we simply now say
void foo() { boost::begin(r); }
and get full ADL lookup. This changes the extension protocol to overiding these three functions:
range_adl_begin() range_adl_end() range_adl_size()
Any comments before I commit?
This looks good to me. Jonathan

Thorsten Ottosen wrote:
This changes the extension protocol to overiding these three functions:
range_adl_begin() range_adl_end() range_adl_size()
Any comments before I commit?
There is a larger question of how to handle ADL customization points in general. I like the approach you're proposing, but I dislike the naming of the above functions. The "adl" can go, IMO, and there should be a "boost" in there somewhere. I suggest: boost_range_begin() boost_range_end() boost_range_size() In general, boost libraries that use ADL customization points should name the functions: boost_[library]_[function]() The idea is that these overloads are going to appear in users' code, in their namespace. From a maintenence standpoint, "boost_range_begin" announces more clearly that this function has to do with the Boost.Range library than "range_adl_begin". Comments? -- Eric Niebler Boost Consulting www.boost-consulting.com

"Eric Niebler" <eric@boost-consulting.com> wrote in message news:4241E71B.8060007@boost-consulting.com... | Thorsten Ottosen wrote: | > This changes the extension protocol | > to overiding these three functions: | > | > range_adl_begin() | > range_adl_end() | > range_adl_size() | > | > Any comments before I commit? | > | | There is a larger question of how to handle ADL customization points in | general. I like the approach you're proposing, but I dislike the naming | of the above functions. The "adl" can go, IMO, yes, I would have liked that, but it turned out we clashed with range_size<R>::type | and there should be a | "boost" in there somewhere. I suggest: | | boost_range_begin() | boost_range_end() | boost_range_size() | | In general, boost libraries that use ADL customization points should | name the functions: | | boost_[library]_[function]() | | The idea is that these overloads are going to appear in users' code, in | their namespace. From a maintenence standpoint, "boost_range_begin" | announces more clearly that this function has to do with the Boost.Range | library than "range_adl_begin". | | Comments? I do like that convention for boost.range. But it doesn't seem to apply to all ADL customization points; for example, in the pointer container lib new_clone() delete_clone() are found with ADL from within the heap_clone_allocator: template< class T > T* heap_clone_allocator::allocate_clone( const T& r ) { return new_clone(r); } Free-standing functions seems to have slightly different goals. One consequence of using the name boost_range_begin() is that the users code won't work with the next standard library. I would like to retain compatibility if possible. -Thorsten

Thorsten Ottosen wrote:
"Eric Niebler" <eric@boost-consulting.com> wrote in message | I suggest: | | boost_range_begin() | boost_range_end() | boost_range_size() | | In general, boost libraries that use ADL customization points should | name the functions: | | boost_[library]_[function]() | | The idea is that these overloads are going to appear in users' code, in | their namespace. From a maintenence standpoint, "boost_range_begin" | announces more clearly that this function has to do with the Boost.Range | library than "range_adl_begin". | | Comments?
I do like that convention for boost.range. But it doesn't seem to apply to all ADL customization points; for example, in the pointer container lib
new_clone() delete_clone()
But we can still come up with a convention used by any *new* ADL customization points. That's what you're asking about anyway, right?
Free-standing functions seems to have slightly different goals.
You lost me. What goals?
One consequence of using the name boost_range_begin() is that the users code won't work with the next standard library. I would like to retain compatibility if possible.
First, there's just no reasonable expectation that boost libraries should be forward-compatible with some future version that gets accepted into the standard. Libraries change as they go through standardization -- that's expected. And second, the standardization committee might reason like I did and decide that "std_range_begin()" is a better name than "range_adl_begin()", and you've lost compatibility anyway. -- Eric Niebler Boost Consulting www.boost-consulting.com

"Eric Niebler" <eric@boost-consulting.com> wrote in message news:4241EFF2.3040605@boost-consulting.com... | Thorsten Ottosen wrote: | > "Eric Niebler" <eric@boost-consulting.com> wrote in message | > | I suggest: | > | | > | boost_range_begin() | > | boost_range_end() | > | boost_range_size() | > | | > | In general, boost libraries that use ADL customization points should | > | name the functions: | > | | > | boost_[library]_[function]() | > | | > | The idea is that these overloads are going to appear in users' code, in | > | their namespace. From a maintenence standpoint, "boost_range_begin" | > | announces more clearly that this function has to do with the Boost.Range | > | library than "range_adl_begin". | > | | > | Comments? | > | > I do like that convention for boost.range. | > But it doesn't seem to apply to all ADL customization points; | > for example, in the pointer container lib | > | > new_clone() | > delete_clone() | > | | | But we can still come up with a convention used by any *new* ADL | customization points. That's what you're asking about anyway, right? yes, agreed. | > | > Free-standing functions seems to have slightly different | > goals. | | | You lost me. What goals? that boost:::foo() does ADL. new_clone() is used primarily inside the containers and does therefore not suffer much inconvenience. | > | > One consequence of using the name | > boost_range_begin() is that the users code won't | > work with the next standard library. I would like to retain | > compatibility if possible. | > | | | First, there's just no reasonable expectation that boost libraries | should be forward-compatible with some future version that gets accepted | into the standard. Libraries change as they go through standardization | -- that's expected. And second, the standardization committee might | reason like I did and decide that "std_range_begin()" is a better name | than "range_adl_begin()", and you've lost compatibility anyway. true, that could happen. the difference being that we might not. In some sense it also seems wierd that the same customization point should have different points in different libararies. Seems redundant. Another set of names could be begin_range() end_range() size_range() -Thorsten

Thorsten Ottosen wrote:
"Eric Niebler" <eric@boost-consulting.com> wrote in message | But we can still come up with a convention used by any *new* ADL | customization points. That's what you're asking about anyway, right?
yes, agreed.
| > | > Free-standing functions seems to have slightly different | > goals. | | | You lost me. What goals?
that boost:::foo() does ADL.
new_clone() is used primarily inside the containers and does therefore not suffer much inconvenience.
I'm still lost. What inconvenience?
| > One consequence of using the name | > boost_range_begin() is that the users code won't | > work with the next standard library. I would like to retain | > compatibility if possible. | > | | | First, there's just no reasonable expectation that boost libraries | should be forward-compatible with some future version that gets accepted | into the standard. Libraries change as they go through standardization | -- that's expected. And second, the standardization committee might | reason like I did and decide that "std_range_begin()" is a better name | than "range_adl_begin()", and you've lost compatibility anyway.
true, that could happen. the difference being that we might not. In some sense it also seems wierd that the same customization point should have different points in different libararies. Seems redundant.
What is redundant? What different libraries? We're talking about the ADL customization points of /one particular library/. A customization point cannot be in two libraries simultaneously. I must have missed your point again. Please set me straight.
Another set of names could be
begin_range() end_range() size_range()
But you still haven't given me a reason I can understand why it shouldn't be "boost_range_begin()" etc.. -- Eric Niebler Boost Consulting www.boost-consulting.com

"Eric Niebler" <eric@boost-consulting.com> wrote in message news:42420638.2070604@boost-consulting.com... | | Thorsten Ottosen wrote: | > "Eric Niebler" <eric@boost-consulting.com> wrote in message | > | But we can still come up with a convention used by any *new* ADL | > | customization points. That's what you're asking about anyway, right? | > | > yes, agreed. | > | > | > | > | > Free-standing functions seems to have slightly different | > | > goals. | > | | > | | > | You lost me. What goals? | > | > that boost:::foo() does ADL. | > | > new_clone() is used primarily inside the | > containers and does therefore not suffer much | > inconvenience. | | | I'm still lost. What inconvenience? the fact that you normally would have to write using namespace boost; begin(r);
true, that could happen. the difference being that we might not. | > In some sense it also seems wierd that the same customization point | > should have different points in different libararies. Seems redundant. | | | What is redundant? What different libraries? We're talking about the ADL | customization points of /one particular library/.
are we? The thing is IMO that were are talking about customization points of a concept, not a particular library. | A customization point | cannot be in two libraries simultaneously. I must have missed your point | again. Please set me straight. struct Foo { ... this is a range with adaptation ... } iterator boost_range_begin( Foo& f ); iterator std_range_begin( Foo& f ); iterator adope_range_begin( Foo& f ); what is the difference between the three functions, apart from their name? | > Another set of names could be | > | > begin_range() | > end_range() | > size_range() | | | But you still haven't given me a reason I can understand why it | shouldn't be "boost_range_begin()" etc.. I'm saying that it might not be the right solution; I don't see why we should give the same concept different interfaces. We are already protecting classes by a namespace, shouldn't that be enough. -Thorsten

Thorsten Ottosen wrote:
"Eric Niebler" <eric@boost-consulting.com> wrote in message We're talking about the ADL | customization points of /one particular library/.
are we?
Yes, we are. The thing is IMO that were are talking about customization
points of a concept, not a particular library.
No. boost_range_begin() is *only* called from boost::begin(). Nobody should be calling it directly. It is part of the Boost.Range library's interface that it can be customized this way. Concepts have nothing to do with it.
| A customization point | cannot be in two libraries simultaneously. I must have missed your point | again. Please set me straight.
struct Foo { ... this is a range with adaptation ... }
iterator boost_range_begin( Foo& f );
iterator std_range_begin( Foo& f );
iterator adope_range_begin( Foo& f );
what is the difference between the three functions, apart from their name?
Separate libraries should not be picking the same name for use as a customization point. The Range library is the only place that defines the Range concept, and it has one function, boost::begin(), for finding the beginning of the range. That function has one customization point. What should it be called? That's the only thing we're concerned with here.
| But you still haven't given me a reason I can understand why it | shouldn't be "boost_range_begin()" etc..
I'm saying that it might not be the right solution; I don't see why we should give the same concept different interfaces.
Concepts are not the concern here -- only how to allow users to customize the behavior of a library.
We are already protecting classes by a namespace, shouldn't that be enough.
No, because we're using unqualified calls to turn on ADL. -- Eric Niebler Boost Consulting www.boost-consulting.com

"Eric Niebler" <eric@boost-consulting.com> wrote in message news:42421E16.5000105@boost-consulting.com... | Thorsten Ottosen wrote: | > We are already protecting classes by a namespace, shouldn't that be enough. | > | | No, because we're using unqualified calls to turn on ADL. begin() is protected by a namespace, the hook is protected by a library name. It was because begin() was likely to clash that we need another ungly sounding hook. -Thorsten

"Eric Niebler" <eric@boost-consulting.com> writes:
The thing is IMO that were are talking about customization
points of a concept, not a particular library.
No. boost_range_begin() is *only* called from boost::begin(). Nobody should be calling it directly. It is part of the Boost.Range library's interface that it can be customized this way. Concepts have nothing to do with it.
Please read Peter's posts in the thread I referenced. I have sympathy for both views. The question is whether the range concept "belongs" to the range library or if other libraries will adopt it and begin to use its customization points in the same way that the range library does. -- Dave Abrahams Boost Consulting www.boost-consulting.com

"Eric Niebler" <eric@boost-consulting.com> writes:
But you still haven't given me a reason I can understand why it shouldn't be "boost_range_begin()" etc..
Peter Dimov made some excellent arguments in the thread containing http://article.gmane.org/gmane.comp.lib.boost.user/9718 (click the subject line to see the thread). -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
"Eric Niebler" <eric@boost-consulting.com> writes:
But you still haven't given me a reason I can understand why it shouldn't be "boost_range_begin()" etc..
Peter Dimov made some excellent arguments in the thread containing http://article.gmane.org/gmane.comp.lib.boost.user/9718 (click the subject line to see the thread).
It's true he made some excellent arguments in that thread, but this is a different argument. ;-) Once you accept as a given that we should be using an ADL customization point, what should we call it? In this message: http://article.gmane.org/gmane.comp.lib.boost.user/9837 You say: "You're much safer using boost_range_end or range_end if you're trying to keep it small. I don't see any reason to keep it small, though: users won't be invoking that function directly." And I agree, it should be boost_range_end. We are in agreement. Now we just need to convince Thorsten. :-) -- Eric Niebler Boost Consulting www.boost-consulting.com

"Eric Niebler" <eric@boost-consulting.com> wrote in message news:42425A8C.1050209@boost-consulting.com... | David Abrahams wrote: | > "Eric Niebler" <eric@boost-consulting.com> writes: | > | >>But you still haven't given me a reason I can understand why it | >>shouldn't be "boost_range_begin()" etc.. | > | > Peter Dimov made some excellent arguments in the thread containing | > http://article.gmane.org/gmane.comp.lib.boost.user/9718 (click the | > subject line to see the thread). | > | | It's true he made some excellent arguments in that thread, but this is a | different argument. ;-) Once you accept as a given that we should be | using an ADL customization point, what should we call it? | | In this message: | http://article.gmane.org/gmane.comp.lib.boost.user/9837 | | You say: "You're much safer using boost_range_end or range_end if you're | trying to keep it small. I don't see any reason to keep it small, | though: users won't be invoking that function directly." | | And I agree, it should be boost_range_end. We are in agreement. Now we | just need to convince Thorsten. :-) since we can't use the short version (ity clashes with range_size<TA) then let's go with the boost prefix. I'll commit shortly -Thorsten

"Thorsten Ottosen" <nesotto@cs.auc.dk> writes:
| It's true he made some excellent arguments in that thread, but this is a | different argument. ;-) Once you accept as a given that we should be | using an ADL customization point, what should we call it? | | In this message: | http://article.gmane.org/gmane.comp.lib.boost.user/9837 | | You say: "You're much safer using boost_range_end or range_end if you're | trying to keep it small. I don't see any reason to keep it small, | though: users won't be invoking that function directly." | | And I agree, it should be boost_range_end. We are in agreement. Now we | just need to convince Thorsten. :-)
since we can't use the short version (ity clashes with range_size<TA) then let's go with the boost prefix.
I'll commit shortly
I think you should re-read the boost-users thread and consider all the issues one more time before you do. This is a hard decision to get right. -- Dave Abrahams Boost Consulting www.boost-consulting.com

"Eric Niebler" <eric@boost-consulting.com> writes:
David Abrahams wrote:
"Eric Niebler" <eric@boost-consulting.com> writes:
But you still haven't given me a reason I can understand why it shouldn't be "boost_range_begin()" etc.. Peter Dimov made some excellent arguments in the thread containing http://article.gmane.org/gmane.comp.lib.boost.user/9718 (click the subject line to see the thread).
It's true he made some excellent arguments in that thread, but this is a different argument. ;-) Once you accept as a given that we should be using an ADL customization point, what should we call it?
It's not an entirely different argument. Peter was saying that once you publicize the customization point, it no longer "belongs" to the library. Imagine what happens if some other library wanted to use the same range concept, but not depend on Boost itself. Either they'd be picking a new ugly name for a customization point with identical semantics :( or they'd be using the name "boost_range_begin" in code with no Boost relationship in sight :(. As my wife's co-worker says, "it's a two-headed sword" ;-) For that reason, it might be better to use something like "iterator_range_begin" that has a hope of becoming lingua franca like swap. At least that's how I understand Peter's argument. -- Dave Abrahams Boost Consulting www.boost-consulting.com

"David Abrahams" <dave@boost-consulting.com> wrote in message news:umzstxh18.fsf@boost-consulting.com... | "Eric Niebler" <eric@boost-consulting.com> writes: | It's not an entirely different argument. Peter was saying that once | you publicize the customization point, it no longer "belongs" to the | library. Imagine what happens if some other library wanted to use the | same range concept, but not depend on Boost itself. Either they'd be | picking a new ugly name for a customization point with identical | semantics :( or they'd be using the name "boost_range_begin" in code | with no Boost relationship in sight :(. | | As my wife's co-worker says, "it's a two-headed sword" ;-) | | For that reason, it might be better to use something like | "iterator_range_begin" that has a hope of becoming lingua franca like | swap. At least that's how I understand Peter's argument. Hm.. yeah...I guess you're better at expressing my point than I myself :-) iterator_range_ seems to be a good prefix. What do you say, Eric, do you like iterator_range_begin() etc? -Thorsten

On Thu, Mar 24, 2005 at 05:02:37PM +0100, Thorsten Ottosen wrote:
"David Abrahams" <dave@boost-consulting.com> wrote in message news:umzstxh18.fsf@boost-consulting.com... | "Eric Niebler" <eric@boost-consulting.com> writes:
| It's not an entirely different argument. Peter was saying that once | you publicize the customization point, it no longer "belongs" to the | library. Imagine what happens if some other library wanted to use the | same range concept, but not depend on Boost itself. Either they'd be | picking a new ugly name for a customization point with identical | semantics :( or they'd be using the name "boost_range_begin" in code | with no Boost relationship in sight :(. | | As my wife's co-worker says, "it's a two-headed sword" ;-) | | For that reason, it might be better to use something like | "iterator_range_begin" that has a hope of becoming lingua franca like | swap. At least that's how I understand Peter's argument.
Hm.. yeah...I guess you're better at expressing my point than I myself :-)
iterator_range_ seems to be a good prefix.
What do you say, Eric, do you like iterator_range_begin() etc?
Why iterator_range_? I'm not sure it this is the best, since there is already a class named iterator_range and such a naming might lead to a confusion about the affinity to this class. IIRC, when Boost.Range was accepted as a proper name for this library, it was also accepted as a name of the concept. So why not stick to the simple range_begin() ? I might be missing something? Regards, Pavol

"Pavol Droba" <droba@topmail.sk> wrote in message news:20050324164342.GD15682@lenin.felcer.sk... So why not stick to the simple range_begin() ? | | I might be missing something? range_size() will clash with range_size>T>::type -Thorsten

"Thorsten Ottosen" <nesotto@cs.auc.dk> writes:
"Pavol Droba" <droba@topmail.sk> wrote in message news:20050324164342.GD15682@lenin.felcer.sk...
So why not stick to the simple range_begin() ? | | I might be missing something?
range_size() will clash with range_size>T>::type
...on GCC that uses an overly liberal interpretation of ADL and seems unlikely to change it anytime soon. -- Dave Abrahams Boost Consulting www.boost-consulting.com

"David Abrahams" <dave@boost-consulting.com> wrote in message news:u64zhuf0x.fsf@boost-consulting.com... | "Thorsten Ottosen" <nesotto@cs.auc.dk> writes: | | > "Pavol Droba" <droba@topmail.sk> wrote in message | > news:20050324164342.GD15682@lenin.felcer.sk... | > | > So why not stick to the simple range_begin() ? | > | | > | I might be missing something? | > | > range_size() will clash with range_size>T>::type | | ...on GCC that uses an overly liberal interpretation of ADL and seems | unlikely to change it anytime soon. hm...does this compile on your compiler: int range_size( int ) { return 0; } template< class T > struct range_size { typedef T type; }; template< class T > typename range_size<T>::type size( T t ) { return range_size( t ); } int main() { return size( 0 ); } -Thorsten

"Thorsten Ottosen" <nesotto@cs.auc.dk> writes:
| ...on GCC that uses an overly liberal interpretation of ADL and seems | unlikely to change it anytime soon.
hm...does this compile on your compiler:
No, but I think you have written the wrong test: bleah.cpp:13: error: `template<class T> struct range_size' redeclared as different kind of symbol bleah.cpp:6: error: previous declaration of `int range_size(int)' bleah.cpp: In function `typename range_size<T>::type size(T)': bleah.cpp:21: error: use of class template `template<class T> struct range_size ' as expression -- Dave Abrahams Boost Consulting www.boost-consulting.com

On Thu, Mar 24, 2005 at 06:00:02PM +0100, Thorsten Ottosen wrote:
"Pavol Droba" <droba@topmail.sk> wrote in message news:20050324164342.GD15682@lenin.felcer.sk...
So why not stick to the simple range_begin() ? | | I might be missing something?
range_size() will clash with range_size>T>::type
Might be, that changing range_size would be more appropriate if it is the only problem. Pavol.

Thorsten Ottosen wrote:
"David Abrahams" <dave@boost-consulting.com> wrote in message news:umzstxh18.fsf@boost-consulting.com... | "Eric Niebler" <eric@boost-consulting.com> writes:
| It's not an entirely different argument. Peter was saying that once | you publicize the customization point, it no longer "belongs" to the | library. Imagine what happens if some other library wanted to use the | same range concept, but not depend on Boost itself. Either they'd be | picking a new ugly name for a customization point with identical | semantics :( or they'd be using the name "boost_range_begin" in code | with no Boost relationship in sight :(. | | As my wife's co-worker says, "it's a two-headed sword" ;-) | | For that reason, it might be better to use something like | "iterator_range_begin" that has a hope of becoming lingua franca like | swap. At least that's how I understand Peter's argument.
Hm.. yeah...I guess you're better at expressing my point than I myself :-)
iterator_range_ seems to be a good prefix.
What do you say, Eric, do you like iterator_range_begin() etc?
I'm finally beginning to grasp the full implications of Peter's comments about customization points. Thanks for the clear explanation, Dave, and Thorsten, I now understand what you were saying. I have a couple of concerns with "iterator_range_begin". First, as Pavol says, it suggests an association with the iterator_range<> type. But also, in my understanding, the Range concept is a bit more inclusive than merely "iterator ranges". A std container satisfies the Range concept, doesn't it? Consider iterator_range_size(). I could have a container that satisfies the range concept for which .size() is an O(1) operation, but std::distance( .begin(), .end() ) is O(N). What Big-O is suggested by "iterator_range_size()" when applied to one of those contaiers? So, our concern here is that someone could borrow boost's Range concept without using boost's Range code? But this is still boost's Range concept, so I'm not sure I agree with Dave that there is "no Boost relationship in sight". But I'll put that aside and plan for a future when the Range concept is widely recognized outside Boost. Calling it "range_begin()" leads to conflicts, but can they be resolved? Can we move the conflicting template into a different namespace? -- Eric Niebler Boost Consulting www.boost-consulting.com

"Eric Niebler" <eric@boost-consulting.com> wrote in message news:4242F9E4.4090500@boost-consulting.com... | Thorsten Ottosen wrote: | says, it suggests an association with the iterator_range<> type. But | also, in my understanding, the Range concept is a bit more inclusive | than merely "iterator ranges". A std container satisfies the Range | concept, doesn't it? yes. | Consider iterator_range_size(). I could have a | container that satisfies the range concept for which .size() is an O(1) | operation, but std::distance( .begin(), .end() ) is O(N). What Big-O is | suggested by "iterator_range_size()" when applied to one of those contaiers? O(1) but boost::size(a_range) is allowed to be O(N) | So, our concern here is that someone could borrow boost's Range concept | without using boost's Range code? But this is still boost's Range | concept, so I'm not sure I agree with Dave that there is "no Boost | relationship in sight". But I'll put that aside and plan for a future | when the Range concept is widely recognized outside Boost. Calling it | "range_begin()" leads to conflicts, but can they be resolved? Can we | move the conflicting template into a different namespace? I think so. Let's assume we want the functions to be named namespace boost { range_begin(); range_end(); range_size(); } then we can put the metafunctions into a namespace like namespace boost { namespace range { struct iterator; struct const_iterator; struct value; struct size; struct difference; } } The implementation then does namespace boost { template< class T > typename range::iterator<T>::type begin( T& r ) { return range_begin(r); } } To summarize this extension protocol - put range_begin() etc in your types namespace - (partial) specialize range::X for all X The library protocol would be - put library name as prefix on ADL hooks - put metafunctions in a namespace with the name of the library -Thorsten

"Thorsten Ottosen" <nesotto@cs.auc.dk> writes:
"Eric Niebler" <eric@boost-consulting.com> wrote in message news:4242F9E4.4090500@boost-consulting.com... | Thorsten Ottosen wrote:
| says, it suggests an association with the iterator_range<> type. But | also, in my understanding, the Range concept is a bit more inclusive | than merely "iterator ranges". A std container satisfies the Range | concept, doesn't it?
yes.
In what sense is a standard container not an iterator range? -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
"Thorsten Ottosen" <nesotto@cs.auc.dk> writes:
"Eric Niebler" <eric@boost-consulting.com> wrote in message news:4242F9E4.4090500@boost-consulting.com... | Thorsten Ottosen wrote:
| says, it suggests an association with the iterator_range<> type. But | also, in my understanding, the Range concept is a bit more inclusive | than merely "iterator ranges". A std container satisfies the Range | concept, doesn't it?
yes.
In what sense is a standard container not an iterator range?
You snipped the part of my message where I explain that: << Consider iterator_range_size(). I could have a container that satisfies the range concept for which .size() is an O(1) operation, but std::distance( .begin(), .end() ) is O(N). What Big-O is suggested by "iterator_range_size()" when applied to one of those contaiers?
My point was, there are range operations that are not necessarily implemented in terms of lower-level operations on iterators, so the name "iterator_range_size()" might be misleading. -- Eric Niebler Boost Consulting www.boost-consulting.com

"Eric Niebler" <eric@boost-consulting.com> writes:
David Abrahams wrote:
"Thorsten Ottosen" <nesotto@cs.auc.dk> writes:
"Eric Niebler" <eric@boost-consulting.com> wrote in message news:4242F9E4.4090500@boost-consulting.com... | Thorsten Ottosen wrote:
| says, it suggests an association with the iterator_range<> type. But | also, in my understanding, the Range concept is a bit more inclusive | than merely "iterator ranges". A std container satisfies the Range | concept, doesn't it?
yes. In what sense is a standard container not an iterator range?
You snipped the part of my message where I explain that:
<< Consider iterator_range_size(). I could have a container that satisfies the range concept for which .size() is an O(1) operation, but std::distance( .begin(), .end() ) is O(N). What Big-O is suggested by "iterator_range_size()" when applied to one of those contaiers?
I snipped it because it didn't seem to be relevant to my question.
My point was, there are range operations that are not necessarily implemented in terms of lower-level operations on iterators, so the name "iterator_range_size()" might be misleading.
Implementation details are and should be irrelevant to naming AFAICT. The fact is that the container presents a range of iterators in its interface. I don't see why anyone would assume that the name implies something about how operations are implemented under-the-covers. -- Dave Abrahams Boost Consulting www.boost-consulting.com

On Thu, Mar 24, 2005 at 07:30:42PM +0100, Thorsten Ottosen wrote:
I think so. Let's assume we want the functions to be named
namespace boost { range_begin(); range_end(); range_size(); }
then we can put the metafunctions into a namespace like
namespace boost { namespace range { struct iterator; struct const_iterator; struct value; struct size; struct difference; } }
The implementation then does
namespace boost { template< class T > typename range::iterator<T>::type begin( T& r ) { return range_begin(r); } }
To summarize this extension protocol
- put range_begin() etc in your types namespace - (partial) specialize range::X for all X
The library protocol would be
- put library name as prefix on ADL hooks - put metafunctions in a namespace with the name of the library
I have nothing much to add then simple "I like it". Just a small clarification, I would rewrite paragraph: " The library protocol would be - put concept name as prefix on ADL hooks - put metafunctions in a namespace with the name of the concept " Regards, Pavol.

"Pavol Droba" <droba@topmail.sk> wrote in message news:20050324204219.GF15682@lenin.felcer.sk... | On Thu, Mar 24, 2005 at 07:30:42PM +0100, Thorsten Ottosen wrote: | I have nothing much to add then simple "I like it". | | Just a small clarification, I would rewrite paragraph: | | " | The library protocol would be | | - put concept name as prefix on ADL hooks | - put metafunctions in a namespace with the name of the concept | " ok, this change will break existing libs using range_iterator etc. even so, does anybody have major problems with me committing an update? (Should it be more braodly adverticed in a new thread?) -Thorsten

"Eric Niebler" <eric@boost-consulting.com> writes:
So, our concern here is that someone could borrow boost's Range concept without using boost's Range code?
Or they might wish to provide something that would match the Range concept if used with Boost (or some other library that has adopted it) without actually using any Range code at all.
But this is still boost's Range concept, so I'm not sure I agree with Dave that there is "no Boost relationship in sight".
The point is that once the customization point is released to the public, lots of different code may use it for its own purposes. Some library A may advertise that it accepts types modeling the Range concept. Now library B wants to work with library A so it provides the hooks. Nobody's using Boost! The concept may have come from Boost, but it no longer belongs there. And one day you might want to standardize these hooks without invalidating existing libraries that use them.
But I'll put that aside and plan for a future when the Range concept is widely recognized outside Boost. Calling it "range_begin()" leads to conflicts, but can they be resolved? Can we move the conflicting template into a different namespace?
Not so easy. If you want to avoid trouble with GCC, you really have to pick a name that's unlikely to be used for anything else !&*%(^#@!! Anyway, I'm not totally opposed to boost_range_whatever, I just wanted to make sure that all the arguments were well understood. -- Dave Abrahams Boost Consulting www.boost-consulting.com

"Thorsten Ottosen" <nesotto@cs.auc.dk> writes:
Dear all,
I'm going to change the ADL lookup hook of range functions.
instead of the irritating
void foo() { using namespace boost; begin(r); }
we simply now say
void foo() { boost::begin(r); }
and get full ADL lookup. This changes the extension protocol to overiding these three functions:
range_adl_begin() range_adl_end() range_adl_size()
Any comments before I commit?
Yes. I think you should get rid of "ADL" in the name. It doesn't add enough and is easy to misinterpret. -- Dave Abrahams Boost Consulting www.boost-consulting.com

Thorsten, Thorsten Ottosen wrote:
Dear all,
I'm going to change the ADL lookup hook of range functions.
Actually AFAICS you are changing a basic feature of the lib.
instead of the irritating
void foo() { using namespace boost; begin(r); }
For the record I don't think it's irritating at all. It very clearly states what is going on. I can see it being cumbersome though. BTW shouldn't it be using boost::begin; begin(r);
we simply now say
void foo() { boost::begin(r); }
and get full ADL lookup. This changes the extension protocol to overiding these three functions:
To me the key difference here is not the way hooks a provided, but that currently the user chooses to take advantage of ADL, while with the new scheme the library makes the choice for the user. I am unconvinced that that's actually better.
range_adl_begin() range_adl_end() range_adl_size()
My prior remarks notwithstanding, I think the _adl part should go. Thomas -- Thomas Witt witt@acm.org

"Thomas Witt" <witt@acm.org> wrote in message news:d1tceq$m29$1@sea.gmane.org... | | Thorsten, | | Thorsten Ottosen wrote: | > Dear all, | > | > I'm going to change the ADL lookup hook of range functions. | | Actually AFAICS you are changing a basic feature of the lib. | | > | > instead of the irritating | > | > void foo() | > { | > using namespace boost; | > begin(r); | > } | | For the record I don't think it's irritating at all. It very clearly | states what is going on. I can see it being cumbersome though. | | BTW shouldn't it be | | using boost::begin; | begin(r); yes! its irritating especially for boost authors because it dosn't wok portable; putting the code into boost::begin() solves that once and for all. | > | > we simply now say | > | > void foo() | > { | > boost::begin(r); | > } | > | > and get full ADL lookup. This changes the extension protocol | > to overiding these three functions: | | To me the key difference here is not the way hooks a provided, but that | currently the user chooses to take advantage of ADL, while with the new | scheme the library makes the choice for the user. I am unconvinced that | that's actually better. | | > range_adl_begin() | > range_adl_end() | > range_adl_size() | | My prior remarks notwithstanding, I think the _adl part should go. ok -Thorsten

Thorsten, Thorsten Ottosen wrote:
"Thomas Witt" <witt@acm.org> wrote in message
its irritating especially for boost authors because it dosn't wok portable; putting the code into boost::begin() solves that once and for all.
If all we are concerned about are boost authors, I don't think this is not the correct solution. Neither is it won't work portable an argument to me. Portability issues should not drive such a fundamental point of library interface design. Thomas -- Thomas Witt witt@acm.org

Thomas Witt wrote:
Thorsten,
Thorsten Ottosen wrote:
"Thomas Witt" <witt@acm.org> wrote in message its irritating especially for boost authors because it dosn't wok portable; putting the code into boost::begin() solves that once and for all.
If all we are concerned about are boost authors, I don't think this is not the correct solution. Neither is it won't work portable an argument to me. Portability issues should not drive such a fundamental point of library interface design.
I'll try this again: If all we are concerned about are boost authors, I am not convinced this is the correct solution. Neither is "it won't work portable" an argument to me. I think portability issues should not drive such a fundamental point of library interface design. Thomas -- Thomas Witt witt@acm.org

Thomas Witt <witt@acm.org> writes:
Thomas Witt wrote:
Thorsten, Thorsten Ottosen wrote:
"Thomas Witt" <witt@acm.org> wrote in message its irritating especially for boost authors because it dosn't wok portable; putting the code into boost::begin() solves that once and for all. If all we are concerned about are boost authors, I don't think this is not the correct solution. Neither is it won't work portable an argument to me. Portability issues should not drive such a fundamental point of library interface design.
I'll try this again:
If all we are concerned about are boost authors, I am not convinced this
I've lost the thread. What is "this"?
is the correct solution. Neither is "it won't work portable" an argument to me. I think portability issues should not drive such a fundamental point of library interface design.
-- Dave Abrahams Boost Consulting www.boost-consulting.com

"Thomas Witt" <witt@acm.org> wrote in message news:d1vtma$ojg$1@sea.gmane.org... | Thomas Witt wrote: | > | > Thorsten, | > | > Thorsten Ottosen wrote: | I'll try this again: | | If all we are concerned about are boost authors, I am not convinced this | is the correct solution. Neither is "it won't work portable" an argument | to me. I think portability issues should not drive such a fundamental | point of library interface design. basically we are tryging to solve how ADL is enabled while, at the same time, names are protected by a namespace prefix to avoid clash with similar names in other namespaces. -Thorsten

"Thorsten Ottosen" <nesotto@cs.auc.dk> writes:
"Thomas Witt" <witt@acm.org> wrote in message news:d1vtma$ojg$1@sea.gmane.org... | Thomas Witt wrote: | > | > Thorsten, | > | > Thorsten Ottosen wrote:
| I'll try this again: | | If all we are concerned about are boost authors, I am not convinced this | is the correct solution. Neither is "it won't work portable" an argument | to me. I think portability issues should not drive such a fundamental | point of library interface design.
basically we are tryging to solve how ADL is enabled while, at the same time, names are protected by a namespace prefix to avoid clash with similar names in other namespaces.
Did you look carefully at my posting in the thread "Boost Algorithm Library?" -- Dave Abrahams Boost Consulting www.boost-consulting.com

"David Abrahams" <dave@boost-consulting.com> wrote in message news:u1x9y2vir.fsf@boost-consulting.com... | "Thorsten Ottosen" <nesotto@cs.auc.dk> writes: | > basically we are tryging to solve how ADL is enabled while, at the same time, | > names are protected by a namespace prefix to avoid clash with similar names in | > other namespaces. | | Did you look carefully at my posting in the thread "Boost Algorithm | Library?" no. sorry. I did the impression that the stuff you talk about therein is overkill compared to the simplicity of the problem of the range library. if, not, then I'm sorry. I won't have too much time to dig into it .... -Thorsten

"Thorsten Ottosen" <nesotto@cs.auc.dk> writes:
"David Abrahams" <dave@boost-consulting.com> wrote in message news:u1x9y2vir.fsf@boost-consulting.com... | "Thorsten Ottosen" <nesotto@cs.auc.dk> writes:
| > basically we are tryging to solve how ADL is enabled while, at | > the same time, names are protected by a namespace prefix to | > avoid clash with similar names in other namespaces. | | Did you look carefully at my posting in the thread "Boost Algorithm | Library?"
no. sorry.
I did the impression that the stuff you talk about therein is overkill compared to the simplicity of the problem of the range library.
I'm not sure what "the problem of the range library" is, but I think you may be right. IIUC you're just worried about how authors of range classes can supply the range-related functions such as "begin," and how users of generic ranges will invoke those functions. If so, the stuff I was talking about there is mostly unrelated. It deals with how to select algorithm implementations. I _do_ plan to introduce a new kind of range concept, but that's a separate issue. -- Dave Abrahams Boost Consulting www.boost-consulting.com

"David Abrahams" <dave@boost-consulting.com> wrote in message news:ufyye1cj8.fsf@boost-consulting.com... | "Thorsten Ottosen" <nesotto@cs.auc.dk> writes: | | > "David Abrahams" <dave@boost-consulting.com> wrote in message | > news:u1x9y2vir.fsf@boost-consulting.com... | > | "Thorsten Ottosen" <nesotto@cs.auc.dk> writes: | > | > | > basically we are tryging to solve how ADL is enabled while, at | > | > the same time, names are protected by a namespace prefix to | > | > avoid clash with similar names in other namespaces. | > | | > | Did you look carefully at my posting in the thread "Boost Algorithm | > | Library?" | > | > no. sorry. | > | > I did the impression that the stuff you talk about therein | > is overkill compared to the simplicity of the problem of the | > range library. | | I'm not sure what "the problem of the range library" is, but I think | you may be right. IIUC you're just worried about how authors of range | classes can supply the range-related functions such as "begin," and | how users of generic ranges will invoke those functions. yes, exactly. -Thorsten

"Thorsten Ottosen" <nesotto@cs.auc.dk> writes:
| BTW shouldn't it be | | using boost::begin; | begin(r);
yes!
its irritating especially for boost authors because it dosn't wok portable; putting the code into boost::begin() solves that once and for all.
What portability issue are you referring to? On what compilers is there a portability problem? I should note that old compilers like vc6 and vc7 don't support ADL for regular functions (just operators), so our approach, which puts the code into boost::begin(), doesn't work on those compilers anyway. Not that I care too much about them, but when someone cites portability issues, they're the usual culprits ;-) -- Dave Abrahams Boost Consulting www.boost-consulting.com

"David Abrahams" <dave@boost-consulting.com> wrote in message news:umzslw8lo.fsf@boost-consulting.com... | "Thorsten Ottosen" <nesotto@cs.auc.dk> writes: | | > | BTW shouldn't it be | > | | > | using boost::begin; | > | begin(r); | > | > yes! | > | > its irritating especially for boost authors because it dosn't wok | > portable; putting the code into boost::begin() | > solves that once and for all. | | What portability issue are you referring to? On what compilers is | there a portability problem? borland. | I should note that old compilers like vc6 and vc7 don't support ADL | for regular functions (just operators), so our approach, which puts | the code into boost::begin(), doesn't work on those compilers anyway. no, but the library writers still needs to deal with it. -Thorsten

"Thorsten Ottosen" <nesotto@cs.auc.dk> writes:
| What portability issue are you referring to? On what compilers is | there a portability problem?
borland.
OK. More broken that vc6, I say :(
| I should note that old compilers like vc6 and vc7 don't support ADL | for regular functions (just operators), so our approach, which puts | the code into boost::begin(), doesn't work on those compilers anyway.
no, but the library writers still needs to deal with it.
?? No comprende -- Dave Abrahams Boost Consulting www.boost-consulting.com

"David Abrahams" <dave@boost-consulting.com> wrote in message news:u7jjpw6ve.fsf@boost-consulting.com... | "Thorsten Ottosen" <nesotto@cs.auc.dk> writes: | > | I should note that old compilers like vc6 and vc7 don't support ADL | > | for regular functions (just operators), so our approach, which puts | > | the code into boost::begin(), doesn't work on those compilers anyway. | > | > no, but the library writers still needs to deal with it. | | ?? No comprende as a library witer you want to support as many platforms as possible--you want the code to wok with vc6 and borland, if possible. Hence you have to #ifdef every ADL lookup point in your code. I think some compilers do get ADL when the function is seen *before* the ADL lookup point, but not between the lookup point and the intantiation. I would have to run a new test to be sure of the compiler conformity, though. -Thorsten

Thomas Witt <witt@acm.org> writes:
instead of the irritating void foo() { using namespace boost; begin(r); }
For the record I don't think it's irritating at all. It very clearly states what is going on. I can see it being cumbersome though.
Cumbersomeness is irritating ;-)
BTW shouldn't it be
using boost::begin; begin(r);
Yes it should.
we simply now say void foo() { boost::begin(r); } and get full ADL lookup. This changes the extension protocol to overiding these three functions:
To me the key difference here is not the way hooks a provided, but that currently the user chooses to take advantage of ADL, while with the new scheme the library makes the choice for the user. I am unconvinced that that's actually better.
The user can always call the hook unqualified. That's _going_ to be a public part of the library's interface. -- Dave Abrahams Boost Consulting www.boost-consulting.com

Dave, David Abrahams wrote:
Thomas Witt <witt@acm.org> writes:
For the record I don't think it's irritating at all. It very clearly states what is going on. I can see it being cumbersome though.
Cumbersomeness is irritating ;-)
You are missing my point ;-)
The user can always call the hook unqualified. That's _going_ to be a public part of the library's interface.
Well, if you look at it this way then the _only_ functionality boost::begin provides is a syntactic shortcut. I.e. boost::begin(r); and using boost::range_begin; range_begin(r); are functionally equivalent. Did I miss something? In this case we have the real name in the helper and some artificially uglified name in all class interfaces. This doesn't feel right to me. You could also argue that boost::begin's name does not really describe what it's doing. Having a namespace qualified call disguise an unqualified call is another issue that gives me headaches. Thomas -- Thomas Witt witt@acm.org

Thomas Witt <witt@acm.org> writes:
Dave,
David Abrahams wrote:
Thomas Witt <witt@acm.org> writes:
For the record I don't think it's irritating at all. It very clearly states what is going on. I can see it being cumbersome though.
Cumbersomeness is irritating ;-)
You are missing my point ;-)
I don't think so, but maybe you should try again.
The user can always call the hook unqualified. That's _going_ to be a public part of the library's interface.
Well, if you look at it this way then the _only_ functionality boost::begin provides is a syntactic shortcut. I.e.
boost::begin(r);
and
using boost::range_begin; range_begin(r);
are functionally equivalent.
Did I miss something?
I don't think so. Except maybe that all that C++ provides over C can be viewed as syntactic shortcuts ;-)
In this case we have the real name in the helper and some artificially uglified name in all class interfaces. This doesn't feel right to me.
It's not right, but the language spec (especially when combined with GCC's implementation choices) doesn't give us better options today. Do try to remember that although the "artificially uglified name" will appear in the interfaces of all classes that model the range concept, there will probably be even more uses of the "real name" in user code.
You could also argue that boost::begin's name does not really describe what it's doing. Having a namespace qualified call disguise an unqualified call is another issue that gives me headaches.
Yes, the whole area of dispatching and customization of generic functions is nasty in C++. I've known it's problematic for a long time, but had a hard time expressing how bad the problem is in a way that would communicate to someone who doesn't do heavy generic programming day in and day out. Doug Gregor and I just resolved some related aspects of http://tinyurl.com/6z528 (http://news.gmane.org/find-root.php?message_id=%3cupsxsbv5h.fsf%40boost%2dco...) today, and in the process I think I learned enough to show convincingly that something needs to be done. I'm going to write up our findings next; we'll see how that comes out. -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
Thomas Witt <witt@acm.org> writes:
I don't think so. Except maybe that all that C++ provides over C can be viewed as syntactic shortcuts ;-)
Believe me I am aware of that ;-). Seriously, I am not opposed against the syntactic shortcut per se.
In this case we have the real name in the helper and some artificially uglified name in all class interfaces. This doesn't feel right to me.
It's not right, but the language spec (especially when combined with GCC's implementation choices) doesn't give us better options today.
I can see the problem. What I am unconvinced of is that the proposed solution is the correct solution to the overall problem. If this were some internal boost component meant to make boost library writing easier I would be perfectly happy, but we are talking about a library that deals with an important concept (ranges). I am particularly concerned with the scalability of the solution. How many ADL wrappers do we need to solve the problem? Will they become a legacy at some point?
Do try to remember that although the "artificially uglified name" will appear in the interfaces of all classes that model the range concept, there will probably be even more uses of the "real name" in user code.
Agreed. On the other hand the usibility of these classes now takes a hit when Boost.Range isn't present. The class author can work around this by providing begin and range_begin functions. What might bring us back to square one. The class user might still have trouble to understand and memorize the right way to get at begin.
Yes, the whole area of dispatching and customization of generic functions is nasty in C++. I've known it's problematic for a long time, but had a hard time expressing how bad the problem is in a way that would communicate to someone who doesn't do heavy generic programming day in and day out.
I agree that something needs to be done. I just really want to be convinced that the proposed changes to boost::begin are the right solution Regards Thomas -- Thomas Witt witt@acm.org

Thomas Witt <witt@acm.org> writes:
Yes, the whole area of dispatching and customization of generic functions is nasty in C++. I've known it's problematic for a long time, but had a hard time expressing how bad the problem is in a way that would communicate to someone who doesn't do heavy generic programming day in and day out.
I agree that something needs to be done. I just really want to be convinced that the proposed changes to boost::begin are the right solution
Without going into the description of the language problems too deeply, here's a prototype of what Doug and I came up with. So far it only compiles for me with g++. Things to notice: - ADL is limited to *one* name, lookup_implementation() - ADL is decoupled from the actual types being passed to algorithms via their category tags - You can write generalized lookup_implementation() functions like the one shown, that choose some rules by which to dispatch all algorithms - You can write specific lookup_implementation functions to set different rules for particular algorithms. -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams <dave@boost-consulting.com> writes:
Things to notice:
- ADL is limited to *one* name, lookup_implementation()
- ADL is decoupled from the actual types being passed to algorithms via their category tags
- You can write generalized lookup_implementation() functions like the one shown, that choose some rules by which to dispatch all algorithms
- You can write specific lookup_implementation functions to set different rules for particular algorithms.
I should point out that the primary advantage of what we've done in the posted code is *not* limiting semantic uncertainty and name reservation due to ADL (though I happen to like that feature). The primary advantage is pluggable handling for new algorithm implementation strategies and iterator/range concepts. Note that where algorithms are concerned, the old adage that you should "implement your class and the function customizations for it in the same namespace" just doesn't apply. If Joe implements a deque-like segmented structure and Mary implements a circular queue (which is also segmented and subject to the same algorithm optimizations), should each of them supply a copy of a hierarchical copy, unique, transform, etc. implementation? Clearly not. *That* is what defeats normal overloading as a viable technique for customization. The namespace containing the right algorithm implementation is not neccessarily an "associated namespace" of these ranges or iterators -- the actual arguments passed to an algorithm -- so it won't be searched by ADL. Instead one must do dispatching via category tags associated with the data structures, and to preserve a sane interface for callers of the algorithms, that dispatching has to be hidden. This is the same idea as used by most standard library implementations, except: * We can add new argument concepts and implementation strategies into the system non-intrusively * The algorithm's exact return type may not be deducible without knowing the chosen implementation strategy. * The implementation strategy to use may depend on a _combination_ of the concepts modeled by the algorithm's arguments, instead of just one. We don't want to end up with combinatoric numbers of implementation overloads for each algorithm. At worst we've limited the problem to needing a combinatoric number of simple lookup_implementation overloads for each implementation strategy. In general there will be far more algorithm implementations than strategies, so this is a big win. The fact that we can't handle cases like this without a level of dispatching machinery in C++03 indicates one of those problems I was referring to. -- Dave Abrahams Boost Consulting www.boost-consulting.com

"Thomas Witt" <witt@acm.org> wrote in message news:d1vv3c$rof$1@sea.gmane.org... | David Abrahams wrote: | I can see the problem. What I am unconvinced of is that the proposed | solution is the correct solution to the overall problem. If this were | some internal boost component meant to make boost library writing easier | I would be perfectly happy, but we are talking about a library that | deals with an important concept (ranges). | | I am particularly concerned with the scalability of the solution. | How many ADL wrappers do we need to solve the problem? one for each function. | Will they become | a legacy at some point? who knows? | > | > Do try to remember that although the "artificially uglified name" will | > appear in the interfaces of all classes that model the range concept, | > there will probably be even more uses of the "real name" in user code. | | Agreed. On the other hand the usibility of these classes now takes a hit | when Boost.Range isn't present. The class author can work around this by | providing begin and range_begin functions. What might bring us back to | square one. The class user might still have trouble to understand and | memorize the right way to get at begin. I don't think I get this. | > | > Yes, the whole area of dispatching and customization of generic | > functions is nasty in C++. I've known it's problematic for a long | > time, but had a hard time expressing how bad the problem is in a way | > that would communicate to someone who doesn't do heavy generic | > programming day in and day out. | | I agree that something needs to be done. I just really want to be | convinced that the proposed changes to boost::begin are the right solution What do you suggest then. IMO the ADL problem is fairly simple and can be adequately solved by the current proposed resolution. A more "generic" mechanism when dealing with algorithms might be ok, but I don't see why it is relevant in this context. -Thorsten

"Thorsten Ottosen" <nesotto@cs.auc.dk> writes:
IMO the ADL problem is fairly simple and can be adequately solved by the current proposed resolution.
What do you mean by "the ADL problem?" There are lots of problems related to ADL; which one(s) are you referring to? -- Dave Abrahams Boost Consulting www.boost-consulting.com

"Thorsten Ottosen" <nesotto@cs.auc.dk> writes:
Dear all,
I'm going to change the ADL lookup hook of range functions.
instead of the irritating
void foo() { using namespace boost; begin(r); }
we simply now say
void foo() { boost::begin(r); }
and get full ADL lookup. This changes the extension protocol to overiding these three functions:
range_adl_begin() range_adl_end() range_adl_size()
Any comments before I commit?
[I hope we've dropped "adl_" from the name by now ;-) ] A scheme like this one has at least one advantage that we should be sure to take advantage of: it allows us to reduce the number of overloads required by conforming range classes. I've been working on a similar scheme for an generalized Range concept ("Sequence" -- I know it's used by the standard but how many suitable concept names remain?), so here's some of my code: ---- namespace boost { namespace sequence { // Do not use directly, except to specialize. // Default implementation works for ordinary STL sequences. template <class Sequence> struct traits { typedef typename Sequence::iterator begin_iterator; typedef typename Sequence::iterator end_iterator; typedef typename Sequence::const_iterator begin_const_iterator; typedef typename Sequence::const_iterator end_const_iterator; }; template <class Sequence> struct begin_iterator { typedef typename sequence::traits< Sequence >::begin_iterator type; }; // Note: this partial specialization is important! template <class Sequence> struct begin_iterator<Sequence const> { typedef typename sequence::traits< Sequence >::begin_const_iterator type; }; template <class Sequence> typename begin_const_iterator<Sequence>::type begin(Sequence const& s) { return sequence_begin(s); } template <class Sequence> typename begin_iterator<Sequence>::type begin(Sequence& s) { return sequence_begin(s); } }} namespace my { struct range; // Note: no overload for Range const&. This is never // called directly, so it always receives an lvalue. template <class Range> typename begin_iterator<Sequence>::type sequence_begin(Range& s) { return ... // whatever } ... } -- Dave Abrahams Boost Consulting www.boost-consulting.com

"David Abrahams" <dave@boost-consulting.com> wrote in message news:uhditw87f.fsf@boost-consulting.com... | "Thorsten Ottosen" <nesotto@cs.auc.dk> writes: | > range_adl_begin() | > range_adl_end() | > range_adl_size() | > | > Any comments before I commit? | | [I hope we've dropped "adl_" from the name by now ;-) ] yes. | A scheme like this one has at least one advantage that we should be | sure to take advantage of: it allows us to reduce the number of | overloads required by conforming range classes. | // Note: this partial specialization is important! | template <class Sequence> | struct begin_iterator<Sequence const> | { | typedef typename sequence::traits< | Sequence | >::begin_const_iterator type; | }; | // Note: no overload for Range const&. This is never | // called directly, so it always receives an lvalue. | template <class Range> | typename begin_iterator<Sequence>::type | sequence_begin(Range& s) | { | return ... // whatever | } This is a good observation. You can already do that as template< class R > inline typename range_result_iterator<R>::type range_begin( R& r ); ^^^^^^^^^^^^^^^^^^^^^^^^ I don't use partial specialization, but rather eval_if< is_const<R>, const_iterator, iterator>::type, but I guess that not thaht important. I will update the docs to reflect this easier way to adopt a new type. And I will consider removing half of the actual function implementations. -Thorsten
participants (6)
-
David Abrahams
-
Eric Niebler
-
Jonathan Turkanis
-
Pavol Droba
-
Thomas Witt
-
Thorsten Ottosen