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 | |
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; |
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 |
269 | |