• 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 
18 template<class T, unsigned int Id, bool HasTrueTypes = false>
19 class propagation_test_allocator
20 {
21    BOOST_COPYABLE_AND_MOVABLE(propagation_test_allocator)
22    public:
23 
24    template<class U>
25    struct rebind
26    {
27       typedef propagation_test_allocator<U, Id, HasTrueTypes> other;
28    };
29 
30    typedef boost::container::dtl::bool_<HasTrueTypes>  propagate_on_container_copy_assignment;
31    typedef boost::container::dtl::bool_<HasTrueTypes>  propagate_on_container_move_assignment;
32    typedef boost::container::dtl::bool_<HasTrueTypes>  propagate_on_container_swap;
33    typedef boost::container::dtl::bool_<HasTrueTypes>  is_always_equal;
34    typedef T value_type;
35 
propagation_test_allocator()36    propagation_test_allocator()
37       : m_move_contructed(false), m_move_assigned(false)
38    {}
39 
propagation_test_allocator(const propagation_test_allocator &)40    propagation_test_allocator(const propagation_test_allocator&)
41       : m_move_contructed(false), m_move_assigned(false)
42    {}
43 
propagation_test_allocator(BOOST_RV_REF (propagation_test_allocator))44    propagation_test_allocator(BOOST_RV_REF(propagation_test_allocator) )
45       : m_move_contructed(true), m_move_assigned(false)
46    {}
47 
48    template<class U>
propagation_test_allocator(BOOST_RV_REF_BEG propagation_test_allocator<U,Id,HasTrueTypes> BOOST_RV_REF_END)49    propagation_test_allocator(BOOST_RV_REF_BEG propagation_test_allocator<U, Id, HasTrueTypes> BOOST_RV_REF_END)
50       : m_move_contructed(true), m_move_assigned(false)
51    {}
52 
53    template<class U>
propagation_test_allocator(const propagation_test_allocator<U,Id,HasTrueTypes> &)54    propagation_test_allocator(const propagation_test_allocator<U, Id, HasTrueTypes> &)
55    {}
56 
operator =(BOOST_COPY_ASSIGN_REF (propagation_test_allocator))57    propagation_test_allocator & operator=(BOOST_COPY_ASSIGN_REF(propagation_test_allocator))
58    {
59       return *this;
60    }
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_move_contructed;
78    bool m_move_assigned;
79 };
80 
81 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> &)82 bool operator==( const propagation_test_allocator<T1, Id, HasTrueTypes>&
83                , const propagation_test_allocator<T2, Id, HasTrueTypes>&)
84 {  return true;   }
85 
86 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> &)87 bool operator!=( const propagation_test_allocator<T1, Id, HasTrueTypes>&
88                , const propagation_test_allocator<T2, Id, HasTrueTypes>&)
89 {  return false;   }
90 
91 //This enum lists the construction options
92 //for an allocator-aware type
93 enum ConstructionTypeEnum
94 {
95    ConstructiblePrefix,
96    ConstructibleSuffix,
97    NotUsesAllocator
98 };
99 
100 //This base class provices types for
101 //the derived class to implement each construction
102 //type. If a construction type does not apply
103 //the typedef is set to an internal nat
104 //so that the class is not constructible from
105 //the user arguments.
106 template<ConstructionTypeEnum ConstructionType, unsigned int AllocatorTag>
107 struct uses_allocator_base;
108 
109 template<unsigned int AllocatorTag>
110 struct uses_allocator_base<ConstructibleSuffix, AllocatorTag>
111 {
112    typedef propagation_test_allocator<int, AllocatorTag> allocator_type;
113    typedef allocator_type allocator_constructor_type;
114    struct nat{};
115    typedef nat allocator_arg_type;
116 };
117 
118 template<unsigned int AllocatorTag>
119 struct uses_allocator_base<ConstructiblePrefix, AllocatorTag>
120 {
121    typedef propagation_test_allocator<int, AllocatorTag> allocator_type;
122    typedef allocator_type allocator_constructor_type;
123    typedef boost::container::allocator_arg_t allocator_arg_type;
124 };
125 
126 template<unsigned int AllocatorTag>
127 struct uses_allocator_base<NotUsesAllocator, AllocatorTag>
128 {
129    struct nat{};
130    typedef nat allocator_constructor_type;
131    typedef nat allocator_arg_type;
132 };
133 
134 template<ConstructionTypeEnum ConstructionType, unsigned int AllocatorTag>
135 struct allocator_argument_tester
136    : uses_allocator_base<ConstructionType, AllocatorTag>
137 {
138    private:
139    BOOST_COPYABLE_AND_MOVABLE(allocator_argument_tester)
140 
141    public:
142 
143    typedef uses_allocator_base<ConstructionType, AllocatorTag> base_type;
144 
145    //0 user argument constructors
allocator_argument_testerallocator_argument_tester146    allocator_argument_tester()
147       : construction_type(NotUsesAllocator), value(0)
148    {}
149 
allocator_argument_testerallocator_argument_tester150    explicit allocator_argument_tester
151       (typename base_type::allocator_constructor_type)
152       : construction_type(ConstructibleSuffix), value(0)
153    {}
154 
allocator_argument_testerallocator_argument_tester155    explicit allocator_argument_tester
156       (typename base_type::allocator_arg_type, typename base_type::allocator_constructor_type)
157       : construction_type(ConstructiblePrefix), value(0)
158    {}
159 
160    //1 user argument constructors
allocator_argument_testerallocator_argument_tester161    explicit allocator_argument_tester(int i)
162       : construction_type(NotUsesAllocator), value(i)
163    {}
164 
allocator_argument_testerallocator_argument_tester165    allocator_argument_tester
166       (int i, typename base_type::allocator_constructor_type)
167       : construction_type(ConstructibleSuffix), value(i)
168    {}
169 
allocator_argument_testerallocator_argument_tester170    allocator_argument_tester
171       ( typename base_type::allocator_arg_type
172       , typename base_type::allocator_constructor_type
173       , int i)
174       : construction_type(ConstructiblePrefix), value(i)
175    {}
176 
177    //Copy constructors
allocator_argument_testerallocator_argument_tester178    allocator_argument_tester(const allocator_argument_tester &other)
179       : construction_type(NotUsesAllocator), value(other.value)
180    {}
181 
allocator_argument_testerallocator_argument_tester182    allocator_argument_tester( const allocator_argument_tester &other
183                             , typename base_type::allocator_constructor_type)
184       : construction_type(ConstructibleSuffix), value(other.value)
185    {}
186 
allocator_argument_testerallocator_argument_tester187    allocator_argument_tester( typename base_type::allocator_arg_type
188                             , typename base_type::allocator_constructor_type
189                             , const allocator_argument_tester &other)
190       : construction_type(ConstructiblePrefix), value(other.value)
191    {}
192 
193    //Move constructors
allocator_argument_testerallocator_argument_tester194    allocator_argument_tester(BOOST_RV_REF(allocator_argument_tester) other)
195       : construction_type(NotUsesAllocator), value(other.value)
196    {  other.value = 0;  other.construction_type = NotUsesAllocator;  }
197 
allocator_argument_testerallocator_argument_tester198    allocator_argument_tester( BOOST_RV_REF(allocator_argument_tester) other
199                             , typename base_type::allocator_constructor_type)
200       : construction_type(ConstructibleSuffix), value(other.value)
201    {  other.value = 0;  other.construction_type = ConstructibleSuffix;  }
202 
allocator_argument_testerallocator_argument_tester203    allocator_argument_tester( typename base_type::allocator_arg_type
204                             , typename base_type::allocator_constructor_type
205                             , BOOST_RV_REF(allocator_argument_tester) other)
206       : construction_type(ConstructiblePrefix), value(other.value)
207    {  other.value = 0;  other.construction_type = ConstructiblePrefix;  }
208 
209    ConstructionTypeEnum construction_type;
210    int                  value;
211 };
212 
213 namespace boost {
214 namespace container {
215 
216 template<unsigned int AllocatorTag>
217 struct constructible_with_allocator_prefix
218    < ::allocator_argument_tester<ConstructiblePrefix, AllocatorTag> >
219 {
220    static const bool value = true;
221 };
222 
223 template<unsigned int AllocatorTag>
224 struct constructible_with_allocator_suffix
225    < ::allocator_argument_tester<ConstructibleSuffix, AllocatorTag> >
226 {
227    static const bool value = true;
228 };
229 
230 }  //namespace container {
231 }  //namespace boost {
232 
233 #endif   //BOOST_CONTAINER_TEST_ALLOCATOR_ARGUMENT_TESTER_HPP
234