[boost][range] - Merge trac resolutions from the trunk. The most notable change is the alteration of the size type to be unsigned. This is a potentially breaking change.

[SVN r78860]
This commit is contained in:
Neil Groves
2012-06-08 22:59:54 +00:00
parent 2f3d82be9f
commit dc46fc13ab
27 changed files with 155 additions and 147 deletions

View File

@ -128,7 +128,7 @@
] ]
[ [
[`size(x)`] [`size(x)`]
[`range_difference<X>::type`] [`range_size<X>::type`]
[`range_calculate_size(x)` which by default is `boost::end(x) - boost::begin(x)`. Users may supply alternative implementations by implementing `range_calculate_size(x)` so that it will be found via ADL] [`range_calculate_size(x)` which by default is `boost::end(x) - boost::begin(x)`. Users may supply alternative implementations by implementing `range_calculate_size(x)` so that it will be found via ADL]
[constant time] [constant time]
] ]

View File

@ -5,6 +5,12 @@
/] /]
[section:upgrade Upgrade version of Boost.Range] [section:upgrade Upgrade version of Boost.Range]
[section:upgrade_from_1_49 Upgrade from version 1.49]
# __size__ now returns the type Rng::size_type if the range has size_type;
otherwise range_size<Rng>::type is used. This is the distance type promoted to
an unsigned type.
[section:upgrade_from_1_45 Upgrade from version 1.45] [section:upgrade_from_1_45 Upgrade from version 1.45]
# __size__ in addition to supporting __random_access_range__ now also supports extensibility via calls to the unqualified `range_calculate_size(rng)` function. # __size__ in addition to supporting __random_access_range__ now also supports extensibility via calls to the unqualified `range_calculate_size(rng)` function.

20
include/boost/range/algorithm/equal.hpp Executable file → Normal file
View File

@ -31,7 +31,7 @@ namespace boost
IteratorCategoryTag1, IteratorCategoryTag1,
IteratorCategoryTag2 ) IteratorCategoryTag2 )
{ {
do while (true)
{ {
// If we have reached the end of the left range then this is // If we have reached the end of the left range then this is
// the end of the loop. They are equal if and only if we have // the end of the loop. They are equal if and only if we have
@ -46,7 +46,12 @@ namespace boost
return false; return false;
// continue looping if and only if the values are equal // continue looping if and only if the values are equal
} while(*first1++ == *first2++); if (*first1 != *first2)
break;
++first1;
++first2;
}
// Reaching this line in the algorithm indicates that a value // Reaching this line in the algorithm indicates that a value
// inequality has been detected. // inequality has been detected.
@ -66,7 +71,7 @@ namespace boost
IteratorCategoryTag1, IteratorCategoryTag1,
IteratorCategoryTag2 ) IteratorCategoryTag2 )
{ {
do while (true)
{ {
// If we have reached the end of the left range then this is // If we have reached the end of the left range then this is
// the end of the loop. They are equal if and only if we have // the end of the loop. They are equal if and only if we have
@ -81,7 +86,12 @@ namespace boost
return false; return false;
// continue looping if and only if the values are equal // continue looping if and only if the values are equal
} while(pred(*first1++, *first2++)); if (!pred(*first1, *first2))
break;
++first1;
++first2;
}
// Reaching this line in the algorithm indicates that a value // Reaching this line in the algorithm indicates that a value
// inequality has been detected. // inequality has been detected.
@ -182,7 +192,7 @@ namespace boost
} }
} // namespace range } // namespace range
using range::equal; using ::boost::range::equal;
} // namespace boost } // namespace boost
#endif // include guard #endif // include guard

View File

@ -14,7 +14,6 @@
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/range/concepts.hpp> #include <boost/range/concepts.hpp>
#include <boost/ref.hpp> #include <boost/ref.hpp>
#include <boost/utility.hpp>
#include <algorithm> #include <algorithm>
#if BOOST_WORKAROUND(BOOST_MSVC, == 1600) #if BOOST_WORKAROUND(BOOST_MSVC, == 1600)

8
include/boost/range/algorithm_ext/copy_n.hpp Executable file → Normal file
View File

@ -30,15 +30,15 @@ namespace boost
/// ///
/// \pre SinglePassRange is a model of the SinglePassRangeConcept /// \pre SinglePassRange is a model of the SinglePassRangeConcept
/// \pre OutputIterator is a model of the OutputIteratorConcept /// \pre OutputIterator is a model of the OutputIteratorConcept
/// \pre 0 <= n < distance(rng) /// \pre 0 <= n <= distance(rng)
template< class SinglePassRange, class Size, class OutputIterator > template< class SinglePassRange, class Size, class OutputIterator >
inline OutputIterator copy_n(const SinglePassRange& rng, Size n, OutputIterator out) inline OutputIterator copy_n(const SinglePassRange& rng, Size n, OutputIterator out)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> )); BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
BOOST_ASSERT( n < static_cast<Size>(boost::distance(rng)) ); BOOST_ASSERT( n <= static_cast<Size>(::boost::distance(rng)) );
BOOST_ASSERT( n >= static_cast<Size>(0) ); BOOST_ASSERT( n >= static_cast<Size>(0) );
BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type source = boost::begin(rng); BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange>::type source = ::boost::begin(rng);
for (Size i = 0; i < n; ++i, ++out, ++source) for (Size i = 0; i < n; ++i, ++out, ++source)
*out = *source; *out = *source;
@ -47,7 +47,7 @@ inline OutputIterator copy_n(const SinglePassRange& rng, Size n, OutputIterator
} }
} // namespace range } // namespace range
using range::copy_n; using ::boost::range::copy_n;
} // namespace boost } // namespace boost
#endif // include guard #endif // include guard

View File

@ -74,7 +74,7 @@ namespace boost
#endif #endif
template< class T > template< class T >
inline long is_char_ptr( T /* r */ ) inline long is_char_ptr( const T& /* r */ )
{ {
return 0L; return 0L;
} }

1
include/boost/range/counting_range.hpp Executable file → Normal file
View File

@ -18,7 +18,6 @@
#include <boost/range/iterator_range_core.hpp> #include <boost/range/iterator_range_core.hpp>
#include <boost/range/value_type.hpp> #include <boost/range/value_type.hpp>
#include <boost/iterator/counting_iterator.hpp> #include <boost/iterator/counting_iterator.hpp>
#include <boost/utility.hpp>
namespace boost namespace boost
{ {

View File

@ -11,7 +11,6 @@
#define BOOST_RANGE_DETAIL_ANY_ITERATOR_HPP_INCLUDED #define BOOST_RANGE_DETAIL_ANY_ITERATOR_HPP_INCLUDED
#include <boost/cast.hpp> #include <boost/cast.hpp>
#include <boost/utility.hpp>
#include <boost/mpl/and.hpp> #include <boost/mpl/and.hpp>
#include <boost/mpl/or.hpp> #include <boost/mpl/or.hpp>
#include <boost/mpl/not.hpp> #include <boost/mpl/not.hpp>

View File

@ -13,7 +13,7 @@
#include <boost/array.hpp> #include <boost/array.hpp>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/utility.hpp> #include <boost/noncopyable.hpp>
namespace boost namespace boost
{ {

View File

@ -23,7 +23,7 @@
#include <boost/range/empty.hpp> #include <boost/range/empty.hpp>
#include <boost/range/detail/demote_iterator_traversal_tag.hpp> #include <boost/range/detail/demote_iterator_traversal_tag.hpp>
#include <boost/range/value_type.hpp> #include <boost/range/value_type.hpp>
#include <boost/utility.hpp> #include <boost/next_prior.hpp>
namespace boost namespace boost
{ {

31
include/boost/range/detail/size_type.hpp Executable file → Normal file
View File

@ -22,7 +22,14 @@ namespace boost
namespace range_detail namespace range_detail
{ {
template< typename T > template< typename T >
struct range_size_type_; struct range_size_type_
{
template< typename C >
struct pts
{
typedef std::size_t type;
};
};
template<> template<>
struct range_size_type_<std_container_> struct range_size_type_<std_container_>
@ -33,28 +40,6 @@ namespace boost
typedef BOOST_RANGE_DEDUCED_TYPENAME C::size_type type; typedef BOOST_RANGE_DEDUCED_TYPENAME C::size_type type;
}; };
}; };
template<>
struct range_size_type_<std_pair_>
{
template< typename P >
struct pts
{
typedef std::size_t type;
};
};
template<>
struct range_size_type_<array_>
{
template< typename A >
struct pts
{
typedef std::size_t type;
};
};
} }
template< typename C > template< typename C >

View File

@ -13,7 +13,7 @@
#include <boost/mpl/bool.hpp> #include <boost/mpl/bool.hpp>
#include <boost/mpl/has_xxx.hpp> #include <boost/mpl/has_xxx.hpp>
#include <boost/range/iterator.hpp> #include <boost/range/iterator.hpp>
#include <boost/utility.hpp> #include <boost/utility/enable_if.hpp>
namespace boost namespace boost
{ {

2
include/boost/range/numeric.hpp Executable file → Normal file
View File

@ -40,7 +40,7 @@ namespace boost
template< class SinglePassRange, class Value > template< class SinglePassRange, class Value >
inline Value accumulate( const SinglePassRange& rng, Value init ) inline Value accumulate( const SinglePassRange& rng, Value init )
{ {
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> )); BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
return std::accumulate( boost::begin(rng), boost::end(rng), init ); return std::accumulate( boost::begin(rng), boost::end(rng), init );
} }

View File

@ -18,7 +18,7 @@
#include <boost/range/config.hpp> #include <boost/range/config.hpp>
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/range/difference_type.hpp> #include <boost/range/size_type.hpp>
#include <boost/assert.hpp> #include <boost/assert.hpp>
namespace boost namespace boost
@ -26,7 +26,7 @@ namespace boost
namespace range_detail namespace range_detail
{ {
template<class SinglePassRange> template<class SinglePassRange>
inline BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange>::type inline BOOST_DEDUCED_TYPENAME range_size<const SinglePassRange>::type
range_calculate_size(const SinglePassRange& rng) range_calculate_size(const SinglePassRange& rng)
{ {
BOOST_ASSERT( (boost::end(rng) - boost::begin(rng)) >= 0 && BOOST_ASSERT( (boost::end(rng) - boost::begin(rng)) >= 0 &&
@ -36,7 +36,7 @@ namespace boost
} }
template<class SinglePassRange> template<class SinglePassRange>
inline BOOST_DEDUCED_TYPENAME range_difference<SinglePassRange>::type inline BOOST_DEDUCED_TYPENAME range_size<const SinglePassRange>::type
size(const SinglePassRange& rng) size(const SinglePassRange& rng)
{ {
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \ #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \

View File

@ -16,11 +16,13 @@
#endif #endif
#include <boost/range/config.hpp> #include <boost/range/config.hpp>
#include <boost/range/difference_type.hpp>
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#include <boost/range/detail/size_type.hpp> #include <boost/range/detail/size_type.hpp>
#else #else
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/type_traits/remove_const.hpp> #include <boost/type_traits/remove_const.hpp>
#include <cstddef> #include <cstddef>
#include <utility> #include <utility>
@ -34,31 +36,39 @@ namespace boost
// default // default
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
template<typename T>
class has_size_type
{
typedef char no_type;
struct yes_type { char dummy[2]; };
template<typename C> template<typename C>
static yes_type test(BOOST_DEDUCED_TYPENAME C::size_type x);
template<typename C, typename Arg>
static no_type test(Arg x);
public:
static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
};
template<typename C, typename Enabler=void>
struct range_size struct range_size
{
typedef BOOST_DEDUCED_TYPENAME make_unsigned<
BOOST_DEDUCED_TYPENAME range_difference<C>::type
>::type type;
};
template<typename C>
struct range_size<
C,
BOOST_DEDUCED_TYPENAME enable_if<has_size_type<C>, void>::type
>
{ {
typedef BOOST_DEDUCED_TYPENAME C::size_type type; typedef BOOST_DEDUCED_TYPENAME C::size_type type;
}; };
//////////////////////////////////////////////////////////////////////////
// pair
//////////////////////////////////////////////////////////////////////////
template< typename Iterator >
struct range_size< std::pair<Iterator,Iterator> >
{
typedef std::size_t type;
};
//////////////////////////////////////////////////////////////////////////
// array
//////////////////////////////////////////////////////////////////////////
template< typename T, std::size_t sz >
struct range_size< T[sz] >
{
typedef std::size_t type;
};
} }
template< class T > template< class T >

View File

@ -172,9 +172,9 @@ void check_adl_conformance()
BOOST_CHECK_EQUAL( boost_test::begin( r6 ), global_namespace ); BOOST_CHECK_EQUAL( boost_test::begin( r6 ), global_namespace );
} }
#include <boost/test/included/unit_test_framework.hpp> #include <boost/test/included/unit_test.hpp>
using boost::unit_test_framework::test_suite; using boost::unit_test::test_suite;
test_suite* init_unit_test_suite( int argc, char* argv[] ) test_suite* init_unit_test_suite( int argc, char* argv[] )
{ {

View File

@ -44,7 +44,7 @@ namespace boost
BOOST_CHECK_EQUAL( boost::udistance(rng), result_fn.invocation_count() ); BOOST_CHECK_EQUAL( boost::udistance(rng), result_fn.invocation_count() );
fn_t result_fn2 = boost::for_each(boost::make_iterator_range(rng), fn_t(rng)); fn_t result_fn2 = boost::for_each(boost::make_iterator_range(rng), fn_t(rng));
BOOST_CHECK_EQUAL( boost::udistance(rng), result_fn.invocation_count() ); BOOST_CHECK_EQUAL( boost::udistance(rng), result_fn2.invocation_count() );
// Test the constant version // Test the constant version
const SinglePassRange& cref_rng = rng; const SinglePassRange& cref_rng = rng;

View File

@ -18,7 +18,7 @@
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <boost/test/test_tools.hpp> #include <boost/test/test_tools.hpp>
#include <boost/test/included/unit_test_framework.hpp> #include <boost/test/included/unit_test.hpp>
namespace mock_std namespace mock_std
{ {
@ -104,12 +104,12 @@ namespace
} }
} }
using boost::unit_test_framework::test_suite; using boost::unit_test::test_suite;
boost::unit_test_framework::test_suite* boost::unit_test::test_suite*
init_unit_test_suite( int argc, char* argv[] ) init_unit_test_suite( int argc, char* argv[] )
{ {
boost::unit_test_framework::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite - begin() ADL namespace barrier" ); boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite - begin() ADL namespace barrier" );
test->add( BOOST_TEST_CASE( &test_range_begin ) ); test->add( BOOST_TEST_CASE( &test_range_begin ) );

View File

@ -53,9 +53,9 @@ void compat1()
iterator_of< std::vector<int> >::type i = v.begin(); iterator_of< std::vector<int> >::type i = v.begin();
} }
#include <boost/test/included/unit_test_framework.hpp> #include <boost/test/included/unit_test.hpp>
using boost::unit_test_framework::test_suite; using boost::unit_test::test_suite;
test_suite* init_unit_test_suite( int argc, char* argv[] ) test_suite* init_unit_test_suite( int argc, char* argv[] )
{ {

4
test/compat3.cpp Executable file → Normal file
View File

@ -53,9 +53,9 @@ void compat1()
iterator_of< std::vector<int> >::type i = v.begin(); iterator_of< std::vector<int> >::type i = v.begin();
} }
#include <boost/test/included/unit_test_framework.hpp> #include <boost/test/included/unit_test.hpp>
using boost::unit_test_framework::test_suite; using boost::unit_test::test_suite;
test_suite* init_unit_test_suite( int argc, char* argv[] ) test_suite* init_unit_test_suite( int argc, char* argv[] )
{ {

View File

@ -18,7 +18,7 @@
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <boost/test/test_tools.hpp> #include <boost/test/test_tools.hpp>
#include <boost/test/included/unit_test_framework.hpp> #include <boost/test/included/unit_test.hpp>
namespace mock_std namespace mock_std
{ {
@ -104,12 +104,12 @@ namespace
} }
} }
using boost::unit_test_framework::test_suite; using boost::unit_test::test_suite;
boost::unit_test_framework::test_suite* boost::unit_test::test_suite*
init_unit_test_suite( int argc, char* argv[] ) init_unit_test_suite( int argc, char* argv[] )
{ {
boost::unit_test_framework::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite - end() ADL namespace barrier" ); boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite - end() ADL namespace barrier" );
test->add( BOOST_TEST_CASE( &test_range_end_adl_avoidance ) ); test->add( BOOST_TEST_CASE( &test_range_end_adl_avoidance ) );

View File

@ -40,7 +40,7 @@ namespace boost_range_extension_size_test
impl_t m_impl; impl_t m_impl;
}; };
inline boost::range_difference<std::list<int> >::type inline boost::range_size<std::list<int> >::type
range_calculate_size(const FooWithoutSize& rng) range_calculate_size(const FooWithoutSize& rng)
{ {
return 2u; return 2u;