DNA Calib 1.1
Project brief
DynArray.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#ifdef _MSC_VER
6 #pragma warning(push)
7 #pragma warning(disable : 4365 4987)
8#endif
9#include <algorithm>
10#include <cassert>
11#include <cstddef>
12#include <cstring>
13#include <functional>
14#include <iterator>
15#include <memory>
16#include <type_traits>
17#ifdef _MSC_VER
18 #pragma warning(pop)
19#endif
20
21namespace terse {
22
26template<typename T, class TAllocator>
27class DynArray {
28 public:
29 static_assert(std::is_trivial<T>::value, "Uninitialized vector doesn't support non-trivial types.");
30
31 using value_type = T;
32 using allocator_type = TAllocator;
33
34 private:
35 using pointer_type = std::unique_ptr<value_type, std::function<void (value_type*)> >;
36
37 public:
38 explicit DynArray(const allocator_type& allocator) :
39 alloc{allocator},
40 sz{},
41 ptr{nullptr} {
42 }
43
45 }
46
47 DynArray(std::size_t size, const allocator_type& allocator = allocator_type{}) :
48 alloc{allocator},
49 sz{size},
50 ptr{create(sz, alloc)} {
51 }
52
53 DynArray(std::size_t size, const value_type& value, const allocator_type& allocator = allocator_type{}) :
54 DynArray{size, allocator} {
55
56 std::fill_n(data(), size, value);
57 }
58
59 DynArray(const value_type* source, std::size_t size, const allocator_type& allocator = allocator_type{}) :
60 DynArray{size, allocator} {
61
62 if ((data() != nullptr) && (source != nullptr)) {
63 std::memcpy(data(), source, size * sizeof(value_type));
64 }
65 }
66
67 template<typename TIterator>
68 DynArray(TIterator start, TIterator end, const allocator_type& allocator = allocator_type{}) :
69 DynArray{static_cast<std::size_t>(std::distance(start, end)), allocator} {
70
71 #if defined(_MSC_VER) && !defined(__clang__)
72 if (size() != 0ul) {
73 std::copy(start, end, stdext::checked_array_iterator<value_type*>(data(), size()));
74 }
75 #else
76 std::copy(start, end, data());
77 #endif
78 }
79
80 ~DynArray() = default;
81
82 DynArray(const DynArray& rhs) : DynArray{rhs.size(), rhs.get_allocator()} {
83 if ((data() != nullptr) && (rhs.data() != nullptr)) {
84 std::memcpy(data(), rhs.data(), rhs.size() * sizeof(value_type));
85 }
86 }
87
89 DynArray tmp{rhs};
90 std::swap(alloc, tmp.alloc);
91 std::swap(ptr, tmp.ptr);
92 std::swap(sz, tmp.sz);
93 return *this;
94 }
95
96 DynArray(DynArray&& rhs) noexcept :
97 alloc{},
98 sz{},
99 ptr{} {
100
101 std::swap(alloc, rhs.alloc);
102 std::swap(ptr, rhs.ptr);
103 std::swap(sz, rhs.sz);
104 }
105
106 DynArray& operator=(DynArray&& rhs) noexcept {
107 std::swap(alloc, rhs.alloc);
108 std::swap(ptr, rhs.ptr);
109 std::swap(sz, rhs.sz);
110 return *this;
111 }
112
113 allocator_type get_allocator() const noexcept {
114 return alloc;
115 }
116
117 void clear() {
118 ptr.reset();
119 sz = 0ul;
120 }
121
123 return ptr.get();
124 }
125
126 const value_type* data() const {
127 return ptr.get();
128 }
129
130 std::size_t size() const {
131 return sz;
132 }
133
134 bool empty() const {
135 return (sz == 0ul);
136 }
137
138 value_type& operator[](std::size_t index) {
139 assert(index < size());
140 return data()[index];
141 }
142
143 const value_type& operator[](std::size_t index) const {
144 assert(index < size());
145 return data()[index];
146 }
147
149 return data();
150 }
151
153 return data() + sz;
154 }
155
156 const value_type* cbegin() const {
157 return data();
158 }
159
160 const value_type* cend() const {
161 return data() + sz;
162 }
163
164 const value_type* begin() const {
165 return cbegin();
166 }
167
168 const value_type* end() const {
169 return cend();
170 }
171
172 void resize(std::size_t size, const value_type& value) {
173 if (size > sz) {
174 pointer_type old{ptr.release(), [this](value_type* p) {
175 alloc.deallocate(p, sz);
176 }};
177 ptr = create(size, alloc);
178 assert(ptr != nullptr);
179 if (old != nullptr) {
180 std::memcpy(ptr.get(), old.get(), sz * sizeof(value_type));
181 }
182 std::fill_n(begin() + sz, size - sz, value);
183 }
184 sz = size;
185 }
186
187 void resize(std::size_t size) {
189 }
190
191 void resize_uninitialized(std::size_t size) {
192 if (size > sz) {
193 pointer_type old{ptr.release(), [this](value_type* p) {
194 alloc.deallocate(p, sz);
195 }};
196 ptr = create(size, alloc);
197 assert(ptr != nullptr);
198 if (old != nullptr) {
199 std::memcpy(ptr.get(), old.get(), sz * sizeof(value_type));
200 }
201 }
202 sz = size;
203 }
204
205 template<typename TIterator>
206 void assign(TIterator start, TIterator end) {
207 resize_uninitialized(static_cast<std::size_t>(std::distance(start, end)));
208 #if defined(_MSC_VER) && !defined(__clang__)
209 if (size() != 0ul) {
210 std::copy(start, end, stdext::checked_array_iterator<value_type*>(data(), size()));
211 }
212 #else
213 std::copy(start, end, data());
214 #endif
215 }
216
217 private:
219 return pointer_type{alloc.allocate(size), [alloc, size](value_type* p) mutable {
220 alloc.deallocate(p, size);
221 }};
222 }
223
224 private:
226 std::size_t sz;
228
229};
230
231} // namespace terse
Resizable array-like abstraction for trivial-types only.
Definition: DynArray.h:27
DynArray & operator=(const DynArray &rhs)
Definition: DynArray.h:88
~DynArray()=default
void resize_uninitialized(std::size_t size)
Definition: DynArray.h:191
DynArray(DynArray &&rhs) noexcept
Definition: DynArray.h:96
const value_type * end() const
Definition: DynArray.h:168
DynArray(const DynArray &rhs)
Definition: DynArray.h:82
DynArray(const value_type *source, std::size_t size, const allocator_type &allocator=allocator_type{})
Definition: DynArray.h:59
std::unique_ptr< value_type, std::function< void(value_type *)> > pointer_type
Definition: DynArray.h:35
std::size_t size() const
Definition: DynArray.h:130
value_type * end()
Definition: DynArray.h:152
DynArray(std::size_t size, const allocator_type &allocator=allocator_type{})
Definition: DynArray.h:47
allocator_type get_allocator() const noexcept
Definition: DynArray.h:113
DynArray()
Definition: DynArray.h:44
value_type * data()
Definition: DynArray.h:122
DynArray(const allocator_type &allocator)
Definition: DynArray.h:38
allocator_type alloc
Definition: DynArray.h:225
void clear()
Definition: DynArray.h:117
std::size_t sz
Definition: DynArray.h:226
const value_type * data() const
Definition: DynArray.h:126
void assign(TIterator start, TIterator end)
Definition: DynArray.h:206
value_type & operator[](std::size_t index)
Definition: DynArray.h:138
TAllocator allocator_type
Definition: DynArray.h:32
static pointer_type create(std::size_t size, allocator_type alloc)
Definition: DynArray.h:218
DynArray(TIterator start, TIterator end, const allocator_type &allocator=allocator_type{})
Definition: DynArray.h:68
bool empty() const
Definition: DynArray.h:134
T value_type
Definition: DynArray.h:31
DynArray(std::size_t size, const value_type &value, const allocator_type &allocator=allocator_type{})
Definition: DynArray.h:53
pointer_type ptr
Definition: DynArray.h:227
void resize(std::size_t size)
Definition: DynArray.h:187
void resize(std::size_t size, const value_type &value)
Definition: DynArray.h:172
const value_type & operator[](std::size_t index) const
Definition: DynArray.h:143
const value_type * cend() const
Definition: DynArray.h:160
DynArray & operator=(DynArray &&rhs) noexcept
Definition: DynArray.h:106
value_type * begin()
Definition: DynArray.h:148
const value_type * begin() const
Definition: DynArray.h:164
const value_type * cbegin() const
Definition: DynArray.h:156
void copy(const TSource &source, TDestination &destination)
Definition: utils/Extd.h:123
Definition: Archive.h:14