26class FixedArray final {
29 using const_iterator =
const T*;
35 template <
class... Args>
38 FixedArray(FixedArray&& other)
noexcept;
39 FixedArray& operator=(FixedArray&& other)
noexcept;
41 FixedArray(
const FixedArray&) =
delete;
42 FixedArray& operator=(
const FixedArray&) =
delete;
46 std::size_t size()
const noexcept {
return size_; }
47 bool empty()
const noexcept {
return size_ == 0; }
49 const T& operator[](std::size_t i)
const noexcept {
54 T& operator[](std::size_t i)
noexcept {
59 T& front()
noexcept {
return *NonEmptyData(); }
60 const T& front()
const noexcept {
return *NonEmptyData(); }
62 T& back()
noexcept {
return *(NonEmptyData() + size_ - 1); }
63 const T& back()
const noexcept {
return *(NonEmptyData() + size_ - 1); }
65 T* data()
noexcept {
return storage_; }
66 const T* data()
const noexcept {
return storage_; }
68 T* begin()
noexcept {
return data(); }
69 T* end()
noexcept {
return data() + size_; }
70 const T* begin()
const noexcept {
return data(); }
71 const T* end()
const noexcept {
return data() + size_; }
72 const T* cbegin()
const noexcept {
return data(); }
73 const T* cend()
const noexcept {
return data() + size_; }
76 template <
class GeneratorFunc>
77 FixedArray(impl::InternalTag tag, std::size_t size, GeneratorFunc&& generator);
81 T* NonEmptyData()
noexcept {
86 const T* NonEmptyData()
const noexcept {
102template <
class GeneratorFunc>
106template <
class... Args>
107FixedArray<T>::
FixedArray(std::size_t size, Args&&... args) : size_(size) {
108 if (size_ == 0)
return;
109 storage_ = std::allocator<T>{}.allocate(size_);
111 auto* begin = data();
113 for (
auto* end = begin + size - 1; begin != end; ++begin) {
114 new (begin) T(args...);
116 new (begin) T(std::forward<Args>(args)...);
118 std::destroy(data(), begin);
119 std::allocator<T>{}.deallocate(storage_, size);
107FixedArray<T>::
FixedArray(std::size_t size, Args&&... args) : size_(size) {
…}
125template <
class GeneratorFunc>
126FixedArray<T>::FixedArray(impl::InternalTag , std::size_t size, GeneratorFunc&& generator) : size_(size) {
127 if (size_ == 0)
return;
128 storage_ = std::allocator<T>{}.allocate(size_);
130 auto* our_begin = begin();
131 auto*
const our_end = end();
132 std::size_t index = 0;
135 for (; our_begin != our_end; ++our_begin) {
136 new (our_begin) T(generator(index));
140 std::destroy(begin(), our_begin);
141 std::allocator<T>{}.deallocate(storage_, size_);
147FixedArray<T>::FixedArray(FixedArray&& other)
noexcept
148 : storage_(std::exchange(other.storage_,
nullptr)), size_(std::exchange(other.size_, 0)) {}
151FixedArray<T>& FixedArray<T>::operator=(FixedArray&& other)
noexcept {
152 std::swap(storage_, other.storage_);
153 std::swap(size_, other.size_);
158FixedArray<T>::~FixedArray() {
159 std::destroy(begin(), end());
160 std::allocator<T>{}.deallocate(storage_, size_);
163template <
class GeneratorFunc>
165 using ResultType = std::remove_reference_t<std::invoke_result_t<GeneratorFunc&, std::size_t>>;
166 return FixedArray<ResultType>(impl::InternalTag{}, size, std::forward<GeneratorFunc>(generator));