mirror of
https://github.com/boostorg/range.git
synced 2025-07-28 11:57:38 +02:00
[boost][range] - Improved handling of temporary ranges in range algorithms.
[SVN r63904]
This commit is contained in:
@ -15,19 +15,129 @@
|
||||
|
||||
#include <boost/assign.hpp>
|
||||
#include <boost/range/algorithm_ext.hpp>
|
||||
#include <boost/range/sub_range.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include <functional>
|
||||
namespace boost
|
||||
{
|
||||
namespace range3
|
||||
{
|
||||
namespace concept
|
||||
{
|
||||
template<class Range>
|
||||
class PopFrontSubRange
|
||||
{
|
||||
public:
|
||||
void constraints()
|
||||
{
|
||||
Range copied_range(*m_range);
|
||||
BOOST_DEDUCED_TYPENAME range_value<Range>::type v = copied_range.front();
|
||||
copied_range.pop_front();
|
||||
}
|
||||
private:
|
||||
Range* m_range;
|
||||
};
|
||||
|
||||
template<class Range>
|
||||
class PopBackSubRange
|
||||
{
|
||||
public:
|
||||
void constraints()
|
||||
{
|
||||
Range copied_range(*m_range);
|
||||
BOOST_DEDUCED_TYPENAME range_value<Range>::type v = copied_range.back();
|
||||
copied_range.pop_back();
|
||||
}
|
||||
private:
|
||||
Range* m_range;
|
||||
};
|
||||
} // namespace concept
|
||||
namespace adaptor
|
||||
{
|
||||
template<class Range, class Pred>
|
||||
class adjacent_filter_adaptor
|
||||
: private boost::sub_range<Range>
|
||||
, private Pred
|
||||
{
|
||||
public:
|
||||
typedef boost::sub_range<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 Range>
|
||||
class unique_adaptor
|
||||
: public adjacent_filter_adaptor<Range, std::not_equal_to< typename range_value<Range>::type > >
|
||||
{
|
||||
typedef adjacent_filter_adaptor<Range, std::not_equal_to< typename range_value<Range>::type > > base_t;
|
||||
public:
|
||||
typedef std::not_equal_to< typename range_value<Range>::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<int> test_result1;
|
||||
boost::range3::adaptor::unique_adaptor<Container> rng(c);
|
||||
while (!rng.empty())
|
||||
{
|
||||
test_result1.push_back(rng.front());
|
||||
rng.pop_front();
|
||||
}
|
||||
|
||||
std::vector<int> 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;
|
||||
|
@ -17,6 +17,7 @@
|
||||
# pragma warn -8057 // unused argument argc/argv in Boost.Test
|
||||
#endif
|
||||
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/range/as_array.hpp>
|
||||
#include <boost/range/as_literal.hpp>
|
||||
#include <boost/range/functions.hpp>
|
||||
@ -29,6 +30,34 @@
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
|
||||
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<value_type, Length + 1> buffer_t;
|
||||
buffer_t m_buffer;
|
||||
};
|
||||
}
|
||||
|
||||
template< class T >
|
||||
inline BOOST_DEDUCED_TYPENAME boost::range_iterator<T>::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<char, 8> a_string("a string");
|
||||
test_string<char, 14> 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";
|
||||
char* char_s2 = a_string.mutable_sz();
|
||||
|
||||
BOOST_STATIC_ASSERT(( is_same< range_value<char_iterator_t>::type,
|
||||
detail::iterator_traits<char_iterator_t>::value_type>::value ));
|
||||
@ -182,9 +215,13 @@ void check_string()
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
typedef wchar_t* wchar_iterator_t;
|
||||
const wchar_t* char_ws = L"a wide string";
|
||||
|
||||
test_string<wchar_t, 13> a_wide_string(L"a wide string");
|
||||
test_string<wchar_t, 19> 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<wchar_iterator_t>::type,
|
||||
detail::iterator_traits<wchar_iterator_t>::value_type>::value ));
|
||||
@ -204,11 +241,16 @@ void check_string()
|
||||
|
||||
wchar_t to_search = L'n';
|
||||
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
|
||||
|
||||
|
29
test/test_function/true_predicate.hpp
Normal file
29
test/test_function/true_predicate.hpp
Normal file
@ -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<class Arg> bool operator()(Arg) const { return true; }
|
||||
template<class Arg1, class Arg2> bool operator()(Arg1,Arg2) const { return true; }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // include guard
|
Reference in New Issue
Block a user