[Range] breaking update pending

Dear All, I have been trimming boost.range to incorporate the changes we have been discussing some time ago. These changes will break many uses of the library. Inside boost this will affect Boost.foreach Boost.string algo Boost.iostreams (*) (*) I don't this will break The list of major changes is the follwing: 1. ADL hooks renamed boost_range_begin -> range_begin, boost_range_end -> range_end 2. ADL hook boost_range_size removed; boost::size(rng) now requires RandomAccessIterators to guarantee O(1) complexity. 3. range_result_iterator renamed range_iterator and range_iterator renamed mutable_iterator. The correct way to spell const_iterator<T> is now iterator<const T>. 4. intrinsic string support removed. instead a header as_literal.hpp is previded with a small utility for use in string algorithms. I expect that (3) and (4) is where the most work lies. If nobody has anything to add, will add the new version to the cvs within a few days. -Thorsten

Thorsten Ottosen wrote:
Dear All,
I have been trimming boost.range to incorporate the changes we have been discussing some time ago.
These changes will break many uses of the library. Inside boost this will affect
Boost.foreach Boost.string algo Boost.iostreams (*)
(*) I don't this will break
The list of major changes is the follwing:
1. ADL hooks renamed boost_range_begin -> range_begin, boost_range_end -> range_end
Why was such short name accepted?? Even 'const_begin' that calls unqualified 'begin' breaks down Boost.MPL!!
2. ADL hook boost_range_size removed; boost::size(rng) now requires RandomAccessIterators to guarantee O(1) complexity.
3. range_result_iterator renamed range_iterator and range_iterator renamed mutable_iterator. The correct way to spell const_iterator<T> is now iterator<const T>.
range_result_iterator is alive? If so, it's nice. :-)
4. intrinsic string support removed. instead a header as_literal.hpp is previded with a small utility for use in string algorithms.
FWIW, I experienced "Range adaptor syntax" could make it prettier. Regards, MB p-stade.sourceforge.net

MB <mb2act@yahoo.co.jp> writes:
Thorsten Ottosen wrote:
Dear All,
I have been trimming boost.range to incorporate the changes we have been discussing some time ago.
These changes will break many uses of the library. Inside boost this will affect
Boost.foreach Boost.string algo Boost.iostreams (*)
(*) I don't this will break
The list of major changes is the follwing:
1. ADL hooks renamed boost_range_begin -> range_begin, boost_range_end -> range_end
Why was such short name accepted?? Even 'const_begin' that calls unqualified 'begin' breaks down Boost.MPL!!
How so? What happens? Got a small reproducible case?
2. ADL hook boost_range_size removed; boost::size(rng) now requires RandomAccessIterators to guarantee O(1) complexity.
3. range_result_iterator renamed range_iterator and range_iterator renamed mutable_iterator. The correct way to spell const_iterator<T> is now iterator<const T>.
range_result_iterator is alive? If so, it's nice. :-)
4. intrinsic string support removed. instead a header as_literal.hpp is previded with a small utility for use in string algorithms.
FWIW, I experienced "Range adaptor syntax" could make it prettier.
Thorsten, did you consider providing a backward compatibility layer for the transition? -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
MB <mb2act@yahoo.co.jp> writes:
Thorsten Ottosen wrote:
Dear All,
I have been trimming boost.range to incorporate the changes we have been discussing some time ago.
These changes will break many uses of the library. Inside boost this will affect
Boost.foreach Boost.string algo Boost.iostreams (*)
(*) I don't this will break
The list of major changes is the follwing:
1. ADL hooks renamed boost_range_begin -> range_begin, boost_range_end -> range_end
Why was such short name accepted?? Even 'const_begin' that calls unqualified 'begin' breaks down Boost.MPL!!
How so? What happens? Got a small reproducible case?
See: http://lists.boost.org/boost-users/2006/01/16513.php void trouble() { typedef dummy< ::boost::mpl::vector< int > > vt ; typedef ::std::vector< const vt* > ct ; boost::const_begin( ct() ) ; } (though I don't know whether or not this GCC behavior is conforming.) Regards, MB

MB writes:
David Abrahams wrote:
MB <mb2act@yahoo.co.jp> writes:
Even 'const_begin' that calls unqualified 'begin' breaks down Boost.MPL!!
How so? What happens? Got a small reproducible case?
See: http://lists.boost.org/boost-users/2006/01/16513.php
void trouble() { typedef dummy< ::boost::mpl::vector< int > > vt ; typedef ::std::vector< const vt* > ct ;
boost::const_begin( ct() ) ; }
This is a known issue, see http://thread.gmane.org/gmane.comp.lib.boost.devel/115368. I'll try to fix this for 1.34.
(though I don't know whether or not this GCC behavior is conforming.)
Unfortunately, until http://www.open-std.org/jtc1/sc22/wg21/prot/14882fdis/n1729.html#218 is resolved favorably for us, it is. -- Aleksey Gurtovoy MetaCommunications Engineering

Aleksey Gurtovoy wrote:
MB writes:
David Abrahams wrote:
MB <mb2act@yahoo.co.jp> writes:
Even 'const_begin' that calls unqualified 'begin' breaks down Boost.MPL!!
How so? What happens? Got a small reproducible case?
See: http://lists.boost.org/boost-users/2006/01/16513.php
void trouble() { typedef dummy< ::boost::mpl::vector< int > > vt ; typedef ::std::vector< const vt* > ct ;
boost::const_begin( ct() ) ; }
Just to clarify, this was a bug in the current version of boost.range. In the new version , no call to begin(), end(), size(), and empty() is unqualified. -Thorsten

MB <mb2act@yahoo.co.jp> writes:
Thorsten Ottosen wrote:
Dear All,
I have been trimming boost.range to incorporate the changes we have been discussing some time ago.
These changes will break many uses of the library. Inside boost
David Abrahams wrote: this will affect
Boost.foreach Boost.string algo Boost.iostreams (*)
(*) I don't this will break
The list of major changes is the follwing:
1. ADL hooks renamed boost_range_begin -> range_begin, boost_range_end -> range_end
Why was such short name accepted?? Even 'const_begin' that calls unqualified 'begin' breaks down Boost.MPL!!
This was a bug. In the new version there is no unqualified call to begin(), end(), size() and empty().
How so? What happens? Got a small reproducible case?
GCC ADL looks up a class named "end" too. Old story.
2. ADL hook boost_range_size removed; boost::size(rng) now requires RandomAccessIterators to guarantee O(1) complexity.
3. range_result_iterator renamed range_iterator and range_iterator renamed mutable_iterator. The correct way to spell const_iterator<T> is now iterator<const T>.
range_result_iterator is alive? If so, it's nice. :-)
It's dead, sort of, or that was the intention. It's behavior is now modelled by range_iterator.
4. intrinsic string support removed. instead a header as_literal.hpp is previded with a small utility for use in string algorithms.
FWIW, I experienced "Range adaptor syntax" could make it prettier.
Thorsten, did you consider providing a backward compatibility layer for the transition?
Yes, but I don't have a good way to do this. putting the old version in, say, boost/range/v1 was rejected because of ODR problems. Do you have any ideas? -Thorsten

Thorsten Ottosen <tottosen@dezide.com> writes:
David Abrahams wrote:
MB <mb2act@yahoo.co.jp> writes:
Thorsten Ottosen wrote:
Dear All,
I have been trimming boost.range to incorporate the changes we have been discussing some time ago.
These changes will break many uses of the library. Inside boost this will affect
Boost.foreach Boost.string algo Boost.iostreams (*)
(*) I don't this will break
The list of major changes is the follwing:
1. ADL hooks renamed boost_range_begin -> range_begin, boost_range_end -> range_end
Why was such short name accepted?? Even 'const_begin' that calls unqualified 'begin' breaks down Boost.MPL!!
This was a bug. In the new version there is no unqualified call to begin(), end(), size() and empty().
How so? What happens? Got a small reproducible case?
GCC ADL looks up a class named "end" too. Old story.
You need to read more carefully. A change from boost_range_end to range_end would not cause any interaction with the name "end."
Thorsten, did you consider providing a backward compatibility layer for the transition?
Yes, but I don't have a good way to do this. putting the old version in, say, boost/range/v1 was rejected because of ODR problems.
Do you have any ideas?
I was thinking of a system that would (as much as possible) keep old code working, without substituting different definitions. For example, you could keep boost_range_begin and dispatch to range_begin. I'm not sure of the details, or how well it could work, but I thought it was worth considering. When thinking about it, keep in mind that we can detect the presence of an overloaded function that is supposed to be found via ADL. I don't know if that helps, but it might. Cheers, Dave -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
Thorsten Ottosen <tottosen@dezide.com> writes:
Why was such short name accepted?? Even 'const_begin' that calls unqualified 'begin' breaks down Boost.MPL!!
This was a bug. In the new version there is no unqualified call to begin(), end(), size() and empty().
How so? What happens? Got a small reproducible case?
GCC ADL looks up a class named "end" too. Old story.
You need to read more carefully. A change from boost_range_end to range_end would not cause any interaction with the name "end."
no, but const_begin() called begin() unqualified. similarly for const_end(). -Thorsten

Thorsten Ottosen <tottosen@dezide.com> writes:
David Abrahams wrote:
Thorsten Ottosen <tottosen@dezide.com> writes:
Why was such short name accepted?? Even 'const_begin' that calls unqualified 'begin' breaks down Boost.MPL!!
This was a bug. In the new version there is no unqualified call to begin(), end(), size() and empty().
How so? What happens? Got a small reproducible case?
GCC ADL looks up a class named "end" too. Old story.
You need to read more carefully. A change from boost_range_end to range_end would not cause any interaction with the name "end."
no, but const_begin() called begin() unqualified. similarly for const_end().
The claim was that a name change caused breakage. Note that my questions, "How so?...", etc. were posed to the OP of that claim, not to your assertion that there were incorrect unqualified calls in the library. Your response to my question does not address it. -- Dave Abrahams Boost Consulting www.boost-consulting.com

Thorsten Ottosen wrote:
David Abrahams wrote:
MB <mb2act@yahoo.co.jp> writes:
Thorsten Ottosen wrote:
Dear All,
I have been trimming boost.range to incorporate the changes we have been discussing some time ago.
These changes will break many uses of the library. Inside boost this will affect
Boost.foreach Boost.string algo Boost.iostreams (*)
(*) I don't this will break
The list of major changes is the follwing:
1. ADL hooks renamed boost_range_begin -> range_begin, boost_range_end -> range_end
Why was such short name accepted?? Even 'const_begin' that calls unqualified 'begin' breaks down Boost.MPL!!
This was a bug. In the new version there is no unqualified call to begin(), end(), size() and empty().
How so? What happens? Got a small reproducible case?
GCC ADL looks up a class named "end" too. Old story.
2. ADL hook boost_range_size removed; boost::size(rng) now requires RandomAccessIterators to guarantee O(1) complexity.
3. range_result_iterator renamed range_iterator and range_iterator renamed mutable_iterator. The correct way to spell const_iterator<T> is now iterator<const T>.
range_result_iterator is alive? If so, it's nice. :-)
It's dead, sort of, or that was the intention. It's behavior is now modelled by range_iterator.
You mean all the customization way is deprecated?
4. intrinsic string support removed. instead a header as_literal.hpp is previded with a small utility for use in string algorithms.
FWIW, I experienced "Range adaptor syntax" could make it prettier.
Thorsten, did you consider providing a backward compatibility layer for the transition?
Yes, but I don't have a good way to do this. putting the old version in, say, boost/range/v1 was rejected because of ODR problems.
Do you have any ideas?
Ideally, Boost.Range v2 is needed, which has all the range-style algorithms, all the range adaptors, class-template-based customization using tag-dispatching, supports also ADL customization, can play with Boost.IOStreams, and throws away legacy compilers! :-) range::copy(file_rng|range::filtered(is_even()), out); result_of<range::begin_function(int[10])>::type first = range::begin(array); I already find Boost.Sequence. :-) Regards, MB

MB wrote:
Thorsten Ottosen wrote:
range_result_iterator is alive? If so, it's nice. :-)
It's dead, sort of, or that was the intention. It's behavior is now modelled by range_iterator.
You mean all the customization way is deprecated?
no, it has been renamed to range_iterator and the former range_iterator is now called mutable_iterator.
Ideally, Boost.Range v2 is needed, which has all the range-style algorithms, all the range adaptors, class-template-based customization using tag-dispatching, supports also ADL customization, can play with Boost.IOStreams, and throws away legacy compilers! :-)
range::copy(file_rng|range::filtered(is_even()), out);
Working on this an nearly done. Hopefully a short mini-review can be made so to put it in this release. The above would be wriiten (I think) namspace br = boost::ranges; br::copy( a_rng | br::filtered( is_even() ), out ); -Thorsten

Thorsten Ottosen wrote:
MB wrote:
Thorsten Ottosen wrote:
range_result_iterator is alive? If so, it's nice. :-)
It's dead, sort of, or that was the intention. It's behavior is now modelled by range_iterator.
You mean all the customization way is deprecated?
no, it has been renamed to range_iterator and the former range_iterator is now called mutable_iterator.
But, range_iterator has already been specialized by range implementators.
Ideally, Boost.Range v2 is needed, which has all the range-style algorithms, all the range adaptors, class-template-based customization using tag-dispatching, supports also ADL customization, can play with Boost.IOStreams, and throws away legacy compilers! :-)
range::copy(file_rng|range::filtered(is_even()), out);
Working on this an nearly done. Hopefully a short mini-review can be made so to put it in this release. The above would be wriiten (I think)
namspace br = boost::ranges;
br::copy( a_rng | br::filtered( is_even() ), out );
Nicely! Range revolution has begun! :-) I wonder why the current version that works enough must be changed with pains, when you are making the new striking range library. Regards, MB

MB wrote:
Thorsten Ottosen wrote:
no, it has been renamed to range_iterator and the former range_iterator is now called mutable_iterator.
But, range_iterator has already been specialized by range implementators.
right, that is why it is a breaking update.
Working on this an nearly done. Hopefully a short mini-review can be made so to put it in this release. The above would be wriiten (I think)
namspace br = boost::ranges;
br::copy( a_rng | br::filtered( is_even() ), out );
Nicely! Range revolution has begun! :-)
I wonder why the current version that works enough must be changed with pains, when you are making the new striking range library.
well, it is always unfortunate when the design is not optimal in the first version of a library, but I guess that is just life. something along the follwing might work: find . -name "*.cpp" | xargs sed -e --in-place "s/range_iterator</mutable_iterator</" find . -name "*.cpp" | xargs sed -e --in-place "s/range_result_iterator</range_iterator</" etc -Thorsten BTW: please use your real name when posting

Thorsten Ottosen wrote:
MB wrote:
Thorsten Ottosen wrote:
no, it has been renamed to range_iterator and the former range_iterator is now called mutable_iterator.
But, range_iterator has already been specialized by range implementators.
right, that is why it is a breaking update.
It is possible to hook 'range_iterator' from user specializations? template< class T > struct range_iterator<const T> : range_const_iterator<T> { }; Fortunately, Boost.Range documentation doesn't say 'range_iterator< const Foo::Pair<T> >' must be specialized. User 'range_iterator' specializations still work. From the point of client view, I have never called 'range_iterator', while I called 'range_result_iterator' 159 times. As for 'range_result_iterator', there is no reason why it should be removed. If it were removed, I would add just: // legacy name of range_iterator template< class Range > struct range_result_iterator : range_iterator<Range> { }; As for 'boost_range_begin', the change is rather dangerous. Please do google "range_end". Thus, no problem breaks except for 'char*', doesn't it?
BTW: please use your real name when posting Formal rule? If so, this should be the final post...
Regards, MB

MB wrote:
Thorsten Ottosen wrote:
MB wrote:
Thorsten Ottosen wrote:
no, it has been renamed to range_iterator and the former range_iterator is now called mutable_iterator.
But, range_iterator has already been specialized by range implementators.
right, that is why it is a breaking update.
It is possible to hook 'range_iterator' from user specializations?
template< class T > struct range_iterator<const T> : range_const_iterator<T> { };
Fortunately, Boost.Range documentation doesn't say 'range_iterator< const Foo::Pair<T> >' must be specialized. User 'range_iterator' specializations still work.
I'm not sure what you're saying here. Could you explain?
From the point of client view, I have never called 'range_iterator', while I called 'range_result_iterator' 159 times.
As for 'range_result_iterator', there is no reason why it should be removed. If it were removed, I would add just:
// legacy name of range_iterator template< class Range > struct range_result_iterator : range_iterator<Range> { };
right, this could be done to provide some form of backwards compatibility.
As for 'boost_range_begin', the change is rather dangerous. Please do google "range_end".
I don't get a lot of hits that uses range_end as a function.
Thus, no problem breaks except for 'char*', doesn't it?
well, - char[N] returns the same as T[N] - range_iterator is named range_mutable_iterator.
BTW: please use your real name when posting
Formal rule? If so, this should be the final post...
I don't think so, but I like to know whom I'm speaking with. -Thorsten

Thorsten Ottosen wrote:
It is possible to hook 'range_iterator' from user specializations?
template< class T > struct range_iterator<const T> : range_const_iterator<T> { };
Fortunately, Boost.Range documentation doesn't say 'range_iterator< const Foo::Pair<T> >' must be specialized. User 'range_iterator' specializations still work.
I'm not sure what you're saying here. Could you explain?
Sorry, please forget this code. I was confused or drunken. I had ever specialized 'range_iterator<const MyX>' to return "mutable" iterator, before I removed it some time ago. I see "range_iterator -> range_mutable_iterator" change doesn't break any current user customizations. Am I right?
From the point of client view, I have never called 'range_iterator', while I called 'range_result_iterator' 159 times.
As for 'range_result_iterator', there is no reason why it should be removed. If it were removed, I would add just:
// legacy name of range_iterator template< class Range > struct range_result_iterator : range_iterator<Range> { };
right, this could be done to provide some form of backwards compatibility.
As for 'boost_range_begin', the change is rather dangerous. Please do google "range_end".
I don't get a lot of hits that uses range_end as a function.
If 'range_end' is a function, it is rather lucky. Once "int range_end;" is defined, I think there is no workaround. I read the long discussion why 'boost_range_begin' was born. Did I overlook another discussion about the birth of 'range_begin'?
Thus, no problem breaks except for 'char*', doesn't it?
well,
- char[N] returns the same as T[N] - range_iterator is named range_mutable_iterator.
BTW: please use your real name when posting
Formal rule? If so, this should be the final post...
I don't think so, but I like to know whom I'm speaking with.
Nice to meet you and the world. Regards, Shunsuke Sogame

MB wrote:
Thorsten Ottosen wrote:
It is possible to hook 'range_iterator' from user specializations?
template< class T > struct range_iterator<const T> : range_const_iterator<T> { };
Fortunately, Boost.Range documentation doesn't say 'range_iterator< const Foo::Pair<T> >' must be specialized. User 'range_iterator' specializations still work.
I'm not sure what you're saying here. Could you explain?
Sorry, please forget this code. I was confused or drunken. I had ever specialized 'range_iterator<const MyX>' to return "mutable" iterator, before I removed it some time ago.
I see "range_iterator -> range_mutable_iterator" change doesn't break any current user customizations. Am I right?
well, it could break any specialization of range_iterator. I'll see if I can avoid it, but I won't promise that I can.
As for 'boost_range_begin', the change is rather dangerous. Please do google "range_end".
I don't get a lot of hits that uses range_end as a function.
If 'range_end' is a function, it is rather lucky. Once "int range_end;" is defined, I think there is no workaround.
right, if you have a namespace static variable called range_end, then you can't define a function of the same name in that namespace. But what are the chances of that? remember there is no problem with { // some scope int range_end; boost::end(rng); }
I read the long discussion why 'boost_range_begin' was born. Did I overlook another discussion about the birth of 'range_begin'?
maybe, there was some discussion about the problems of tying a concept to a library name. the range concept exists out-side of boost and any type T conforms to it if it implements range_begin(T&) and range_end(T&) etc.
BTW: please use your real name when posting
Formal rule? If so, this should be the final post...
I don't think so, but I like to know whom I'm speaking with.
Nice to meet you and the world.
Regards, Shunsuke Sogame
Nice to meet you too, Shunsuke. And welcome to boost :-) best regards Thorsten

Thorsten Ottosen wrote:
MB wrote:
Thorsten Ottosen wrote:
It is possible to hook 'range_iterator' from user specializations?
template< class T > struct range_iterator<const T> : range_const_iterator<T> { };
Fortunately, Boost.Range documentation doesn't say 'range_iterator< const Foo::Pair<T> >' must be specialized. User 'range_iterator' specializations still work.
I'm not sure what you're saying here. Could you explain?
Sorry, please forget this code. I was confused or drunken. I had ever specialized 'range_iterator<const MyX>' to return "mutable" iterator, before I removed it some time ago.
I see "range_iterator -> range_mutable_iterator" change doesn't break any current user customizations. Am I right?
well, it could break any specialization of range_iterator.
I'll see if I can avoid it, but I won't promise that I can.
As for 'boost_range_begin', the change is rather dangerous. Please do google "range_end".
I don't get a lot of hits that uses range_end as a function.
If 'range_end' is a function, it is rather lucky. Once "int range_end;" is defined, I think there is no workaround.
right, if you have a namespace static variable called range_end, then you can't define a function of the same name in that namespace. But what are the chances of that? remember there is no problem with
{ // some scope int range_end; boost::end(rng); }
I already define a function as a functor to support 'result_of': const range_end_function& range_end = ...;
I read the long discussion why 'boost_range_begin' was born. Did I overlook another discussion about the birth of 'range_begin'?
maybe, there was some discussion about the problems of tying a concept to a library name. the range concept exists out-side of boost and any type T conforms to it if it implements range_begin(T&) and range_end(T&) etc.
Where the range concept belongs? "Global"? I'm maybe an worrier, struggling with ADL invasions. But short names conflict. Regards, Shunsuke Sogame

Shunsuke Sogame wrote:
Thorsten Ottosen wrote:
I read the long discussion why 'boost_range_begin' was born. Did I overlook another discussion about the birth of 'range_begin'?
maybe, there was some discussion about the problems of tying a concept to a library name. the range concept exists out-side of boost and any type T conforms to it if it implements range_begin(T&) and range_end(T&) etc.
Where the range concept belongs? "Global"?
yep, in the sense that customization points are not tied to a particular library.
I'm maybe an worrier, struggling with ADL invasions. But short names conflict.
true, that is why begin()/end() were abadened. -Thorsten

Thorsten Ottosen wrote:
Shunsuke Sogame wrote:
Thorsten Ottosen wrote:
I read the long discussion why 'boost_range_begin' was born. Did I overlook another discussion about the birth of 'range_begin'?
maybe, there was some discussion about the problems of tying a concept to a library name. the range concept exists out-side of boost and any type T conforms to it if it implements range_begin(T&) and range_end(T&) etc.
Where the range concept belongs? "Global"?
yep, in the sense that customization points are not tied to a particular library.
I'm maybe an worrier, struggling with ADL invasions. But short names conflict.
true, that is why begin()/end() were abadened.
I maybe failed persuasion. :-) But "mathematically", I believe ADL customization must be full name that emulates namespace. Well, I request tag-dispatching customization using class template partial specialization to next Boost.Ranges. Now that I really need tag-dispatching, I'm against ADL customization. I recall you said something like that. You were right. My current ATL/WTL CString range implementation code is horror. Will you add it to TODO list of next Boost.Ranges! Regards, Shunsuke Sogame

Shunsuke Sogame wrote:
Thorsten Ottosen wrote:
I'm maybe an worrier, struggling with ADL invasions. But short names conflict.
true, that is why begin()/end() were abadened.
I maybe failed persuasion. :-) But "mathematically", I believe ADL customization must be full name that emulates namespace.
Well, I request tag-dispatching customization using class template partial specialization to next Boost.Ranges. Now that I really need tag-dispatching, I'm against ADL customization. I recall you said something like that. You were right. My current ATL/WTL CString range implementation code is horror. Will you add it to TODO list of next Boost.Ranges!
Can you elaborate on what exactly you would like to see? -Thorsten

Thorsten Ottosen wrote:
Shunsuke Sogame wrote:
Thorsten Ottosen wrote:
I'm maybe an worrier, struggling with ADL invasions. But short names conflict.
true, that is why begin()/end() were abadened.
I maybe failed persuasion. :-) But "mathematically", I believe ADL customization must be full name that emulates namespace.
Well, I request tag-dispatching customization using class template partial specialization to next Boost.Ranges. Now that I really need tag-dispatching, I'm against ADL customization. I recall you said something like that. You were right. My current ATL/WTL CString range implementation code is horror. Will you add it to TODO list of next Boost.Ranges!
Can you elaborate on what exactly you would like to see?
For instance, ATL/WTL have four strings. They have the same interfaces. I want to share the implementation. You may say "Forward them to one implementation function", but: template< class BaseT, class TraitsT > inline typename boost::range_iterator< CStringT<BaseT, TraitsT> >::type boost_range_begin(CStringT<BaseT, TraitsT>& str) { return str.GetBuffer(0); } template< class BaseT, class TraitsT > inline typename boost::range_const_iterator< CStringT<BaseT, TraitsT> >::type boost_range_begin(const CStringT<BaseT, TraitsT>& str) { return str.GetString(); } Even forwarding is horror. Moreover, the different version of ATL has different template parameters. I found Boost.Sequence draft by Mr.Abrahams one week ago: http://boost-consulting.com/projects/mtl4/libs/sequence/doc/html/ http://boost-consulting.com/projects/mtl4/libs/sequence/doc/html/intrinsics.... #include <vector> struct vector_tag { }; namespace poost { namespace customization { template< class ValueT > struct tag< std::vector<ValueT> > { typedef ::vector_tag type; }; template< class VectorT > struct operations< VectorT, ::vector_tag > { struct begin { typedef typename VectorT::iterator type; type operator()(VectorT& vec) const { return vec.begin(); } }; struct end { typedef typename VectorT::iterator type; type operator()(VectorT& vec) const { return vec.end(); } }; }; } } // namespace poost::customization It is impressive to me. Regards, Shunsuke Sogame

Shunsuke Sogame wrote:
Thorsten Ottosen wrote:
Shunsuke Sogame wrote:
Thorsten Ottosen wrote:
I'm maybe an worrier, struggling with ADL invasions. But short names conflict.
true, that is why begin()/end() were abadened.
I maybe failed persuasion. :-) But "mathematically", I believe ADL customization must be full name that emulates namespace.
Well, I request tag-dispatching customization using class template partial specialization to next Boost.Ranges. Now that I really need tag-dispatching, I'm against ADL customization. I recall you said something like that. You were right. My current ATL/WTL CString range implementation code is horror. Will you add it to TODO list of next Boost.Ranges!
Can you elaborate on what exactly you would like to see?
For instance, ATL/WTL have four strings. They have the same interfaces. I want to share the implementation. You may say "Forward them to one implementation function", but:
template< class BaseT, class TraitsT > inline typename boost::range_iterator< CStringT<BaseT, TraitsT> >::type boost_range_begin(CStringT<BaseT, TraitsT>& str) { return str.GetBuffer(0); }
template< class BaseT, class TraitsT > inline typename boost::range_const_iterator< CStringT<BaseT, TraitsT> >::type boost_range_begin(const CStringT<BaseT, TraitsT>& str) { return str.GetString(); }
Even forwarding is horror.
right. not much to do about that. As Peter Dimov and others argued, you can easy forwarding, but the problem is that we still need free-standing boost::begin() and boost::end() on their own.
Moreover, the different version of ATL has different template parameters.
if ATL actually uses a namespace, you could add a unconstrained overload of range_begin/range_end. -Thorsten

Thorsten Ottosen wrote:
Shunsuke Sogame wrote:
Thorsten Ottosen wrote:
Shunsuke Sogame wrote:
Thorsten Ottosen wrote:
I'm maybe an worrier, struggling with ADL invasions. But short names conflict.
true, that is why begin()/end() were abadened.
I maybe failed persuasion. :-) But "mathematically", I believe ADL customization must be full name that emulates namespace.
Well, I request tag-dispatching customization using class template partial specialization to next Boost.Ranges. Now that I really need tag-dispatching, I'm against ADL customization. I recall you said something like that. You were right. My current ATL/WTL CString range implementation code is horror. Will you add it to TODO list of next Boost.Ranges!
Can you elaborate on what exactly you would like to see?
For instance, ATL/WTL have four strings. They have the same interfaces. I want to share the implementation. You may say "Forward them to one implementation function", but:
template< class BaseT, class TraitsT > inline typename boost::range_iterator< CStringT<BaseT, TraitsT> >::type boost_range_begin(CStringT<BaseT, TraitsT>& str) { return str.GetBuffer(0); }
template< class BaseT, class TraitsT > inline typename boost::range_const_iterator< CStringT<BaseT, TraitsT> >::type boost_range_begin(const CStringT<BaseT, TraitsT>& str) { return str.GetString(); }
Even forwarding is horror.
right. not much to do about that. As Peter Dimov and others argued, you can easy forwarding, but the problem is that we still need free-standing boost::begin() and boost::end() on their own.
Moreover, the different version of ATL has different template parameters.
if ATL actually uses a namespace, you could add a unconstrained overload of range_begin/range_end.
ATL/WTL has also many containers that can conform to Boost.Range. I request tag-dispatching! -- Regards, Shunsuke Sogame

Shunsuke Sogame wrote:
Thorsten Ottosen wrote:
Can you elaborate on what exactly you would like to see?
Moreover, the different version of ATL has different template parameters.
if ATL actually uses a namespace, you could add a unconstrained overload of range_begin/range_end.
ATL/WTL has also many containers that can conform to Boost.Range. I request tag-dispatching!
How will a different mechanism save you from provding specializations of alle the types you want to support? -Thorsten

Thorsten Ottosen wrote:
Shunsuke Sogame wrote:
Thorsten Ottosen wrote:
Can you elaborate on what exactly you would like to see?
Moreover, the different version of ATL has different template parameters.
if ATL actually uses a namespace, you could add a unconstrained overload of range_begin/range_end.
ATL/WTL has also many containers that can conform to Boost.Range. I request tag-dispatching!
How will a different mechanism save you from provding specializations of alle the types you want to support?
I tried to write Boost.Range implementation of ATL/WTL collections. But I gave up. There are 13 classes. They form a simple hierarchy, but we cannot take advantage of it. Partial class template specialization ignores base/derived relationship. And "primary" range_detail::boost_range_begin(C&) eats all the derived classes. Thus, I have to write 13 implementations. Now I see ADL customization way is blob. Type itself has another job, that is, implementation selector. Left the job to tag... For example, std::pair range implementation could be simplified to something like: namespace customization { namespace std_pair_detail { struct tag { }; } // namespace std_pair_detail template< class T > struct tag< std::pair<T, T> > : boost::mpl::identity<std_pair_detail::tag> { }; template< class PairT > struct metafunctions<PairT, std_pair_detail::tag> { typedef typename PairT::first_type iterator; typedef iterator const_iterator; }; template< > struct functions<std_pair_detail::tag> { template< class PairT > typename boost::range_iterator<PairT>::type begin(PairT& p) { return p.first; } template< class PairT > typename boost::range_iterator<PairT>::type end(PairT& p) { return p.second; } }; } Now 'PairT' is almost concept. A type derived from std::pair<> specializes only tag<>. Moreover, 'const' overloads disappear. (though such overloads also are possible.) Of course, default implementation can call 'boost_range_begin'. Compatibility holds. I said range metafunctions were "public virtual interfaces". IMHO, next version should make them non-virtual. By doing this, you can contrive any nice customization way anytime. -- Regards, Shunsuke Sogame

Shunsuke Sogame wrote:
Thorsten Ottosen wrote:
How will a different mechanism save you from provding specializations of alle the types you want to support?
I tried to write Boost.Range implementation of ATL/WTL collections. But I gave up. There are 13 classes.
Is that without counting typdefs like CString etc? That is a lot.
They form a simple hierarchy, but we cannot take advantage of it. Partial class template specialization ignores base/derived relationship.
right.
And "primary" range_detail::boost_range_begin(C&) eats all the derived classes.
yes, a wierd feature of the language that we have to lieve with.
Thus, I have to write 13 implementations.
maybe the easiest would be to write a function, say, make_mfc_range(), that returns an iterator_range<...> of some sort. Then on all range boundaries you just call make_mfc_range(mfc_rng). (well,not great, but at least something)
Now I see ADL customization way is blob. Type itself has another job, that is, implementation selector. Left the job to tag...
For example, std::pair range implementation could be simplified to something like:
namespace customization {
namespace std_pair_detail {
struct tag { };
} // namespace std_pair_detail
template< class T > struct tag< std::pair<T, T> > : boost::mpl::identity<std_pair_detail::tag> { };
template< class PairT > struct metafunctions<PairT, std_pair_detail::tag> { typedef typename PairT::first_type iterator; typedef iterator const_iterator; };
template< > struct functions<std_pair_detail::tag> { template< class PairT > typename boost::range_iterator<PairT>::type begin(PairT& p) { return p.first; }
template< class PairT > typename boost::range_iterator<PairT>::type end(PairT& p) { return p.second; } };
}
Now 'PairT' is almost concept. A type derived from std::pair<> specializes only tag<>.
that is clever.
Moreover, 'const' overloads disappear.
also clever.
(though such overloads also are possible.) Of course, default implementation can call 'boost_range_begin'. Compatibility holds.
I said range metafunctions were "public virtual interfaces". IMHO, next version should make them non-virtual.
I don't plan to add such customization, sorry. But Iød be happy to include your support for mfc with the library. Maybe you can get some help from the preprocessor? -Thorsten

Thorsten Ottosen wrote:
Shunsuke Sogame wrote:
Thorsten Ottosen wrote:
How will a different mechanism save you from provding specializations of alle the types you want to support?
I tried to write Boost.Range implementation of ATL/WTL collections. But I gave up. There are 13 classes.
Is that without counting typdefs like CString etc?
That is a lot.
I guess the same tragedy has already been happening in Boost.Serialization.
They form a simple hierarchy, but we cannot take advantage of it. Partial class template specialization ignores base/derived relationship.
right.
And "primary" range_detail::boost_range_begin(C&) eats all the derived classes.
yes, a wierd feature of the language that we have to lieve with.
Thus, I have to write 13 implementations.
maybe the easiest would be to write a function, say, make_mfc_range(), that returns an iterator_range<...> of some sort. Then on all range boundaries you just call make_mfc_range(mfc_rng).
(well,not great, but at least something)
Maybe that is the solution. Not bad.
I said range metafunctions were "public virtual interfaces". IMHO, next version should make them non-virtual.
I don't plan to add such customization, sorry. But Iød be happy to include your support for mfc with the library.
Maybe you can get some help from the preprocessor?
I would be glad to write something like 'ranges::make_mfc_range' which use private customization framework for 13 collections and 4 strings. Thus, Boost.Range itself doesn't use its public customization way. Something unfair! :-) FWIW, I have already written such framework, which might send feedback someday. -- Regards, Shunsuke Sogame
participants (5)
-
Aleksey Gurtovoy
-
David Abrahams
-
MB
-
Shunsuke Sogame
-
Thorsten Ottosen