]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | ////////////////////////////////////////////////////////////////////////////// |
2 | // | |
3 | // (C) Copyright Ion Gaztanaga 2015-2015. 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 | #ifndef BOOST_CONTAINER_TEST_ALLOCATOR_ARGUMENT_TESTER_HPP | |
12 | #define BOOST_CONTAINER_TEST_ALLOCATOR_ARGUMENT_TESTER_HPP | |
13 | ||
14 | #include <boost/container/uses_allocator.hpp> | |
15 | #include <boost/container/detail/mpl.hpp> | |
16 | #include <boost/move/core.hpp> | |
17 | #include <boost/container/pmr/polymorphic_allocator.hpp> | |
18 | ||
19 | ||
20 | template<class T, unsigned int Id, bool HasTrueTypes = false> | |
21 | class propagation_test_allocator | |
22 | { | |
23 | BOOST_COPYABLE_AND_MOVABLE(propagation_test_allocator) | |
24 | public: | |
25 | ||
26 | template<class U> | |
27 | struct rebind | |
28 | { | |
29 | typedef propagation_test_allocator<U, Id, HasTrueTypes> other; | |
30 | }; | |
31 | ||
11fdf7f2 TL |
32 | typedef boost::container::dtl::bool_<HasTrueTypes> propagate_on_container_copy_assignment; |
33 | typedef boost::container::dtl::bool_<HasTrueTypes> propagate_on_container_move_assignment; | |
34 | typedef boost::container::dtl::bool_<HasTrueTypes> propagate_on_container_swap; | |
35 | typedef boost::container::dtl::bool_<HasTrueTypes> is_always_equal; | |
7c673cae FG |
36 | typedef T value_type; |
37 | ||
38 | propagation_test_allocator() | |
39 | : m_default_contructed(true), m_move_contructed(false), m_move_assigned(false) | |
40 | {} | |
41 | ||
42 | propagation_test_allocator(const propagation_test_allocator&) | |
43 | : m_default_contructed(false), m_move_contructed(false), m_move_assigned(false) | |
44 | {} | |
45 | ||
46 | propagation_test_allocator(BOOST_RV_REF(propagation_test_allocator) ) | |
47 | : m_default_contructed(false), m_move_contructed(true), m_move_assigned(false) | |
48 | {} | |
49 | ||
50 | template<class U> | |
51 | propagation_test_allocator(BOOST_RV_REF_BEG propagation_test_allocator<U, Id, HasTrueTypes> BOOST_RV_REF_END) | |
52 | : m_default_contructed(false), m_move_contructed(true), m_move_assigned(false) | |
53 | {} | |
54 | ||
55 | template<class U> | |
56 | propagation_test_allocator(const propagation_test_allocator<U, Id, HasTrueTypes> &) | |
57 | {} | |
58 | ||
59 | propagation_test_allocator & operator=(BOOST_COPY_ASSIGN_REF(propagation_test_allocator)) | |
60 | { return *this; } | |
61 | ||
62 | propagation_test_allocator & operator=(BOOST_RV_REF(propagation_test_allocator)) | |
63 | { | |
64 | m_move_assigned = true; | |
65 | return *this; | |
66 | } | |
67 | ||
68 | std::size_t max_size() const | |
69 | { return std::size_t(-1); } | |
70 | ||
71 | T* allocate(std::size_t n) | |
72 | { return (T*)::new char[n*sizeof(T)]; } | |
73 | ||
74 | void deallocate(T*p, std::size_t) | |
75 | { delete []static_cast<char*>(static_cast<void*>(p)); } | |
76 | ||
77 | bool m_default_contructed; | |
78 | bool m_move_contructed; | |
79 | bool m_move_assigned; | |
80 | }; | |
81 | ||
82 | template <class T1, class T2, unsigned int Id, bool HasTrueTypes> | |
83 | bool operator==( const propagation_test_allocator<T1, Id, HasTrueTypes>& | |
84 | , const propagation_test_allocator<T2, Id, HasTrueTypes>&) | |
85 | { return true; } | |
86 | ||
87 | template <class T1, class T2, unsigned int Id, bool HasTrueTypes> | |
88 | bool operator!=( const propagation_test_allocator<T1, Id, HasTrueTypes>& | |
89 | , const propagation_test_allocator<T2, Id, HasTrueTypes>&) | |
90 | { return false; } | |
91 | ||
92 | //This enum lists the construction options | |
93 | //for an allocator-aware type | |
94 | enum ConstructionTypeEnum | |
95 | { | |
96 | ConstructiblePrefix, | |
97 | ConstructibleSuffix, | |
98 | ErasedTypePrefix, | |
99 | ErasedTypeSuffix, | |
100 | NotUsesAllocator | |
101 | }; | |
102 | ||
103 | //This base class provices types for | |
104 | //the derived class to implement each construction | |
105 | //type. If a construction type does not apply | |
106 | //the typedef is set to an internal nat | |
107 | //so that the class is not constructible from | |
108 | //the user arguments. | |
109 | template<ConstructionTypeEnum ConstructionType, unsigned int AllocatorTag> | |
110 | struct uses_allocator_base; | |
111 | ||
112 | template<unsigned int AllocatorTag> | |
113 | struct uses_allocator_base<ConstructibleSuffix, AllocatorTag> | |
114 | { | |
115 | typedef propagation_test_allocator<int, AllocatorTag> allocator_type; | |
116 | typedef allocator_type allocator_constructor_type; | |
117 | struct nat{}; | |
118 | typedef nat allocator_arg_type; | |
119 | }; | |
120 | ||
121 | template<unsigned int AllocatorTag> | |
122 | struct uses_allocator_base<ConstructiblePrefix, AllocatorTag> | |
123 | { | |
124 | typedef propagation_test_allocator<int, AllocatorTag> allocator_type; | |
125 | typedef allocator_type allocator_constructor_type; | |
126 | typedef boost::container::allocator_arg_t allocator_arg_type; | |
127 | }; | |
128 | ||
129 | template<unsigned int AllocatorTag> | |
130 | struct uses_allocator_base<ErasedTypePrefix, AllocatorTag> | |
131 | { | |
132 | typedef boost::container::erased_type allocator_type; | |
133 | typedef boost::container::pmr::polymorphic_allocator<int> allocator_constructor_type; | |
134 | typedef boost::container::allocator_arg_t allocator_arg_type; | |
135 | }; | |
136 | ||
137 | template<unsigned int AllocatorTag> | |
138 | struct uses_allocator_base<ErasedTypeSuffix, AllocatorTag> | |
139 | { | |
140 | typedef boost::container::erased_type allocator_type; | |
141 | typedef boost::container::pmr::polymorphic_allocator<int> allocator_constructor_type; | |
142 | struct nat{}; | |
143 | typedef nat allocator_arg_type; | |
144 | }; | |
145 | ||
146 | template<unsigned int AllocatorTag> | |
147 | struct uses_allocator_base<NotUsesAllocator, AllocatorTag> | |
148 | { | |
149 | struct nat{}; | |
150 | typedef nat allocator_constructor_type; | |
151 | typedef nat allocator_arg_type; | |
152 | }; | |
153 | ||
154 | template<ConstructionTypeEnum ConstructionType, unsigned int AllocatorTag> | |
155 | struct allocator_argument_tester | |
156 | : uses_allocator_base<ConstructionType, AllocatorTag> | |
157 | { | |
158 | private: | |
159 | BOOST_COPYABLE_AND_MOVABLE(allocator_argument_tester) | |
160 | ||
161 | public: | |
162 | ||
163 | typedef uses_allocator_base<ConstructionType, AllocatorTag> base_type; | |
164 | ||
165 | //0 user argument constructors | |
166 | allocator_argument_tester() | |
167 | : construction_type(NotUsesAllocator), value(0) | |
168 | {} | |
169 | ||
170 | explicit allocator_argument_tester | |
171 | (typename base_type::allocator_constructor_type) | |
172 | : construction_type(ConstructibleSuffix), value(0) | |
173 | {} | |
174 | ||
175 | explicit allocator_argument_tester | |
176 | (typename base_type::allocator_arg_type, typename base_type::allocator_constructor_type) | |
177 | : construction_type(ConstructiblePrefix), value(0) | |
178 | {} | |
179 | ||
180 | //1 user argument constructors | |
181 | explicit allocator_argument_tester(int i) | |
182 | : construction_type(NotUsesAllocator), value(i) | |
183 | {} | |
184 | ||
185 | allocator_argument_tester | |
186 | (int i, typename base_type::allocator_constructor_type) | |
187 | : construction_type(ConstructibleSuffix), value(i) | |
188 | {} | |
189 | ||
190 | allocator_argument_tester | |
191 | ( typename base_type::allocator_arg_type | |
192 | , typename base_type::allocator_constructor_type | |
193 | , int i) | |
194 | : construction_type(ConstructiblePrefix), value(i) | |
195 | {} | |
196 | ||
197 | //Copy constructors | |
198 | allocator_argument_tester(const allocator_argument_tester &other) | |
199 | : construction_type(NotUsesAllocator), value(other.value) | |
200 | {} | |
201 | ||
202 | allocator_argument_tester( const allocator_argument_tester &other | |
203 | , typename base_type::allocator_constructor_type) | |
204 | : construction_type(ConstructibleSuffix), value(other.value) | |
205 | {} | |
206 | ||
207 | allocator_argument_tester( typename base_type::allocator_arg_type | |
208 | , typename base_type::allocator_constructor_type | |
209 | , const allocator_argument_tester &other) | |
210 | : construction_type(ConstructiblePrefix), value(other.value) | |
211 | {} | |
212 | ||
213 | //Move constructors | |
214 | allocator_argument_tester(BOOST_RV_REF(allocator_argument_tester) other) | |
215 | : construction_type(NotUsesAllocator), value(other.value) | |
216 | { other.value = 0; other.construction_type = NotUsesAllocator; } | |
217 | ||
218 | allocator_argument_tester( BOOST_RV_REF(allocator_argument_tester) other | |
219 | , typename base_type::allocator_constructor_type) | |
220 | : construction_type(ConstructibleSuffix), value(other.value) | |
221 | { other.value = 0; other.construction_type = ConstructibleSuffix; } | |
222 | ||
223 | allocator_argument_tester( typename base_type::allocator_arg_type | |
224 | , typename base_type::allocator_constructor_type | |
225 | , BOOST_RV_REF(allocator_argument_tester) other) | |
226 | : construction_type(ConstructiblePrefix), value(other.value) | |
227 | { other.value = 0; other.construction_type = ConstructiblePrefix; } | |
228 | ||
229 | ConstructionTypeEnum construction_type; | |
230 | int value; | |
231 | }; | |
232 | ||
233 | namespace boost { | |
234 | namespace container { | |
235 | ||
236 | template<unsigned int AllocatorTag> | |
237 | struct constructible_with_allocator_prefix | |
238 | < ::allocator_argument_tester<ConstructiblePrefix, AllocatorTag> > | |
239 | { | |
240 | static const bool value = true; | |
241 | }; | |
242 | ||
243 | template<unsigned int AllocatorTag> | |
244 | struct constructible_with_allocator_prefix | |
245 | < ::allocator_argument_tester<ErasedTypePrefix, AllocatorTag> > | |
246 | { | |
247 | static const bool value = true; | |
248 | }; | |
249 | ||
250 | ||
251 | template<unsigned int AllocatorTag> | |
252 | struct constructible_with_allocator_suffix | |
253 | < ::allocator_argument_tester<ConstructibleSuffix, AllocatorTag> > | |
254 | { | |
255 | static const bool value = true; | |
256 | }; | |
257 | ||
258 | template<unsigned int AllocatorTag> | |
259 | struct constructible_with_allocator_suffix | |
260 | < ::allocator_argument_tester<ErasedTypeSuffix, AllocatorTag> > | |
261 | { | |
262 | static const bool value = true; | |
263 | }; | |
264 | ||
265 | } //namespace container { | |
266 | } //namespace boost { | |
267 | ||
268 | #endif //BOOST_CONTAINER_TEST_ALLOCATOR_ARGUMENT_TESTER_HPP |