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 | #define STABLE_VECTOR_ENABLE_INVARIANT_CHECKING |
11 | #include <memory> |
12 | |
13 | #include <boost/container/stable_vector.hpp> |
14 | #include <boost/container/node_allocator.hpp> |
15 | |
16 | #include "check_equal_containers.hpp" |
17 | #include "movable_int.hpp" |
18 | #include "expand_bwd_test_allocator.hpp" |
19 | #include "expand_bwd_test_template.hpp" |
20 | #include "dummy_test_allocator.hpp" |
21 | #include "propagate_allocator_test.hpp" |
22 | #include "vector_test.hpp" |
23 | #include "default_init_test.hpp" |
24 | #include "../../intrusive/test/iterator_test.hpp" |
25 | |
26 | using namespace boost::container; |
27 | |
28 | class recursive_vector |
29 | { |
30 | public: |
31 | int id_; |
32 | stable_vector<recursive_vector> vector_; |
33 | stable_vector<recursive_vector>::iterator it_; |
34 | stable_vector<recursive_vector>::const_iterator cit_; |
35 | stable_vector<recursive_vector>::reverse_iterator rit_; |
36 | stable_vector<recursive_vector>::const_reverse_iterator crit_; |
37 | |
38 | recursive_vector (const recursive_vector &o) |
39 | : vector_(o.vector_) |
40 | {} |
41 | |
42 | recursive_vector &operator=(const recursive_vector &o) |
43 | { vector_ = o.vector_; return *this; } |
44 | }; |
45 | |
46 | void recursive_vector_test()//Test for recursive types |
47 | { |
48 | stable_vector<recursive_vector> recursive, copy; |
49 | //Test to test both move emulations |
50 | if(!copy.size()){ |
51 | copy = recursive; |
52 | } |
53 | } |
54 | |
55 | template<class VoidAllocator> |
56 | struct GetAllocatorCont |
57 | { |
58 | template<class ValueType> |
59 | struct apply |
60 | { |
61 | typedef stable_vector< ValueType |
62 | , typename allocator_traits<VoidAllocator> |
63 | ::template portable_rebind_alloc<ValueType>::type |
64 | > type; |
65 | }; |
66 | }; |
67 | |
68 | template<class VoidAllocator> |
69 | int test_cont_variants() |
70 | { |
71 | typedef typename GetAllocatorCont<VoidAllocator>::template apply<int>::type MyCont; |
72 | typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::movable_int>::type MyMoveCont; |
73 | typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::movable_and_copyable_int>::type MyCopyMoveCont; |
74 | typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::copyable_int>::type MyCopyCont; |
75 | |
76 | if(test::vector_test<MyCont>()) |
77 | return 1; |
78 | if(test::vector_test<MyMoveCont>()) |
79 | return 1; |
80 | if(test::vector_test<MyCopyMoveCont>()) |
81 | return 1; |
82 | if(test::vector_test<MyCopyCont>()) |
83 | return 1; |
84 | |
85 | return 0; |
86 | } |
87 | |
88 | struct boost_container_stable_vector; |
89 | |
90 | namespace boost { namespace container { namespace test { |
91 | |
92 | template<> |
93 | struct alloc_propagate_base<boost_container_stable_vector> |
94 | { |
95 | template <class T, class Allocator> |
96 | struct apply |
97 | { |
98 | typedef boost::container::stable_vector<T, Allocator> type; |
99 | }; |
100 | }; |
101 | |
102 | }}} //namespace boost::container::test |
103 | |
104 | |
105 | int main() |
106 | { |
107 | recursive_vector_test(); |
108 | { |
109 | //Now test move semantics |
110 | stable_vector<recursive_vector> original; |
111 | stable_vector<recursive_vector> move_ctor(boost::move(t&: original)); |
112 | stable_vector<recursive_vector> move_assign; |
113 | move_assign = boost::move(t&: move_ctor); |
114 | move_assign.swap(x&: original); |
115 | } |
116 | |
117 | //Test non-copy-move operations |
118 | { |
119 | stable_vector<test::non_copymovable_int> sv; |
120 | sv.emplace_back(); |
121 | sv.resize(n: 10); |
122 | sv.resize(n: 1); |
123 | } |
124 | |
125 | //////////////////////////////////// |
126 | // Testing allocator implementations |
127 | //////////////////////////////////// |
128 | // std:allocator |
129 | if(test_cont_variants< std::allocator<void> >()){ |
130 | std::cerr << "test_cont_variants< std::allocator<void> > failed" << std::endl; |
131 | return 1; |
132 | } |
133 | // boost::container::node_allocator |
134 | if(test_cont_variants< node_allocator<void> >()){ |
135 | std::cerr << "test_cont_variants< node_allocator<void> > failed" << std::endl; |
136 | return 1; |
137 | } |
138 | |
139 | //////////////////////////////////// |
140 | // Default init test |
141 | //////////////////////////////////// |
142 | if(!test::default_init_test< stable_vector<int, test::default_init_allocator<int> > >()){ |
143 | std::cerr << "Default init test failed" << std::endl; |
144 | return 1; |
145 | } |
146 | |
147 | //////////////////////////////////// |
148 | // Emplace testing |
149 | //////////////////////////////////// |
150 | const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_BEFORE); |
151 | if(!boost::container::test::test_emplace |
152 | < stable_vector<test::EmplaceInt>, Options>()) |
153 | return 1; |
154 | |
155 | //////////////////////////////////// |
156 | // Allocator propagation testing |
157 | //////////////////////////////////// |
158 | if(!boost::container::test::test_propagate_allocator<boost_container_stable_vector>()) |
159 | return 1; |
160 | |
161 | //////////////////////////////////// |
162 | // Initializer lists testing |
163 | //////////////////////////////////// |
164 | if(!boost::container::test::test_vector_methods_with_initializer_list_as_argument_for |
165 | < boost::container::stable_vector<int> >()) |
166 | { |
167 | std::cerr << "test_methods_with_initializer_list_as_argument failed" << std::endl; |
168 | return 1; |
169 | } |
170 | |
171 | //////////////////////////////////// |
172 | // Iterator testing |
173 | //////////////////////////////////// |
174 | { |
175 | typedef boost::container::stable_vector<int> cont_int; |
176 | cont_int a; a.push_back(x: 0); a.push_back(x: 1); a.push_back(x: 2); |
177 | boost::intrusive::test::test_iterator_random< cont_int >(c&: a); |
178 | if(boost::report_errors() != 0) { |
179 | return 1; |
180 | } |
181 | } |
182 | |
183 | #ifndef BOOST_CONTAINER_NO_CXX17_CTAD |
184 | //////////////////////////////////// |
185 | // Constructor Template Auto Deduction testing |
186 | //////////////////////////////////// |
187 | { |
188 | auto gold = std::vector{ 1, 2, 3 }; |
189 | auto test = boost::container::stable_vector(gold.begin(), gold.end()); |
190 | if (test.size() != 3) { |
191 | return 1; |
192 | } |
193 | if (!(test[0] == 1 && test[1] == 2 && test[2] == 3)) { |
194 | return 1; |
195 | } |
196 | } |
197 | #endif |
198 | |
199 | //////////////////////////////////// |
200 | // has_trivial_destructor_after_move testing |
201 | //////////////////////////////////// |
202 | // default allocator |
203 | { |
204 | typedef boost::container::stable_vector<int> cont; |
205 | typedef cont::allocator_type allocator_type; |
206 | typedef boost::container::allocator_traits<allocator_type>::pointer pointer; |
207 | BOOST_CONTAINER_STATIC_ASSERT_MSG( |
208 | !(boost::has_trivial_destructor_after_move<cont>::value != |
209 | boost::has_trivial_destructor_after_move<allocator_type>::value && |
210 | boost::has_trivial_destructor_after_move<pointer>::value) |
211 | , "has_trivial_destructor_after_move(default allocator) test failed" ); |
212 | } |
213 | // std::allocator |
214 | { |
215 | typedef boost::container::stable_vector<int, std::allocator<int> > cont; |
216 | typedef cont::allocator_type allocator_type; |
217 | typedef boost::container::allocator_traits<allocator_type>::pointer pointer; |
218 | BOOST_CONTAINER_STATIC_ASSERT_MSG( |
219 | !(boost::has_trivial_destructor_after_move<cont>::value != |
220 | boost::has_trivial_destructor_after_move<allocator_type>::value && |
221 | boost::has_trivial_destructor_after_move<pointer>::value) |
222 | , "has_trivial_destructor_after_move(std::allocator) test failed" ); |
223 | } |
224 | |
225 | return 0; |
226 | } |
227 | |