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

source code of boost/libs/container/test/allocator_argument_tester.hpp