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>
118 storage_ = std::allocator<T>{}.allocate(size_);
120 auto* begin = data();
122 for (
auto* end = begin + size - 1; begin != end; ++begin) {
123 new (begin) T(args...);
125 new (begin) T(std::forward<Args>(args)...);
127 std::destroy(data(), begin);
128 std::allocator<T>{}.deallocate(storage_, size);
134template <
class GeneratorFunc>
135FixedArray<T>::FixedArray(
impl::InternalTag , std::size_t size, GeneratorFunc&& generator)
141 storage_ = std::allocator<T>{}.allocate(size_);
143 auto* our_begin = begin();
144 auto*
const our_end = end();
145 std::size_t index = 0;
148 for (; our_begin != our_end; ++our_begin) {
149 new (our_begin) T(generator(index));
153 std::destroy(begin(), our_begin);
154 std::allocator<T>{}.deallocate(storage_, size_);
160FixedArray<T>::FixedArray(FixedArray&& other)
noexcept
161 : storage_(std::exchange(other.storage_,
nullptr)), size_(std::exchange(other.size_, 0)) {}
164FixedArray<T>& FixedArray<T>::operator=(FixedArray&& other)
noexcept {
165 std::swap(storage_, other.storage_);
166 std::swap(size_, other.size_);
171FixedArray<T>::~FixedArray() {
172 std::destroy(begin(), end());
173 std::allocator<T>{}.deallocate(storage_, size_);
176template <
class GeneratorFunc>
178 using ResultType = std::remove_reference_t<std::invoke_result_t<GeneratorFunc&, std::size_t>>;
179 return FixedArray<ResultType>(
impl::InternalTag{}, size, std::forward<GeneratorFunc>(generator));