28class FixedArray final {
31 using const_iterator =
const T*;
37 template <
class... Args>
40 FixedArray(FixedArray&& other)
noexcept;
41 FixedArray& operator=(FixedArray&& other)
noexcept;
43 FixedArray(
const FixedArray&) =
delete;
44 FixedArray& operator=(
const FixedArray&) =
delete;
48 std::size_t size()
const noexcept {
return size_; }
49 bool empty()
const noexcept {
return size_ == 0; }
51 const T& operator[](std::size_t i)
const noexcept {
56 T& operator[](std::size_t i)
noexcept {
61 T& front()
noexcept {
return *NonEmptyData(); }
62 const T& front()
const noexcept {
return *NonEmptyData(); }
64 T& back()
noexcept {
return *(NonEmptyData() + size_ - 1); }
65 const T& back()
const noexcept {
return *(NonEmptyData() + size_ - 1); }
67 T* data()
noexcept {
return storage_; }
68 const T* data()
const noexcept {
return storage_; }
70 T* begin()
noexcept {
return data(); }
71 T* end()
noexcept {
return data() + size_; }
72 const T* begin()
const noexcept {
return data(); }
73 const T* end()
const noexcept {
return data() + size_; }
74 const T* cbegin()
const noexcept {
return data(); }
75 const T* cend()
const noexcept {
return data() + size_; }
78 template <
class GeneratorFunc>
79 FixedArray(impl::InternalTag tag, std::size_t size, GeneratorFunc&& generator);
83 T* NonEmptyData()
noexcept {
88 const T* NonEmptyData()
const noexcept {
107template <
class GeneratorFunc>
111template <
class... Args>
112FixedArray<T>::
FixedArray(std::size_t size, Args&&... args) : size_(size) {
113 if (size_ == 0)
return;
114 storage_ = std::allocator<T>{}.allocate(size_);
116 auto* begin = data();
118 for (
auto* end = begin + size - 1; begin != end; ++begin) {
119 new (begin) T(args...);
121 new (begin) T(std::forward<Args>(args)...);
123 std::destroy(data(), begin);
124 std::allocator<T>{}.deallocate(storage_, size);
130template <
class GeneratorFunc>
131FixedArray<T>::FixedArray(impl::InternalTag , std::size_t size, GeneratorFunc&& generator) : size_(size) {
132 if (size_ == 0)
return;
133 storage_ = std::allocator<T>{}.allocate(size_);
135 auto* our_begin = begin();
136 auto*
const our_end = end();
137 std::size_t index = 0;
140 for (; our_begin != our_end; ++our_begin) {
141 new (our_begin) T(generator(index));
145 std::destroy(begin(), our_begin);
146 std::allocator<T>{}.deallocate(storage_, size_);
152FixedArray<T>::FixedArray(FixedArray&& other)
noexcept
153 : storage_(std::exchange(other.storage_,
nullptr)), size_(std::exchange(other.size_, 0)) {}
156FixedArray<T>& FixedArray<T>::operator=(FixedArray&& other)
noexcept {
157 std::swap(storage_, other.storage_);
158 std::swap(size_, other.size_);
163FixedArray<T>::~FixedArray() {
164 std::destroy(begin(), end());
165 std::allocator<T>{}.deallocate(storage_, size_);
168template <
class GeneratorFunc>
170 using ResultType = std::remove_reference_t<std::invoke_result_t<GeneratorFunc&, std::size_t>>;
171 return FixedArray<ResultType>(impl::InternalTag{}, size, std::forward<GeneratorFunc>(generator));