diff --git a/include/boost/range/iterator_range.hpp b/include/boost/range/iterator_range.hpp index 4d33587..dbaa236 100755 --- a/include/boost/range/iterator_range.hpp +++ b/include/boost/range/iterator_range.hpp @@ -28,31 +28,33 @@ a rich subset of Container interface. */ -namespace boost { - namespace range_detail +namespace boost +{ + namespace iterator_range_detail { template< class Left, class Right > inline bool equal( const Left& l, const Right& r ) { - typedef BOOST_DEDUCED_TYPENAME range_size::type sz_type; - sz_type l_size = boost::size( l ), - r_size = boost::size( r ); + typedef BOOST_DEDUCED_TYPENAME boost::range_size::type sz_type; + + sz_type l_size = size( l ), + r_size = size( r ); if( l_size != r_size ) return false; - return std::equal( boost::begin(l), boost::end(l), - boost::begin(r) ); + return std::equal( begin(l), end(l), + begin(r) ); } template< class Left, class Right > inline bool less_than( const Left& l, const Right& r ) { - return std::lexicographical_compare( boost::begin(l), - boost::end(l), - boost::begin(r), - boost::end(r) ); + return std::lexicographical_compare( begin(l), + end(l), + begin(r), + end(r) ); } } @@ -195,7 +197,7 @@ namespace boost { bool operator==( const iterator_range& r ) const { - return range_detail::equal( *this, r ); + return iterator_range_detail::equal( *this, r ); } bool operator!=( const iterator_range& r ) const @@ -205,7 +207,7 @@ namespace boost { bool operator<( const iterator_range& r ) const { - return range_detail::less_than( *this, r ); + return iterator_range_detail::less_than( *this, r ); } #endif @@ -220,7 +222,8 @@ namespace boost { value_type& back() const { BOOST_ASSERT( !empty() ); - return *--m_End; + IteratorT last( m_End ); + return *--last; } value_type& operator[]( size_type sz ) const @@ -230,42 +233,7 @@ namespace boost { return m_Begin[sz]; } - value_type& at( size_type sz ) const - { - //BOOST_STATIC_ASSERT( is_random_access ); - if( sz < size() ) - throw "foo"; - return m_Begin[sz]; - } - - void advance( size_type sz ) - { - BOOST_ASSERT( sz <= size() ); - std::advance( m_Begin, sz ); - } - - void narrow( size_type left, size_type right ) - { - BOOST_ASSERT( left + right <= size() ); - std::advance( m_Begin, left ); - std::advance( m_End, -right ); - } - - public: // iterable - iterator_range& operator++() - { - BOOST_ASSERT( !empty() ); - ++m_End; - return *this; - } - - value_type& operator*() const - { - BOOST_ASSERT( !empty() ); - return front(); - } - - private: + protected: template< class ForwardRange > iterator adl_begin( ForwardRange& r ) { @@ -332,21 +300,21 @@ namespace boost { inline bool operator==( const ForwardRange& l, const iterator_range& r ) { - return range_detail::equal( l, r ); + return iterator_range_detail::equal( l, r ); } template< class IteratorT, class ForwardRange > inline bool operator!=( const ForwardRange& l, const iterator_range& r ) { - return !range_detail::equal( l, r ); + return !iterator_range_detail::equal( l, r ); } template< class IteratorT, class ForwardRange > inline bool operator<( const ForwardRange& l, const iterator_range& r ) { - return range_detail::less_than( l, r ); + return iterator_range_detail::less_than( l, r ); } #ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING @@ -355,14 +323,14 @@ namespace boost { inline bool operator==( const iterator_range& l, const iterator_range& r ) { - return range_detail::equal( l, r ); + return iterator_range_detail::equal( l, r ); } template< class IteratorT, class ForwardRange > inline bool operator==( const iterator_range& l, const ForwardRange& r ) { - return range_detail::equal( l, r ); + return iterator_range_detail::equal( l, r ); } @@ -370,14 +338,14 @@ namespace boost { inline bool operator!=( const iterator_range& l, const iterator_range& r ) { - return !range_detail::equal( l, r ); + return !iterator_range_detail::equal( l, r ); } template< class IteratorT, class ForwardRange > inline bool operator!=( const iterator_range& l, const ForwardRange& r ) { - return !range_detail::equal( l, r ); + return !iterator_range_detail::equal( l, r ); } @@ -385,16 +353,16 @@ namespace boost { inline bool operator<( const iterator_range& l, const iterator_range& r ) { - return range_detail::less_than( l, r ); + return iterator_range_detail::less_than( l, r ); } template< class IteratorT, class ForwardRange > inline bool operator<( const iterator_range& l, const ForwardRange& r ) - { - return range_detail::less_than( l, r ); + { + return iterator_range_detail::less_than( l, r ); } - + #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING // iterator range utilities -----------------------------------------// @@ -413,8 +381,7 @@ namespace boost { { return iterator_range( Begin, End ); } - - + #ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING template< typename Range > @@ -447,6 +414,62 @@ namespace boost { ( r ); } +#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + namespace iterator_range_detail + { + template< class Range > + inline iterator_range< BOOST_DEDUCED_TYPENAME range_result_iterator::type > + make_range_impl( Range& r, + BOOST_DEDUCED_TYPENAME range_difference::type advance_begin, + BOOST_DEDUCED_TYPENAME range_difference::type advance_end ) + { + if( advance_begin == 0 && advance_end == 0 ) + return make_iterator_range( r ); + + BOOST_DEDUCED_TYPENAME range_result_iterator::type + new_begin = begin( r ), + new_end = end( r ); + std::advance( new_begin, advance_begin ); + std::advance( new_end, advance_end ); + return make_iterator_range( new_begin, new_end ); + } + } + +#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + template< class Range > + inline iterator_range< BOOST_DEDUCED_TYPENAME range_result_iterator::type > + make_iterator_range( Range& r, + BOOST_DEDUCED_TYPENAME range_difference::type advance_begin, + BOOST_DEDUCED_TYPENAME range_difference::type advance_end ) + { + //BOOST_ASSERT( advance_begin - advance_end <= size(r) && "creating invalid range" ); + return iterator_range_detail::make_range_impl( r, advance_begin, advance_end ); + } + +#else + + template< class Range > + inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator::type > + make_iterator_range( Range& r, + BOOST_DEDUCED_TYPENAME range_difference::type advance_begin, + BOOST_DEDUCED_TYPENAME range_difference::type advance_end ) + { + //BOOST_ASSERT( advance_begin - advance_end <= size(r) && "creating invalid range" ); + return iterator_range_detail::make_range_impl( r, advance_begin, advance_end ); + } + + template< class Range > + inline iterator_range< BOOST_DEDUCED_TYPENAME range_const_iterator::type > + make_iterator_range( const Range& r, + BOOST_DEDUCED_TYPENAME range_difference::type advance_begin, + BOOST_DEDUCED_TYPENAME range_difference::type advance_end ) + { + //BOOST_ASSERT( advance_begin - advance_end <= size(r) && "creating invalid range" ); + return iterator_range_detail::make_range_impl( r, advance_begin, advance_end ); + } + #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING //! copy a range into a sequence diff --git a/include/boost/range/sub_range.hpp b/include/boost/range/sub_range.hpp index 1bb6581..b6e2094 100755 --- a/include/boost/range/sub_range.hpp +++ b/include/boost/range/sub_range.hpp @@ -43,7 +43,7 @@ namespace boost sub_range( ForwardRange2& r ) : #if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 800 ) - base( boost::begin( r ), boost::end( r ) ) + base( this->adl_begin( r ), this->adl_end( r ) ) #else base( r ) #endif @@ -53,7 +53,7 @@ namespace boost sub_range( const ForwardRange2& r ) : #if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 800 ) - base( boost::begin( r ), boost::end( r ) ) + base( this->adl_begin( r ), this->adl_end( r ) ) #else base( r ) #endif @@ -90,91 +90,55 @@ namespace boost public: // convenience value_type& front() { - BOOST_ASSERT( !empty() ); - return *m_Begin; + return base::front(); } const value_type& front() const { - BOOST_ASSERT( !empty() ); - return *m_Begin; + return base::front(); } value_type& back() { - BOOST_ASSERT( !empty() ); - return *--m_End; + return base::back(); } const value_type& back() const { - BOOST_ASSERT( !empty() ); - return *--m_End; + return base::back(); } value_type& operator[]( size_type sz ) { - //BOOST_STATIC_ASSERT( is_random_access ); - BOOST_ASSERT( sz < size() ); - return m_Begin[sz]; + return base::operator[](sz); } const value_type& operator[]( size_type sz ) const { - //BOOST_STATIC_ASSERT( is_random_access ); - BOOST_ASSERT( sz < size() ); - return m_Begin[sz]; + return base::operator[](sz); } - value_type& at( size_type sz ) - { - //BOOST_STATIC_ASSERT( is_random_access ); - if( sz < size() ) - throw "foo"; - return m_Begin[sz]; - } - - const value_type& at( size_type sz ) const - { - //BOOST_STATIC_ASSERT( is_random_access ); - if( sz < size() ) - throw "foo"; - return m_Begin[sz]; - } - - public: // iterable - value_type& operator*() - { - BOOST_ASSERT( !empty() ); - return front(); - } - - const value_type& operator*() const - { - BOOST_ASSERT( !empty() ); - return front(); - } }; template< class ForwardRange, class ForwardRange2 > inline bool operator==( const sub_range& l, const sub_range& r ) { - return range_detail::equal( l, r ); + return iterator_range_detail::equal( l, r ); } template< class ForwardRange, class ForwardRange2 > inline bool operator!=( const sub_range& l, const sub_range& r ) { - return !range_detail::equal( l, r ); + return !iterator_range_detail::equal( l, r ); } template< class ForwardRange, class ForwardRange2 > inline bool operator<( const sub_range& l, const sub_range& r ) { - return range_detail::less_than( l, r ); + return iterator_range_detail::less_than( l, r ); } diff --git a/test/Jamfile b/test/Jamfile index 30fd632..b4e6c85 100755 --- a/test/Jamfile +++ b/test/Jamfile @@ -10,94 +10,28 @@ subproject libs/range/test ; -SEARCH on testing.jam = $(BOOST_BUILD_PATH) ; -include testing.jam ; -DEPENDS all : test ; +import testing ; +rule range-test ( name ) { -test-suite range - : [ run - array.cpp - : : - : - : array_test - ] - [ run - iterator_pair.cpp - : : - : - : iterator_pair_test - ] - [ run - std_container.cpp - : : - : - : std_container_test - ] - [ run - string.cpp - : : - : - : string_test - ] - [ run - iterator_range.cpp - : : - : - : iterator_range - ] - [ run - sub_range.cpp - : : - : - : sub_range - ] + return [ + run $(name).cpp + ../../test/build/boost_unit_test_framework + : : : $(BOOST_ROOT) + ] ; +} - [ run - partial_workaround.cpp - : : - : - : workaround_test - ] - [ run - algorithm_example.cpp - : : - : - : example_test - ] - - [ run - reversible_range.cpp - : : - : - : reversible_range_test - ] - [ run - const_ranges.cpp - : : - : - : const_ranges - ] -# [ run -# compat3.cpp -# : : -# : -# : compat3_test -# ] -# -# [ run -# adl_conformance.cpp -# : : -# : -# : adl_conformance -# ] -# [ run -# adl_conformance_no_using.cpp -# : : -# : -# : adl_conformance_no_using_declaration -# ] +test-suite range : + [ range-test array ] + [ range-test iterator_pair ] + [ range-test std_container ] + [ range-test string ] + [ range-test iterator_range ] + [ range-test sub_range ] + [ range-test partial_workaround ] + [ range-test algorithm_example ] + [ range-test reversible_range ] + [ range-test const_ranges ] ; -} diff --git a/test/algorithm_example.cpp b/test/algorithm_example.cpp index a684da1..cd6e0e0 100755 --- a/test/algorithm_example.cpp +++ b/test/algorithm_example.cpp @@ -17,7 +17,6 @@ #include #include -#include #include #include #include @@ -80,9 +79,8 @@ void check_algorithm() } -#include - -using boost::unit_test_framework::test_suite; +#include +using boost::unit_test::test_suite; test_suite* init_unit_test_suite( int argc, char* argv[] ) { diff --git a/test/array.cpp b/test/array.cpp index 953a57f..13759e3 100755 --- a/test/array.cpp +++ b/test/array.cpp @@ -19,15 +19,9 @@ #include #include #include -#include #include #include -// This should be included before "using namespace boost", -// otherwise gcc headers will be confused with boost::iterator -// namespace. -#include - using namespace boost; using namespace std; @@ -69,9 +63,8 @@ void check_array() } - - -using boost::unit_test_framework::test_suite; +#include +using boost::unit_test::test_suite; test_suite* init_unit_test_suite( int argc, char* argv[] ) { diff --git a/test/const_ranges.cpp b/test/const_ranges.cpp index 81080da..3e91b67 100755 --- a/test/const_ranges.cpp +++ b/test/const_ranges.cpp @@ -17,13 +17,9 @@ #endif #include +#include #include -// This should be included before "using namespace boost", -// otherwise gcc headers will be confused with boost::iterator -// namespace. -#include - using namespace boost; using namespace std; @@ -52,7 +48,8 @@ void check_const_ranges() -using boost::unit_test_framework::test_suite; +#include +using boost::unit_test::test_suite; test_suite* init_unit_test_suite( int argc, char* argv[] ) { diff --git a/test/iterator_pair.cpp b/test/iterator_pair.cpp index 97d2a07..74358ef 100755 --- a/test/iterator_pair.cpp +++ b/test/iterator_pair.cpp @@ -19,12 +19,10 @@ #include #include #include -#include #include #include using namespace boost; -using boost::unit_test_framework::test_suite; void check_iterator_pair() { @@ -79,10 +77,8 @@ void check_iterator_pair() } - -#include - -using boost::unit_test_framework::test_suite; +#include +using boost::unit_test::test_suite; test_suite* init_unit_test_suite( int argc, char* argv[] ) { diff --git a/test/iterator_range.cpp b/test/iterator_range.cpp index f7984d0..9c05d9c 100755 --- a/test/iterator_range.cpp +++ b/test/iterator_range.cpp @@ -16,18 +16,13 @@ # pragma warn -8057 // unused argument argc/argv in Boost.Test #endif + #include #include -#include #include #include #include -// This should be included before "using namespace boost", -// otherwise gcc headers will be confused with boost::iterator -// namespace. -#include - using namespace boost; using namespace std; @@ -85,10 +80,21 @@ void check_iterator_range() BOOST_CHECK( rrr == rr ); BOOST_CHECK( !( rrr != rr ) ); BOOST_CHECK( !( rrr < rr ) ); + + const irange cr = make_iterator_range( str ); + BOOST_CHECK_EQUAL( cr.front(), 'h' ); + BOOST_CHECK_EQUAL( cr.back(), 'd' ); + BOOST_CHECK_EQUAL( cr[1], 'e' ); + + rrr = make_iterator_range( str, 1, -1 ); + BOOST_CHECK( rrr == "ello worl" ); + rrr = make_iterator_range( rrr, -1, 1 ); + BOOST_CHECK( rrr == str ); } -using boost::unit_test_framework::test_suite; +#include +using boost::unit_test::test_suite; test_suite* init_unit_test_suite( int argc, char* argv[] ) { diff --git a/test/partial_workaround.cpp b/test/partial_workaround.cpp index f77827a..78a26e2 100755 --- a/test/partial_workaround.cpp +++ b/test/partial_workaround.cpp @@ -33,7 +33,6 @@ #include #include -#include #include #include #include @@ -92,9 +91,8 @@ void check_partial_workaround() } -#include - -using boost::unit_test_framework::test_suite; +#include +using boost::unit_test::test_suite; test_suite* init_unit_test_suite( int argc, char* argv[] ) { diff --git a/test/reversible_range.cpp b/test/reversible_range.cpp index 2e0f90a..26d953a 100755 --- a/test/reversible_range.cpp +++ b/test/reversible_range.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -82,10 +81,9 @@ void check_iterator() } +#include +using boost::unit_test::test_suite; -#include - -using boost::unit_test_framework::test_suite; test_suite* init_unit_test_suite( int argc, char* argv[] ) { diff --git a/test/std_container.cpp b/test/std_container.cpp index 7bb40f5..d3d060f 100755 --- a/test/std_container.cpp +++ b/test/std_container.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -61,11 +60,8 @@ void check_std_container() } - - -#include - -using boost::unit_test_framework::test_suite; +#include +using boost::unit_test::test_suite; test_suite* init_unit_test_suite( int argc, char* argv[] ) { diff --git a/test/string.cpp b/test/string.cpp index 7eb1b3c..c09e86e 100755 --- a/test/string.cpp +++ b/test/string.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -184,12 +183,10 @@ void check_string() } +#include +using boost::unit_test::test_suite; -#include - -using boost::unit_test_framework::test_suite; - test_suite* init_unit_test_suite( int argc, char* argv[] ) { test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" ); diff --git a/test/sub_range.cpp b/test/sub_range.cpp index f62ec31..57d373a 100755 --- a/test/sub_range.cpp +++ b/test/sub_range.cpp @@ -16,19 +16,12 @@ # pragma warn -8057 // unused argument argc/argv in Boost.Test #endif -#include #include -#include #include #include #include #include -// This should be included before "using namespace boost", -// otherwise gcc headers will be confused with boost::iterator -// namespace. -#include - using namespace boost; using namespace std; @@ -41,10 +34,9 @@ struct add_one } }; -void check_iterator_range() +void check_sub_range() { - - + typedef string::iterator iterator; typedef string::const_iterator const_iterator; typedef iterator_range irange; @@ -139,16 +131,30 @@ void check_iterator_range() BOOST_CHECK( rrr == rr ); BOOST_CHECK( !( rrr != rr ) ); BOOST_CHECK( !( rrr < rr ) ); -} + const irange cr = make_iterator_range( str ); + BOOST_CHECK_EQUAL( cr.front(), 'h' ); + BOOST_CHECK_EQUAL( cr.back(), 'd' ); + BOOST_CHECK_EQUAL( cr[1], 'e' ); -using boost::unit_test_framework::test_suite; + rrr = make_iterator_range( str, 1, -1 ); + BOOST_CHECK( rrr == "ello worl" ); + rrr = make_iterator_range( rrr, -1, 1 ); + BOOST_CHECK( rrr == str ); + rrr.front() = 'H'; + rrr.back() = 'D'; + rrr[1] = 'E'; + BOOST_CHECK( rrr == "HEllo worlD" ); +} + +#include +using boost::unit_test::test_suite; test_suite* init_unit_test_suite( int argc, char* argv[] ) { test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" ); - test->add( BOOST_TEST_CASE( &check_iterator_range ) ); + test->add( BOOST_TEST_CASE( &check_sub_range ) ); return test; }