From 5bb66037d368ed7d989dca27b34b577ec4db49b7 Mon Sep 17 00:00:00 2001 From: Neil Groves Date: Mon, 12 Jul 2010 00:14:07 +0000 Subject: [PATCH] [boost][range] - Improved handling of temporary ranges in range algorithms. [SVN r63904] --- test/adaptor_test/uniqued.cpp | 110 ++++++++++++++++++++++++++ test/string.cpp | 58 ++++++++++++-- test/test_function/true_predicate.hpp | 29 +++++++ 3 files changed, 189 insertions(+), 8 deletions(-) create mode 100644 test/test_function/true_predicate.hpp diff --git a/test/adaptor_test/uniqued.cpp b/test/adaptor_test/uniqued.cpp index 9c96744..cfc3fb7 100644 --- a/test/adaptor_test/uniqued.cpp +++ b/test/adaptor_test/uniqued.cpp @@ -15,19 +15,129 @@ #include #include +#include #include #include #include #include +#include namespace boost { + namespace range3 + { + namespace concept + { + template + class PopFrontSubRange + { + public: + void constraints() + { + Range copied_range(*m_range); + BOOST_DEDUCED_TYPENAME range_value::type v = copied_range.front(); + copied_range.pop_front(); + } + private: + Range* m_range; + }; + + template + class PopBackSubRange + { + public: + void constraints() + { + Range copied_range(*m_range); + BOOST_DEDUCED_TYPENAME range_value::type v = copied_range.back(); + copied_range.pop_back(); + } + private: + Range* m_range; + }; + } // namespace concept + namespace adaptor + { + template + class adjacent_filter_adaptor + : private boost::sub_range + , private Pred + { + public: + typedef boost::sub_range range_t; + typedef Pred pred_t; + typedef typename range_t::value_type value_type; + using range_t::reference; + using range_t::const_reference; + using range_t::empty; + using range_t::front; + using range_t::back; + + adjacent_filter_adaptor(Range& rng, Pred pred) + : range_t(rng) + , pred_t(pred) + { + } + + void pop_front() + { + BOOST_ASSERT( !empty() ); + const value_type& old_front = front(); + range_t::pop_front(); + while (!empty() && !pred_t::operator()(front(), old_front)) + range_t::pop_front(); + } + + void pop_back() + { + BOOST_ASSERT( !empty() ); + const value_type& old_back = back(); + range_t::pop_back(); + while (!empty() && !pred_t::operator()(old_back, back())) + range_t::pop_back(); + } + }; + + template + class unique_adaptor + : public adjacent_filter_adaptor::type > > + { + typedef adjacent_filter_adaptor::type > > base_t; + public: + typedef std::not_equal_to< typename range_value::type > pred_t; + explicit unique_adaptor(Range& rng) : base_t(rng, pred_t()) {} + }; + } + } + namespace { + template< class Container > + void new_uniqued_adaptor_test(Container& c) + { + std::vector test_result1; + boost::range3::adaptor::unique_adaptor rng(c); + while (!rng.empty()) + { + test_result1.push_back(rng.front()); + rng.pop_front(); + } + + std::vector test_result2; + boost::push_back(test_result2, adaptors::unique(c)); + + BOOST_CHECK_EQUAL_COLLECTIONS( + test_result1.begin(), test_result1.end(), + test_result2.begin(), test_result2.end() + ); + } + template< class Container > void uniqued_test_impl( Container& c ) { + new_uniqued_adaptor_test(c); + using namespace boost::adaptors; std::vector< int > test_result1; diff --git a/test/string.cpp b/test/string.cpp index 127f70a..f73abb0 100644 --- a/test/string.cpp +++ b/test/string.cpp @@ -17,6 +17,7 @@ # pragma warn -8057 // unused argument argc/argv in Boost.Test #endif +#include #include #include #include @@ -29,6 +30,34 @@ #include #include +namespace +{ + template< class CharT, std::size_t Length > + class test_string + { + public: + typedef CharT value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef std::size_t size_type; + typedef value_type array_t[Length]; + typedef const value_type const_array_t[Length]; + + explicit test_string(const CharT literal_sz[]) + { + std::copy(literal_sz, literal_sz + Length, m_buffer.data()); + m_buffer[Length] = value_type(); + } + + const_pointer const_sz() const { return m_buffer.data(); } + pointer mutable_sz() { return m_buffer.data(); } + + private: + typedef boost::array buffer_t; + buffer_t m_buffer; + }; +} + template< class T > inline BOOST_DEDUCED_TYPENAME boost::range_iterator::type str_begin( T& r ) @@ -105,11 +134,15 @@ void check_char() { typedef char* char_iterator_t; typedef char char_array_t[10]; - const char* char_s = "a string"; - char my_string[] = "another string"; + + test_string a_string("a string"); + test_string another_string("another string"); + + const char* char_s = a_string.const_sz(); + char my_string[] = "another_string"; const char my_const_string[] = "another string"; - const unsigned my_string_length = 14; - char* char_s2 = "a string"; + const unsigned my_string_length = 14; + char* char_s2 = a_string.mutable_sz(); BOOST_STATIC_ASSERT(( is_same< range_value::type, detail::iterator_traits::value_type>::value )); @@ -181,10 +214,14 @@ void check_string() check_char(); #ifndef BOOST_NO_STD_WSTRING - typedef wchar_t* wchar_iterator_t; - const wchar_t* char_ws = L"a wide string"; + typedef wchar_t* wchar_iterator_t; + + test_string a_wide_string(L"a wide string"); + test_string another_wide_string(L"another wide string"); + + const wchar_t* char_ws = a_wide_string.const_sz(); wchar_t my_wstring[] = L"another wide string"; - wchar_t* char_ws2 = L"a wide string"; + wchar_t* char_ws2 = a_wide_string.mutable_sz(); BOOST_STATIC_ASSERT(( is_same< range_value::type, detail::iterator_traits::value_type>::value )); @@ -203,12 +240,17 @@ void check_string() BOOST_CHECK_EQUAL( sz, std::char_traits::length( char_ws ) ); wchar_t to_search = L'n'; - BOOST_CHECK( find( char_ws, to_search ) != str_end(char_ws) ); + BOOST_CHECK( find( char_ws, to_search ) != str_end(char_ws) ); + BOOST_CHECK( find( char_ws2, to_search ) != str_end(char_ws2) ); #if BOOST_WORKAROUND(_MSC_VER, BOOST_TESTED_AT(1300)) BOOST_CHECK( find( my_wstring, to_search ) != str_end(my_wstring) ); +#else + + boost::ignore_unused_variable_warning( my_wstring ); + #endif #endif diff --git a/test/test_function/true_predicate.hpp b/test/test_function/true_predicate.hpp new file mode 100644 index 0000000..87a0dca --- /dev/null +++ b/test/test_function/true_predicate.hpp @@ -0,0 +1,29 @@ +// Boost.Range library +// +// Copyright Neil Groves 2010. 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_TEST_TEST_FUNCTION_TRUE_PREDICATE_HPP_INCLUDED +#define BOOST_RANGE_TEST_TEST_FUNCTION_TRUE_PREDICATE_HPP_INCLUDED + +namespace boost +{ + namespace range_test_function + { + struct true_predicate + { + typedef bool result_type; + + bool operator()() const { return true; } + template bool operator()(Arg) const { return true; } + template bool operator()(Arg1,Arg2) const { return true; } + }; + } +} + +#endif // include guard