1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // See http://www.boost.org/libs/container for documentation.
8 //
9 //////////////////////////////////////////////////////////////////////////////
10 #include <boost/container/detail/config_begin.hpp>
11 #include <boost/container/slist.hpp>
12 #include <boost/container/allocator.hpp>
13 #include <boost/container/node_allocator.hpp>
14 #include <boost/container/adaptive_pool.hpp>
15 
16 #include <memory>
17 #include "dummy_test_allocator.hpp"
18 #include "movable_int.hpp"
19 #include "list_test.hpp"
20 #include "propagate_allocator_test.hpp"
21 #include "emplace_test.hpp"
22 #include "../../intrusive/test/iterator_test.hpp"
23 
24 using namespace boost::container;
25 
26 namespace boost {
27 namespace container {
28 
29 //Explicit instantiation to detect compilation errors
30 template class boost::container::slist
31    < test::movable_and_copyable_int
32    , test::simple_allocator<test::movable_and_copyable_int> >;
33 
34 template class boost::container::slist
35    < test::movable_and_copyable_int
36    , test::dummy_test_allocator<test::movable_and_copyable_int> >;
37 
38 template class boost::container::slist
39    < test::movable_and_copyable_int
40    , std::allocator<test::movable_and_copyable_int> >;
41 
42 template class boost::container::slist
43    < test::movable_and_copyable_int
44    , allocator<test::movable_and_copyable_int> >;
45 
46 template class boost::container::slist
47    < test::movable_and_copyable_int
48    , adaptive_pool<test::movable_and_copyable_int> >;
49 
50 template class boost::container::slist
51    < test::movable_and_copyable_int
52    , node_allocator<test::movable_and_copyable_int> >;
53 
54 }}
55 
56 class recursive_slist
57 {
58 public:
59    int id_;
60    slist<recursive_slist> slist_;
61    slist<recursive_slist>::iterator it_;
62    slist<recursive_slist>::const_iterator cit_;
63 
operator =(const recursive_slist & o)64    recursive_slist &operator=(const recursive_slist &o)
65    { slist_ = o.slist_;  return *this; }
66 };
67 
recursive_slist_test()68 void recursive_slist_test()//Test for recursive types
69 {
70    slist<recursive_slist> recursive_list_list;
71 }
72 
73 template<class VoidAllocator>
74 struct GetAllocatorCont
75 {
76    template<class ValueType>
77    struct apply
78    {
79       typedef slist< ValueType
80                    , typename allocator_traits<VoidAllocator>
81                         ::template portable_rebind_alloc<ValueType>::type
82                    > type;
83    };
84 };
85 
86 template<class VoidAllocator>
test_cont_variants()87 int test_cont_variants()
88 {
89    typedef typename GetAllocatorCont<VoidAllocator>::template apply<int>::type MyCont;
90    typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::movable_int>::type MyMoveCont;
91    typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::movable_and_copyable_int>::type MyCopyMoveCont;
92    typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::copyable_int>::type MyCopyCont;
93 
94    if(test::list_test<MyCont, false>())
95       return 1;
96    if(test::list_test<MyMoveCont, false>())
97       return 1;
98    if(test::list_test<MyCopyMoveCont, false>())
99       return 1;
100    if(test::list_test<MyCopyMoveCont, false>())
101       return 1;
102    if(test::list_test<MyCopyCont, false>())
103       return 1;
104 
105    return 0;
106 }
107 
test_support_for_initializer_list()108 bool test_support_for_initializer_list()
109 {
110 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
111    const std::initializer_list<int> il = {5, 10, 15};
112    const slist<int> expected_list(il.begin(), il.end());
113    {
114       slist<int> sl = il;
115       if(sl != expected_list)
116          return false;
117    }
118 
119    {
120       slist<int> sl = {1, 2};
121       sl = il;
122       if(sl != expected_list)
123          return false;
124    }
125    {
126       slist<int> sl({ 1, 2 }, slist<int>::allocator_type());
127       sl = il;
128       if (sl != expected_list)
129          return false;
130    }
131    {
132       slist<int> sl = {4, 5};
133       sl.assign(il);
134       if(sl != expected_list)
135          return false;
136    }
137 
138    {
139       slist<int> sl = {15};
140       sl.insert(sl.cbegin(), {5, 10});
141       if(sl != expected_list)
142          return false;
143    }
144 
145    {
146        slist<int> sl = {5};
147        sl.insert_after(sl.cbegin(), {10, 15});
148        if(sl != expected_list)
149           return false;
150    }
151    return true;
152 #endif
153    return true;
154 }
155 
156 struct boost_container_slist;
157 
158 namespace boost {
159 namespace container {
160 namespace test {
161 
162 template<>
163 struct alloc_propagate_base<boost_container_slist>
164 {
165    template <class T, class Allocator>
166    struct apply
167    {
168       typedef boost::container::slist<T, Allocator> type;
169    };
170 };
171 
172 }}}
173 
main()174 int main ()
175 {
176    recursive_slist_test();
177    {
178       //Now test move semantics
179       slist<recursive_slist> original;
180       slist<recursive_slist> move_ctor(boost::move(original));
181       slist<recursive_slist> move_assign;
182       move_assign = boost::move(move_ctor);
183       move_assign.swap(original);
184       {
185          slist<recursive_slist> recursive, copy;
186          //Test to test both move emulations
187          if(!copy.size()){
188             copy = recursive;
189          }
190       }
191    }
192    ////////////////////////////////////
193    //    Testing allocator implementations
194    ////////////////////////////////////
195    //       std:allocator
196    if(test_cont_variants< std::allocator<void> >()){
197       std::cerr << "test_cont_variants< std::allocator<void> > failed" << std::endl;
198       return 1;
199    }
200    //       boost::container::allocator
201    if(test_cont_variants< allocator<void> >()){
202       std::cerr << "test_cont_variants< allocator<void> > failed" << std::endl;
203       return 1;
204    }
205    //       boost::container::node_allocator
206    if(test_cont_variants< node_allocator<void> >()){
207       std::cerr << "test_cont_variants< node_allocator<void> > failed" << std::endl;
208       return 1;
209    }
210    //       boost::container::adaptive_pool
211    if(test_cont_variants< adaptive_pool<void> >()){
212       std::cerr << "test_cont_variants< adaptive_pool<void> > failed" << std::endl;
213       return 1;
214    }
215 
216    ////////////////////////////////////
217    //    Emplace testing
218    ////////////////////////////////////
219    const test::EmplaceOptions Options = (test::EmplaceOptions)
220       (test::EMPLACE_FRONT | test::EMPLACE_AFTER | test::EMPLACE_BEFORE  | test::EMPLACE_AFTER);
221 
222    if(!boost::container::test::test_emplace
223       < slist<test::EmplaceInt>, Options>())
224       return 1;
225 
226    ////////////////////////////////////
227    //    Allocator propagation testing
228    ////////////////////////////////////
229    if(!boost::container::test::test_propagate_allocator<boost_container_slist>())
230       return 1;
231 
232    ////////////////////////////////////
233    //    Initializer lists
234    ////////////////////////////////////
235    if(!test_support_for_initializer_list())
236       return 1;
237 
238    ////////////////////////////////////
239    //    Iterator testing
240    ////////////////////////////////////
241    {
242       typedef boost::container::slist<int> vector_int;
243       vector_int a; a.push_front(2); a.push_front(1); a.push_front(0);
244       boost::intrusive::test::test_iterator_forward< boost::container::slist<int> >(a);
245       if(boost::report_errors() != 0) {
246          return 1;
247       }
248    }
249 }
250 
251 #include <boost/container/detail/config_end.hpp>
252 
253