#pragma once #include #include #include #include #include namespace xnnpack { namespace internal { template void ArrayApplyImpl(std::array&& args, F&& f, std::integer_sequence seq) { f(std::move(args[Indx])...); } template > void ArrayApply(std::array&& args, F&& f) { return ArrayApplyImpl(std::move(args), f, Indx{}); } template constexpr std::array MakeArrayImpl( V value, std::integer_sequence) { return {((void)Is, value)...}; } template constexpr std::array MakeArray(V value) { return MakeArrayImpl(value, std::make_index_sequence{}); } template class ArrayPrefix { public: constexpr ArrayPrefix(size_t size, T t) : size_(size), array_(MakeArray(t)) { assert(size_ <= max_size); } explicit constexpr ArrayPrefix(size_t size) : size_(size) { assert(size_ <= max_size); } template ().begin())> explicit constexpr ArrayPrefix(Array&& array, T placeholder) : ArrayPrefix(0, placeholder) { for (const auto& v : array) { push_back(v); } } constexpr ArrayPrefix(std::initializer_list init) : ArrayPrefix(init.size(), T{}) { assert(size_ <= max_size); std::copy(init.begin(), init.end(), begin()); } auto begin() { return array_.begin(); } auto begin() const { return array_.cbegin(); } auto end() { auto result = array_.begin(); std::advance(result, size_); return result; } auto end() const { auto result = array_.cbegin(); std::advance(result, size_); return result; } auto& operator[](size_t index) { assert(index < size_); return array_[index]; } const auto& operator[](size_t index) const { assert(index < size_); return array_[index]; } void push_back(const T& t) { assert(size_ + 1 <= max_size); array_[size_++] = t; } template void emplace_back(Args&&... args) { if (size_ + 1 <= max_size) { new (&array_[size_++]) T(args...); } } size_t size() const { return size_; } private: size_t size_; std::array array_; }; } // namespace internal } // namespace xnnpack