diff --git a/include/boost/range/adaptor/filtered.hpp b/include/boost/range/adaptor/filtered.hpp index 9e050a6..b6d3ab1 100644 --- a/include/boost/range/adaptor/filtered.hpp +++ b/include/boost/range/adaptor/filtered.hpp @@ -12,6 +12,7 @@ #define BOOST_RANGE_ADAPTOR_FILTERED_HPP #include +#include #include #include #include @@ -23,21 +24,28 @@ namespace boost template< class P, class R > struct filtered_range : boost::iterator_range< - boost::filter_iterator< P, - BOOST_DEDUCED_TYPENAME range_iterator::type + boost::filter_iterator< + typename default_constructible_unary_fn_gen::type, + typename range_iterator::type > > { private: typedef boost::iterator_range< - boost::filter_iterator< P, - BOOST_DEDUCED_TYPENAME range_iterator::type - > - > base; + boost::filter_iterator< + typename default_constructible_unary_fn_gen::type, + typename range_iterator::type + > + > base; public: - filtered_range( P p, R& r ) - : base( make_filter_iterator( p, boost::begin(r), boost::end(r) ), - make_filter_iterator( p, boost::end(r), boost::end(r) ) ) + typedef typename default_constructible_unary_fn_gen::type + pred_t; + + filtered_range(P p, R& r) + : base(make_filter_iterator(pred_t(p), + boost::begin(r), boost::end(r)), + make_filter_iterator(pred_t(p), + boost::end(r), boost::end(r))) { } }; diff --git a/include/boost/range/adaptor/replaced.hpp b/include/boost/range/adaptor/replaced.hpp index 2a6ab56..1950b82 100644 --- a/include/boost/range/adaptor/replaced.hpp +++ b/include/boost/range/adaptor/replaced.hpp @@ -20,6 +20,7 @@ #include #include #include +#include namespace boost { @@ -32,19 +33,36 @@ namespace boost typedef const Value& result_type; typedef const Value& first_argument_type; + // Rationale: + // The default constructor is required to allow the transform + // iterator to properly model the iterator concept. + replace_value() + { + } + replace_value(const Value& from, const Value& to) - : m_from(from), m_to(to) + : m_impl(data(from, to)) { } const Value& operator()(const Value& x) const { - return (x == m_from) ? m_to : x; + return (x == m_impl->m_from) ? m_impl->m_to : x; } private: - Value m_from; - Value m_to; + struct data + { + data(const Value& from, const Value& to) + : m_from(from) + , m_to(to) + { + } + + Value m_from; + Value m_to; + }; + boost::optional m_impl; }; template< class R > diff --git a/include/boost/range/adaptor/replaced_if.hpp b/include/boost/range/adaptor/replaced_if.hpp index b9f73ae..e425e7d 100644 --- a/include/boost/range/adaptor/replaced_if.hpp +++ b/include/boost/range/adaptor/replaced_if.hpp @@ -20,6 +20,7 @@ #include #include #include +#include namespace boost { @@ -32,19 +33,34 @@ namespace boost typedef const Value& result_type; typedef const Value& first_argument_type; + // Rationale: + // required to allow the iterator to be default constructible. + replace_value_if() + { + } + replace_value_if(const Pred& pred, const Value& to) - : m_pred(pred), m_to(to) + : m_impl(data(pred, to)) { } const Value& operator()(const Value& x) const { - return m_pred(x) ? m_to : x; + return m_impl->m_pred(x) ? m_impl->m_to : x; } private: - Pred m_pred; - Value m_to; + struct data + { + data(const Pred& p, const Value& t) + : m_pred(p), m_to(t) + { + } + + Pred m_pred; + Value m_to; + }; + boost::optional m_impl; }; template< class Pred, class R > diff --git a/include/boost/range/adaptor/transformed.hpp b/include/boost/range/adaptor/transformed.hpp index 9edd27c..428ff4b 100644 --- a/include/boost/range/adaptor/transformed.hpp +++ b/include/boost/range/adaptor/transformed.hpp @@ -12,6 +12,7 @@ #define BOOST_RANGE_ADAPTOR_TRANSFORMED_HPP #include +#include #include #include #include @@ -21,31 +22,46 @@ namespace boost { namespace range_detail { + // A type generator to produce the transform_iterator type conditionally + // including a wrapped predicate as appropriate. + template + struct transform_iterator_gen + { + typedef transform_iterator< + typename default_constructible_unary_fn_gen< + P, + typename transform_iterator::reference + >::type, + It + > type; + }; template< class F, class R > struct transformed_range : public boost::iterator_range< - boost::transform_iterator< F, - BOOST_DEDUCED_TYPENAME range_iterator::type - > - > + typename transform_iterator_gen< + F, typename range_iterator::type>::type> { private: - typedef boost::iterator_range< - boost::transform_iterator< F, - BOOST_DEDUCED_TYPENAME range_iterator::type - > - > - base; + typedef typename transform_iterator_gen< + F, typename range_iterator::type>::type transform_iter_t; + + typedef boost::iterator_range base; public: - typedef F transform_fn_type; + typedef typename default_constructible_unary_fn_gen< + F, + typename transform_iterator< + F, + typename range_iterator::type + >::reference + >::type transform_fn_type; + typedef R source_range_type; - transformed_range( F f, R& r ) - : base( boost::make_transform_iterator( boost::begin(r), f ), - boost::make_transform_iterator( boost::end(r), f ) ) - + transformed_range(transform_fn_type f, R& r) + : base(transform_iter_t(boost::begin(r), f), + transform_iter_t(boost::end(r), f)) { } }; diff --git a/include/boost/range/adaptor/type_erased.hpp b/include/boost/range/adaptor/type_erased.hpp index 2298de6..ba5b159 100644 --- a/include/boost/range/adaptor/type_erased.hpp +++ b/include/boost/range/adaptor/type_erased.hpp @@ -15,7 +15,6 @@ #include #include #include -#include namespace boost { diff --git a/include/boost/range/adaptors.hpp b/include/boost/range/adaptors.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/adjacent_find.hpp b/include/boost/range/algorithm/adjacent_find.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/binary_search.hpp b/include/boost/range/algorithm/binary_search.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/copy_backward.hpp b/include/boost/range/algorithm/copy_backward.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/count.hpp b/include/boost/range/algorithm/count.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/count_if.hpp b/include/boost/range/algorithm/count_if.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/equal_range.hpp b/include/boost/range/algorithm/equal_range.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/fill.hpp b/include/boost/range/algorithm/fill.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/fill_n.hpp b/include/boost/range/algorithm/fill_n.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/find.hpp b/include/boost/range/algorithm/find.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/find_end.hpp b/include/boost/range/algorithm/find_end.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/find_first_of.hpp b/include/boost/range/algorithm/find_first_of.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/find_if.hpp b/include/boost/range/algorithm/find_if.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/generate.hpp b/include/boost/range/algorithm/generate.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/heap_algorithm.hpp b/include/boost/range/algorithm/heap_algorithm.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/inplace_merge.hpp b/include/boost/range/algorithm/inplace_merge.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/lexicographical_compare.hpp b/include/boost/range/algorithm/lexicographical_compare.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/lower_bound.hpp b/include/boost/range/algorithm/lower_bound.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/max_element.hpp b/include/boost/range/algorithm/max_element.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/merge.hpp b/include/boost/range/algorithm/merge.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/min_element.hpp b/include/boost/range/algorithm/min_element.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/mismatch.hpp b/include/boost/range/algorithm/mismatch.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/nth_element.hpp b/include/boost/range/algorithm/nth_element.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/partial_sort.hpp b/include/boost/range/algorithm/partial_sort.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/partial_sort_copy.hpp b/include/boost/range/algorithm/partial_sort_copy.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/partition.hpp b/include/boost/range/algorithm/partition.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/permutation.hpp b/include/boost/range/algorithm/permutation.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/random_shuffle.hpp b/include/boost/range/algorithm/random_shuffle.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/remove.hpp b/include/boost/range/algorithm/remove.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/remove_copy.hpp b/include/boost/range/algorithm/remove_copy.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/remove_copy_if.hpp b/include/boost/range/algorithm/remove_copy_if.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/remove_if.hpp b/include/boost/range/algorithm/remove_if.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/replace.hpp b/include/boost/range/algorithm/replace.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/replace_copy.hpp b/include/boost/range/algorithm/replace_copy.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/replace_copy_if.hpp b/include/boost/range/algorithm/replace_copy_if.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/replace_if.hpp b/include/boost/range/algorithm/replace_if.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/reverse.hpp b/include/boost/range/algorithm/reverse.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/reverse_copy.hpp b/include/boost/range/algorithm/reverse_copy.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/rotate.hpp b/include/boost/range/algorithm/rotate.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/rotate_copy.hpp b/include/boost/range/algorithm/rotate_copy.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/search.hpp b/include/boost/range/algorithm/search.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/set_algorithm.hpp b/include/boost/range/algorithm/set_algorithm.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/sort.hpp b/include/boost/range/algorithm/sort.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/stable_partition.hpp b/include/boost/range/algorithm/stable_partition.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/stable_sort.hpp b/include/boost/range/algorithm/stable_sort.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/swap_ranges.hpp b/include/boost/range/algorithm/swap_ranges.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/transform.hpp b/include/boost/range/algorithm/transform.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/unique_copy.hpp b/include/boost/range/algorithm/unique_copy.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm/upper_bound.hpp b/include/boost/range/algorithm/upper_bound.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm_ext.hpp b/include/boost/range/algorithm_ext.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm_ext/erase.hpp b/include/boost/range/algorithm_ext/erase.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm_ext/for_each.hpp b/include/boost/range/algorithm_ext/for_each.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm_ext/insert.hpp b/include/boost/range/algorithm_ext/insert.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm_ext/overwrite.hpp b/include/boost/range/algorithm_ext/overwrite.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm_ext/push_back.hpp b/include/boost/range/algorithm_ext/push_back.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/algorithm_ext/push_front.hpp b/include/boost/range/algorithm_ext/push_front.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/any_range.hpp b/include/boost/range/any_range.hpp index 9b7f87c..1cb5996 100644 --- a/include/boost/range/any_range.hpp +++ b/include/boost/range/any_range.hpp @@ -19,7 +19,6 @@ #include #include #include -#include namespace boost { diff --git a/include/boost/range/combine.hpp b/include/boost/range/combine.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/detail/any_iterator.hpp b/include/boost/range/detail/any_iterator.hpp index 9d1057c..555bd57 100644 --- a/include/boost/range/detail/any_iterator.hpp +++ b/include/boost/range/detail/any_iterator.hpp @@ -10,7 +10,6 @@ #ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_HPP_INCLUDED #define BOOST_RANGE_DETAIL_ANY_ITERATOR_HPP_INCLUDED -#include #include #include #include diff --git a/include/boost/range/detail/any_iterator_wrapper.hpp b/include/boost/range/detail/any_iterator_wrapper.hpp index c542d39..bcd9b7f 100644 --- a/include/boost/range/detail/any_iterator_wrapper.hpp +++ b/include/boost/range/detail/any_iterator_wrapper.hpp @@ -10,7 +10,7 @@ #ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_WRAPPER_HPP_INCLUDED #define BOOST_RANGE_DETAIL_ANY_ITERATOR_WRAPPER_HPP_INCLUDED -#include +#include #include #include #include diff --git a/include/boost/range/detail/collection_traits.hpp b/include/boost/range/detail/collection_traits.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/detail/default_constructible_unary_fn.hpp b/include/boost/range/detail/default_constructible_unary_fn.hpp new file mode 100644 index 0000000..374ddda --- /dev/null +++ b/include/boost/range/detail/default_constructible_unary_fn.hpp @@ -0,0 +1,64 @@ +// 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_DEFAULT_CONSTRUCTIBLE_UNARY_FN_HPP_INCLUDED +#define BOOST_RANGE_DETAIL_DEFAULT_CONSTRUCTIBLE_UNARY_FN_HPP_INCLUDED + +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + +template +class default_constructible_unary_fn_wrapper +{ +public: + typedef R result_type; + + default_constructible_unary_fn_wrapper() + { + } + default_constructible_unary_fn_wrapper(const F& source) + : m_impl(source) + { + } + template + R operator()(const Arg& arg) const + { + BOOST_ASSERT(m_impl); + return (*m_impl)(arg); + } + template + R operator()(Arg& arg) const + { + BOOST_ASSERT(m_impl); + return (*m_impl)(arg); + } +private: + boost::optional m_impl; +}; + +template +struct default_constructible_unary_fn_gen +{ + typedef typename boost::mpl::if_< + boost::has_trivial_default_constructor, + F, + default_constructible_unary_fn_wrapper + >::type type; +}; + + } // namespace range_detail +} // namespace boost + +#endif // include guard diff --git a/include/boost/range/detail/difference_type.hpp b/include/boost/range/detail/difference_type.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/detail/empty.hpp b/include/boost/range/detail/empty.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/detail/extract_optional_type.hpp b/include/boost/range/detail/extract_optional_type.hpp index aa4dd80..0381434 100644 --- a/include/boost/range/detail/extract_optional_type.hpp +++ b/include/boost/range/detail/extract_optional_type.hpp @@ -15,36 +15,32 @@ #endif #include +#include +#include -#ifdef BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS - -#define BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( a_typedef ) \ - template< typename C > \ - struct extract_ ## a_typedef \ - { \ - typedef BOOST_DEDUCED_TYPENAME C::a_typedef type; \ - }; - -#else - -namespace boost { - namespace range_detail { - template< typename T > struct exists { typedef void type; }; - } -} +#if !defined(BOOST_MPL_CFG_NO_HAS_XXX) // Defines extract_some_typedef which exposes T::some_typedef as // extract_some_typedef::type if T::some_typedef exists. Otherwise // extract_some_typedef is empty. -#define BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( a_typedef ) \ - template< typename C, typename Enable=void > \ - struct extract_ ## a_typedef \ - {}; \ - template< typename C > \ - struct extract_ ## a_typedef< C \ - , BOOST_DEDUCED_TYPENAME boost::range_detail::exists< BOOST_DEDUCED_TYPENAME C::a_typedef >::type \ - > { \ - typedef BOOST_DEDUCED_TYPENAME C::a_typedef type; \ +#define BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( a_typedef ) \ + BOOST_MPL_HAS_XXX_TRAIT_DEF(a_typedef) \ + template< typename C, bool B = BOOST_PP_CAT(has_, a_typedef)::value > \ + struct BOOST_PP_CAT(extract_, a_typedef) \ + {}; \ + template< typename C > \ + struct BOOST_PP_CAT(extract_, a_typedef)< C, true > \ + { \ + typedef BOOST_DEDUCED_TYPENAME C::a_typedef type; \ + }; + +#else + +#define BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( a_typedef ) \ + template< typename C > \ + struct BOOST_PP_CAT(extract_, a_typedef) \ + { \ + typedef BOOST_DEDUCED_TYPENAME C::a_typedef type; \ }; #endif diff --git a/include/boost/range/detail/misc_concept.hpp b/include/boost/range/detail/misc_concept.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/detail/remove_extent.hpp b/include/boost/range/detail/remove_extent.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/detail/sfinae.hpp b/include/boost/range/detail/sfinae.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/detail/str_types.hpp b/include/boost/range/detail/str_types.hpp old mode 100755 new mode 100644 diff --git a/include/boost/range/detail/value_type.hpp b/include/boost/range/detail/value_type.hpp old mode 100755 new mode 100644 diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 5f84421..2c6a2a0 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -57,6 +57,7 @@ test-suite range : [ compile-fail compile_fail/adaptor/uniqued_concept3.cpp ] [ compile-fail compile_fail/adaptor/uniqued_concept4.cpp ] [ range-test adaptor_test/adjacent_filtered ] + [ range-test adaptor_test/chained ] [ range-test adaptor_test/copied ] [ range-test adaptor_test/filtered ] [ range-test adaptor_test/indexed ] diff --git a/test/adaptor_test/chained.cpp b/test/adaptor_test/chained.cpp new file mode 100644 index 0000000..1b756c9 --- /dev/null +++ b/test/adaptor_test/chained.cpp @@ -0,0 +1,117 @@ +// 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/ +// +// Credits: +// Jurgen Hunold provided a test case that demonstrated that the range adaptors +// were producing iterators that were not default constructible. This became +// symptomatic after enabling concept checking assertions. This test is a +// lightly modified version of his supplied code to ensure that his use case +// never breaks again. (hopefully!) +// + +#include +#include +#include +#include + +#include +#include + +#include +#include + +namespace boost_range_test +{ + namespace + { + +class foo +{ +public: + static foo from_string(const std::string& source) + { + foo f; + f.m_valid = true; + f.m_value = 0u; + for (std::string::const_iterator it = source.begin(); + it != source.end(); ++it) + { + f.m_value += *it; + if ((*it < 'a') || (*it > 'z')) + f.m_valid = false; + } + return f; + } + bool is_valid() const + { + return m_valid; + } + bool operator<(const foo& other) const + { + return m_value < other.m_value; + } + bool operator==(const foo& other) const + { + return m_value == other.m_value && m_valid == other.m_valid; + } + bool operator!=(const foo& other) const + { + return !operator==(other); + } + + friend inline std::ostream& operator<<(std::ostream& out, const foo& obj) + { + out << "{value=" << obj.m_value + << ", valid=" << std::boolalpha << obj.m_valid << "}\n"; + return out; + } + +private: + boost::uint64_t m_value; + bool m_valid; +}; + +void chained_adaptors_test() +{ + std::vector sep; + + sep.push_back("AB"); + sep.push_back("ab"); + sep.push_back("aghj"); + + std::set foos; + + boost::copy(sep + | boost::adaptors::transformed(boost::bind(&foo::from_string, _1)) + | boost::adaptors::filtered(boost::bind(&foo::is_valid, _1)), + std::inserter(foos, foos.end())); + + std::vector reference; + reference.push_back(foo::from_string("ab")); + reference.push_back(foo::from_string("aghj")); + + BOOST_CHECK_EQUAL_COLLECTIONS( + reference.begin(), reference.end(), + foos.begin(), foos.end()); +} + + } // 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( "RangeTestSuite.adaptor.chained adaptors" ); + + test->add(BOOST_TEST_CASE( boost_range_test::chained_adaptors_test)); + + return test; +} diff --git a/test/adl_conformance_no_using.cpp b/test/adl_conformance_no_using.cpp old mode 100755 new mode 100644 diff --git a/test/algorithm_test/copy_backward.cpp b/test/algorithm_test/copy_backward.cpp index 3fd5679..4879c28 100644 --- a/test/algorithm_test/copy_backward.cpp +++ b/test/algorithm_test/copy_backward.cpp @@ -8,6 +8,10 @@ // // For more information, see http://www.boost.org/libs/range/ // +// Credits: +// awulkiew highlighted that this test was not successfully testing the +// algorithm. +// #include #include @@ -17,52 +21,64 @@ #include #include #include -#include #include -namespace boost +namespace boost_range_test { namespace { - template< class Container > - void test_copy_backward_impl() - { - Container source; - typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t; +template +void test_copy_backward_impl(std::size_t n) +{ + Container source; + typedef typename Container::value_type value_t; + for (std::size_t i = 0; i < n; ++i) + source.push_back(static_cast(i)); - std::vector target; - target.resize(source.size()); + std::vector target(n); - typedef BOOST_DEDUCED_TYPENAME range_iterator< std::vector >::type iterator_t; - iterator_t it = boost::copy_backward(source, target.begin()); + typedef typename boost::range_iterator< + std::vector + >::type iterator_t; - BOOST_CHECK( it == target.end() ); - BOOST_CHECK_EQUAL_COLLECTIONS( target.begin(), target.end(), - source.rbegin(), source.rend() ); - - BOOST_CHECK( it == boost::copy_backward(boost::make_iterator_range(source), target.begin()) ); - BOOST_CHECK_EQUAL_COLLECTIONS( target.begin(), target.end(), - source.rbegin(), source.rend() ); - } + iterator_t it = boost::copy_backward(source, target.end()); - void test_copy_backward() - { - test_copy_backward_impl< std::vector >(); - test_copy_backward_impl< std::list >(); - test_copy_backward_impl< std::set >(); - test_copy_backward_impl< std::multiset >(); - } - } + BOOST_CHECK(it == target.begin()); + + BOOST_CHECK_EQUAL_COLLECTIONS(target.begin(), target.end(), + source.begin(), source.end()); + + BOOST_CHECK(it == boost::copy_backward( + boost::make_iterator_range(source), target.end())); + + BOOST_CHECK_EQUAL_COLLECTIONS(target.begin(), target.end(), + source.begin(), source.end()); } +template +void test_copy_backward_impl() +{ + test_copy_backward_impl(0u); + test_copy_backward_impl(1u); + test_copy_backward_impl(100u); +} + +void test_copy_backward() +{ + test_copy_backward_impl >(); + test_copy_backward_impl >(); +} + } // anonymous namespace +} // namespace boost_range_test + boost::unit_test::test_suite* -init_unit_test_suite(int argc, char* argv[]) +init_unit_test_suite(int, char*[]) { boost::unit_test::test_suite* test - = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.copy_backward" ); + = BOOST_TEST_SUITE("RangeTestSuite.algorithm.copy_backward"); - test->add( BOOST_TEST_CASE( &boost::test_copy_backward ) ); + test->add(BOOST_TEST_CASE(&boost_range_test::test_copy_backward)); return test; } diff --git a/test/mfc.cpp b/test/mfc.cpp old mode 100755 new mode 100644