From 3ed0626756419d1f570111ad429acec7cf22c749 Mon Sep 17 00:00:00 2001 From: Neil Groves Date: Sat, 8 Mar 2014 20:52:10 +0000 Subject: [PATCH 1/9] ticket 8028 - combine reimplemented and now documented. --- doc/.gitignore | 1 + doc/reference/utilities.qbk | 77 +++++ doc/upgrade.qbk | 2 + include/boost/range/combine.hpp | 307 ++---------------- include/boost/range/const_iterator.hpp | 63 ++-- .../boost/range/const_reverse_iterator.hpp | 4 +- include/boost/range/detail/combine_cxx03.hpp | 131 ++++++++ include/boost/range/detail/combine_cxx11.hpp | 40 +++ .../boost/range/detail/combine_no_rvalue.hpp | 73 +++++ include/boost/range/detail/combine_rvalue.hpp | 32 ++ include/boost/range/iterator.hpp | 13 +- test/combine.cpp | 151 +++++++-- 12 files changed, 550 insertions(+), 344 deletions(-) create mode 100644 doc/.gitignore create mode 100644 include/boost/range/detail/combine_cxx03.hpp create mode 100644 include/boost/range/detail/combine_cxx11.hpp create mode 100644 include/boost/range/detail/combine_no_rvalue.hpp create mode 100644 include/boost/range/detail/combine_rvalue.hpp diff --git a/doc/.gitignore b/doc/.gitignore new file mode 100644 index 0000000..2d19fc7 --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1 @@ +*.html diff --git a/doc/reference/utilities.qbk b/doc/reference/utilities.qbk index ccad7b0..cde1720 100644 --- a/doc/reference/utilities.qbk +++ b/doc/reference/utilities.qbk @@ -273,6 +273,83 @@ sub_range sub = find_first( str, "ll" ); [endsect] +[section:combine Function combine] + +The `combine` function is used to make one range from multiple ranges. The +`combine` function returns a `combined_range` which is an `iterator_range` of +a `zip_iterator` from the Boost.Iterator library. + +[h4 Synopsis] + +`` +namespace boost +{ + namespace range + { + +template +class combined_range + : public iterator_range > +{ +public: + combined_range(IterTuple first, IterTuple last); +}; + +template +auto combine(Ranges&&... rngs) -> + combined_range + + } // namespace range +} // namespace boost +`` + +* [*Precondition:] For each type `r` in `Ranges`, `r` is a model of +__single_pass_range__ or better. +* [*Return Type:] `combined_range::type...> >` +* [*Returned Range Category:] The minimum of the range category of every range +`r` in `Ranges`. + +[h4 Example] + +`` +#include +#include +#include +#include +#include + +int main(int, const char*[]) +{ + std::vector v; + std::list l; + for (int i = 0; i < 5; ++i) + { + v.push_back(i); + l.push_back(static_cast(i) + 'a'); + } + + int ti; + char tc; + BOOST_FOREACH(boost::tie(ti, tc), boost::combine(v, l)) + { + std::cout << '(' << ti << ',' << tv << ')' << '\n'; + } + + return 0; +} +`` + +This produces the output: +`` +(0,a) +(1,b) +(2,c) +(3,d) +(4,e) +`` + +[endsect] + [section:join Function join] The intention of the `join` function is to join two ranges into one longer range. diff --git a/doc/upgrade.qbk b/doc/upgrade.qbk index ef66325..9bbf904 100644 --- a/doc/upgrade.qbk +++ b/doc/upgrade.qbk @@ -16,6 +16,8 @@ been noted that some calling code was relying on member functions such as due to `iterator_reference::type` not being a reference. The suggested refactoring is to use `boost::size(rng)`. +[endsect] + [section:upgrade_from_1_49 Upgrade from version 1.49] # __size__ now returns the type Rng::size_type if the range has size_type; diff --git a/include/boost/range/combine.hpp b/include/boost/range/combine.hpp index 999bbc3..26cef9a 100755 --- a/include/boost/range/combine.hpp +++ b/include/boost/range/combine.hpp @@ -9,296 +9,37 @@ #ifndef BOOST_RANGE_COMBINE_HPP #define BOOST_RANGE_COMBINE_HPP -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include +#include +#include namespace boost { - namespace range_detail + namespace range + { + +template +class combined_range + : public iterator_range > +{ + typedef iterator_range > base; +public: + combined_range(IterTuple first, IterTuple last) + : base(first, last) { - struct void_ { typedef void_ type; }; - } - - template<> struct range_iterator< ::boost::range_detail::void_ > - { - typedef ::boost::tuples::null_type type; - }; - - namespace range_detail - { - inline ::boost::tuples::null_type range_begin( ::boost::range_detail::void_& ) - { return ::boost::tuples::null_type(); } - - inline ::boost::tuples::null_type range_begin( const ::boost::range_detail::void_& ) - { return ::boost::tuples::null_type(); } - - inline ::boost::tuples::null_type range_end( ::boost::range_detail::void_& ) - { return ::boost::tuples::null_type(); } - - inline ::boost::tuples::null_type range_end( const ::boost::range_detail::void_& ) - { return ::boost::tuples::null_type(); } - - template< class T > - struct tuple_iter - { - typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::eval_if_c< - ::boost::is_same::value, - ::boost::mpl::identity< ::boost::tuples::null_type >, - ::boost::range_iterator - >::type type; - }; - - template< class Rng1, class Rng2 > - struct tuple_range - { - typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::eval_if_c< - ::boost::is_same::value, - ::boost::range_detail::void_, - ::boost::mpl::identity - >::type type; - }; - - template - < - class R1, - class R2, - class R3, - class R4, - class R5, - class R6 - > - struct generate_tuple - { - typedef ::boost::tuples::tuple< - BOOST_DEDUCED_TYPENAME tuple_iter::type, - BOOST_DEDUCED_TYPENAME tuple_iter::type, - BOOST_DEDUCED_TYPENAME tuple_iter::type, - BOOST_DEDUCED_TYPENAME tuple_iter::type, - BOOST_DEDUCED_TYPENAME tuple_iter::type, - BOOST_DEDUCED_TYPENAME tuple_iter::type - > type; - - static type begin( R1& r1, R2& r2, R3& r3, R4& r4, R5& r5, R6& r6 ) - { - return ::boost::tuples::make_tuple( ::boost::begin(r1), - ::boost::begin(r2), - ::boost::begin(r3), - ::boost::begin(r4), - ::boost::begin(r5), - ::boost::begin(r6) ); - } - - static type end( R1& r1, R2& r2, R3& r3, R4& r4, R5& r5, R6& r6 ) - { - return ::boost::tuples::make_tuple( ::boost::end(r1), - ::boost::end(r2), - ::boost::end(r3), - ::boost::end(r4), - ::boost::end(r5), - ::boost::end(r6) ); - } - }; - - template - < - class R1, - class R2 = void_, - class R3 = void_, - class R4 = void_, - class R5 = void_, - class R6 = void_ - > - struct zip_rng - : iterator_range< - zip_iterator< - BOOST_DEDUCED_TYPENAME generate_tuple::type - > - > - { - private: - typedef generate_tuple generator_t; - typedef BOOST_DEDUCED_TYPENAME generator_t::type tuple_t; - typedef zip_iterator zip_iter_t; - typedef iterator_range base_t; - - public: - zip_rng( R1& r1, R2& r2, R3& r3, R4& r4, R5& r5, R6& r6 ) - : base_t( zip_iter_t( generator_t::begin(r1,r2,r3,r4,r5,r6) ), - zip_iter_t( generator_t::end(r1,r2,r3,r4,r5,r6) ) ) - { - BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r2)); - BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r3)); - BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r4)); - BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r5)); - BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r6)); - } - - template< class Zip, class Rng > - zip_rng( Zip& z, Rng& r ) - : base_t( zip_iter_t( generator_t::begin( z, r ) ), - zip_iter_t( generator_t::end( z, r ) ) ) - { - - // @todo: tuple::begin( should be overloaded for this situation - } - - struct tuple_length : ::boost::tuples::length - { }; - - template< unsigned N > - struct get - { - template< class Z, class R > - static BOOST_DEDUCED_TYPENAME ::boost::tuples::element::type begin( Z& z, R& ) - { - return get( z.begin().get_iterator_tuple() ); - } - - template< class Z, class R > - static BOOST_DEDUCED_TYPENAME ::boost::tuples::element::type end( Z& z, R& r ) - { - return get( z.end().get_iterator_tuple() ); - } - }; - - }; - - template< class Rng1, class Rng2 > - struct zip_range - : iterator_range< - zip_iterator< - ::boost::tuples::tuple< - BOOST_DEDUCED_TYPENAME ::boost::range_iterator::type, - BOOST_DEDUCED_TYPENAME ::boost::range_iterator::type - > - > - > - { - private: - typedef zip_iterator< - ::boost::tuples::tuple< - BOOST_DEDUCED_TYPENAME ::boost::range_iterator::type, - BOOST_DEDUCED_TYPENAME ::boost::range_iterator::type - > - > zip_iter_t; - typedef iterator_range base_t; - - public: - zip_range( Rng1& r1, Rng2& r2 ) - : base_t( zip_iter_t( ::boost::tuples::make_tuple(::boost::begin(r1), - ::boost::begin(r2)) ), - zip_iter_t( ::boost::tuples::make_tuple(::boost::end(r1), - ::boost::end(r2)) ) ) - { - BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r2)); - } - }; - - template< class Rng1, class Rng2, class Rng3 > - struct zip_range3 - : iterator_range< - zip_iterator< - ::boost::tuples::tuple< - BOOST_DEDUCED_TYPENAME ::boost::range_iterator::type, - BOOST_DEDUCED_TYPENAME ::boost::range_iterator::type, - BOOST_DEDUCED_TYPENAME ::boost::range_iterator::type - > - > - > - { - private: - typedef zip_iterator< - ::boost::tuples::tuple< - BOOST_DEDUCED_TYPENAME ::boost::range_iterator::type, - BOOST_DEDUCED_TYPENAME ::boost::range_iterator::type, - BOOST_DEDUCED_TYPENAME ::boost::range_iterator::type - > - > zip_iter_t; - typedef iterator_range base_t; - - public: - zip_range3( Rng1& r1, Rng2& r2, Rng3& r3 ) - : base_t( zip_iter_t( ::boost::tuples::make_tuple(::boost::begin(r1), - ::boost::begin(r2), - ::boost::begin(r3)) ), - zip_iter_t( ::boost::tuples::make_tuple(::boost::end(r1), - ::boost::end(r2), - ::boost::end(r3)) ) - ) - { - BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r2)); - BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r3)); - } - }; - - - struct combine_tag {}; - - template< class Rng > - inline zip_rng - operator&( combine_tag, Rng& r ) - { - return zip_rng(r); - } - - template< class Rng > - inline iterator_range - operator&( combine_tag, const Rng& r ) - { - return iterator_range(r); - } - - template - < - class R1, - class R2, - class R3, - class R4, - class R5, - class Rng - > - inline BOOST_DEDUCED_TYPENAME zip_rng::next - operator&( const zip_rng& zip, - Rng& r ) - { - return zip_rng::next( zip, r ); - } - - } // namespace range_detail - - template< class Rng1, class Rng2 > - inline ::boost::range_detail::zip_range combine( Rng1& r1, Rng2& r2 ) - { - return ::boost::range_detail::zip_range(r1, r2); - } - - template< class Rng1, class Rng2 > - inline ::boost::range_detail::zip_range combine( const Rng1& r1, Rng2& r2 ) - { - return ::boost::range_detail::zip_range(r1, r2); - } - - template< class Rng1, class Rng2 > - inline ::boost::range_detail::zip_range combine( Rng1& r1, const Rng2& r2 ) - { - return ::boost::range_detail::zip_range(r1, r2); - } - - template< class Rng1, class Rng2 > - inline ::boost::range_detail::zip_range combine( const Rng1& r1, const Rng2& r2 ) - { - return ::boost::range_detail::zip_range(r1, r2); } +}; + } // namespace range } // namespace boost +#if defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) || \ + defined(BOOST_NO_CXX11_DECLTYPE) || \ + defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || \ + defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +# include +#else +# include +#endif + #endif diff --git a/include/boost/range/const_iterator.hpp b/include/boost/range/const_iterator.hpp index 5512939..1cdbf03 100644 --- a/include/boost/range/const_iterator.hpp +++ b/include/boost/range/const_iterator.hpp @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -29,33 +30,45 @@ namespace boost // default ////////////////////////////////////////////////////////////////////////// - namespace range_detail { - BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( const_iterator ) - } - - template< typename C > - struct range_const_iterator : range_detail::extract_const_iterator - {}; - - ////////////////////////////////////////////////////////////////////////// - // pair - ////////////////////////////////////////////////////////////////////////// - - template< typename Iterator > - struct range_const_iterator< std::pair > + namespace range_detail { - typedef Iterator type; - }; - - ////////////////////////////////////////////////////////////////////////// - // array - ////////////////////////////////////////////////////////////////////////// - template< typename T, std::size_t sz > - struct range_const_iterator< T[sz] > - { - typedef const T* type; - }; +BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( const_iterator ) + +template< typename C > +struct range_const_iterator + : extract_const_iterator +{}; + +////////////////////////////////////////////////////////////////////////// +// pair +////////////////////////////////////////////////////////////////////////// + +template< typename Iterator > +struct range_const_iterator > +{ + typedef Iterator type; +}; + +////////////////////////////////////////////////////////////////////////// +// array +////////////////////////////////////////////////////////////////////////// + +template< typename T, std::size_t sz > +struct range_const_iterator< T[sz] > +{ + typedef const T* type; +}; + + } // namespace range_detail + +template +struct range_const_iterator + : range_detail::range_const_iterator< + typename remove_reference::type + > +{ +}; } // namespace boost diff --git a/include/boost/range/const_reverse_iterator.hpp b/include/boost/range/const_reverse_iterator.hpp index a1f49b7..d580aee 100644 --- a/include/boost/range/const_reverse_iterator.hpp +++ b/include/boost/range/const_reverse_iterator.hpp @@ -16,6 +16,7 @@ #endif #include +#include namespace boost { @@ -24,7 +25,8 @@ namespace boost // template< typename C > - struct range_const_reverse_iterator : range_reverse_iterator + struct range_const_reverse_iterator + : range_reverse_iterator::type> { }; } // namespace boost diff --git a/include/boost/range/detail/combine_cxx03.hpp b/include/boost/range/detail/combine_cxx03.hpp new file mode 100644 index 0000000..2040fe8 --- /dev/null +++ b/include/boost/range/detail/combine_cxx03.hpp @@ -0,0 +1,131 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. 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/ +// +#ifndef BOOST_RANGE_DETAIL_COMBINE_CXX03_HPP +#define BOOST_RANGE_DETAIL_COMBINE_CXX03_HPP + +#ifndef BOOST_RANGE_MIN_COMBINE_ARGS +#define BOOST_RANGE_MIN_COMBINE_ARGS 2 +#endif + +#ifndef BOOST_RANGE_MAX_COMBINE_ARGS +#define BOOST_RANGE_MAX_COMBINE_ARGS 5 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace boost +{ + namespace range_detail + { + +template +struct combined_result_impl; + +template +struct combined_result + : combined_result_impl::value> +{ +}; + +#define BOOST_RANGE_combined_element(z, n, data) \ + typename tuples::element::type + +#define BOOST_RANGE_combined_result(z, n, data) \ + template \ + struct combined_result_impl \ + : result_of \ + { \ + }; + +#define BOOST_PP_LOCAL_MACRO(n) BOOST_RANGE_combined_result(~,n,~) + +#define BOOST_PP_LOCAL_LIMITS (BOOST_RANGE_MIN_COMBINE_ARGS, \ + BOOST_RANGE_MAX_COMBINE_ARGS) +#include BOOST_PP_LOCAL_ITERATE() + +#define BOOST_RANGE_combined_get(z, n, data) get(tuple) + +#define BOOST_RANGE_combined_unpack(z, n, data) \ + template inline \ + typename combined_result::type \ + unpack_(mpl::int_, F f, const T& tuple) \ + { \ + return f(BOOST_PP_ENUM(n, BOOST_RANGE_combined_get, ~)); \ + } + +#define BOOST_PP_LOCAL_MACRO(n) BOOST_RANGE_combined_unpack(~,n,~) +#define BOOST_PP_LOCAL_LIMITS (BOOST_RANGE_MIN_COMBINE_ARGS, \ + BOOST_RANGE_MAX_COMBINE_ARGS) +#include BOOST_PP_LOCAL_ITERATE() + +} // namespace range_detail + +namespace range +{ + +#define BOOST_RANGE_combined_seq(z, n, data) boost::data(BOOST_PP_CAT(r,n)) + +#ifdef BOOST_NO_RVALUE_REFERENCES + +#include + +#else // by using rvalue references we avoid requiring 2^n overloads. + +#include + +#endif + +#define BOOST_PP_LOCAL_MACRO(n) BOOST_RANGE_combine(~,n,~) +#define BOOST_PP_LOCAL_LIMITS (BOOST_RANGE_MIN_COMBINE_ARGS, \ + BOOST_RANGE_MAX_COMBINE_ARGS) +#include BOOST_PP_LOCAL_ITERATE() + + } // namespace range + + using boost::range::combine; + +} // namespace boost + +#endif // include guard + +#undef BOOST_RANGE_combined_element +#undef BOOST_RANGE_combined_result +#undef BOOST_RANGE_combined_get +#undef BOOST_RANGE_combined_unpack +#undef BOOST_RANGE_combined_seq +#undef BOOST_RANGE_combined_exp_pred +#undef BOOST_RANGE_combined_exp_op +#undef BOOST_RANGE_combined_exp +#undef BOOST_RANGE_combined_bitset_pred +#undef BOOST_RANGE_combined_bitset_op +#undef BOOST_RANGE_combined_bitset +#undef BOOST_RANGE_combined_range_iterator +#undef BOOST_RANGE_combined_args +#undef BOOST_RANGE_combine_impl +#undef BOOST_RANGE_combine diff --git a/include/boost/range/detail/combine_cxx11.hpp b/include/boost/range/detail/combine_cxx11.hpp new file mode 100644 index 0000000..a7fa5b1 --- /dev/null +++ b/include/boost/range/detail/combine_cxx11.hpp @@ -0,0 +1,40 @@ +// Copyright Neil Groves 2014. 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/ +// +#ifndef BOOST_RANGE_DETAIL_COMBINE_CXX11_HPP +#define BOOST_RANGE_DETAIL_COMBINE_CXX11_HPP + +#include +#include +#include +#include +#include + +#include + +namespace boost +{ + namespace range + { + +template +auto combine(Ranges&&... rngs) -> + combined_range +{ + return combined_range( + boost::make_tuple(boost::begin(rngs)...), + boost::make_tuple(boost::end(rngs)...)); +} + + } // namespace range + +using range::combine; + +} // namespace boost + +#endif // include guard diff --git a/include/boost/range/detail/combine_no_rvalue.hpp b/include/boost/range/detail/combine_no_rvalue.hpp new file mode 100644 index 0000000..bdb3950 --- /dev/null +++ b/include/boost/range/detail/combine_no_rvalue.hpp @@ -0,0 +1,73 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. 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/ +// +#define BOOST_RANGE_combined_exp_pred(d, data) BOOST_PP_TUPLE_ELEM(3, 0, data) + +#define BOOST_RANGE_combined_exp_op(d, data) \ + ( \ + BOOST_PP_DEC( \ + BOOST_PP_TUPLE_ELEM(3, 0, data) \ + ), \ + BOOST_PP_TUPLE_ELEM(3, 1, data), \ + BOOST_PP_MUL_D( \ + d, \ + BOOST_PP_TUPLE_ELEM(3, 2, data), \ + BOOST_PP_TUPLE_ELEM(3, 1, data) \ + ) \ + ) + +#define BOOST_RANGE_combined_exp(x, n) \ + BOOST_PP_TUPLE_ELEM(3, 2, \ + BOOST_PP_WHILE(BOOST_RANGE_combined_exp_pred, \ + BOOST_RANGE_combined_exp_op, (n, x, 1))) + +#define BOOST_RANGE_combined_bitset_pred(n, state) \ + BOOST_PP_TUPLE_ELEM(2,1,state) + +#define BOOST_RANGE_combined_bitset_op(d, state) \ + (BOOST_PP_DIV_D(d, BOOST_PP_TUPLE_ELEM(2,0,state), 2), \ + BOOST_PP_DEC(BOOST_PP_TUPLE_ELEM(2,1,state))) + +#define BOOST_RANGE_combined_bitset(i, n) \ +BOOST_PP_MOD(BOOST_PP_TUPLE_ELEM(2, 0, \ + BOOST_PP_WHILE(BOOST_RANGE_combined_bitset_pred, \ + BOOST_RANGE_combined_bitset_op, (i,n))), 2) + +#define BOOST_RANGE_combined_range_iterator(z, n, i) \ + typename range_iterator< \ + BOOST_PP_CAT(R,n) \ + BOOST_PP_IF( \ + BOOST_RANGE_combined_bitset(i,n), \ + BOOST_PP_IDENTITY(const), \ + BOOST_PP_EMPTY)() \ + >::type + +#define BOOST_RANGE_combined_args(z, n, i) \ + BOOST_PP_CAT(R, n) \ + BOOST_PP_IF(BOOST_RANGE_combined_bitset(i,n), const&, &) \ + BOOST_PP_CAT(r, n) + +#define BOOST_RANGE_combine_impl(z, i, n)\ + template \ + inline range::combined_range< \ + boost::tuple \ + > \ + combine(BOOST_PP_ENUM(n, BOOST_RANGE_combined_args, i)) \ + { \ + typedef tuple< \ + BOOST_PP_ENUM(n, BOOST_RANGE_combined_range_iterator, i) \ + > rng_tuple_t; \ + return range::combined_range( \ + rng_tuple_t(BOOST_PP_ENUM(n, BOOST_RANGE_combined_seq, begin)), \ + rng_tuple_t(BOOST_PP_ENUM(n, BOOST_RANGE_combined_seq, end))); \ + } + + +#define BOOST_RANGE_combine(z, n, data) \ + BOOST_PP_REPEAT(BOOST_RANGE_combined_exp(2,n), BOOST_RANGE_combine_impl, n) diff --git a/include/boost/range/detail/combine_rvalue.hpp b/include/boost/range/detail/combine_rvalue.hpp new file mode 100644 index 0000000..2e323b7 --- /dev/null +++ b/include/boost/range/detail/combine_rvalue.hpp @@ -0,0 +1,32 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. 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/ +// +#define BOOST_RANGE_combined_args(z, n, i) \ + BOOST_PP_CAT(R, n)&& BOOST_PP_CAT(r, n) + +#define BOOST_RANGE_combined_range_iterator(z, n, i) \ + typename range_iterator< \ + typename remove_reference::type \ + >::type + + +#define BOOST_RANGE_combine(z, n, data) \ + template \ + inline range::combined_range< \ + tuple \ + > \ + combine(BOOST_PP_ENUM(n, BOOST_RANGE_combined_args, ~)) \ + { \ + typedef tuple< \ + BOOST_PP_ENUM(n, BOOST_RANGE_combined_range_iterator, ~) \ + > rng_tuple_t; \ + return range::combined_range( \ + rng_tuple_t(BOOST_PP_ENUM(n, BOOST_RANGE_combined_seq, begin)), \ + rng_tuple_t(BOOST_PP_ENUM(n, BOOST_RANGE_combined_seq, end))); \ + } diff --git a/include/boost/range/iterator.hpp b/include/boost/range/iterator.hpp index 2966bdf..3ba9952 100644 --- a/include/boost/range/iterator.hpp +++ b/include/boost/range/iterator.hpp @@ -57,10 +57,15 @@ namespace boost #else - typedef BOOST_RANGE_DEDUCED_TYPENAME - mpl::eval_if_c< is_const::value, - range_const_iterator< typename remove_const::type >, - range_mutable_iterator >::type type; + private: + typedef typename remove_reference::type param_t; + + public: + typedef typename mpl::eval_if_c< + is_const::value, + range_const_iterator::type>, + range_mutable_iterator + >::type type; #endif }; diff --git a/test/combine.cpp b/test/combine.cpp index c020626..11f674b 100644 --- a/test/combine.cpp +++ b/test/combine.cpp @@ -1,5 +1,7 @@ // Boost.Range library // +// Copyright Neil Groves 2014 +// // Copyright Thorsten Ottosen 2006. Use, modification and // distribution is subject to the Boost Software License, Version // 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -7,65 +9,152 @@ // // For more information, see http://www.boost.org/libs/range/ // - #include + +#include + #include #include -#include #include #include - -struct add +namespace boost_range_test { - template< class T > - int operator()( const T& tuple ) const + namespace { - return boost::get<0>(tuple) + boost::get<1>(tuple); - } -}; -template< class CombinedRng > -void apply( const CombinedRng& r ) +template +void test_combine2() { std::vector v; - typedef BOOST_DEDUCED_TYPENAME boost::range_iterator::type iterator_t; + std::list l; - iterator_t e = boost::end(r); - for (iterator_t i = boost::begin(r); i != e; ++i) + for (int i = 0; i < 10; ++i) { + v.push_back(i); + l.push_back(i * 2); + } + + ContRef1& in1 = v; + ContRef2& in2 = l; + + std::vector > output; + boost::push_back(output, boost::combine(in1, in2)); + + int index = 0; + int i1, i2; + BOOST_FOREACH(boost::tie(i1,i2), output) + { + BOOST_CHECK_EQUAL(i1, index); + BOOST_CHECK_EQUAL(i2, index * 2); + ++index; } } -void test_combine() +template +void test_combine3() { - std::vector v1, v2, v3; - for (int i = 1; i <= 4; ++i) + std::vector v1; + std::vector v2; + std::vector v3; + + for (int i = 0; i < 10; ++i) { v1.push_back(i); - v2.push_back(i); + v2.push_back(i * 2); + v3.push_back(i * 3); } - int i1, i2; - BOOST_FOREACH( boost::tie( i1, i2 ), boost::combine(v1,v2) ) + ContRef1& in1 = v1; + ContRef2& in2 = v2; + ContRef3& in3 = v3; + + std::vector > output; + boost::push_back(output, boost::combine(in1, in2, in3)); + + int index = 0; + int i1, i2, i3; + + BOOST_FOREACH(boost::tie(i1,i2,i3), output) { - v3.push_back( i1 + i2 ); + BOOST_CHECK_EQUAL(i1, index); + BOOST_CHECK_EQUAL(i2, index * 2); + BOOST_CHECK_EQUAL(i3, index * 3); + ++index; } - - BOOST_CHECK_EQUAL( v3.size(), v1.size() ); } + } // anonymous namespace +} // namespace boost_range_test - -using boost::unit_test::test_suite; - -test_suite* init_unit_test_suite( int argc, char* argv[] ) +boost::unit_test::test_suite* init_unit_test_suite(int, char*[] ) { - test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" ); + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE( "Boost.Range combine() test suite" ); - test->add( BOOST_TEST_CASE( &test_combine ) ); + test->add(BOOST_TEST_CASE(( + &boost_range_test::test_combine2< + const std::vector, const std::list >))); + + test->add(BOOST_TEST_CASE(( + &boost_range_test::test_combine2< + const std::vector, std::list >))); + + test->add(BOOST_TEST_CASE(( + &boost_range_test::test_combine2< + std::vector, const std::list >))); + + test->add(BOOST_TEST_CASE(( + &boost_range_test::test_combine2< + std::vector, std::list >))); + + test->add(BOOST_TEST_CASE(( + &boost_range_test::test_combine3< + std::vector, + std::vector, + std::vector >))); + + test->add(BOOST_TEST_CASE(( + &boost_range_test::test_combine3< + std::vector, + std::vector, + const std::vector >))); + + test->add(BOOST_TEST_CASE(( + &boost_range_test::test_combine3< + std::vector, + const std::vector, + std::vector >))); + + test->add(BOOST_TEST_CASE(( + &boost_range_test::test_combine3< + std::vector, + const std::vector, + const std::vector >))); + + test->add(BOOST_TEST_CASE(( + &boost_range_test::test_combine3< + const std::vector, + std::vector, + std::vector >))); + + test->add(BOOST_TEST_CASE(( + &boost_range_test::test_combine3< + const std::vector, + std::vector, + const std::vector >))); + + test->add(BOOST_TEST_CASE(( + &boost_range_test::test_combine3< + const std::vector, + const std::vector, + std::vector >))); + + test->add(BOOST_TEST_CASE(( + &boost_range_test::test_combine3< + const std::vector, + const std::vector, + const std::vector >))); return test; } - - From 7147a00fd7d1797762dd05cd5c140b2296d58aef Mon Sep 17 00:00:00 2001 From: Neil Groves Date: Sat, 8 Mar 2014 21:19:03 +0000 Subject: [PATCH 2/9] ticket 5817 any_range default template params. --- include/boost/range/any_range.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/range/any_range.hpp b/include/boost/range/any_range.hpp index ba4c224..9b7f87c 100644 --- a/include/boost/range/any_range.hpp +++ b/include/boost/range/any_range.hpp @@ -75,8 +75,8 @@ namespace boost template< class Value , class Traversal - , class Reference - , class Difference + , class Reference = Value& + , class Difference = std::ptrdiff_t , class Buffer = use_default > class any_range From 7cd8b9ec24747647c0f0dd3e69d07e490d6be6f2 Mon Sep 17 00:00:00 2001 From: Neil Groves Date: Sat, 8 Mar 2014 21:28:52 +0000 Subject: [PATCH 3/9] updated algorithms.qbk to explicitly mention range_return_value so that this can be searched for. --- doc/reference/algorithms.qbk | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/reference/algorithms.qbk b/doc/reference/algorithms.qbk index 5cfabc7..ce4b140 100644 --- a/doc/reference/algorithms.qbk +++ b/doc/reference/algorithms.qbk @@ -37,7 +37,9 @@ boost::copy(boost::unique(boost::sort(vec)), std::ostream_iterator(std::cout)); `` -Algorithms like `boost::unique` usually return the same range: `[boost::begin(rng), found)`. However, this behaviour may be changed by supplying the algorithms with a template argument: +Algorithms like `boost::unique` usually return the range: `[boost::begin(rng), found)`. +However, this behaviour may be changed by supplying a `range_return_value` +as a template parameter to the algorithm: [table [[Expression] [Return]] @@ -177,4 +179,4 @@ and there is no need to worry about generating an invalid range. Furthermore, if [include numeric/inner_product.qbk] [include numeric/partial_sum.qbk] [endsect] -[endsect] \ No newline at end of file +[endsect] From 343e74b8e3d532eaf9e896b00cafa82bb63c5129 Mon Sep 17 00:00:00 2001 From: Neil Groves Date: Sat, 8 Mar 2014 21:42:42 +0000 Subject: [PATCH 4/9] added algorithm_ext insert algorithm for containers without a where iterator. --- doc/reference/algorithm_ext/insert.qbk | 10 +++++++++- include/boost/range/algorithm_ext/insert.hpp | 10 ++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/doc/reference/algorithm_ext/insert.qbk b/doc/reference/algorithm_ext/insert.qbk index 532e256..e9f48eb 100644 --- a/doc/reference/algorithm_ext/insert.qbk +++ b/doc/reference/algorithm_ext/insert.qbk @@ -11,10 +11,18 @@ template< class Container, class SinglePassRange - > +> Container& insert(Container& target, typename Container::iterator before, const SinglePassRange& from); + +// This overload is for target containers that do not require an insertion +// position e.g. set/map +template< + class Container, + class SinglePassRange +> +Container& insert(Container& target, const SinglePassRange& from); `` [heading Description] diff --git a/include/boost/range/algorithm_ext/insert.hpp b/include/boost/range/algorithm_ext/insert.hpp index b9adfdd..c0c04c8 100755 --- a/include/boost/range/algorithm_ext/insert.hpp +++ b/include/boost/range/algorithm_ext/insert.hpp @@ -29,12 +29,18 @@ inline Container& insert( Container& on, { BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); - BOOST_ASSERT( (void*)&on != (void*)&from && - "cannot copy from a container to itself" ); on.insert( before, boost::begin(from), boost::end(from) ); return on; } +template< class Container, class Range > +inline Container& insert( Container& on, const Range& from ) +{ + BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + on.insert(boost::begin(from), boost::end(from)); +} + } // namespace range using range::insert; } // namespace boost From 9d0d5199ba11307025cffa403dfbebf36a000c75 Mon Sep 17 00:00:00 2001 From: Neil Groves Date: Sat, 8 Mar 2014 21:54:55 +0000 Subject: [PATCH 5/9] ticket 9072 iterator_range accept reference to function type. --- include/boost/range/iterator_range_core.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/boost/range/iterator_range_core.hpp b/include/boost/range/iterator_range_core.hpp index e30f1a6..ba842ab 100644 --- a/include/boost/range/iterator_range_core.hpp +++ b/include/boost/range/iterator_range_core.hpp @@ -7,6 +7,10 @@ // // For more information, see http://www.boost.org/libs/range/ // +// Credits: +// 'michel' reported Trac 9072 which included a patch for allowing references +// to function types. +// #ifndef BOOST_RANGE_ITERATOR_RANGE_CORE_HPP_INCLUDED #define BOOST_RANGE_ITERATOR_RANGE_CORE_HPP_INCLUDED @@ -25,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -300,6 +305,9 @@ public: >, boost::is_array< BOOST_DEDUCED_TYPENAME base_type::value_type + >, + boost::is_function< + BOOST_DEDUCED_TYPENAME base_type::value_type > >, BOOST_DEDUCED_TYPENAME base_type::reference, From 90faa3941c5bba322cc9fe9541442ed80f3d51e2 Mon Sep 17 00:00:00 2001 From: Neil Groves Date: Sat, 8 Mar 2014 22:00:27 +0000 Subject: [PATCH 6/9] ticket 7328 gccxml compatibility. --- include/boost/range/concepts.hpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/boost/range/concepts.hpp b/include/boost/range/concepts.hpp index 5a02a21..722b14f 100644 --- a/include/boost/range/concepts.hpp +++ b/include/boost/range/concepts.hpp @@ -72,6 +72,13 @@ namespace boost { #endif #endif + #ifdef __GCCXML__ + // GCC XML, unsurprisingly, has the same issues + #if __GCCXML_GNUC__ == 4 && __GCCXML_GNUC_MINOR__ == 2 + #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0 + #endif + #endif + #ifdef __BORLANDC__ #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0 #endif From f86d4877060a1349a1f9c18f3bbec8e2a5cd57fd Mon Sep 17 00:00:00 2001 From: Neil Groves Date: Sat, 8 Mar 2014 22:23:22 +0000 Subject: [PATCH 7/9] ticket 7294 iterator_range hash_value support. --- include/boost/range/iterator_range_hash.hpp | 22 +++++++++ test/Jamfile.v2 | 1 + test/iterator_range_hash.cpp | 52 +++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 include/boost/range/iterator_range_hash.hpp create mode 100644 test/iterator_range_hash.cpp diff --git a/include/boost/range/iterator_range_hash.hpp b/include/boost/range/iterator_range_hash.hpp new file mode 100644 index 0000000..615d22f --- /dev/null +++ b/include/boost/range/iterator_range_hash.hpp @@ -0,0 +1,22 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014 +// 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 + +namespace boost +{ + +template +std::size_t hash_value(const iterator_range& rng) +{ + return boost::hash_range(rng.begin(), rng.end()); +} + +} // namespace boost diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 8b9463e..c5bf79e 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -161,6 +161,7 @@ test-suite range : [ range-test iterator_pair ] [ range-test iterator_range ] [ range-test iterator_range_drop ] + [ range-test iterator_range_hash ] [ range-test iterator_range_variant ] # [ range-test mfc : $(VC71_ROOT)/atlmfc/include ] [ range-test join ] diff --git a/test/iterator_range_hash.cpp b/test/iterator_range_hash.cpp new file mode 100644 index 0000000..3ef9007 --- /dev/null +++ b/test/iterator_range_hash.cpp @@ -0,0 +1,52 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. 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 + +namespace boost_range_test +{ + namespace + { + +void test_iterator_range_hash() +{ + std::vector v; + + for (boost::int32_t i = 0; i < 10; ++i) + { + v.push_back(i); + } + + std::size_t ref_output = boost::hash_range(v.begin(), v.end()); + + boost::iterator_range::iterator> rng(v); + + std::size_t test_output = boost::hash_value(rng); + + BOOST_CHECK_EQUAL(ref_output, test_output); +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range iterator_range hash function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_iterator_range_hash)); + + return test; +} From be85e295e8eb77a13eca01d4ebeba70e8412cc10 Mon Sep 17 00:00:00 2001 From: Neil Groves Date: Sat, 8 Mar 2014 22:38:25 +0000 Subject: [PATCH 8/9] updated docs for hash_value iterator_range support. --- doc/reference/utilities.qbk | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/reference/utilities.qbk b/doc/reference/utilities.qbk index cde1720..b39904f 100644 --- a/doc/reference/utilities.qbk +++ b/doc/reference/utilities.qbk @@ -9,6 +9,7 @@ Having an abstraction that encapsulates a pair of iterators is very useful. The * Class `iterator_range` * Class `sub_range` +* Function `combine` * Function `join` The `iterator_range` class is templated on an __forward_traversal_iterator__ and should be used whenever fairly general code is needed. The `sub_range` class is templated on an __forward_range__ and it is less general, but a bit easier to use since its template argument is easier to specify. The biggest difference is, however, that a `sub_range` can propagate constness because it knows what a corresponding `const_iterator` is. @@ -26,6 +27,14 @@ Recall that many default constructed iterators are [*/singular/] and hence can o [h4 Synopsis] +The core functionality is in the header file +`` this includes all of the functionality +except the `boost::hash_value` and `std::iostream` support. + +The `std::iostream` support is in the header `` +while the `boost::hash_value` support is in +`` + `` namespace boost { From 4ebbbba82b62e6f7deaefe1ad22a26a894ff3417 Mon Sep 17 00:00:00 2001 From: Neil Groves Date: Sun, 9 Mar 2014 00:28:43 +0000 Subject: [PATCH 9/9] ticket 7885 rvalue support for metafunctions. --- include/boost/range/const_iterator.hpp | 2 +- .../boost/range/const_reverse_iterator.hpp | 3 +- include/boost/range/difference_type.hpp | 8 ++- include/boost/range/has_range_iterator.hpp | 7 ++- include/boost/range/mutable_iterator.hpp | 6 +- include/boost/range/pointer.hpp | 3 +- include/boost/range/reverse_iterator.hpp | 4 +- test/Jamfile.v2 | 13 ++++ test/category.cpp | 61 ++++++++++++++++++ test/const_iterator.cpp | 61 ++++++++++++++++++ test/const_reverse_iterator.cpp | 62 +++++++++++++++++++ test/difference_type.cpp | 61 ++++++++++++++++++ test/has_range_iterator.cpp | 11 ++++ test/iterator.cpp | 61 ++++++++++++++++++ test/mutable_iterator.cpp | 61 ++++++++++++++++++ test/pointer.cpp | 61 ++++++++++++++++++ test/reference.cpp | 61 ++++++++++++++++++ test/result_iterator.cpp | 61 ++++++++++++++++++ test/reverse_iterator.cpp | 61 ++++++++++++++++++ test/reverse_result_iterator.cpp | 62 +++++++++++++++++++ test/size_type.cpp | 61 ++++++++++++++++++ test/value_type.cpp | 61 ++++++++++++++++++ 22 files changed, 844 insertions(+), 8 deletions(-) create mode 100644 test/category.cpp create mode 100644 test/const_iterator.cpp create mode 100644 test/const_reverse_iterator.cpp create mode 100644 test/difference_type.cpp create mode 100644 test/iterator.cpp create mode 100644 test/mutable_iterator.cpp create mode 100644 test/pointer.cpp create mode 100644 test/reference.cpp create mode 100644 test/result_iterator.cpp create mode 100644 test/reverse_iterator.cpp create mode 100644 test/reverse_result_iterator.cpp create mode 100644 test/size_type.cpp create mode 100644 test/value_type.cpp diff --git a/include/boost/range/const_iterator.hpp b/include/boost/range/const_iterator.hpp index 1cdbf03..1876794 100644 --- a/include/boost/range/const_iterator.hpp +++ b/include/boost/range/const_iterator.hpp @@ -65,7 +65,7 @@ struct range_const_iterator< T[sz] > template struct range_const_iterator : range_detail::range_const_iterator< - typename remove_reference::type + BOOST_DEDUCED_TYPENAME remove_reference::type > { }; diff --git a/include/boost/range/const_reverse_iterator.hpp b/include/boost/range/const_reverse_iterator.hpp index d580aee..bfe1615 100644 --- a/include/boost/range/const_reverse_iterator.hpp +++ b/include/boost/range/const_reverse_iterator.hpp @@ -26,7 +26,8 @@ namespace boost template< typename C > struct range_const_reverse_iterator - : range_reverse_iterator::type> + : range_reverse_iterator< + const BOOST_DEDUCED_TYPENAME remove_reference::type> { }; } // namespace boost diff --git a/include/boost/range/difference_type.hpp b/include/boost/range/difference_type.hpp index 4578002..afd8b07 100644 --- a/include/boost/range/difference_type.hpp +++ b/include/boost/range/difference_type.hpp @@ -18,11 +18,17 @@ #include #include #include +#include namespace boost { template< class T > - struct range_difference : iterator_difference< typename range_iterator::type > + struct range_difference + : iterator_difference< + BOOST_DEDUCED_TYPENAME range_iterator< + BOOST_DEDUCED_TYPENAME remove_reference::type + >::type + > { }; } diff --git a/include/boost/range/has_range_iterator.hpp b/include/boost/range/has_range_iterator.hpp index 3c7b083..26a6452 100644 --- a/include/boost/range/has_range_iterator.hpp +++ b/include/boost/range/has_range_iterator.hpp @@ -17,6 +17,7 @@ #include #include #include +#include #include namespace boost @@ -67,12 +68,14 @@ namespace boost template struct has_range_iterator - : range_detail::has_range_iterator_impl + : range_detail::has_range_iterator_impl< + BOOST_DEDUCED_TYPENAME remove_reference::type> {}; template struct has_range_const_iterator - : range_detail::has_range_const_iterator_impl + : range_detail::has_range_const_iterator_impl< + BOOST_DEDUCED_TYPENAME remove_reference::type> {}; } // namespace boost diff --git a/include/boost/range/mutable_iterator.hpp b/include/boost/range/mutable_iterator.hpp index f1bd1a1..387262f 100644 --- a/include/boost/range/mutable_iterator.hpp +++ b/include/boost/range/mutable_iterator.hpp @@ -19,12 +19,14 @@ #include +#include #include #include #include namespace boost { + ////////////////////////////////////////////////////////////////////////// // default ////////////////////////////////////////////////////////////////////////// @@ -34,7 +36,9 @@ namespace boost } template< typename C > - struct range_mutable_iterator : range_detail::extract_iterator + struct range_mutable_iterator + : range_detail::extract_iterator< + BOOST_DEDUCED_TYPENAME remove_reference::type> {}; ////////////////////////////////////////////////////////////////////////// diff --git a/include/boost/range/pointer.hpp b/include/boost/range/pointer.hpp index c3ed503..b1e8dc5 100644 --- a/include/boost/range/pointer.hpp +++ b/include/boost/range/pointer.hpp @@ -22,7 +22,8 @@ namespace boost { template< class T > - struct range_pointer : iterator_pointer< typename range_iterator::type > + struct range_pointer + : iterator_pointer< BOOST_DEDUCED_TYPENAME range_iterator::type > { }; } diff --git a/include/boost/range/reverse_iterator.hpp b/include/boost/range/reverse_iterator.hpp index 2569b17..a2c492e 100644 --- a/include/boost/range/reverse_iterator.hpp +++ b/include/boost/range/reverse_iterator.hpp @@ -17,6 +17,7 @@ #include #include +#include #include @@ -30,7 +31,8 @@ namespace boost struct range_reverse_iterator { typedef reverse_iterator< - BOOST_DEDUCED_TYPENAME range_iterator::type > type; + BOOST_DEDUCED_TYPENAME range_iterator< + BOOST_DEDUCED_TYPENAME remove_reference::type>::type > type; }; diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index c5bf79e..59251f1 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -147,17 +147,22 @@ test-suite range : [ range-test array ] # [ range-test atl : $(VC71_ROOT)/atlmfc/include ] [ range-test begin ] + [ range-test category ] [ range-test combine ] [ range-test compat2 ] [ range-test compat3 ] + [ range-test const_iterator ] [ range-test const_ranges ] + [ range-test const_reverse_iterator ] [ range-test counting_range ] + [ range-test difference_type ] [ range-test end ] [ range-test extension_mechanism ] [ range-test extension_size ] [ range-test has_range_iterator ] [ range-test irange ] [ range-test istream_range ] + [ range-test iterator ] [ range-test iterator_pair ] [ range-test iterator_range ] [ range-test iterator_range_drop ] @@ -165,9 +170,16 @@ test-suite range : [ range-test iterator_range_variant ] # [ range-test mfc : $(VC71_ROOT)/atlmfc/include ] [ range-test join ] + [ range-test mutable_iterator ] [ range-test partial_workaround ] + [ range-test pointer ] [ range-test pointer_as_iterator ] + [ range-test reference ] + [ range-test result_iterator ] + [ range-test reverse_iterator ] + [ range-test reverse_result_iterator ] [ range-test reversible_range ] + [ range-test size_type ] [ range-test std_container ] [ range-test string ] [ range-test sub_range ] @@ -178,5 +190,6 @@ test-suite range : [ range-test ticket_5811_indirected_optional ] [ range-test ticket_6715_iterator_range_equality ] [ range-test ticket_6944 ] + [ range-test value_type ] ; diff --git a/test/category.cpp b/test/category.cpp new file mode 100644 index 0000000..154c411 --- /dev/null +++ b/test/category.cpp @@ -0,0 +1,61 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. 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_range_test +{ + namespace + { + +void test_category() +{ + typedef std::vector cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::iterator_category::type, + boost::range_category::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::iterator_category::type, + boost::range_category::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::iterator_category::type, + boost::range_category::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range range_category meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_category)); + + return test; +} diff --git a/test/const_iterator.cpp b/test/const_iterator.cpp new file mode 100644 index 0000000..63238c8 --- /dev/null +++ b/test/const_iterator.cpp @@ -0,0 +1,61 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. 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_range_test +{ + namespace + { + +void test_const_iterator() +{ + typedef std::vector cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::const_iterator, + boost::range_const_iterator::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::const_iterator, + boost::range_const_iterator::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::const_iterator, + boost::range_const_iterator::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range range_const_iterator meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_const_iterator)); + + return test; +} diff --git a/test/const_reverse_iterator.cpp b/test/const_reverse_iterator.cpp new file mode 100644 index 0000000..44726fd --- /dev/null +++ b/test/const_reverse_iterator.cpp @@ -0,0 +1,62 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. 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_range_test +{ + namespace + { + +void test_const_reverse_iterator() +{ + typedef std::vector cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::reverse_iterator, + boost::range_const_reverse_iterator::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::reverse_iterator, + boost::range_const_reverse_iterator::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::reverse_iterator, + boost::range_const_reverse_iterator::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE( + "Boost.Range range_const_reverse_iterator meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_const_reverse_iterator)); + + return test; +} diff --git a/test/difference_type.cpp b/test/difference_type.cpp new file mode 100644 index 0000000..556250a --- /dev/null +++ b/test/difference_type.cpp @@ -0,0 +1,61 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. 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_range_test +{ + namespace + { + +void test_difference() +{ + typedef std::vector cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::difference_type, + boost::range_difference::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::difference_type, + boost::range_difference::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::difference_type, + boost::range_difference::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range range_difference meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_difference)); + + return test; +} diff --git a/test/has_range_iterator.cpp b/test/has_range_iterator.cpp index eabb630..2efc88b 100644 --- a/test/has_range_iterator.cpp +++ b/test/has_range_iterator.cpp @@ -9,6 +9,7 @@ // For more information, see http://www.boost.org/libs/range/ // #include +#include #include #include @@ -35,12 +36,22 @@ namespace { test_has_range_iterator_impl< std::vector >(true); test_has_range_iterator_impl< MockClassWithoutIterators >(false); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + test_has_range_iterator_impl&&>(true); + test_has_range_iterator_impl(false); +#endif } void test_has_range_const_iterator() { test_has_range_const_iterator_impl< std::vector >(true); test_has_range_const_iterator_impl< MockClassWithoutIterators >(false); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + test_has_range_const_iterator_impl&&>(true); + test_has_range_const_iterator_impl(false); +#endif } } diff --git a/test/iterator.cpp b/test/iterator.cpp new file mode 100644 index 0000000..76c915a --- /dev/null +++ b/test/iterator.cpp @@ -0,0 +1,61 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. 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_range_test +{ + namespace + { + +void test_iterator() +{ + typedef std::vector cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::iterator, + boost::range_iterator::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::const_iterator, + boost::range_iterator::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::iterator, + boost::range_iterator::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range range_iterator meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_iterator)); + + return test; +} diff --git a/test/mutable_iterator.cpp b/test/mutable_iterator.cpp new file mode 100644 index 0000000..40a3879 --- /dev/null +++ b/test/mutable_iterator.cpp @@ -0,0 +1,61 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. 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_range_test +{ + namespace + { + +void test_mutable_iterator() +{ + typedef std::vector cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::iterator, + boost::range_mutable_iterator::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::iterator, + boost::range_mutable_iterator::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::iterator, + boost::range_mutable_iterator::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range range_mutable_iterator meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_mutable_iterator)); + + return test; +} diff --git a/test/pointer.cpp b/test/pointer.cpp new file mode 100644 index 0000000..94e78f3 --- /dev/null +++ b/test/pointer.cpp @@ -0,0 +1,61 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. 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_range_test +{ + namespace + { + +void test_pointer() +{ + typedef std::vector cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::pointer, + boost::range_pointer::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::const_pointer, + boost::range_pointer::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::pointer, + boost::range_pointer::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range range_pointer meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_pointer)); + + return test; +} diff --git a/test/reference.cpp b/test/reference.cpp new file mode 100644 index 0000000..755be0e --- /dev/null +++ b/test/reference.cpp @@ -0,0 +1,61 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. 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_range_test +{ + namespace + { + +void test_reference() +{ + typedef std::vector cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::reference, + boost::range_reference::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::const_reference, + boost::range_reference::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::reference, + boost::range_reference::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range range_reference meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_reference)); + + return test; +} diff --git a/test/result_iterator.cpp b/test/result_iterator.cpp new file mode 100644 index 0000000..88dd7a5 --- /dev/null +++ b/test/result_iterator.cpp @@ -0,0 +1,61 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. 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_range_test +{ + namespace + { + +void test_result_iterator() +{ + typedef std::vector cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::iterator, + boost::range_result_iterator::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::const_iterator, + boost::range_result_iterator::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::iterator, + boost::range_result_iterator::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range range_result_iterator meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_result_iterator)); + + return test; +} diff --git a/test/reverse_iterator.cpp b/test/reverse_iterator.cpp new file mode 100644 index 0000000..827f244 --- /dev/null +++ b/test/reverse_iterator.cpp @@ -0,0 +1,61 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. 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_range_test +{ + namespace + { + +void test_reverse_iterator() +{ + typedef std::vector cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::reverse_iterator, + boost::range_reverse_iterator::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::reverse_iterator, + boost::range_reverse_iterator::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::reverse_iterator, + boost::range_reverse_iterator::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range range_reverse_iterator meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_reverse_iterator)); + + return test; +} diff --git a/test/reverse_result_iterator.cpp b/test/reverse_result_iterator.cpp new file mode 100644 index 0000000..7d160fe --- /dev/null +++ b/test/reverse_result_iterator.cpp @@ -0,0 +1,62 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. 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_range_test +{ + namespace + { + +void test_reverse_result_iterator() +{ + typedef std::vector cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::reverse_iterator, + boost::range_reverse_result_iterator::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::reverse_iterator, + boost::range_reverse_result_iterator::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::reverse_iterator, + boost::range_reverse_result_iterator::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE( + "Boost.Range range_reverse_result_iterator meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_reverse_result_iterator)); + + return test; +} diff --git a/test/size_type.cpp b/test/size_type.cpp new file mode 100644 index 0000000..9c335f1 --- /dev/null +++ b/test/size_type.cpp @@ -0,0 +1,61 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. 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_range_test +{ + namespace + { + +void test_size() +{ + typedef std::vector cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::size_type, + boost::range_size::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::size_type, + boost::range_size::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::size_type, + boost::range_size::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range range_size meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_size)); + + return test; +} diff --git a/test/value_type.cpp b/test/value_type.cpp new file mode 100644 index 0000000..9a18b2f --- /dev/null +++ b/test/value_type.cpp @@ -0,0 +1,61 @@ +// Boost.Range library +// +// Copyright Neil Groves 2014. 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_range_test +{ + namespace + { + +void test_value_type() +{ + typedef std::vector cont; + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::value_type, + boost::range_value::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::value_type, + boost::range_value::type + >::value)); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + cont::value_type, + boost::range_value::type + >::value)); +#endif +} + + } // anonymous namespace +} // namespace boost_range_test + +boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("Boost.Range range_value meta-function"); + + test->add(BOOST_TEST_CASE(&boost_range_test::test_value_type)); + + return test; +}