16 #include <string_view>
19 #if defined(__clang__)
20 # pragma clang diagnostic push
21 # pragma clang diagnostic ignored "-Wuninitialized"
32 std::memcpy(heap, sb.heap, sb.
size());
37 if (sb.usingAllocatedBuffer) {
39 bufferCapacity = sb.bufferCapacity;
40 usingAllocatedBuffer = sb.usingAllocatedBuffer;
41 nonOwning = sb.nonOwning;
42 sb.usingAllocatedBuffer =
false;
44 std::memcpy(buffer.data(), sb.heap, sb.bufferSize);
47 bufferSize = sb.bufferSize;
48 sb.heap = sb.buffer.data();
49 sb.bufferCapacity = 64;
54 typename T = std::enable_if_t<std::is_constructible_v<std::string_view, U>>>
57 std::string_view val(std::forward<U>(u));
59 std::memcpy(heap, val.data(), val.size());
75 resize(
size, std::byte{val});
80 if (usingAllocatedBuffer && !nonOwning) {
90 std::memcpy(heap, sb.heap, sb.
size());
93 SmallBuffer& operator=(SmallBuffer&& sb) noexcept
97 const SmallBuffer& buf = sb;
99 return operator=(buf);
101 catch (std::bad_alloc&) {
106 if (usingAllocatedBuffer) {
108 if (sb.heap == heap) {
109 bufferSize = sb.bufferSize;
110 bufferCapacity = sb.bufferCapacity;
114 if (sb.heap == heap) {
115 bufferSize = sb.bufferSize;
122 if (sb.usingAllocatedBuffer) {
124 bufferCapacity = sb.bufferCapacity;
125 usingAllocatedBuffer =
true;
126 nonOwning = sb.nonOwning;
128 std::memcpy(buffer.data(), sb.heap, sb.bufferSize);
129 usingAllocatedBuffer =
false;
131 heap = buffer.data();
135 bufferSize = sb.bufferSize;
136 sb.heap = sb.buffer.data();
137 sb.bufferCapacity = 64;
139 sb.usingAllocatedBuffer =
false;
145 typename T = std::enable_if_t<std::is_constructible_v<std::string_view, U>>>
146 SmallBuffer& operator=(U&& u)
148 std::string_view val(std::forward<U>(u));
149 if (
reinterpret_cast<const std::byte*
>(val.data()) == heap) {
150 bufferSize = val.size();
154 if (val.size() > 0) {
155 std::memcpy(heap, val.data(), val.size());
160 std::byte*
data()
const {
return heap; }
164 std::byte*
end() {
return heap + bufferSize; }
166 const std::byte*
begin()
const {
return heap; }
168 const std::byte*
end()
const {
return heap + bufferSize; }
170 std::byte
operator[](
size_t index)
const {
return heap[index]; }
174 std::byte
at(
size_t index)
const
176 if (index >= bufferSize) {
177 throw(std::out_of_range(
"specified index is not valid"));
182 std::byte&
at(
size_t index)
184 if (index >= bufferSize) {
185 throw(std::out_of_range(
"specified index is not valid"));
194 std::invalid_argument(
"invalid range specified, end pointer before start pointer"));
196 const auto* st1 =
reinterpret_cast<const std::byte*
>(start);
197 const auto* end1 =
reinterpret_cast<const std::byte*
>(
end);
199 std::memcpy(heap, st1, end1 - st1);
201 void assign(
const void* start, std::size_t
size)
203 const auto* st1 =
reinterpret_cast<const std::byte*
>(start);
205 std::memcpy(heap, st1,
size);
207 void append(
const void* start,
const void*
end)
211 std::invalid_argument(
"invalid range specified, end pointer before start pointer"));
213 const auto* st1 =
reinterpret_cast<const std::byte*
>(start);
214 const auto* end1 =
reinterpret_cast<const std::byte*
>(
end);
215 auto csize = bufferSize;
216 resize(bufferSize + (end1 - st1));
217 std::memcpy(heap + csize, st1, end1 - st1);
219 void append(
const void* start, std::size_t
size)
221 const auto* st1 =
reinterpret_cast<const std::byte*
>(start);
222 auto csize = bufferSize;
223 resize(bufferSize +
size);
224 std::memcpy(heap + csize, st1,
size);
226 void append(std::string_view
data)
228 const auto* st1 =
reinterpret_cast<const std::byte*
>(
data.data());
229 auto csize = bufferSize;
230 resize(bufferSize +
data.size());
231 std::memcpy(heap + csize, st1,
data.size());
234 void push_back(
char c) { append(&c, 1); }
236 void pop_back() { bufferSize > 0 ? --bufferSize : 0; }
240 return std::string_view{
reinterpret_cast<const char*
>(heap), bufferSize};
246 if (bufferCapacity > bufferSize) {
247 heap[bufferSize] = std::byte(0);
254 const char*
char_data()
const {
return reinterpret_cast<const char*
>(heap); }
258 auto* newHeap =
reinterpret_cast<std::byte*
>(
data);
259 if (usingAllocatedBuffer && !nonOwning) {
260 if (newHeap != heap) {
268 usingAllocatedBuffer =
true;
274 auto* newHeap =
reinterpret_cast<std::byte*
>(
data);
275 if (usingAllocatedBuffer && !nonOwning) {
276 if (newHeap == heap) {
290 usingAllocatedBuffer =
true;
292 void resize(
size_t size)
297 void resize(
size_t size, std::byte val)
300 if (
size > bufferSize) {
301 std::memset(heap + bufferSize, std::to_integer<int>(val),
size - bufferSize);
305 void reserve(
size_t size)
307 static constexpr
size_t bigSize{
sizeof(size_t) == 8 ? 0x010'0000'0000U : 0xFFFF'0000U};
308 if (
size > bufferCapacity) {
309 if (
size > bigSize || locked) {
310 throw(std::bad_alloc());
312 auto* ndata =
new std::byte[
size + 8];
313 std::memcpy(ndata, heap, bufferSize);
314 if (usingAllocatedBuffer && !nonOwning) {
319 usingAllocatedBuffer =
true;
320 bufferCapacity =
size + 8;
323 void lock(
bool lockStatus =
true) { locked = lockStatus; }
325 bool isLocked()
const {
return locked; }
329 bool empty()
const {
return (bufferSize == 0); }
331 std::size_t
size()
const {
return bufferSize; }
333 std::size_t
capacity()
const {
return bufferCapacity; }
340 if (sb2.usingAllocatedBuffer && usingAllocatedBuffer) {
341 std::swap(heap, sb2.heap);
342 std::swap(nonOwning, sb2.nonOwning);
343 std::swap(bufferCapacity, sb2.bufferCapacity);
344 std::swap(bufferSize, sb2.bufferSize);
345 }
else if (usingAllocatedBuffer) {
347 sb2.bufferCapacity = bufferCapacity;
348 sb2.usingAllocatedBuffer =
true;
349 sb2.nonOwning = nonOwning;
350 usingAllocatedBuffer =
false;
352 heap = buffer.data();
355 std::memcpy(heap, sb2.buffer.data(), sb2.size());
356 std::swap(sb2.bufferSize, bufferSize);
357 }
else if (sb2.usingAllocatedBuffer) {
359 bufferCapacity = sb2.bufferCapacity;
360 usingAllocatedBuffer =
true;
361 nonOwning = sb2.nonOwning;
362 sb2.usingAllocatedBuffer =
false;
363 sb2.nonOwning =
false;
364 sb2.heap = buffer.data();
365 sb2.bufferCapacity = 64;
367 std::memcpy(sb2.heap, buffer.data(), bufferSize);
368 std::swap(sb2.bufferSize, bufferSize);
370 std::swap(sb2.buffer, buffer);
371 std::swap(sb2.bufferSize, bufferSize);
377 if (!usingAllocatedBuffer) {
380 auto* released = heap;
381 heap = buffer.data();
382 usingAllocatedBuffer =
false;
391 std::array<std::byte, 64> buffer{{std::byte{0}}};
392 std::size_t bufferSize{0};
393 std::size_t bufferCapacity{64};
395 bool nonOwning{
false};
397 bool usingAllocatedBuffer{
false};
398 std::int8_t errorCondition{0};
401 std::uint32_t userKey{0};
417 #if defined(__clang__)
418 # pragma clang diagnostic pop
Definition: SmallBuffer.hpp:25
void swap(SmallBuffer &sb2) noexcept
Definition: SmallBuffer.hpp:338
std::byte * release()
Definition: SmallBuffer.hpp:375
~SmallBuffer()
Definition: SmallBuffer.hpp:78
const std::byte * end() const
Definition: SmallBuffer.hpp:168
const std::byte * begin() const
Definition: SmallBuffer.hpp:166
std::byte * data() const
Definition: SmallBuffer.hpp:160
std::byte & operator[](size_t index)
Definition: SmallBuffer.hpp:172
void clear()
Definition: SmallBuffer.hpp:335
std::byte operator[](size_t index) const
Definition: SmallBuffer.hpp:170
std::string_view to_string() const
Definition: SmallBuffer.hpp:238
void spanAssign(void *data, std::size_t size, std::size_t capacity)
Definition: SmallBuffer.hpp:272
void moveAssign(void *data, std::size_t size, std::size_t capacity)
Definition: SmallBuffer.hpp:256
const char * char_data() const
Definition: SmallBuffer.hpp:254
bool empty() const
Definition: SmallBuffer.hpp:329
std::byte * end()
Definition: SmallBuffer.hpp:164
std::int8_t errorState() const
Definition: SmallBuffer.hpp:327
SmallBuffer(std::size_t size, std::byte val)
Definition: SmallBuffer.hpp:71
std::size_t capacity() const
Definition: SmallBuffer.hpp:333
std::byte * begin()
Definition: SmallBuffer.hpp:162
SmallBuffer(std::size_t size, unsigned char val)
Definition: SmallBuffer.hpp:73
void assign(const void *start, const void *end)
Definition: SmallBuffer.hpp:190
SmallBuffer(std::size_t size)
Definition: SmallBuffer.hpp:68
std::byte at(size_t index) const
Definition: SmallBuffer.hpp:174
std::size_t size() const
Definition: SmallBuffer.hpp:331
void null_terminate()
Definition: SmallBuffer.hpp:244
std::byte & at(size_t index)
Definition: SmallBuffer.hpp:182
the main namespace for the helics co-simulation library User functions will be in the helics namespac...
Definition: AsyncFedCallInfo.hpp:14
bool operator!=(const SmallBuffer &sb1, const SmallBuffer &sb2)
Definition: SmallBuffer.hpp:412
bool operator==(const SmallBuffer &sb1, const SmallBuffer &sb2)
Definition: SmallBuffer.hpp:406