• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2014-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_NEW_ALLOCATOR_HPP
12 #define BOOST_CONTAINER_NEW_ALLOCATOR_HPP
13 
14 #ifndef BOOST_CONFIG_HPP
15 #  include <boost/config.hpp>
16 #endif
17 
18 #if defined(BOOST_HAS_PRAGMA_ONCE)
19 #  pragma once
20 #endif
21 
22 #include <boost/container/detail/config_begin.hpp>
23 #include <boost/container/detail/workaround.hpp>
24 #include <boost/container/throw_exception.hpp>
25 #include <cstddef>
26 
27 //!\file
28 
29 namespace boost {
30 namespace container {
31 
32 /// @cond
33 
34 template<bool Value>
35 struct new_allocator_bool
36 {  static const bool value = Value;  };
37 
38 template<class T>
39 class new_allocator;
40 
41 /// @endcond
42 
43 //! Specialization of new_allocator for void types
44 template<>
45 class new_allocator<void>
46 {
47    public:
48    typedef void                                 value_type;
49    typedef void *                               pointer;
50    typedef const void*                          const_pointer;
51    //!A integral constant of type bool with value true
52    typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) propagate_on_container_move_assignment;
53    //!A integral constant of type bool with value true
54    typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) is_always_equal;
55    // reference-to-void members are impossible
56 
57    //!Obtains an new_allocator that allocates
58    //!objects of type T2
59    template<class T2>
60    struct rebind
61    {
62       typedef new_allocator< T2> other;
63    };
64 
65    //!Default constructor
66    //!Never throws
new_allocator()67    new_allocator() BOOST_NOEXCEPT_OR_NOTHROW
68    {}
69 
70    //!Constructor from other new_allocator.
71    //!Never throws
new_allocator(const new_allocator &)72    new_allocator(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
73    {}
74 
75    //!Copy assignment operator from other new_allocator.
76    //!Never throws
operator =(const new_allocator &)77    new_allocator& operator=(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
78    {
79        return *this;
80    }
81 
82    //!Constructor from related new_allocator.
83    //!Never throws
84    template<class T2>
new_allocator(const new_allocator<T2> &)85    new_allocator(const new_allocator<T2> &) BOOST_NOEXCEPT_OR_NOTHROW
86    {}
87 
88    //!Swaps two allocators, does nothing
89    //!because this new_allocator is stateless
swap(new_allocator &,new_allocator &)90    friend void swap(new_allocator &, new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
91    {}
92 
93    //!An new_allocator always compares to true, as memory allocated with one
94    //!instance can be deallocated by another instance
operator ==(const new_allocator &,const new_allocator &)95    friend bool operator==(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
96    {  return true;   }
97 
98    //!An new_allocator always compares to false, as memory allocated with one
99    //!instance can be deallocated by another instance
operator !=(const new_allocator &,const new_allocator &)100    friend bool operator!=(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
101    {  return false;   }
102 };
103 
104 
105 //! This class is a reduced STL-compatible allocator that allocates memory using operator new
106 template<class T>
107 class new_allocator
108 {
109    public:
110    typedef T                                    value_type;
111    typedef T *                                  pointer;
112    typedef const T *                            const_pointer;
113    typedef T &                                  reference;
114    typedef const T &                            const_reference;
115    typedef std::size_t                          size_type;
116    typedef std::ptrdiff_t                       difference_type;
117    //!A integral constant of type bool with value true
118    typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) propagate_on_container_move_assignment;
119    //!A integral constant of type bool with value true
120    typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) is_always_equal;
121 
122    //!Obtains an new_allocator that allocates
123    //!objects of type T2
124    template<class T2>
125    struct rebind
126    {
127       typedef new_allocator<T2> other;
128    };
129 
130    //!Default constructor
131    //!Never throws
new_allocator()132    new_allocator() BOOST_NOEXCEPT_OR_NOTHROW
133    {}
134 
135    //!Constructor from other new_allocator.
136    //!Never throws
new_allocator(const new_allocator &)137    new_allocator(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
138    {}
139 
140    //!Copy assignment operator from other new_allocator.
141    //!Never throws
operator =(const new_allocator &)142    new_allocator& operator=(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
143    {
144        return *this;
145    }
146 
147    //!Constructor from related new_allocator.
148    //!Never throws
149    template<class T2>
new_allocator(const new_allocator<T2> &)150    new_allocator(const new_allocator<T2> &) BOOST_NOEXCEPT_OR_NOTHROW
151    {}
152 
153    //!Allocates memory for an array of count elements.
154    //!Throws std::bad_alloc if there is no enough memory
allocate(size_type count)155    pointer allocate(size_type count)
156    {
157       const std::size_t max_count = std::size_t(-1)/(2*sizeof(T));
158       if(BOOST_UNLIKELY(count > max_count))
159          throw_bad_alloc();
160       return static_cast<T*>(::operator new(count*sizeof(T)));
161    }
162 
163    //!Deallocates previously allocated memory.
164    //!Never throws
deallocate(pointer ptr,size_type)165    void deallocate(pointer ptr, size_type) BOOST_NOEXCEPT_OR_NOTHROW
166      { ::operator delete((void*)ptr); }
167 
168    //!Returns the maximum number of elements that could be allocated.
169    //!Never throws
max_size() const170    size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
171    {  return std::size_t(-1)/(2*sizeof(T));   }
172 
173    //!Swaps two allocators, does nothing
174    //!because this new_allocator is stateless
swap(new_allocator &,new_allocator &)175    friend void swap(new_allocator &, new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
176    {}
177 
178    //!An new_allocator always compares to true, as memory allocated with one
179    //!instance can be deallocated by another instance
operator ==(const new_allocator &,const new_allocator &)180    friend bool operator==(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
181    {  return true;   }
182 
183    //!An new_allocator always compares to false, as memory allocated with one
184    //!instance can be deallocated by another instance
operator !=(const new_allocator &,const new_allocator &)185    friend bool operator!=(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
186    {  return false;   }
187 };
188 
189 }  //namespace container {
190 }  //namespace boost {
191 
192 #include <boost/container/detail/config_end.hpp>
193 
194 #endif   //BOOST_CONTAINER_NEW_ALLOCATOR_HPP
195