
Thorsten Ottosen wrote:
Btw, my range_size uses this code
template< class T > struct add_unsigned;
template<> struct add_unsigned<short> { typedef unsigned short type; };
template<> struct add_unsigned<int> { typedef unsigned int type; };
template<> struct add_unsigned<long> { typedef unsigned long type; };
#ifdef BOOST_HAS_LONG_LONG
template<> struct add_unsigned<long long> { typedef unsigned long long type; }; #endif
Can anybody spot weaknesses in that approach?
Well, you haven't defined a primary template, so add_unsigned<unsigned> will not compile. IMO, your primary template should "typedef T type;". But depending on what you're trying to do, this may work, and it's a lot shorter: template< typename Int > struct add_unsigned { typedef typename boost::uint_t< sizeof(Int) * CHAR_BIT >::least type; };
Regarding the concepts, it is correct to say, as you do, that the calls to begin(), end(), et al., must be qualified by boost::. But they also must say that the following
<quote>
is also well formed and has the same meaning:
using namespace unspecified-namespace; boost_range_begin(x);
</quote>
I think you should also say somewhere (but not necessarily in the Concepts section) that unspecified-namespace contains the implementations of boost_range_begin(), et al., for the std containers, std::pair, arrays and null-terminated strings. I think that should do it. Does anybody have a better suggestion?
The Range concepts have been a fruitful source of confusion. I'm still myself a bit puzzled sometimes :-)
We want to say a range r supports the expressions
boost::begin(r) boost::end(r) boost::size(r)
That is true fo certain types if we do include a certain header, otherwise it is not. That has really irritated me: in one translation-unit T could be conforming to a range, in others it need not to.
If you want to treat a type as a range, you need to include the file that makes that type a conforming range. I don't see any problem with that.
If we use your quote above, it seems to me that the to expressions are not equivalent: you can't exchange one with the other.
Why not?
A Range concept is composed of more than the concept defining boost_range_begin()/boost_range_end().
Of course. And I'm saying that for a type to conform to the range concept, it must do more than ensure that boost::begin(), boost::end(), and boost::size() are well-formed and have the proper semantics. I'm suggesting that you *add* the following requirements _in addition to_ the ones already listed: using namespace unspecified-namespace; boost_range_begin(r); is well-formed and has the same semantics as boost::begin(r). And the same for boost_range_end() and boost_range_size().
We might want to say the following:
T models a Range if it models one of the following concepts
??? -- Eric Niebler Boost Consulting www.boost-consulting.com