1/*
2Copyright 2019 Glen Joseph Fernandes
3(glenjofe@gmail.com)
4
5Distributed under the Boost Software License, Version 1.0.
6(http://www.boost.org/LICENSE_1_0.txt)
7*/
8#ifndef BOOST_CORE_DEFAULT_ALLOCATOR_HPP
9#define BOOST_CORE_DEFAULT_ALLOCATOR_HPP
10
11#include <boost/config.hpp>
12#include <new>
13
14namespace boost {
15
16#if defined(BOOST_NO_EXCEPTIONS)
17BOOST_NORETURN void throw_exception(const std::exception&);
18#endif
19
20namespace default_ {
21
22template<bool V>
23struct bool_constant {
24 typedef bool value_type;
25 typedef bool_constant type;
26
27 static const bool value = V;
28
29 operator bool() const BOOST_NOEXCEPT {
30 return V;
31 }
32
33 bool operator()() const BOOST_NOEXCEPT {
34 return V;
35 }
36};
37
38template<bool V>
39const bool bool_constant<V>::value;
40
41template<class T>
42struct add_reference {
43 typedef T& type;
44};
45
46template<>
47struct add_reference<void> {
48 typedef void type;
49};
50
51template<>
52struct add_reference<const void> {
53 typedef const void type;
54};
55
56template<class T>
57struct default_allocator {
58 typedef T value_type;
59 typedef T* pointer;
60 typedef const T* const_pointer;
61 typedef typename add_reference<T>::type reference;
62 typedef typename add_reference<const T>::type const_reference;
63 typedef std::size_t size_type;
64 typedef std::ptrdiff_t difference_type;
65 typedef bool_constant<true> propagate_on_container_move_assignment;
66 typedef bool_constant<true> is_always_equal;
67
68 template<class U>
69 struct rebind {
70 typedef default_allocator<U> other;
71 };
72
73#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
74 default_allocator() = default;
75#else
76 BOOST_CONSTEXPR default_allocator() BOOST_NOEXCEPT { }
77#endif
78
79 template<class U>
80 BOOST_CONSTEXPR default_allocator(const default_allocator<U>&)
81 BOOST_NOEXCEPT { }
82
83 BOOST_CONSTEXPR std::size_t max_size() const BOOST_NOEXCEPT {
84 return static_cast<std::size_t>(-1) / (2 < sizeof(T) ? sizeof(T) : 2);
85 }
86
87#if !defined(BOOST_NO_EXCEPTIONS)
88 T* allocate(std::size_t n) {
89 if (n > max_size()) {
90 throw std::bad_alloc();
91 }
92 return static_cast<T*>(::operator new(sizeof(T) * n));
93 }
94
95 void deallocate(T* p, std::size_t) {
96 ::operator delete(p);
97 }
98#else
99 T* allocate(std::size_t n) {
100 if (n > max_size()) {
101 boost::throw_exception(std::bad_alloc());
102 }
103 void* p = ::operator new(sizeof(T) * n, std::nothrow);
104 if (!p) {
105 boost::throw_exception(std::bad_alloc());
106 }
107 return static_cast<T*>(p);
108 }
109
110 void deallocate(T* p, std::size_t) {
111 ::operator delete(p, std::nothrow);
112 }
113#endif
114
115#if defined(BOOST_NO_CXX11_ALLOCATOR)
116 T* allocate(std::size_t n, const void*) {
117 return allocate(n);
118 }
119#endif
120
121#if (defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 60000) || \
122 defined(BOOST_NO_CXX11_ALLOCATOR)
123 template<class U, class V>
124 void construct(U* p, const V& v) {
125 ::new(p) U(v);
126 }
127
128 template<class U>
129 void destroy(U* p) {
130 p->~U();
131 (void)p;
132 }
133#endif
134};
135
136template<class T, class U>
137BOOST_CONSTEXPR inline bool
138operator==(const default_allocator<T>&,
139 const default_allocator<U>&) BOOST_NOEXCEPT
140{
141 return true;
142}
143
144template<class T, class U>
145BOOST_CONSTEXPR inline bool
146operator!=(const default_allocator<T>&,
147 const default_allocator<U>&) BOOST_NOEXCEPT
148{
149 return false;
150}
151
152} /* default_ */
153
154using default_::default_allocator;
155
156} /* boost */
157
158#endif
159