jaulib v1.3.0
Jau Support Library (C++, Java, ..)
callocator.hpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2021 Gothel Software e.K.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25#ifndef C_ALLOCATOR_HPP
26#define C_ALLOCATOR_HPP
27
28#include <cinttypes>
29#include <memory>
30
31#include <jau/basic_types.hpp>
32
33namespace jau {
34
35/**
36 * A simple allocator using POSIX C functions: <code>::malloc()</code>, <code>::free()</code> and <code>::realloc()</code>.<br>
37 * It is the missing <code>::realloc()</code> in <code>std::allocator</code>, motivating this class.<br>
38 * Since <code>realloc()</code> requires the passed pointer to originate from <code>malloc()</code> or <code>calloc</code>,
39 * we have to use it for <code>allocate()</code> as well.
40 *
41 * Added method is <code>reallocate()</code> using the native <code>realloc()</code>.
42 *
43 * This class shall be compliant with <i>C++ named requirements for Allocator</i>.
44 *
45 * Not implementing deprecated (C++17) and removed (C++20)
46 * methods: address(), max_size(), construct() and destroy().
47 */
48template <class T>
50{
51 public:
52 // typedefs' for C++ named requirements: Allocator
53 typedef T value_type;
54 typedef std::size_t size_type;
55 typedef std::ptrdiff_t difference_type;
57
58 // C++17, deprecated in C++20
59 typedef std::true_type is_always_equal;
60
61 // deprecated in C++17 and removed in C++20
62 typedef T* pointer;
63 typedef const T* const_pointer;
64 typedef T& reference;
65 typedef const T& const_reference;
66 template <class U> struct rebind {typedef callocator<U> other;};
67
68 private:
69 typedef std::remove_const_t<T> value_type_mutable;
70 /** Required to create and move immutable elements, aka const */
71 typedef value_type_mutable* pointer_mutable;
72
73 public:
74 callocator() noexcept = default; // C++11
75
76#if __cplusplus > 201703L
77 constexpr callocator(const callocator&) noexcept // NOLINT(modernize-use-equals-default)
78 {} // C++20
79#else
80 callocator(const callocator&) noexcept // NOLINT(modernize-use-equals-default)
81 {}
82#endif
83
84#if __cplusplus > 201703L
85 template <typename U>
86 constexpr callocator(const callocator<U>&) noexcept // NOLINT(modernize-use-equals-default)
87 { } // C++20
88#else
89 template <typename U>
90 callocator(const callocator<U>&) noexcept // NOLINT(modernize-use-equals-default)
91 { }
92#endif
93
94#if __cplusplus > 201703L
95 constexpr ~callocator() = default; // C++20
96#else
97 ~callocator() = default;
98#endif
99
100#if __cplusplus <= 201703L
101 value_type* allocate(std::size_t n, const void *) { // C++17 deprecated; C++20 removed
102 return reinterpret_cast<value_type*>( ::malloc( n * sizeof(value_type) ) );
103 }
104#endif
105
106#if __cplusplus > 201703L
107 [[nodiscard]] constexpr value_type* allocate(std::size_t n) { // C++20
108 return reinterpret_cast<value_type*>( ::malloc( n * sizeof(value_type) ) ); // NOLINT(bugprone-sizeof-expression)
109 }
110#else
111 value_type* allocate(std::size_t n) { // C++17
112 return reinterpret_cast<value_type*>( ::malloc( n * sizeof(value_type) ) ); // NOLINT(bugprone-sizeof-expression)
113 }
114#endif
115
116 [[nodiscard]] constexpr value_type* reallocate(value_type* p, std::size_t, std::size_t new_size) {
117 return reinterpret_cast<value_type*>(
118 ::realloc( reinterpret_cast<void*>(const_cast<pointer_mutable>(p)), new_size * sizeof(value_type) ) );
119 }
120
121#if __cplusplus > 201703L
122 constexpr void deallocate(value_type* p, std::size_t) {
123 ::free( reinterpret_cast<void*>( const_cast<pointer_mutable>( p ) ) );
124 }
125#else
126 void deallocate(value_type* p, std::size_t) {
127 ::free( reinterpret_cast<void*>( const_cast<pointer_mutable>( p ) ) );
128 }
129#endif
130
131};
132
133
134#if __cplusplus > 201703L
135template <class T1, class T2>
136 constexpr bool operator==(const callocator<T1>& lhs, const callocator<T2>& rhs) noexcept {
137#if 0
138 if( &lhs == &rhs ) {
139 return true;
140 }
141 return lhs.memory_usage == rhs.memory_usage;
142#else
143 (void)lhs;
144 (void)rhs;
145 return true;
146#endif
147 }
148#else
149 template <class T1, class T2>
150 bool operator==(const callocator<T1>& lhs, const callocator<T2>& rhs) noexcept {
151#if 0
152 if( &lhs == &rhs ) {
153 return true;
154 }
155 return lhs.memory_usage == rhs.memory_usage;
156#else
157 (void)lhs;
158 (void)rhs;
159 return true;
160#endif
161 }
162 template <class T1, class T2>
163 bool operator!=(const callocator<T1>& lhs, const callocator<T2>& rhs) noexcept {
164 return !(lhs==rhs);
165 }
166#endif
167
168} /* namespace jau */
169
170#endif // TEST_ALLOCATOR_HPP
171
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition: backtrace.hpp:32
bool operator==(const callocator< T1 > &lhs, const callocator< T2 > &rhs) noexcept
Definition: callocator.hpp:150
bool operator!=(const callocator< T1 > &lhs, const callocator< T2 > &rhs) noexcept
Definition: callocator.hpp:163
callocator< U > other
Definition: callocator.hpp:66
A simple allocator using POSIX C functions: ::malloc(), ::free() and ::realloc().
Definition: callocator.hpp:50
std::true_type is_always_equal
Definition: callocator.hpp:59
callocator() noexcept=default
callocator(const callocator &) noexcept
Definition: callocator.hpp:80
~callocator()=default
constexpr value_type * reallocate(value_type *p, std::size_t, std::size_t new_size)
Definition: callocator.hpp:116
std::ptrdiff_t difference_type
Definition: callocator.hpp:55
callocator(const callocator< U > &) noexcept
Definition: callocator.hpp:90
const T * const_pointer
Definition: callocator.hpp:63
const T & const_reference
Definition: callocator.hpp:65
value_type * allocate(std::size_t n)
Definition: callocator.hpp:111
value_type * allocate(std::size_t n, const void *)
Definition: callocator.hpp:101
std::size_t size_type
Definition: callocator.hpp:54
std::true_type propagate_on_container_move_assignment
Definition: callocator.hpp:56
void deallocate(value_type *p, std::size_t)
Definition: callocator.hpp:126