FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
co-cpp19/src/array19.lib/array19/AllocatedArrayUtils.h at develop · basicpp/co-cpp19 · GitHub
Uh oh!
There was an error while loading.
Please reload this page
.
basicpp
/
co-cpp19
Public
Notifications
You must be signed in to change notification settings
Fork
3
Star
14
Code
Issues
1
Pull requests
0
Actions
Projects
Security and quality
0
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
co-cpp19
/
src
/
array19.lib
/
array19
/
AllocatedArrayUtils.h
Copy path
More file actions
More file actions
Latest commit
History
History
History
183 lines (168 loc) · 7.35 KB
Breadcrumbs
co-cpp19
/
src
/
array19.lib
/
array19
/
AllocatedArrayUtils.h
Copy path
File metadata and controls
183 lines (168 loc) · 7.35 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#
pragma
once
#
include
"
MoveSliceOf.h
"
#
include
"
SliceOf.h
"
#
include
<
new
>
//
::operator new, ::operator delete
#
include
<
stddef.h
>
//
size_t
#
include
<
string.h
>
//
memcpy
#
include
<
type_traits
>
#
include
<
utility
>
namespace
array19
{
//
/ Utility functions that implement the meat of allocated arrays
//
/
//
/ note:
//
/ * This replaces the algorithmns form std <memory> header.
//
/ * It works with Slices instead of iterators to simplify the interface
template
<
class
T
>
struct
AllocatedArrayUtils
{
static_assert
(std::is_nothrow_move_constructible_v<T>,
"
Please ensure move constructior is marked noexcept!
"
);
static_assert
(std::is_nothrow_move_assignable_v<T>,
"
Please ensure move assignment is marked noexcept!
"
);
static_assert
(std::is_nothrow_destructible_v<T>,
"
Please ensure destructor is marked noexcept!
"
);
using
Slice = SliceOf<T>;
using
ConstSlice = SliceOf<
const
T>;
using
MoveSlice = MoveSliceOf<T>;
//
/ returns uninitialized storage for \param count elements with proper alignment
//
/ note:
//
/ * use deallocate to free the storage!
//
/ * exceptions from new will terminate - without memory no recovery is possible!
[[nodiscard]]
static
auto
allocate
(
size_t
count)
noexcept
-> T* {
if
(
0
== count)
return
nullptr
;
if
constexpr
(__STDCPP_DEFAULT_NEW_ALIGNMENT__ <
alignof
(T)) {
return
reinterpret_cast
<T*>(::
operator
new
[](count *
sizeof
(T), std::
align_val_t
{
alignof
(T)}));
}
else
{
return
reinterpret_cast
<T*>(::
operator
new
[](count *
sizeof
(T)));
}
}
//
/ frees the storage pointed to by the slice
//
/ note:
//
/ * slice.begin() has to be the pointer returned by allocate(size.count())
//
/ * exceptions form delete will terminate - we assume memory is corrupted!
static
void
deallocate
(Slice slice)
noexcept
{
#
if
__cpp_sized_deallocation
if
constexpr
(__STDCPP_DEFAULT_NEW_ALIGNMENT__ <
alignof
(T)) {
::
operator
delete[]
(slice.
begin
(), slice.
count
() *
sizeof
(T), std::
align_val_t
{
alignof
(T)});
}
else
{
::
operator
delete[]
(slice.
begin
(), slice.
count
() *
sizeof
(T));
}
#
else
if
constexpr
(__STDCPP_DEFAULT_NEW_ALIGNMENT__ <
alignof
(T)) {
::
operator
delete[]
(slice.
begin
(), std::
align_val_t
{
alignof
(T)});
}
else
{
::
operator
delete[]
(slice.
begin
());
}
#
endif
}
//
/ default construct every element of \param slice if necessary
static
void
defaultConstruct
(Slice slice)
noexcept
(std::is_nothrow_default_constructible_v<T>) {
if
constexpr
(!std::is_trivially_default_constructible_v<T>)
for
(
auto
& e : slice)
new
(&e)
T
();
}
//
/ calls destructor for every element of \param slice if necessary
//
/ note:
//
/ * we assume destructors are always noexcept
static
void
destruct
(Slice slice)
noexcept
{
if
constexpr
(!std::is_trivially_destructible_v<T>)
for
(
auto
& elem : slice) elem.
~T
();
}
//
/ constructs a copy of \param fromSlice at \param toPointer
//
/ note:
//
/ * toPointer has to point to least fromSlice.count() elements
//
/ * assumes toPointer and fromSlice do not overlap
static
void
copyConstruct
(T* toPointer, ConstSlice fromSlice)
noexcept
(std::is_nothrow_copy_constructible_v<T>) {
if
constexpr
(std::is_trivially_copy_constructible_v<T>) {
if
(!fromSlice.
isEmpty
()) {
memcpy
(toPointer, fromSlice.
begin
(), fromSlice.
count
() *
sizeof
(T));
}
}
else
{
for
(
auto
& from : fromSlice)
new
(toPointer++)
T
(from);
}
}
//
/ move constructs elements of \param fromSlice into \param to Pointer
//
/ note:
//
/ * toPointer has to point to least fromSlice.count() elements
//
/ * assumes toPointer and fromSlice do not overlap
//
/ * we assume move is always noexcept!
static
void
moveConstruct
(T* toPointer, MoveSlice fromSlice)
noexcept
{
if
constexpr
(std::is_trivially_move_constructible_v<T>) {
if
(!fromSlice.
isEmpty
()) {
memcpy
(toPointer, fromSlice.
begin
(), fromSlice.
count
() *
sizeof
(T));
}
}
else
{
for
(
auto
& from : fromSlice)
new
(toPointer++)
T
(
std::move
(from));
}
}
//
/ assigns elements of \param fromSlice into \param toPointer
//
/ note:
//
/ * toPointer has to point to least fromSlice.count() initialized elements
//
/ * assumes toPointer and fromSlice do not overlap
static
void
copyAssign
(T* toPointer, ConstSlice fromSlice)
noexcept
(std::is_nothrow_copy_assignable_v<T>) {
if
constexpr
(std::is_trivially_copy_assignable_v<T>) {
if
(!fromSlice.
isEmpty
()) {
memcpy
(toPointer, fromSlice.
begin
(), fromSlice.
count
() *
sizeof
(T));
}
}
else
{
for
(
const
auto
& from : fromSlice) *toPointer++ = from;
}
}
//
/ move assigns elements of \param fromSlice into \param to Pointer
//
/ note:
//
/ * toPointer has to point to least fromSlice.count() elements
//
/ * assumes toPointer and fromSlice do not overlap
//
/ * we assume move is always noexcept!
static
void
moveAssign
(T* toPointer, MoveSlice fromSlice)
noexcept
{
if
constexpr
(std::is_trivially_move_assignable_v<T>) {
if
(!fromSlice.
isEmpty
()) {
memcpy
(toPointer, fromSlice.
begin
(), fromSlice.
count
() *
sizeof
(T));
}
}
else
{
for
(
auto
& from : fromSlice) *toPointer++ =
std::move
(from);
}
}
//
/ move assigns elements of \param fromSlice into \param to Pointer
//
/ note:
//
/ * toPointer has to point to least fromSlice.count() elements
//
/ * toPointer has to be before fromSlice.begin() if ranges overlap
//
/ * we assume move is always noexcept!
//
/
//
/ example:
//
/ [ e e e e e e e ]
//
/ toPointer ^ ^ fromSlice.begin()
static
void
moveAssignForward
(T* toPointer, MoveSlice fromSlice)
noexcept
{
if
constexpr
(std::is_trivially_move_constructible_v<T>) {
if
(!fromSlice.
isEmpty
()) {
memmove
(toPointer, fromSlice.
begin
(), fromSlice.
count
() *
sizeof
(T));
}
}
else
{
for
(
auto
& from : fromSlice) *toPointer++ =
std::move
(from);
}
}
//
/ move assigns elements of \param fromSlice into \param to Pointer
//
/ note:
//
/ * toPointer has to point to least fromSlice.count() elements
//
/ * toPointer has to be behind fromSlice.begin() if ranges overlap
//
/ * we assume move is always noexcept!
//
/
//
/ example:
//
/ [ e e e e e e e ]
//
/ fromSlice.begin() ^ ^ toPointer
static
void
moveAssignReverse
(T* toPointer, MoveSlice fromSlice)
noexcept
{
if
constexpr
(std::is_trivially_move_assignable_v<T>) {
if
(!fromSlice.
isEmpty
()) {
memmove
(toPointer, fromSlice.
begin
(), fromSlice.
count
() *
sizeof
(T));
}
}
else
{
auto
rTo = toPointer + fromSlice.
count
();
auto
rFrom = fromSlice.
end
();
auto
rFromEnd = fromSlice.
begin
();
while
(rFrom != rFromEnd) *(--rTo) =
std::move
(*(--rFrom));
}
}
};
}
//
namespace array19
Back
|
FazBrowse Home
|
New Git URL