• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
11 #include <boost/container/list.hpp>
12 #include <boost/container/adaptive_pool.hpp>
13 
14 #include "dummy_test_allocator.hpp"
15 #include <memory>
16 #include "movable_int.hpp"
17 #include "list_test.hpp"
18 #include "propagate_allocator_test.hpp"
19 #include "emplace_test.hpp"
20 #include "../../intrusive/test/iterator_test.hpp"
21 
22 using namespace boost::container;
23 
24 namespace boost {
25 namespace container {
26 
27 //Explicit instantiation to detect compilation errors
28 template class boost::container::list
29    < test::movable_and_copyable_int
30    , test::simple_allocator<test::movable_and_copyable_int> >;
31 
32 template class boost::container::list
33    < test::movable_and_copyable_int
34    , adaptive_pool<test::movable_and_copyable_int> >;
35 
36 namespace dtl {
37 
38 template class iterator_from_iiterator
39    <intrusive_list_type< std::allocator<int> >::container_type::iterator, true >;
40 template class iterator_from_iiterator
41    <intrusive_list_type< std::allocator<int> >::container_type::iterator, false>;
42 
43 }
44 
45 }}
46 
47 class recursive_list
48 {
49 public:
50    int id_;
51    list<recursive_list> list_;
52    list<recursive_list>::iterator it_;
53    list<recursive_list>::const_iterator cit_;
54    list<recursive_list>::reverse_iterator rit_;
55    list<recursive_list>::const_reverse_iterator crit_;
56 
operator =(const recursive_list & o)57    recursive_list &operator=(const recursive_list &o)
58    { list_ = o.list_;  return *this; }
59 };
60 
recursive_list_test()61 void recursive_list_test()//Test for recursive types
62 {
63    list<recursive_list> recursive, copy;
64    //Test to test both move emulations
65    if(!copy.size()){
66       copy = recursive;
67    }
68 }
69 
70 template<class VoidAllocator>
71 struct GetAllocatorCont
72 {
73    template<class ValueType>
74    struct apply
75    {
76       typedef list< ValueType
77                   , typename allocator_traits<VoidAllocator>
78                         ::template portable_rebind_alloc<ValueType>::type
79                   > type;
80    };
81 };
82 
83 template<class VoidAllocator>
test_cont_variants()84 int test_cont_variants()
85 {
86    typedef typename GetAllocatorCont<VoidAllocator>::template apply<int>::type MyCont;
87    typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::movable_int>::type MyMoveCont;
88    typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::movable_and_copyable_int>::type MyCopyMoveCont;
89    typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::copyable_int>::type MyCopyCont;
90 
91    if(test::list_test<MyCont, true>())
92       return 1;
93    if(test::list_test<MyMoveCont, true>())
94       return 1;
95    if(test::list_test<MyCopyMoveCont, true>())
96       return 1;
97    if(test::list_test<MyCopyMoveCont, true>())
98       return 1;
99    if(test::list_test<MyCopyCont, true>())
100       return 1;
101 
102    return 0;
103 }
104 
test_support_for_initializer_list()105 bool test_support_for_initializer_list()
106 {
107 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
108    const std::initializer_list<int> il = {1, 10};
109    const list<int> expectedList(il.begin(), il.end());
110 
111    const list<int> testConstructor((il));
112    if(testConstructor != expectedList)
113       return false;
114 
115    const list<int> testConstructorAllocator(il, list<int>::allocator_type());
116    if (testConstructorAllocator != expectedList)
117       return false;
118 
119    list<int> testAssignOperator = {10, 11};
120    testAssignOperator = il;
121    if(testAssignOperator != expectedList)
122       return false;
123 
124    list<int> testAssignMethod = {99};
125    testAssignMethod = il;
126    if(testAssignMethod != expectedList)
127       return false;
128 
129    list<int> testInsertMethod;
130    testInsertMethod.insert(testInsertMethod.cbegin(), il);
131    if(testInsertMethod != testInsertMethod)
132       return false;
133 
134    return true;
135 #endif
136    return true;
137 }
138 
139 struct boost_container_list;
140 
141 namespace boost { namespace container {   namespace test {
142 
143 template<>
144 struct alloc_propagate_base<boost_container_list>
145 {
146    template <class T, class Allocator>
147    struct apply
148    {
149       typedef boost::container::list<T, Allocator> type;
150    };
151 };
152 
153 }}}   //namespace boost::container::test
154 
main()155 int main ()
156 {
157    recursive_list_test();
158    {
159       //Now test move semantics
160       list<recursive_list> original;
161       list<recursive_list> move_ctor(boost::move(original));
162       list<recursive_list> move_assign;
163       move_assign = boost::move(move_ctor);
164       move_assign.swap(original);
165    }
166 
167    ////////////////////////////////////
168    //    Testing allocator implementations
169    ////////////////////////////////////
170    //       int variants
171    if (test::list_test<list<int, std::allocator<int> >, true>())
172       return 1;
173    if (test::list_test<list<int>, true>())
174       return 1;
175    if (test::list_test<list<int, adaptive_pool<int> >, true>())
176       return 1;
177    if (test::list_test<list<test::movable_int>, true>())
178       return 1;
179    if (test::list_test<list<test::movable_and_copyable_int>, true>())
180       return 1;
181    if (test::list_test<list<test::copyable_int>, true>())
182       return 1;
183 
184    ////////////////////////////////////
185    //    Emplace testing
186    ////////////////////////////////////
187    const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_FRONT | test::EMPLACE_BEFORE);
188 
189    if(!boost::container::test::test_emplace<list<test::EmplaceInt>, Options>())
190       return 1;
191 
192    ////////////////////////////////////
193    //    Allocator propagation testing
194    ////////////////////////////////////
195    if(!boost::container::test::test_propagate_allocator<boost_container_list>())
196       return 1;
197 
198    ////////////////////////////////////
199    //    Initializer lists
200    ////////////////////////////////////
201    if(!test_support_for_initializer_list())
202       return 1;
203 
204    ////////////////////////////////////
205    //    Iterator testing
206    ////////////////////////////////////
207    {
208       typedef boost::container::list<int> cont_int;
209       cont_int a; a.push_back(0); a.push_back(1); a.push_back(2);
210       boost::intrusive::test::test_iterator_bidirectional< cont_int >(a);
211       if(boost::report_errors() != 0) {
212          return 1;
213       }
214    }
215 
216 #ifndef BOOST_CONTAINER_NO_CXX17_CTAD
217    ////////////////////////////////////
218    //    Constructor Template Auto Deduction Tests
219    ////////////////////////////////////
220    {
221       auto gold = std::list{ 1, 2, 3 };
222       auto test = boost::container::list(gold.begin(), gold.end());
223       if (test.size() != 3) {
224          return 1;
225       }
226       if (test.front() != 1)
227          return 1;
228       test.pop_front();
229       if (test.front() != 2)
230          return 1;
231       test.pop_front();
232       if (test.front() != 3)
233          return 1;
234       test.pop_front();
235    }
236    {
237       auto gold = std::list{ 1, 2, 3 };
238       auto test = boost::container::list(gold.begin(), gold.end(), new_allocator<int>());
239       if (test.size() != 3) {
240          return 1;
241       }
242       if (test.front() != 1)
243          return 1;
244       test.pop_front();
245       if (test.front() != 2)
246          return 1;
247       test.pop_front();
248       if (test.front() != 3)
249          return 1;
250       test.pop_front();
251    }
252 #endif
253 
254    ////////////////////////////////////
255    //    has_trivial_destructor_after_move testing
256    ////////////////////////////////////
257    // default allocator
258    {
259       typedef boost::container::list<int> cont;
260       typedef cont::allocator_type allocator_type;
261       typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
262       if (boost::has_trivial_destructor_after_move<cont>::value !=
263           boost::has_trivial_destructor_after_move<allocator_type>::value &&
264           boost::has_trivial_destructor_after_move<pointer>::value) {
265          std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl;
266          return 1;
267       }
268    }
269    // std::allocator
270    {
271       typedef boost::container::list<int, std::allocator<int> > cont;
272       typedef cont::allocator_type allocator_type;
273       typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
274       if (boost::has_trivial_destructor_after_move<cont>::value !=
275           boost::has_trivial_destructor_after_move<allocator_type>::value &&
276           boost::has_trivial_destructor_after_move<pointer>::value) {
277          std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl;
278          return 1;
279       }
280    }
281 
282    return 0;
283 }
284