• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
propagation_test_allocator()38    propagation_test_allocator()
39       : m_default_contructed(true), m_move_contructed(false), m_move_assigned(false)
40    {}
41 
propagation_test_allocator(const propagation_test_allocator &)42    propagation_test_allocator(const propagation_test_allocator&)
43       : m_default_contructed(false), m_move_contructed(false), m_move_assigned(false)
44    {}
45 
propagation_test_allocator(BOOST_RV_REF (propagation_test_allocator))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>
propagation_test_allocator(BOOST_RV_REF_BEG propagation_test_allocator<U,Id,HasTrueTypes> BOOST_RV_REF_END)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>
propagation_test_allocator(const propagation_test_allocator<U,Id,HasTrueTypes> &)56    propagation_test_allocator(const propagation_test_allocator<U, Id, HasTrueTypes> &)
57    {}
58 
operator =(BOOST_COPY_ASSIGN_REF (propagation_test_allocator))59    propagation_test_allocator & operator=(BOOST_COPY_ASSIGN_REF(propagation_test_allocator))
60    {  return *this;  }
61 
operator =(BOOST_RV_REF (propagation_test_allocator))62    propagation_test_allocator & operator=(BOOST_RV_REF(propagation_test_allocator))
63    {
64       m_move_assigned = true;
65       return *this;
66    }
67 
max_size() const68    std::size_t max_size() const
69    {  return std::size_t(-1);  }
70 
allocate(std::size_t n)71    T* allocate(std::size_t n)
72    {  return (T*)::new char[n*sizeof(T)];  }
73 
deallocate(T * p,std::size_t)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>
operator ==(const propagation_test_allocator<T1,Id,HasTrueTypes> &,const propagation_test_allocator<T2,Id,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>
operator !=(const propagation_test_allocator<T1,Id,HasTrueTypes> &,const propagation_test_allocator<T2,Id,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
allocator_argument_testerallocator_argument_tester166    allocator_argument_tester()
167       : construction_type(NotUsesAllocator), value(0)
168    {}
169 
allocator_argument_testerallocator_argument_tester170    explicit allocator_argument_tester
171       (typename base_type::allocator_constructor_type)
172       : construction_type(ConstructibleSuffix), value(0)
173    {}
174 
allocator_argument_testerallocator_argument_tester175    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
allocator_argument_testerallocator_argument_tester181    explicit allocator_argument_tester(int i)
182       : construction_type(NotUsesAllocator), value(i)
183    {}
184 
allocator_argument_testerallocator_argument_tester185    allocator_argument_tester
186       (int i, typename base_type::allocator_constructor_type)
187       : construction_type(ConstructibleSuffix), value(i)
188    {}
189 
allocator_argument_testerallocator_argument_tester190    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
allocator_argument_testerallocator_argument_tester198    allocator_argument_tester(const allocator_argument_tester &other)
199       : construction_type(NotUsesAllocator), value(other.value)
200    {}
201 
allocator_argument_testerallocator_argument_tester202    allocator_argument_tester( const allocator_argument_tester &other
203                             , typename base_type::allocator_constructor_type)
204       : construction_type(ConstructibleSuffix), value(other.value)
205    {}
206 
allocator_argument_testerallocator_argument_tester207    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
allocator_argument_testerallocator_argument_tester214    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 
allocator_argument_testerallocator_argument_tester218    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 
allocator_argument_testerallocator_argument_tester223    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