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