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