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
29namespace boost {
30namespace container {
31
32/// @cond
33
34template<bool Value>
35struct new_allocator_bool
36{ static const bool value = Value; };
37
38template<class T>
39class new_allocator;
40
41/// @endcond
42
43//! Specialization of new_allocator for void types
44template<>
45class 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
67 new_allocator() BOOST_NOEXCEPT_OR_NOTHROW
68 {}
69
70 //!Constructor from other new_allocator.
71 //!Never throws
72 new_allocator(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
73 {}
74
75 //!Constructor from related new_allocator.
76 //!Never throws
77 template<class T2>
78 new_allocator(const new_allocator<T2> &) BOOST_NOEXCEPT_OR_NOTHROW
79 {}
80
81 //!Swaps two allocators, does nothing
82 //!because this new_allocator is stateless
83 friend void swap(new_allocator &, new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
84 {}
85
86 //!An new_allocator always compares to true, as memory allocated with one
87 //!instance can be deallocated by another instance
88 friend bool operator==(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
89 { return true; }
90
91 //!An new_allocator always compares to false, as memory allocated with one
92 //!instance can be deallocated by another instance
93 friend bool operator!=(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
94 { return false; }
95};
96
97
98//! This class is a reduced STL-compatible allocator that allocates memory using operator new
99template<class T>
100class new_allocator
101{
102 public:
103 typedef T value_type;
104 typedef T * pointer;
105 typedef const T * const_pointer;
106 typedef T & reference;
107 typedef const T & const_reference;
108 typedef std::size_t size_type;
109 typedef std::ptrdiff_t difference_type;
110 //!A integral constant of type bool with value true
111 typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) propagate_on_container_move_assignment;
112 //!A integral constant of type bool with value true
113 typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) is_always_equal;
114
115 //!Obtains an new_allocator that allocates
116 //!objects of type T2
117 template<class T2>
118 struct rebind
119 {
120 typedef new_allocator<T2> other;
121 };
122
123 //!Default constructor
124 //!Never throws
125 new_allocator() BOOST_NOEXCEPT_OR_NOTHROW
126 {}
127
128 //!Constructor from other new_allocator.
129 //!Never throws
130 new_allocator(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
131 {}
132
133 //!Constructor from related new_allocator.
134 //!Never throws
135 template<class T2>
136 new_allocator(const new_allocator<T2> &) BOOST_NOEXCEPT_OR_NOTHROW
137 {}
138
139 //!Allocates memory for an array of count elements.
140 //!Throws std::bad_alloc if there is no enough memory
141 pointer allocate(size_type count)
142 {
143 if(BOOST_UNLIKELY(count > this->max_size()))
144 throw_bad_alloc();
145 return static_cast<T*>(::operator new(count*sizeof(T)));
146 }
147
148 //!Deallocates previously allocated memory.
149 //!Never throws
150 void deallocate(pointer ptr, size_type) BOOST_NOEXCEPT_OR_NOTHROW
151 { ::operator delete((void*)ptr); }
152
153 //!Returns the maximum number of elements that could be allocated.
154 //!Never throws
155 size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
156 { return size_type(-1)/sizeof(T); }
157
158 //!Swaps two allocators, does nothing
159 //!because this new_allocator is stateless
160 friend void swap(new_allocator &, new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
161 {}
162
163 //!An new_allocator always compares to true, as memory allocated with one
164 //!instance can be deallocated by another instance
165 friend bool operator==(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
166 { return true; }
167
168 //!An new_allocator always compares to false, as memory allocated with one
169 //!instance can be deallocated by another instance
170 friend bool operator!=(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
171 { return false; }
172};
173
174} //namespace container {
175} //namespace boost {
176
177#include <boost/container/detail/config_end.hpp>
178
179#endif //BOOST_CONTAINER_NEW_ALLOCATOR_HPP
180