2017-12-21 07:45:38 +08:00
|
|
|
/*
|
2022-03-03 02:51:53 +08:00
|
|
|
* Copyright (C) 2018-2022 Intel Corporation
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
2018-09-18 15:11:08 +08:00
|
|
|
* SPDX-License-Identifier: MIT
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/helpers/debug_helpers.h"
|
2018-01-05 19:54:12 +08:00
|
|
|
|
2022-04-07 21:09:40 +08:00
|
|
|
#include <algorithm>
|
2017-12-21 07:45:38 +08:00
|
|
|
#include <cinttypes>
|
|
|
|
#include <cstddef>
|
2019-01-28 21:26:33 +08:00
|
|
|
#include <iterator>
|
2020-02-25 05:07:46 +08:00
|
|
|
#include <limits>
|
|
|
|
#include <type_traits>
|
|
|
|
#include <utility>
|
2017-12-21 07:45:38 +08:00
|
|
|
#include <vector>
|
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
template <size_t OnStackCapacity>
|
|
|
|
struct StackVecSize {
|
|
|
|
static constexpr size_t max32 = std::numeric_limits<uint32_t>::max();
|
|
|
|
static constexpr size_t max16 = std::numeric_limits<uint16_t>::max();
|
|
|
|
static constexpr size_t max8 = std::numeric_limits<uint8_t>::max();
|
|
|
|
|
|
|
|
using SizeT = std::conditional_t<(OnStackCapacity < max8), uint8_t,
|
|
|
|
std::conditional_t<(OnStackCapacity < max16), uint16_t,
|
|
|
|
std::conditional_t<(OnStackCapacity < max32), uint32_t, size_t>>>;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename DataType, size_t OnStackCapacity,
|
|
|
|
typename StackSizeT = typename StackVecSize<OnStackCapacity>::SizeT>
|
2022-05-10 01:40:30 +08:00
|
|
|
class StackVec { // NOLINT(clang-analyzer-optin.performance.Padding)
|
2017-12-21 07:45:38 +08:00
|
|
|
public:
|
2022-05-10 01:40:30 +08:00
|
|
|
using value_type = DataType;
|
2020-02-25 05:07:46 +08:00
|
|
|
using SizeT = StackSizeT;
|
2018-01-05 19:54:12 +08:00
|
|
|
using iterator = DataType *;
|
|
|
|
using const_iterator = const DataType *;
|
2018-12-17 22:23:35 +08:00
|
|
|
using reverse_iterator = std::reverse_iterator<iterator>;
|
|
|
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
static constexpr SizeT onStackCaps = OnStackCapacity;
|
2018-01-05 19:54:12 +08:00
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
StackVec() {
|
|
|
|
onStackMem = reinterpret_cast<DataType *const>(onStackMemRawBytes);
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
template <typename ItType>
|
2020-02-25 05:07:46 +08:00
|
|
|
StackVec(ItType beginIt, ItType endIt) {
|
|
|
|
onStackMem = reinterpret_cast<DataType *const>(onStackMemRawBytes);
|
2017-12-21 07:45:38 +08:00
|
|
|
size_t count = (endIt - beginIt);
|
|
|
|
if (count > OnStackCapacity) {
|
|
|
|
dynamicMem = new std::vector<DataType>(beginIt, endIt);
|
2020-02-25 05:07:46 +08:00
|
|
|
setUsesDynamicMem();
|
2017-12-21 07:45:38 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (beginIt != endIt) {
|
|
|
|
push_back(*beginIt);
|
|
|
|
++beginIt;
|
|
|
|
}
|
2020-02-25 05:07:46 +08:00
|
|
|
onStackSize = static_cast<SizeT>(count);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
StackVec(const StackVec &rhs) {
|
|
|
|
onStackMem = reinterpret_cast<DataType *const>(onStackMemRawBytes);
|
2017-12-21 07:45:38 +08:00
|
|
|
if (onStackCaps < rhs.size()) {
|
|
|
|
dynamicMem = new std::vector<DataType>(rhs.begin(), rhs.end());
|
2020-02-25 05:07:46 +08:00
|
|
|
setUsesDynamicMem();
|
2017-12-21 07:45:38 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const auto &v : rhs) {
|
|
|
|
push_back(v);
|
|
|
|
}
|
|
|
|
}
|
2018-01-05 19:54:12 +08:00
|
|
|
|
|
|
|
explicit StackVec(size_t initialSize)
|
|
|
|
: StackVec() {
|
2020-02-25 05:07:46 +08:00
|
|
|
onStackMem = reinterpret_cast<DataType *const>(onStackMemRawBytes);
|
2018-01-05 19:54:12 +08:00
|
|
|
resize(initialSize);
|
|
|
|
}
|
|
|
|
|
2019-01-28 21:26:33 +08:00
|
|
|
StackVec(std::initializer_list<DataType> init) {
|
2020-02-25 05:07:46 +08:00
|
|
|
onStackMem = reinterpret_cast<DataType *const>(onStackMemRawBytes);
|
2019-01-28 21:26:33 +08:00
|
|
|
reserve(init.size());
|
|
|
|
for (const auto &obj : init) {
|
|
|
|
push_back(obj);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
StackVec &operator=(const StackVec &rhs) {
|
2021-07-23 02:51:08 +08:00
|
|
|
if (this == &rhs) {
|
|
|
|
return *this;
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
clear();
|
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
|
|
|
this->dynamicMem->assign(rhs.begin(), rhs.end());
|
2017-12-21 07:45:38 +08:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (onStackCaps < rhs.size()) {
|
|
|
|
this->dynamicMem = new std::vector<DataType>(rhs.begin(), rhs.end());
|
2020-02-25 05:07:46 +08:00
|
|
|
setUsesDynamicMem();
|
2017-12-21 07:45:38 +08:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const auto &v : rhs) {
|
|
|
|
push_back(v);
|
|
|
|
}
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
2018-01-05 19:54:12 +08:00
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
StackVec(StackVec &&rhs) {
|
|
|
|
onStackMem = reinterpret_cast<DataType *const>(onStackMemRawBytes);
|
|
|
|
if (rhs.usesDynamicMem()) {
|
|
|
|
this->dynamicMem = rhs.dynamicMem;
|
|
|
|
setUsesDynamicMem();
|
|
|
|
rhs.onStackSize = 0U;
|
2017-12-21 07:45:38 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const auto &v : rhs) {
|
|
|
|
push_back(v);
|
|
|
|
}
|
2020-02-25 05:07:46 +08:00
|
|
|
rhs.clear();
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2018-01-05 19:54:12 +08:00
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
StackVec &operator=(StackVec &&rhs) {
|
2021-07-23 02:51:08 +08:00
|
|
|
if (this == &rhs) {
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
clear();
|
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
if (rhs.usesDynamicMem()) {
|
|
|
|
if (usesDynamicMem()) {
|
|
|
|
delete this->dynamicMem;
|
|
|
|
}
|
|
|
|
this->dynamicMem = rhs.dynamicMem;
|
|
|
|
this->setUsesDynamicMem();
|
|
|
|
rhs.onStackSize = 0U;
|
2017-12-21 07:45:38 +08:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
|
|
|
this->dynamicMem->assign(rhs.begin(), rhs.end());
|
2017-12-21 07:45:38 +08:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const auto &v : rhs) {
|
|
|
|
push_back(v);
|
|
|
|
}
|
2020-02-25 05:07:46 +08:00
|
|
|
rhs.clear();
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2022-03-03 02:51:53 +08:00
|
|
|
template <typename RhsT>
|
|
|
|
void swap(RhsT &rhs) {
|
|
|
|
if (this->usesDynamicMem() && rhs.usesDynamicMem()) {
|
|
|
|
this->dynamicMem->swap(*rhs.dynamicMem);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
size_t smallerSize = this->size() < rhs.size() ? this->size() : rhs.size();
|
|
|
|
size_t i = 0;
|
|
|
|
for (; i < smallerSize; ++i) {
|
|
|
|
std::swap((*this)[i], rhs[i]);
|
|
|
|
}
|
|
|
|
if (this->size() == smallerSize) {
|
|
|
|
auto biggerSize = rhs.size();
|
|
|
|
for (; i < biggerSize; ++i) {
|
|
|
|
this->push_back(std::move(rhs[i]));
|
|
|
|
}
|
|
|
|
rhs.resize(smallerSize);
|
|
|
|
} else {
|
|
|
|
auto biggerSize = this->size();
|
|
|
|
for (; i < biggerSize; ++i) {
|
|
|
|
rhs.push_back(std::move((*this)[i]));
|
|
|
|
}
|
|
|
|
this->resize(smallerSize);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
~StackVec() {
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
2017-12-21 07:45:38 +08:00
|
|
|
delete dynamicMem;
|
|
|
|
return;
|
|
|
|
}
|
2020-02-25 05:07:46 +08:00
|
|
|
clearStackObjects();
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t size() const {
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
2017-12-21 07:45:38 +08:00
|
|
|
return dynamicMem->size();
|
|
|
|
}
|
|
|
|
return onStackSize;
|
|
|
|
}
|
|
|
|
|
2019-10-28 02:48:26 +08:00
|
|
|
bool empty() const {
|
|
|
|
return 0U == size();
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
size_t capacity() const {
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
2017-12-21 07:45:38 +08:00
|
|
|
return dynamicMem->capacity();
|
|
|
|
}
|
|
|
|
return OnStackCapacity;
|
|
|
|
}
|
|
|
|
|
|
|
|
void reserve(size_t newCapacity) {
|
|
|
|
if (newCapacity > onStackCaps) {
|
|
|
|
ensureDynamicMem();
|
|
|
|
dynamicMem->reserve(newCapacity);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void clear() {
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
2017-12-21 07:45:38 +08:00
|
|
|
dynamicMem->clear();
|
|
|
|
return;
|
|
|
|
}
|
2018-01-05 19:54:12 +08:00
|
|
|
clearStackObjects();
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2022-05-10 01:40:30 +08:00
|
|
|
void push_back(const DataType &v) { // NOLINT(readability-identifier-naming)
|
2022-07-20 23:05:27 +08:00
|
|
|
isDynamicMemNeeded();
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
2017-12-21 07:45:38 +08:00
|
|
|
dynamicMem->push_back(v);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
new (reinterpret_cast<DataType *>(onStackMemRawBytes) + onStackSize) DataType(v);
|
2017-12-21 07:45:38 +08:00
|
|
|
++onStackSize;
|
|
|
|
}
|
|
|
|
|
2022-07-20 23:05:27 +08:00
|
|
|
void push_back(DataType &&v) { // NOLINT(readability-identifier-naming)
|
|
|
|
isDynamicMemNeeded();
|
|
|
|
|
|
|
|
if (usesDynamicMem()) {
|
|
|
|
dynamicMem->push_back(std::move(v));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
new (reinterpret_cast<DataType *>(onStackMemRawBytes) + onStackSize) DataType(std::move(v));
|
|
|
|
++onStackSize;
|
|
|
|
}
|
|
|
|
|
2022-04-07 21:09:40 +08:00
|
|
|
void sort() {
|
|
|
|
std::sort(this->begin(), this->end());
|
|
|
|
}
|
|
|
|
|
2022-05-10 01:40:30 +08:00
|
|
|
void remove_duplicates() { // NOLINT(readability-identifier-naming)
|
2022-04-07 21:09:40 +08:00
|
|
|
if (1 >= this->size()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this->sort();
|
|
|
|
const auto last = std::unique(this->begin(), this->end());
|
|
|
|
auto currentEnd = this->end();
|
|
|
|
while (last != currentEnd--) {
|
|
|
|
this->pop_back();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-10 01:40:30 +08:00
|
|
|
void pop_back() { // NOLINT(readability-identifier-naming)
|
2020-05-25 22:39:16 +08:00
|
|
|
if (usesDynamicMem()) {
|
|
|
|
dynamicMem->pop_back();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
UNRECOVERABLE_IF(0 == onStackSize);
|
|
|
|
|
|
|
|
clearStackObjects(onStackSize - 1, 1U);
|
|
|
|
--onStackSize;
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
DataType &operator[](std::size_t idx) {
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
2017-12-21 07:45:38 +08:00
|
|
|
return (*dynamicMem)[idx];
|
|
|
|
}
|
2020-02-25 05:07:46 +08:00
|
|
|
return *(reinterpret_cast<DataType *>(onStackMemRawBytes) + idx);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2022-03-03 02:51:53 +08:00
|
|
|
DataType &at(std::size_t idx) { return this->operator[](idx); }
|
|
|
|
|
|
|
|
const DataType &at(std::size_t idx) const { return this->operator[](idx); }
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
const DataType &operator[](std::size_t idx) const {
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
2017-12-21 07:45:38 +08:00
|
|
|
return (*dynamicMem)[idx];
|
|
|
|
}
|
2020-02-25 05:07:46 +08:00
|
|
|
return *(reinterpret_cast<const DataType *>(onStackMemRawBytes) + idx);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-01-05 19:54:12 +08:00
|
|
|
iterator begin() {
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
2017-12-21 07:45:38 +08:00
|
|
|
return dynamicMem->data();
|
|
|
|
}
|
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
return reinterpret_cast<DataType *>(onStackMemRawBytes);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-12-17 22:23:35 +08:00
|
|
|
reverse_iterator rbegin() {
|
|
|
|
return reverse_iterator(end());
|
|
|
|
}
|
|
|
|
|
|
|
|
const_reverse_iterator crbegin() const {
|
|
|
|
return const_reverse_iterator(end());
|
|
|
|
}
|
|
|
|
|
2018-01-05 19:54:12 +08:00
|
|
|
const_iterator begin() const {
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
2017-12-21 07:45:38 +08:00
|
|
|
return dynamicMem->data();
|
|
|
|
}
|
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
return reinterpret_cast<const DataType *>(onStackMemRawBytes);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-01-05 19:54:12 +08:00
|
|
|
iterator end() {
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
2017-12-21 07:45:38 +08:00
|
|
|
return dynamicMem->data() + dynamicMem->size();
|
|
|
|
}
|
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
return reinterpret_cast<DataType *>(onStackMemRawBytes) + onStackSize;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-12-17 22:23:35 +08:00
|
|
|
reverse_iterator rend() {
|
|
|
|
return reverse_iterator(begin());
|
|
|
|
}
|
|
|
|
|
|
|
|
const_reverse_iterator crend() const {
|
|
|
|
return const_reverse_iterator(begin());
|
|
|
|
}
|
|
|
|
|
2018-01-05 19:54:12 +08:00
|
|
|
const_iterator end() const {
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
2017-12-21 07:45:38 +08:00
|
|
|
return dynamicMem->data() + dynamicMem->size();
|
|
|
|
}
|
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
return reinterpret_cast<const DataType *>(onStackMemRawBytes) + onStackSize;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-01-05 19:54:12 +08:00
|
|
|
void resize(size_t newSize) {
|
|
|
|
this->resizeImpl(newSize, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void resize(size_t newSize, const DataType &value) {
|
|
|
|
resizeImpl(newSize, &value);
|
|
|
|
}
|
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
bool usesDynamicMem() const {
|
|
|
|
return std::numeric_limits<decltype(onStackSize)>::max() == this->onStackSize;
|
|
|
|
}
|
|
|
|
|
2020-10-16 18:41:41 +08:00
|
|
|
auto data() {
|
2020-06-09 20:17:19 +08:00
|
|
|
if (usesDynamicMem()) {
|
|
|
|
return dynamicMem->data();
|
|
|
|
}
|
2020-10-16 18:41:41 +08:00
|
|
|
return reinterpret_cast<DataType *>(onStackMemRawBytes);
|
2020-06-09 20:17:19 +08:00
|
|
|
}
|
|
|
|
|
2018-01-05 19:54:12 +08:00
|
|
|
private:
|
2022-03-03 02:51:53 +08:00
|
|
|
template <typename RhsDataType, size_t RhsOnStackCapacity, typename RhsStackSizeT>
|
|
|
|
friend class StackVec;
|
2020-02-25 05:07:46 +08:00
|
|
|
void setUsesDynamicMem() {
|
|
|
|
this->onStackSize = std::numeric_limits<decltype(onStackSize)>::max();
|
|
|
|
}
|
|
|
|
|
2018-01-05 19:54:12 +08:00
|
|
|
void resizeImpl(size_t newSize, const DataType *value) {
|
|
|
|
// new size does not fit into internal mem
|
|
|
|
if (newSize > onStackCaps) {
|
2017-12-21 07:45:38 +08:00
|
|
|
ensureDynamicMem();
|
2018-01-05 19:54:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// memory already backed by stl vector
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
2018-01-05 19:54:12 +08:00
|
|
|
if (value != nullptr) {
|
|
|
|
dynamicMem->resize(newSize, *value);
|
|
|
|
} else {
|
|
|
|
dynamicMem->resize(newSize);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (newSize <= onStackSize) {
|
|
|
|
// trim elements
|
|
|
|
clearStackObjects(newSize, onStackSize - newSize);
|
2020-02-25 05:07:46 +08:00
|
|
|
onStackSize = static_cast<SizeT>(newSize);
|
2018-01-05 19:54:12 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// add new elements
|
|
|
|
if (value != nullptr) {
|
|
|
|
// copy-construct elements
|
|
|
|
while (onStackSize < newSize) {
|
2020-02-25 05:07:46 +08:00
|
|
|
new (reinterpret_cast<DataType *>(onStackMemRawBytes) + onStackSize) DataType(*value);
|
2018-01-05 19:54:12 +08:00
|
|
|
++onStackSize;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// default-construct elements
|
|
|
|
while (onStackSize < newSize) {
|
2020-02-25 05:07:46 +08:00
|
|
|
new (reinterpret_cast<DataType *>(onStackMemRawBytes) + onStackSize) DataType();
|
2018-01-05 19:54:12 +08:00
|
|
|
++onStackSize;
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-20 23:05:27 +08:00
|
|
|
void isDynamicMemNeeded() {
|
|
|
|
if (onStackSize == onStackCaps) {
|
|
|
|
ensureDynamicMem();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
void ensureDynamicMem() {
|
2020-02-25 05:07:46 +08:00
|
|
|
if (usesDynamicMem()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
dynamicMem = new std::vector<DataType>();
|
|
|
|
if (onStackSize > 0) {
|
|
|
|
dynamicMem->reserve(onStackSize);
|
|
|
|
for (auto it = reinterpret_cast<DataType *>(onStackMemRawBytes), end = reinterpret_cast<DataType *>(onStackMemRawBytes) + onStackSize; it != end; ++it) {
|
|
|
|
dynamicMem->push_back(std::move(*it));
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2020-02-25 05:07:46 +08:00
|
|
|
clearStackObjects();
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2020-02-25 05:07:46 +08:00
|
|
|
setUsesDynamicMem();
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-01-05 19:54:12 +08:00
|
|
|
void clearStackObjects() {
|
|
|
|
clearStackObjects(0, onStackSize);
|
|
|
|
onStackSize = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void clearStackObjects(size_t offset, size_t count) {
|
|
|
|
UNRECOVERABLE_IF(offset + count > onStackSize);
|
2020-02-25 05:07:46 +08:00
|
|
|
for (auto it = reinterpret_cast<DataType *>(onStackMemRawBytes) + offset, end = reinterpret_cast<DataType *>(onStackMemRawBytes) + offset + count; it != end; ++it) {
|
2017-12-21 07:45:38 +08:00
|
|
|
it->~DataType();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
union {
|
|
|
|
std::vector<DataType> *dynamicMem;
|
|
|
|
DataType *onStackMem;
|
|
|
|
};
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
alignas(alignof(DataType)) char onStackMemRawBytes[sizeof(DataType[onStackCaps])];
|
2020-02-25 05:07:46 +08:00
|
|
|
SizeT onStackSize = 0U;
|
2017-12-21 07:45:38 +08:00
|
|
|
};
|
2018-01-05 19:54:12 +08:00
|
|
|
|
2020-02-25 05:07:46 +08:00
|
|
|
namespace {
|
|
|
|
static_assert(sizeof(StackVec<char, 1U>::SizeT) == 1u, "");
|
|
|
|
static_assert(sizeof(StackVec<char, 7U>) <= 16u, "");
|
|
|
|
static_assert(sizeof(StackVec<uint32_t, 3U>) <= 24u, "");
|
|
|
|
} // namespace
|
|
|
|
|
2018-01-05 19:54:12 +08:00
|
|
|
template <typename T, size_t LhsStackCaps, size_t RhsStackCaps>
|
|
|
|
bool operator==(const StackVec<T, LhsStackCaps> &lhs,
|
|
|
|
const StackVec<T, RhsStackCaps> &rhs) {
|
|
|
|
if (lhs.size() != rhs.size()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto lhsIt = lhs.begin();
|
|
|
|
auto lhsEnd = lhs.end();
|
|
|
|
auto rhsIt = rhs.begin();
|
|
|
|
|
|
|
|
for (; lhsIt != lhsEnd; ++lhsIt, ++rhsIt) {
|
|
|
|
if (*lhsIt != *rhsIt) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2019-01-28 21:26:33 +08:00
|
|
|
|
|
|
|
template <typename T, size_t LhsStackCaps, size_t RhsStackCaps>
|
|
|
|
bool operator!=(const StackVec<T, LhsStackCaps> &lhs,
|
|
|
|
const StackVec<T, RhsStackCaps> &rhs) {
|
|
|
|
return false == (lhs == rhs);
|
|
|
|
}
|
2022-04-07 21:09:40 +08:00
|
|
|
|
|
|
|
using RootDeviceIndicesContainer = StackVec<uint32_t, 16>;
|