diff --git a/doc/reference/adaptors/examples/adjacent_filtered.cpp b/doc/reference/adaptors/examples/adjacent_filtered.cpp index 7830a1d..cc7cd9b 100644 --- a/doc/reference/adaptors/examples/adjacent_filtered.cpp +++ b/doc/reference/adaptors/examples/adjacent_filtered.cpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include diff --git a/doc/reference/adaptors/examples/indexed.cpp b/doc/reference/adaptors/examples/indexed.cpp index 3178457..bb141e8 100644 --- a/doc/reference/adaptors/examples/indexed.cpp +++ b/doc/reference/adaptors/examples/indexed.cpp @@ -41,5 +41,5 @@ int main(int argc, const char* argv[]) display_element_and_index( input | indexed(0) ); return 0; -] +} diff --git a/doc/reference/adaptors/examples/transformed.cpp b/doc/reference/adaptors/examples/transformed.cpp index f2a46f5..62bf5d4 100644 --- a/doc/reference/adaptors/examples/transformed.cpp +++ b/doc/reference/adaptors/examples/transformed.cpp @@ -9,7 +9,7 @@ // #include #include -#include +#include #include #include #include diff --git a/include/boost/range/adaptor/adjacent_filtered.hpp b/include/boost/range/adaptor/adjacent_filtered.hpp index edc1dff..f717cb3 100644 --- a/include/boost/range/adaptor/adjacent_filtered.hpp +++ b/include/boost/range/adaptor/adjacent_filtered.hpp @@ -143,10 +143,6 @@ namespace boost skip_iter(boost::end(r), boost::end(r), p)) { } - - private: - P m_pred; - R* m_range; }; template< class T > diff --git a/include/boost/range/adaptor/define_adaptor.hpp b/include/boost/range/adaptor/define_adaptor.hpp index 26f4016..b228df3 100644 --- a/include/boost/range/adaptor/define_adaptor.hpp +++ b/include/boost/range/adaptor/define_adaptor.hpp @@ -44,24 +44,6 @@ return range_adaptor (rng); \ } -#define BOOST_DEFINE_RANGE_ADAPTOR_1( adaptor_name, range_adaptor, adaptor_class ) \ - template range_adaptor \ - operator|(Range& rng, const adaptor_name & args) \ - { \ - return range_adaptor (rng, args.arg1); \ - } \ - template range_adaptor \ - operator|(const Range& rng, const adaptor_name & args) \ - { \ - return range_adaptor (rng, args.arg1); \ - } \ - template \ - range_adaptor \ - make_##adaptor_name(Range& rng, Arg1 arg1) \ - { \ - return range_adaptor(rng, arg1); \ - } - #define BOOST_DEFINE_RANGE_ADAPTOR_1( adaptor_name, range_adaptor, arg1_type ) \ struct adaptor_name \ { \ diff --git a/include/boost/range/adaptor/strided.hpp b/include/boost/range/adaptor/strided.hpp old mode 100755 new mode 100644 index abfad5e..e843f62 --- a/include/boost/range/adaptor/strided.hpp +++ b/include/boost/range/adaptor/strided.hpp @@ -176,6 +176,7 @@ namespace boost strided_iterator() : m_first() , m_last() + , m_index(0) , m_stride() { } @@ -184,6 +185,7 @@ namespace boost : super_t(it) , m_first(first) , m_last(last) + , m_index(stride ? (it - first) / stride : 0) , m_stride(stride) { } @@ -194,6 +196,7 @@ namespace boost : super_t(other.base()) , m_first(other.base_begin()) , m_last(other.base_end()) + , m_index(other.get_index()) , m_stride(other.get_stride()) { } @@ -201,44 +204,37 @@ namespace boost base_iterator base_begin() const { return m_first; } base_iterator base_end() const { return m_last; } difference_type get_stride() const { return m_stride; } + difference_type get_index() const { return m_index; } private: void increment() { - base_iterator& it = this->base_reference(); - if ((m_last - it) > m_stride) - it += m_stride; + m_index += m_stride; + if (m_index < (m_last - m_first)) + this->base_reference() = m_first + m_index; else - it = m_last; + this->base_reference() = m_last; } void decrement() { - base_iterator& it = this->base_reference(); - if ((it - m_first) > m_stride) - it -= m_stride; + m_index -= m_stride; + if (m_index >= 0) + this->base_reference() = m_first + m_index; else - it = m_first; + this->base_reference() = m_first; } void advance(difference_type offset) { - base_iterator& it = this->base_reference(); offset *= m_stride; - if (offset >= 0) - { - if ((m_last - it) > offset) - it += offset; - else - it = m_last; - } + m_index += offset; + if (m_index < 0) + this->base_reference() = m_first; + else if (m_index > (m_last - m_first)) + this->base_reference() = m_last; else - { - if ((m_first - it) > offset) - it += offset; - else - it = m_first; - } + this->base_reference() = m_first + m_index; } template @@ -252,12 +248,13 @@ namespace boost bool equal(const strided_iterator& other) const { - return other.base() == this->base(); + return this->base() == other.base(); } private: base_iterator m_first; base_iterator m_last; + difference_type m_index; difference_type m_stride; }; diff --git a/include/boost/range/adaptor/transformed.hpp b/include/boost/range/adaptor/transformed.hpp old mode 100755 new mode 100644 index ee4ab34..96d2dab --- a/include/boost/range/adaptor/transformed.hpp +++ b/include/boost/range/adaptor/transformed.hpp @@ -42,8 +42,8 @@ namespace boost typedef R source_range_type; transformed_range( F f, R& r ) - : base( make_transform_iterator( boost::begin(r), f ), - make_transform_iterator( boost::end(r), f ) ) + : base( boost::make_transform_iterator( boost::begin(r), f ), + boost::make_transform_iterator( boost::end(r), f ) ) { } }; diff --git a/include/boost/range/algorithm/for_each.hpp b/include/boost/range/algorithm/for_each.hpp old mode 100755 new mode 100644 index 714a06f..12c9d4d --- a/include/boost/range/algorithm/for_each.hpp +++ b/include/boost/range/algorithm/for_each.hpp @@ -13,13 +13,53 @@ #include #include #include +#include +#include #include +#if BOOST_WORKAROUND(BOOST_MSVC, == 1600) +#include +#endif + namespace boost { namespace range { +#if BOOST_WORKAROUND(BOOST_MSVC, == 1600) + namespace for_each_detail + { + template + inline UnaryFunction + for_each_impl(Iterator first, Iterator last, UnaryFunction fun, + typename enable_if< + is_reference_wrapper, + void + >::type* = 0) + { + typedef typename std::_Get_unchecked_type::type + unchecked_iterator; + + unchecked_iterator unchecked_last = std::_Unchecked(last); + for (unchecked_iterator unchecked_first = std::_Unchecked(first); first != last; ++first) + fun.get()(*unchecked_first); + + return fun; + } + + template + inline UnaryFunction + for_each_impl(Iterator first, Iterator last, UnaryFunction fn, + typename disable_if< + is_reference_wrapper, + void + >::type* = 0) + { + return std::for_each(first, last, fn); + } + } +#endif + /// \brief template function for_each /// /// range-based version of the for_each std algorithm @@ -30,7 +70,18 @@ template< class SinglePassRange, class UnaryFunction > inline UnaryFunction for_each(SinglePassRange & rng, UnaryFunction fun) { BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); - return std::for_each(boost::begin(rng),boost::end(rng),fun); + +#if BOOST_WORKAROUND(BOOST_MSVC, == 1600) + return for_each_detail::for_each_impl< + typename range_iterator::type, + UnaryFunction + >(boost::begin(rng), boost::end(rng), fun); +#else + return std::for_each< + BOOST_DEDUCED_TYPENAME range_iterator::type, + UnaryFunction + >(boost::begin(rng),boost::end(rng),fun); +#endif } /// \overload @@ -38,7 +89,18 @@ template< class SinglePassRange, class UnaryFunction > inline UnaryFunction for_each(const SinglePassRange& rng, UnaryFunction fun) { BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); - return std::for_each(boost::begin(rng), boost::end(rng), fun); + +#if BOOST_WORKAROUND(BOOST_MSVC, == 1600) + return for_each_detail::for_each_impl< + typename range_iterator::type, + UnaryFunction + >(boost::begin(rng), boost::end(rng), fun); +#else + return std::for_each< + BOOST_DEDUCED_TYPENAME range_iterator::type, + UnaryFunction + >(boost::begin(rng), boost::end(rng), fun); +#endif } } // namespace range diff --git a/include/boost/range/algorithm_ext/is_sorted.hpp b/include/boost/range/algorithm_ext/is_sorted.hpp old mode 100755 new mode 100644 index 54fc038..3d00729 --- a/include/boost/range/algorithm_ext/is_sorted.hpp +++ b/include/boost/range/algorithm_ext/is_sorted.hpp @@ -1,3 +1,4 @@ +// Copyright Bryce Lelbach 2010 // Copyright Neil Groves 2009. Use, modification and // distribution is subject to the Boost Software License, Version // 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -14,45 +15,26 @@ #include #include #include +#include #include namespace boost { - namespace range_detail - { - template - inline bool is_sorted(ForwardIterator first, ForwardIterator last) - { - for (ForwardIterator next = first; first != last && ++next != last; ++first) - if (*next < *first) - return false; - return true; - } - - template - inline bool is_sorted(ForwardIterator first, ForwardIterator last, BinaryPredicate pred) - { - for (ForwardIterator next = first; first != last && ++next != last; ++first) - if (pred(*next, *first)) - return false; - return true; - } - } - namespace range { -/// \brief template function count +/// \brief template function is_sorted /// -/// range-based version of the count std algorithm +/// range-based version of the is_sorted std algorithm /// /// \pre SinglePassRange is a model of the SinglePassRangeConcept template inline bool is_sorted(const SinglePassRange& rng) { BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept)); - BOOST_RANGE_CONCEPT_ASSERT((LessThanComparableConcept::type>)); - return range_detail::is_sorted(boost::begin(rng), boost::end(rng)); + BOOST_RANGE_CONCEPT_ASSERT((LessThanComparableConcept::type>)); + return ::boost::detail::is_sorted(boost::begin(rng), boost::end(rng)); } /// \overload @@ -60,12 +42,16 @@ template inline bool is_sorted(const SinglePassRange& rng, BinaryPredicate pred) { BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept)); - BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept::type, BOOST_DEDUCED_TYPENAME range_value::type>)); - return range_detail::is_sorted(boost::begin(rng), boost::end(rng), pred); + BOOST_RANGE_CONCEPT_ASSERT((BinaryPredicateConcept::type, + BOOST_DEDUCED_TYPENAME range_value::type>)); + return ::boost::detail::is_sorted(boost::begin(rng), boost::end(rng), pred); } } // namespace range - using range::is_sorted; + +using range::is_sorted; + } // namespace boost #endif // include guard diff --git a/include/boost/range/any_range.hpp b/include/boost/range/any_range.hpp index 2155b2c..ba4c224 100644 --- a/include/boost/range/any_range.hpp +++ b/include/boost/range/any_range.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/include/boost/range/detail/demote_iterator_traversal_tag.hpp b/include/boost/range/detail/demote_iterator_traversal_tag.hpp old mode 100755 new mode 100644 index 5d77678..2127de9 --- a/include/boost/range/detail/demote_iterator_traversal_tag.hpp +++ b/include/boost/range/detail/demote_iterator_traversal_tag.hpp @@ -5,6 +5,9 @@ // 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // +// Acknowledgements: +// aschoedl supplied a fix to supply the level of interoperability I had +// originally intended, but failed to implement. // // For more information, see http://www.boost.org/libs/range/ // @@ -19,12 +22,12 @@ namespace boost { template -struct demote_iterator_traversal_tag +struct inner_demote_iterator_traversal_tag { }; #define BOOST_DEMOTE_TRAVERSAL_TAG( Tag1, Tag2, ResultTag ) \ -template<> struct demote_iterator_traversal_tag< Tag1 , Tag2 > \ +template<> struct inner_demote_iterator_traversal_tag< Tag1 , Tag2 > \ { \ typedef ResultTag type; \ }; @@ -73,6 +76,15 @@ BOOST_DEMOTE_TRAVERSAL_TAG( random_access_traversal_tag, random_access_traversal #undef BOOST_DEMOTE_TRAVERSAL_TAG +template +struct demote_iterator_traversal_tag + : inner_demote_iterator_traversal_tag< + typename boost::detail::pure_traversal_tag< IteratorTraversalTag1 >::type, + typename boost::detail::pure_traversal_tag< IteratorTraversalTag2 >::type + > +{ +}; + } // namespace range_detail } // namespace boost diff --git a/include/boost/range/detail/detail_str.hpp b/include/boost/range/detail/detail_str.hpp old mode 100755 new mode 100644 index d5ad5b3..5ef7a34 --- a/include/boost/range/detail/detail_str.hpp +++ b/include/boost/range/detail/detail_str.hpp @@ -134,8 +134,8 @@ namespace boost #include #include -#include -#include +#include +#include #include namespace boost diff --git a/include/boost/range/detail/join_iterator.hpp b/include/boost/range/detail/join_iterator.hpp index d22292b..ce86467 100644 --- a/include/boost/range/detail/join_iterator.hpp +++ b/include/boost/range/detail/join_iterator.hpp @@ -5,6 +5,9 @@ // 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // +// Acknowledgements: +// aschoedl contributed an improvement to the determination +// of the Reference type parameter. // // For more information, see http://www.boost.org/libs/range/ // @@ -120,7 +123,32 @@ private: template::type - , typename Reference = typename iterator_reference::type + // find least demanding, commonly supported reference type, in the order &, const&, and by-value: + , typename Reference = typename mpl::if_c< + !is_reference::type>::value + || !is_reference::type>::value, + typename remove_const< + typename remove_reference< + typename iterator_reference::type + >::type + >::type, + typename mpl::if_c< + is_const< + typename remove_reference< + typename iterator_reference::type + >::type + >::value + || is_const< + typename remove_reference< + typename iterator_reference::type + >::type + >::value, + typename add_const< + typename iterator_reference::type + >::type, + typename iterator_reference::type + >::type + >::type , typename Traversal = typename demote_iterator_traversal_tag< typename iterator_traversal::type , typename iterator_traversal::type>::type diff --git a/include/boost/range/has_range_iterator.hpp b/include/boost/range/has_range_iterator.hpp index b2bca39..432efad 100644 --- a/include/boost/range/has_range_iterator.hpp +++ b/include/boost/range/has_range_iterator.hpp @@ -19,7 +19,7 @@ namespace boost { namespace range_detail { - BOOST_MPL_HAS_XXX_TRAIT_DEF(type); + BOOST_MPL_HAS_XXX_TRAIT_DEF(type) template struct has_range_iterator_impl diff --git a/include/boost/range/irange.hpp b/include/boost/range/irange.hpp index 8045550..3b5a6cc 100644 --- a/include/boost/range/irange.hpp +++ b/include/boost/range/irange.hpp @@ -124,13 +124,11 @@ namespace boost typedef typename base_t::difference_type difference_type; typedef typename base_t::reference reference; - integer_iterator_with_step(value_type first, value_type step, difference_type step_size) + integer_iterator_with_step(value_type first, difference_type step, value_type step_size) : m_first(first) , m_step(step) , m_step_size(step_size) { - BOOST_ASSERT( step >= 0 ); - BOOST_ASSERT( step_size != 0 ); } private: @@ -213,16 +211,18 @@ namespace boost { BOOST_ASSERT( step_size != 0 ); BOOST_ASSERT( (step_size > 0) ? (last >= first) : (last <= first) ); - + typedef typename range_detail::integer_iterator_with_step iterator_t; - const std::ptrdiff_t last_step - = (static_cast(last) - static_cast(first)) - / (static_cast(step_size)); - + const std::ptrdiff_t sz = static_cast(step_size >= 0 ? step_size : -step_size); + const Integer l = step_size >= 0 ? last : first; + const Integer f = step_size >= 0 ? first : last; + const std::ptrdiff_t num_steps = (l + ((l-f) % sz) - f) / sz; + BOOST_ASSERT(num_steps >= 0); + return strided_integer_range( iterator_t(first, 0, step_size), - iterator_t(first, last_step, step_size)); + iterator_t(first, num_steps, step_size)); } } // namespace boost diff --git a/include/boost/range/iterator_range_core.hpp b/include/boost/range/iterator_range_core.hpp index faa0d6b..60c7670 100644 --- a/include/boost/range/iterator_range_core.hpp +++ b/include/boost/range/iterator_range_core.hpp @@ -53,13 +53,13 @@ namespace boost template< class ForwardRange > static IteratorT adl_begin( ForwardRange& r ) { - return IteratorT( boost::begin( r ) ); + return static_cast( boost::begin( r ) ); } template< class ForwardRange > static IteratorT adl_end( ForwardRange& r ) { - return IteratorT( boost::end( r ) ); + return static_cast( boost::end( r ) ); } }; @@ -71,6 +71,24 @@ namespace boost boost::begin(r), boost::end(r) ); } + + template< class Left, class Right > + inline bool greater_than( const Left& l, const Right& r ) + { + return less_than(r,l); + } + + template< class Left, class Right > + inline bool less_or_equal_than( const Left& l, const Right& r ) + { + return !iterator_range_detail::less_than(r,l); + } + + template< class Left, class Right > + inline bool greater_or_equal_than( const Left& l, const Right& r ) + { + return !iterator_range_detail::less_than(l,r); + } // This version is maintained since it is used in other boost libraries // such as Boost.Assign @@ -271,6 +289,21 @@ namespace boost { return iterator_range_detail::less_than( *this, r ); } + + bool operator>( const iterator_range& r ) const + { + return iterator_range_detail::greater_than( *this, r ); + } + + bool operator<=( const iterator_range& r ) const + { + return iterator_range_detail::less_or_equal_than( *this, r ); + } + + bool operator>=( const iterator_range& r ) const + { + return iterator_range_detail::greater_or_equal_than( *this, r ); + } #endif @@ -370,6 +403,27 @@ namespace boost { return iterator_range_detail::less_than( l, r ); } + + template< class IteratorT, class ForwardRange > + inline bool operator<=( const ForwardRange& l, + const iterator_range& r ) + { + return iterator_range_detail::less_or_equal_than( l, r ); + } + + template< class IteratorT, class ForwardRange > + inline bool operator>( const ForwardRange& l, + const iterator_range& r ) + { + return iterator_range_detail::greater_than( l, r ); + } + + template< class IteratorT, class ForwardRange > + inline bool operator>=( const ForwardRange& l, + const iterator_range& r ) + { + return iterator_range_detail::greater_or_equal_than( l, r ); + } #ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING #else @@ -416,6 +470,48 @@ namespace boost { return iterator_range_detail::less_than( l, r ); } + + template< class Iterator1T, class Iterator2T > + inline bool operator<=( const iterator_range& l, + const iterator_range& r ) + { + return iterator_range_detail::less_or_equal_than( l, r ); + } + + template< class IteratorT, class ForwardRange > + inline bool operator<=( const iterator_range& l, + const ForwardRange& r ) + { + return iterator_range_detail::less_or_equal_than( l, r ); + } + + template< class Iterator1T, class Iterator2T > + inline bool operator>( const iterator_range& l, + const iterator_range& r ) + { + return iterator_range_detail::greater_than( l, r ); + } + + template< class IteratorT, class ForwardRange > + inline bool operator>( const iterator_range& l, + const ForwardRange& r ) + { + return iterator_range_detail::greater_than( l, r ); + } + + template< class Iterator1T, class Iterator2T > + inline bool operator>=( const iterator_range& l, + const iterator_range& r ) + { + return iterator_range_detail::greater_or_equal_than( l, r ); + } + + template< class IteratorT, class ForwardRange > + inline bool operator>=( const iterator_range& l, + const ForwardRange& r ) + { + return iterator_range_detail::greater_or_equal_than( l, r ); + } #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING diff --git a/include/boost/range/join.hpp b/include/boost/range/join.hpp index ad0217e..aacc0a3 100644 --- a/include/boost/range/join.hpp +++ b/include/boost/range/join.hpp @@ -36,6 +36,9 @@ public: } // namespace range_detail +namespace range +{ + template class joined_range : public range_detail::joined_type::type @@ -78,6 +81,11 @@ join(SinglePassRange1& r1, SinglePassRange2& r2) return joined_range(r1, r2); } +} // namespace range + +using ::boost::range::joined_range; +using ::boost::range::join; + } // namespace boost #endif // include guard diff --git a/include/boost/range/sub_range.hpp b/include/boost/range/sub_range.hpp index d5544b9..0b00086 100644 --- a/include/boost/range/sub_range.hpp +++ b/include/boost/range/sub_range.hpp @@ -12,12 +12,13 @@ #ifndef BOOST_RANGE_SUB_RANGE_HPP #define BOOST_RANGE_SUB_RANGE_HPP -#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500)) +#include + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500)) #pragma warning( push ) #pragma warning( disable : 4996 ) #endif -#include #include #include #include @@ -30,9 +31,9 @@ namespace boost { - - template< class ForwardRange > - class sub_range : public iterator_range< BOOST_DEDUCED_TYPENAME range_iterator::type > + + template< class ForwardRange > + class sub_range : public iterator_range< BOOST_DEDUCED_TYPENAME range_iterator::type > { typedef BOOST_DEDUCED_TYPENAME range_iterator::type iterator_t; typedef iterator_range< iterator_t > base; @@ -53,40 +54,40 @@ namespace boost reference >::type const_reference; public: - sub_range() : base() - { } - -#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500) ) - sub_range( const sub_range& r ) - : base( static_cast( r ) ) + sub_range() : base() { } + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500) ) + sub_range( const sub_range& r ) + : base( static_cast( r ) ) + { } #endif template< class ForwardRange2 > - sub_range( ForwardRange2& r ) : + sub_range( ForwardRange2& r ) : + +#if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 800 ) + base( impl::adl_begin( r ), impl::adl_end( r ) ) +#else + base( r ) +#endif + { } + + template< class ForwardRange2 > + sub_range( const ForwardRange2& r ) : #if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 800 ) base( impl::adl_begin( r ), impl::adl_end( r ) ) #else base( r ) -#endif - { } - - template< class ForwardRange2 > - sub_range( const ForwardRange2& r ) : - -#if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 800 ) - base( impl::adl_begin( r ), impl::adl_end( r ) ) -#else - base( r ) -#endif +#endif { } template< class Iter > sub_range( Iter first, Iter last ) : base( first, last ) { } - + template< class ForwardRange2 > sub_range& operator=( ForwardRange2& r ) { @@ -99,23 +100,23 @@ namespace boost { base::operator=( r ); return *this; - } + } sub_range& operator=( const sub_range& r ) { base::operator=( static_cast(r) ); - return *this; + return *this; } - + public: - + iterator begin() { return base::begin(); } const_iterator begin() const { return base::begin(); } iterator end() { return base::end(); } const_iterator end() const { return base::end(); } - difference_type size() const { return base::size(); } - + difference_type size() const { return base::size(); } + public: // convenience reference front() { @@ -173,7 +174,7 @@ namespace boost } // namespace 'boost' -#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500)) +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500)) #pragma warning( pop ) #endif diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index e0087fb..afab584 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -31,6 +31,22 @@ rule range-test ( name : includes * ) } test-suite range : + [ compile ../doc/reference/adaptors/examples/adjacent_filtered.cpp : : example_adjacent_filtered ] + [ compile ../doc/reference/adaptors/examples/copied.cpp : : example_copied ] + [ compile ../doc/reference/adaptors/examples/filtered.cpp : : example_filtered ] + [ compile ../doc/reference/adaptors/examples/indexed.cpp : : example_indexed ] + [ compile ../doc/reference/adaptors/examples/indirected.cpp : : example_indirected ] + [ compile ../doc/reference/adaptors/examples/map_keys.cpp : : example_map_keys ] + [ compile ../doc/reference/adaptors/examples/map_values.cpp : : example_map_values ] + [ compile ../doc/reference/adaptors/examples/replaced.cpp : : example_replaced ] + [ compile ../doc/reference/adaptors/examples/replaced_if.cpp : : example_replaced_if ] + [ compile ../doc/reference/adaptors/examples/reversed.cpp : : example_reversed ] + [ compile ../doc/reference/adaptors/examples/sliced.cpp : : example_sliced ] + [ compile ../doc/reference/adaptors/examples/strided.cpp : : example_strided ] + [ compile ../doc/reference/adaptors/examples/tokenized.cpp : : example_tokenized ] + [ compile ../doc/reference/adaptors/examples/transformed.cpp : : example_transformed ] + [ compile ../doc/reference/adaptors/examples/uniqued.cpp : : example_uniqued ] + [ compile-fail compile_fail/iterator_range1.cpp ] [ range-test adaptor_test/adjacent_filtered ] [ range-test adaptor_test/copied ] [ range-test adaptor_test/filtered ] @@ -155,5 +171,9 @@ test-suite range : [ range-test std_container ] [ range-test string ] [ range-test sub_range ] + [ range-test ticket_5486 ] + [ range-test ticket_5544_terminate_irange ] + [ range-test ticket_5547 ] + [ range-test ticket_5556_is_sorted_namespace ] ; diff --git a/test/adaptor_test/strided.cpp b/test/adaptor_test/strided.cpp index 91beb81..1198a10 100644 --- a/test/adaptor_test/strided.cpp +++ b/test/adaptor_test/strided.cpp @@ -250,6 +250,38 @@ namespace boost BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), output.begin(), output.end() ); } + + template + void strided_test_ticket_5236_check_bidirectional(const Range& rng) + { + BOOST_CHECK_EQUAL( boost::distance(rng), 1 ); + BOOST_CHECK_EQUAL( std::distance(boost::begin(rng), boost::prior(boost::end(rng))), 0 ); + } + + template + void strided_test_ticket_5236_check(const Range& rng) + { + strided_test_ticket_5236_check_bidirectional(rng); + + typename boost::range_iterator::type it = boost::end(rng); + it = it - 1; + BOOST_CHECK_EQUAL( std::distance(boost::begin(rng), it), 0 ); + } + + void strided_test_ticket_5236() + { + std::vector v; + v.push_back(1); + strided_test_ticket_5236_check( v | boost::adaptors::strided(2) ); + + // Ensure that there is consistency between the random-access implementation + // and the bidirectional. + + std::list l; + l.push_back(1); + strided_test_ticket_5236_check_bidirectional( l | boost::adaptors::strided(2) ); + } + } } @@ -262,6 +294,7 @@ init_unit_test_suite(int argc, char* argv[]) test->add( BOOST_TEST_CASE( &boost::strided_test ) ); test->add( BOOST_TEST_CASE( &boost::strided_defect_Trac5014 ) ); test->add( BOOST_TEST_CASE( &boost::strided_test_traversal ) ); + test->add( BOOST_TEST_CASE( &boost::strided_test_ticket_5236 ) ); return test; } diff --git a/test/compile_fail/iterator_range1.cpp b/test/compile_fail/iterator_range1.cpp new file mode 100644 index 0000000..eed4ea9 --- /dev/null +++ b/test/compile_fail/iterator_range1.cpp @@ -0,0 +1,21 @@ +// Boost.Range library +// +// Copyright Neil Groves 2011. Use, modification and distribution is subject +// to the Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org/libs/range +// + +#include + +namespace iterator_range_test_detail +{ + void check_iterator_range_doesnt_convert_pointers() + { + double source[] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 }; + boost::iterator_range rng = boost::make_iterator_range(source); + } +} + diff --git a/test/irange.cpp b/test/irange.cpp index d71f184..358a2b1 100644 --- a/test/irange.cpp +++ b/test/irange.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include namespace boost @@ -35,27 +34,38 @@ namespace boost BOOST_CHECK_EQUAL_COLLECTIONS( test.begin(), test.end(), reference.begin(), reference.end() ); } + + template + std::ptrdiff_t test_irange_calculate_num_steps(Integer first, Integer last, int step) + { + const std::ptrdiff_t sz = static_cast(step >= 0 ? step : -step); + const std::ptrdiff_t l = static_cast(step >= 0 ? last : first); + const std::ptrdiff_t f = static_cast(step >= 0 ? first : last); + return (l + ((l-f) % sz) - f) / sz; + } // Test an integer range with a runtime specified step size. - template - void test_irange_impl(Integer first, Integer last, int step) + template + void test_irange_impl(IntegerInput first, IntegerInput last, int step) { BOOST_ASSERT( step != 0 ); + + // Skip tests that have negative values if the type is + // unsigned + if ((static_cast(static_cast(first)) != first) + || (static_cast(static_cast(last)) != last)) + return; + std::vector reference; - if (step > 0) - { - for (Integer i = first; i < last; i += step) - reference.push_back(i); - } - else - { - for (Integer i = first; i > last; i += step) - reference.push_back(i); - } + + const std::ptrdiff_t num_steps = test_irange_calculate_num_steps(first, last, step); + Integer current_value = first; + for (std::ptrdiff_t i = 0; i < num_steps; ++i, current_value += step) + reference.push_back(current_value); std::vector test; boost::push_back(test, boost::irange(first, last, step)); - + BOOST_CHECK_EQUAL_COLLECTIONS( test.begin(), test.end(), reference.begin(), reference.end() ); } @@ -81,7 +91,6 @@ namespace boost void test_irange(int first, int last, int step_size) { BOOST_ASSERT( step_size != 0 ); - BOOST_ASSERT( (last - first) % step_size == 0 ); test_irange_impl(first, last, step_size); test_irange_impl(first, last, step_size); test_irange_impl(first, last, step_size); @@ -114,8 +123,27 @@ namespace boost test_irange(10, 0, -1); test_irange(0, 2, 2); test_irange(2, 0, -2); + test_irange(0, 9, 2); + test_irange(9, 0, -2); + test_irange(-9, 0, 2); + test_irange(-9, 9, 2); + test_irange(9, -9, -2); test_irange(10, 20, 5); test_irange(20, 10, -5); + + test_irange(0, 0, 3); + test_irange(0, 1, 3); + test_irange(0, 2, 3); + test_irange(0, 3, 3); + test_irange(0, 4, 3); + test_irange(0, 10, 3); + + test_irange(0, 0, -3); + test_irange(0, -1, -3); + test_irange(0, -2, -3); + test_irange(0, -3, -3); + test_irange(0, -4, -3); + test_irange(0, -10, -3); } } // namespace boost diff --git a/test/iterator_range.cpp b/test/iterator_range.cpp index 7c53a8b..1d9539b 100644 --- a/test/iterator_range.cpp +++ b/test/iterator_range.cpp @@ -24,6 +24,7 @@ #include #include #include +#include void check_reference_type(); @@ -102,17 +103,136 @@ void check_iterator_range() check_reference_type(); } +namespace iterator_range_test_detail +{ + struct less + { + template< class Left, class Right > + bool operator()(const Left& l, const Right& r) const + { + return l < r; + } + }; + + struct greater + { + template< class Left, class Right > + bool operator()(const Left& l, const Right& r) const + { + return l > r; + } + }; + + struct less_or_equal + { + template< class Left, class Right > + bool operator()(const Left& l, const Right& r) const + { + return l <= r; + } + }; + + struct greater_or_equal + { + template< class Left, class Right > + bool operator()(const Left& l, const Right& r) const + { + return l >= r; + } + }; + + struct equal_to + { + template< class Left, class Right > + bool operator()(const Left& l, const Right& r) const + { + return l == r; + } + }; + + struct not_equal_to + { + template< class Left, class Right > + bool operator()(const Left& l, const Right& r) const + { + return l != r; + } + }; + + template< class Pred > + void check_iterator_range_operators_impl(Pred pred) + { + std::vector vals; + vals.push_back(std::string()); + vals.push_back("a"); + vals.push_back("b"); + vals.push_back("z"); + vals.push_back("ab"); + vals.push_back("ba"); + vals.push_back("abc"); + vals.push_back("cba"); + vals.push_back("aa"); + vals.push_back("aaa"); + vals.push_back("aab"); + vals.push_back("bba"); + + typedef std::string::const_iterator citer; + typedef boost::iterator_range iter_range; + + typedef std::vector::const_iterator value_const_iterator; + value_const_iterator first_val = vals.begin(); + value_const_iterator last_val = vals.end(); + + for (value_const_iterator left_it = first_val; left_it != last_val; ++left_it) + { + const std::string& leftValue = *left_it; + for (value_const_iterator right_it = first_val; right_it != last_val; ++right_it) + { + const std::string& rightValue = *right_it; + iter_range left = boost::make_iterator_range(leftValue); + iter_range right = boost::make_iterator_range(rightValue); + + const bool reference = pred(leftValue, rightValue); + + BOOST_CHECK_EQUAL( pred(left, right), reference ); + BOOST_CHECK_EQUAL( pred(left, rightValue), reference ); + BOOST_CHECK_EQUAL( pred(leftValue, right), reference ); + } + } + } + + void check_iterator_range_from_array() + { + double source[] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 }; + boost::iterator_range rng = boost::make_iterator_range(source); + BOOST_CHECK_EQUAL_COLLECTIONS( rng.begin(), rng.end(), + source, source + 6 ); + } + +} // namespace iterator_range_test_detail + +template +inline void check_iterator_range_operator() +{ + iterator_range_test_detail::check_iterator_range_operators_impl( + Pred()); +} boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) { boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" ); - test->add( BOOST_TEST_CASE( &check_iterator_range ) ); + test->add(BOOST_TEST_CASE(&check_iterator_range)); + test->add(BOOST_TEST_CASE(&check_iterator_range_operator)); + test->add(BOOST_TEST_CASE(&check_iterator_range_operator)); + test->add(BOOST_TEST_CASE(&check_iterator_range_operator)); + test->add(BOOST_TEST_CASE(&check_iterator_range_operator)); + test->add(BOOST_TEST_CASE(&check_iterator_range_operator)); + test->add(BOOST_TEST_CASE(&check_iterator_range_operator)); return test; } - // // // Check that constness is propgated correct from diff --git a/test/test_driver/range_return_test_driver.hpp b/test/test_driver/range_return_test_driver.hpp index bcd2533..3dfd2a2 100644 --- a/test/test_driver/range_return_test_driver.hpp +++ b/test/test_driver/range_return_test_driver.hpp @@ -371,7 +371,7 @@ namespace boost Container reference(cont); Container test(cont); - + iterator_t range_result = policy.test_iter(test); iterator_t reference_it = policy.reference(reference); @@ -391,7 +391,8 @@ namespace boost Container reference(cont); Container test_cont(cont); - range_return_t range_result = test_range_t()(policy, test_cont); + test_range_t test_range_fn; + range_return_t range_result = test_range_fn(policy, test_cont); iterator_t reference_it = policy.reference(reference); check_results::test(test_cont, reference, diff --git a/test/ticket_5486.cpp b/test/ticket_5486.cpp new file mode 100644 index 0000000..3a6bf4b --- /dev/null +++ b/test/ticket_5486.cpp @@ -0,0 +1,56 @@ +// Boost.Range library +// +// Copyright Neil Groves 2011. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// For more information, see http://www.boost.org/libs/range/ +// +#include +#include + +#include +#include + +#include +#include + +namespace boost +{ + namespace + { + class TestTicket5486Pred + : public std::binary_function + { + public: + explicit TestTicket5486Pred(int x) {} + bool operator()(int,int) const { return true; } + private: + TestTicket5486Pred(); + }; + + // Ticket 5486 - pertained to predicates erroneous + // requiring default construction + void test_ticket_5486() + { + std::vector v; + boost::push_back(v, v | boost::adaptors::adjacent_filtered(TestTicket5486Pred(1))); + + BOOST_CHECK_EQUAL_COLLECTIONS( v.begin(), v.end(), + v.begin(), v.end() ); + } + } +} + +boost::unit_test::test_suite* +init_unit_test_suite(int argc, char* argv[]) +{ + boost::unit_test::test_suite* test + = BOOST_TEST_SUITE( "RangeTestSuite.ticket_5486" ); + + test->add( BOOST_TEST_CASE( &boost::test_ticket_5486 ) ); + + return test; +} diff --git a/test/ticket_5544_terminate_irange.cpp b/test/ticket_5544_terminate_irange.cpp new file mode 100644 index 0000000..fa64436 --- /dev/null +++ b/test/ticket_5544_terminate_irange.cpp @@ -0,0 +1,47 @@ +// Boost.Range library +// +// Copyright Neil Groves 2011. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// For more information, see http://www.boost.org/libs/range/ +// +#include +#include + +#include +#include + +#include + +namespace boost +{ + namespace + { + void test_irange_termination() + { + std::vector reference; + for (int i = 0; i < 9; i += 2) + reference.push_back(i); + + std::vector actual; + boost::push_back(actual, boost::irange(0,9,2)); + + BOOST_CHECK_EQUAL_COLLECTIONS(actual.begin(), actual.end(), + reference.begin(), reference.end()); + } + } +} + +boost::unit_test::test_suite* +init_unit_test_suite(int argc, char* argv[]) +{ + boost::unit_test::test_suite* test + = BOOST_TEST_SUITE( "RangeTestSuite.ticket_5544" ); + + test->add( BOOST_TEST_CASE( &boost::test_irange_termination ) ); + + return test; +} diff --git a/test/ticket_5547.cpp b/test/ticket_5547.cpp new file mode 100644 index 0000000..1b9d3f6 --- /dev/null +++ b/test/ticket_5547.cpp @@ -0,0 +1,42 @@ +// Boost.Range library +// +// Copyright Neil Groves 2011. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// For more information, see http://www.boost.org/libs/range/ +// +#include +#include + +#include +#include + +#include + +namespace boost +{ + namespace + { + + // Ticket 5547 - boost::join ambiguous with algorithm::join + void test_ticket_5547() + { + std::vector x; + boost::range::join(x,x); + } + } +} + +boost::unit_test::test_suite* +init_unit_test_suite(int argc, char* argv[]) +{ + boost::unit_test::test_suite* test + = BOOST_TEST_SUITE( "RangeTestSuite.ticket_5547" ); + + test->add( BOOST_TEST_CASE( &boost::test_ticket_5547 ) ); + + return test; +} diff --git a/test/ticket_5556_is_sorted_namespace.cpp b/test/ticket_5556_is_sorted_namespace.cpp new file mode 100644 index 0000000..78a75cd --- /dev/null +++ b/test/ticket_5556_is_sorted_namespace.cpp @@ -0,0 +1,37 @@ +// Boost.Range library +// +// Copyright Neil Groves 2011. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// For more information, see http://www.boost.org/libs/range/ +// + +// Embarrasingly, the mere inclusion of these headers in this order was +// enough to trigger the defect. +#include +#include + +#include +#include + +namespace boost +{ + namespace + { + void test_ticket_5556() {} + } +} + +boost::unit_test::test_suite* +init_unit_test_suite(int argc, char* argv[]) +{ + boost::unit_test::test_suite* test + = BOOST_TEST_SUITE( "RangeTestSuite.ticket_5556" ); + + test->add( BOOST_TEST_CASE( &boost::test_ticket_5556 ) ); + + return test; +}