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