1 // Boost.Range library
2 //
3 //  Copyright Neil Groves 2009. 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 #include <boost/range/adaptor/uniqued.hpp>
12 #include <boost/range/adaptor/transformed.hpp>
13 #include <boost/range/algorithm/unique_copy.hpp>
14 #include <boost/range/algorithm_ext/push_back.hpp>
15 #include <boost/algorithm/string/predicate.hpp>
16 
17 #include <boost/test/test_tools.hpp>
18 #include <boost/test/unit_test.hpp>
19 
20 #include <boost/assign.hpp>
21 #include <boost/range/algorithm_ext.hpp>
22 
23 #include <algorithm>
24 #include <list>
25 #include <set>
26 #include <vector>
27 
28 namespace boost
29 {
30     namespace
31     {
32         template< class Container >
uniqued_test_impl(Container & c)33         void uniqued_test_impl( Container& c )
34         {
35             using namespace boost::adaptors;
36 
37             std::vector< int > test_result1;
38             boost::push_back(test_result1, c | uniqued);
39 
40             std::vector< int > test_result2;
41             boost::push_back(test_result2, adaptors::unique(c));
42 
43             std::vector< int > reference(c.begin(), c.end());
44             reference.erase(
45                 std::unique(reference.begin(), reference.end()),
46                 reference.end());
47 
48             BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
49                                            test_result1.begin(), test_result1.end() );
50 
51             BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
52                                            test_result2.begin(), test_result2.end() );
53         }
54 
55         template< class Container >
uniqued_test_impl()56         void uniqued_test_impl()
57         {
58             using namespace boost::assign;
59 
60             Container c;
61 
62             // Test empty
63             uniqued_test_impl(c);
64 
65             // Test one
66             c += 1;
67             uniqued_test_impl(c);
68 
69             // Test many
70             c += 1,1,1,2,2,2,2,2,3,3,3,3,4,5,6,6,6,7,7,7,8,8,9,9,9,9,9,10;
71             uniqued_test_impl(c);
72         }
73 
uniqued_test()74         void uniqued_test()
75         {
76             uniqued_test_impl< std::vector< int > >();
77             uniqued_test_impl< std::list< int > >();
78             uniqued_test_impl< std::set< int > >();
79             uniqued_test_impl< std::multiset< int > >();
80         }
81 
82 class istring
83 {
84 public:
istring()85     istring()
86         : m_value("")
87     {
88     }
89 
istring(const char * value)90     explicit istring(const char* value)
91         : m_value(value)
92     {
93     }
94 
operator ==(istring r) const95     bool operator==(istring r) const
96     {
97         return boost::iequals(m_value, r.m_value);
98     }
99 
operator !=(istring r) const100     bool operator!=(istring r) const
101     {
102         return !operator==(r);
103     }
104 
operator <<(std::ostream & out,istring o)105     inline friend std::ostream& operator<<(std::ostream& out, istring o)
106     {
107         return out << o.m_value;
108     }
109 
get() const110     const char* get() const { return m_value; }
111 
112 private:
113     const char* m_value;
114 };
115 
116 struct istring_to_string
117 {
118     typedef std::string result_type;
119 
operator ()boost::__anon4f4e6bb40111::istring_to_string120     std::string operator()(istring s) const
121     {
122         return s.get();
123     }
124 };
125 
126 // This is based on a test-case provided by Eric Neibler.
uniqued_return_first()127 void uniqued_return_first()
128 {
129     using namespace boost::adaptors;
130 
131     std::vector<istring> strs;
132     strs.push_back(istring("hello"));
133     strs.push_back(istring("hElLo"));
134     strs.push_back(istring("HELLO"));
135     strs.push_back(istring("ZZZZ"));
136 
137     std::vector<istring> output1;
138 
139     boost::unique_copy(strs, std::back_inserter(output1));
140 
141     std::vector<istring> output2;
142     boost::push_back(output2, strs | uniqued);
143 
144     std::vector<std::string> test1;
145     boost::push_back(test1, output1 | transformed(istring_to_string()));
146 
147     std::vector<std::string> test2;
148     boost::push_back(test2, output2 | transformed(istring_to_string()));
149 
150     BOOST_CHECK_EQUAL_COLLECTIONS(test1.begin(), test1.end(),
151                                   test2.begin(), test2.end());
152 }
153 
154     } // anonymous namespace
155 } // namespace boost
156 
157 boost::unit_test::test_suite*
init_unit_test_suite(int argc,char * argv[])158 init_unit_test_suite(int argc, char* argv[])
159 {
160     boost::unit_test::test_suite* test
161         = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.uniqued" );
162 
163     test->add( BOOST_TEST_CASE( &boost::uniqued_test ) );
164 
165     test->add(BOOST_TEST_CASE(&boost::uniqued_return_first));
166 
167     return test;
168 }
169