1// Boost.Range library
2//
3// Copyright Neil Groves 2014. Use, modification and
4// distribution is subject to the Boost Software License, Version
5// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6// http://www.boost.org/LICENSE_1_0.txt)
7//
8//
9// For more information, see http://www.boost.org/libs/range/
10//
11// Credits:
12// Jurgen Hunold provided a test case that demonstrated that the range adaptors
13// were producing iterators that were not default constructible. This became
14// symptomatic after enabling concept checking assertions. This test is a
15// lightly modified version of his supplied code to ensure that his use case
16// never breaks again. (hopefully!)
17//
18
19#include <boost/range/adaptor/transformed.hpp>
20#include <boost/range/adaptor/filtered.hpp>
21#include <boost/range/algorithm/copy.hpp>
22#include <boost/bind/bind.hpp>
23
24#include <boost/test/test_tools.hpp>
25#include <boost/test/unit_test.hpp>
26
27#include <vector>
28#include <set>
29
30namespace boost_range_test
31{
32 namespace
33 {
34
35class foo
36{
37public:
38 static foo from_string(const std::string& source)
39 {
40 foo f;
41 f.m_valid = true;
42 f.m_value = 0u;
43 for (std::string::const_iterator it = source.begin();
44 it != source.end(); ++it)
45 {
46 f.m_value += *it;
47 if ((*it < 'a') || (*it > 'z'))
48 f.m_valid = false;
49 }
50 return f;
51 }
52 bool is_valid() const
53 {
54 return m_valid;
55 }
56 bool operator<(const foo& other) const
57 {
58 return m_value < other.m_value;
59 }
60 bool operator==(const foo& other) const
61 {
62 return m_value == other.m_value && m_valid == other.m_valid;
63 }
64 bool operator!=(const foo& other) const
65 {
66 return !operator==(other);
67 }
68
69 friend inline std::ostream& operator<<(std::ostream& out, const foo& obj)
70 {
71 out << "{value=" << obj.m_value
72 << ", valid=" << std::boolalpha << obj.m_valid << "}\n";
73 return out;
74 }
75
76private:
77 boost::uint64_t m_value;
78 bool m_valid;
79};
80
81void chained_adaptors_test()
82{
83 std::vector<std::string> sep;
84
85 sep.push_back(x: "AB");
86 sep.push_back(x: "ab");
87 sep.push_back(x: "aghj");
88
89 std::set<foo> foos;
90
91 using namespace boost::placeholders;
92
93 boost::copy(rng: sep
94 | boost::adaptors::transformed(boost::bind(f: &foo::from_string, a1: _1))
95 | boost::adaptors::filtered(boost::bind(f: &foo::is_valid, a1: _1)),
96 out: std::inserter(x&: foos, i: foos.end()));
97
98 std::vector<foo> reference;
99 reference.push_back(x: foo::from_string(source: "ab"));
100 reference.push_back(x: foo::from_string(source: "aghj"));
101
102 BOOST_CHECK_EQUAL_COLLECTIONS(
103 reference.begin(), reference.end(),
104 foos.begin(), foos.end());
105}
106
107 } // anonymous namespace
108} // namespace boost_range_test
109
110boost::unit_test::test_suite*
111init_unit_test_suite(int argc, char* argv[])
112{
113 boost::unit_test::test_suite* test
114 = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.chained adaptors" );
115
116 test->add(BOOST_TEST_CASE( boost_range_test::chained_adaptors_test));
117
118 return test;
119}
120

source code of boost/libs/range/test/adaptor_test/chained.cpp