30class FixedArray final {
33 using const_iterator =
const T*;
39 template <
class... Args>
40 explicit FixedArray(std::size_t size, Args&&... args);
43 template <
std::forward_iterator ForwardIterator>
44 FixedArray(ForwardIterator first, ForwardIterator last);
46 FixedArray(FixedArray&& other)
noexcept;
47 FixedArray& operator=(FixedArray&& other)
noexcept;
49 FixedArray(
const FixedArray&) =
delete;
50 FixedArray& operator=(
const FixedArray&) =
delete;
54 std::size_t size()
const noexcept {
return size_; }
55 bool empty()
const noexcept {
return size_ == 0; }
57 const T& operator[](std::size_t i)
const noexcept USERVER_IMPL_LIFETIME_BOUND {
62 T& operator[](std::size_t i)
noexcept USERVER_IMPL_LIFETIME_BOUND {
67 T& front()
noexcept USERVER_IMPL_LIFETIME_BOUND {
return *NonEmptyData(); }
68 const T& front()
const noexcept USERVER_IMPL_LIFETIME_BOUND {
return *NonEmptyData(); }
70 T& back()
noexcept USERVER_IMPL_LIFETIME_BOUND {
return *(NonEmptyData() + size_ - 1); }
71 const T& back()
const noexcept USERVER_IMPL_LIFETIME_BOUND {
return *(NonEmptyData() + size_ - 1); }
73 T* data()
noexcept USERVER_IMPL_LIFETIME_BOUND {
return storage_; }
74 const T* data()
const noexcept USERVER_IMPL_LIFETIME_BOUND {
return storage_; }
76 T* begin()
noexcept USERVER_IMPL_LIFETIME_BOUND {
return data(); }
77 T* end()
noexcept USERVER_IMPL_LIFETIME_BOUND {
return data() + size_; }
78 const T* begin()
const noexcept USERVER_IMPL_LIFETIME_BOUND {
return data(); }
79 const T* end()
const noexcept USERVER_IMPL_LIFETIME_BOUND {
return data() + size_; }
80 const T* cbegin()
const noexcept USERVER_IMPL_LIFETIME_BOUND {
return data(); }
81 const T* cend()
const noexcept USERVER_IMPL_LIFETIME_BOUND {
return data() + size_; }
84 template <
class GeneratorFunc>
85 FixedArray(impl::InternalTag tag, std::size_t size, GeneratorFunc&& generator);
89 T* NonEmptyData()
noexcept {
94 const T* NonEmptyData()
const noexcept {
100 std::size_t size_{0};
124 storage_ = std::allocator<T>{}.allocate(size_);
126 auto* begin = data();
128 for (
auto* end = begin + size - 1; begin != end; ++begin) {
129 new (begin) T(args...);
131 new (begin) T(std::forward<Args>(args)...);
133 std::destroy(data(), begin);
134 std::allocator<T>{}.deallocate(storage_, size);
179 : storage_(std::exchange(other.storage_,
nullptr)), size_(std::exchange(other.size_, 0)) {}
196 using ResultType = std::remove_cvref_t<std::invoke_result_t<GeneratorFunc&, std::size_t>>;
197 return FixedArray<ResultType>(impl::InternalTag{}, size, std::forward<GeneratorFunc>(generator));