#pragma once #include #include #include #include #include #include #include #include namespace stdx { inline namespace v1 { template class cx_vector { std::array storage{}; std::size_t current_size{}; public: using value_type = T; using size_type = std::size_t; using difference_type = std::ptrdiff_t; using reference = value_type &; using const_reference = value_type const &; using pointer = value_type *; using const_pointer = value_type const *; using iterator = pointer; using const_iterator = const_pointer; using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; constexpr cx_vector() = default; template ), int> = 0> constexpr explicit cx_vector(Ts const &...ts) : storage{static_cast(ts)...}, current_size{sizeof...(Ts)} { } [[nodiscard]] constexpr auto begin() LIFETIMEBOUND -> iterator { return std::data(storage); } [[nodiscard]] constexpr auto begin() const LIFETIMEBOUND -> const_iterator { return std::data(storage); } [[nodiscard]] constexpr auto cbegin() const LIFETIMEBOUND -> const_iterator { return std::data(storage); } [[nodiscard]] constexpr auto end() LIFETIMEBOUND -> iterator { return begin() + current_size; } [[nodiscard]] constexpr auto end() const LIFETIMEBOUND -> const_iterator { return begin() + current_size; } [[nodiscard]] constexpr auto cend() const LIFETIMEBOUND -> const_iterator { return cbegin() + current_size; } [[nodiscard]] constexpr auto rbegin() LIFETIMEBOUND -> reverse_iterator { return end(); } [[nodiscard]] constexpr auto rbegin() const LIFETIMEBOUND -> const_reverse_iterator { return end(); } [[nodiscard]] constexpr auto crbegin() const LIFETIMEBOUND -> const_reverse_iterator { return cend(); } [[nodiscard]] constexpr auto rend() LIFETIMEBOUND -> reverse_iterator { return begin(); } [[nodiscard]] constexpr auto rend() const LIFETIMEBOUND -> const_reverse_iterator { return begin(); } [[nodiscard]] constexpr auto crend() const LIFETIMEBOUND -> const_reverse_iterator { return cbegin(); } [[nodiscard]] constexpr auto front() LIFETIMEBOUND -> reference { return storage[0]; } [[nodiscard]] constexpr auto front() const LIFETIMEBOUND -> const_reference { return storage[0]; } [[nodiscard]] constexpr auto back() LIFETIMEBOUND -> reference { return storage[current_size - 1]; } [[nodiscard]] constexpr auto back() const LIFETIMEBOUND -> const_reference { return storage[current_size - 1]; } [[nodiscard]] constexpr auto size() const -> size_type { return current_size; } constexpr static std::integral_constant capacity{}; [[nodiscard]] constexpr auto operator[](std::size_t index) LIFETIMEBOUND->reference { return storage[index]; } [[nodiscard]] constexpr auto operator[](std::size_t index) const LIFETIMEBOUND->const_reference { return storage[index]; } template [[nodiscard]] constexpr auto get() LIFETIMEBOUND -> reference { return std::get(storage); } template [[nodiscard]] constexpr auto get() const LIFETIMEBOUND -> const_reference { return std::get(storage); } [[nodiscard]] constexpr auto full() const -> bool { return current_size == N; } [[nodiscard]] constexpr auto empty() const -> bool { return current_size == 0u; } constexpr auto clear() -> void { current_size = 0; } constexpr auto push_back(value_type const &value) LIFETIMEBOUND -> reference { return storage[current_size++] = value; } constexpr auto push_back(value_type &&value) LIFETIMEBOUND -> reference { return storage[current_size++] = std::move(value); } [[nodiscard]] constexpr auto pop_back() -> value_type { return storage[--current_size]; } private: template friend constexpr auto resize_and_overwrite(cx_vector &v, F &&f) -> void { v.current_size = std::forward(f)(std::data(v.storage), std::size(v.storage)); } [[nodiscard]] friend constexpr auto operator==(cx_vector const &lhs, cx_vector const &rhs) -> bool { if (lhs.size() != rhs.size()) { return false; } for (auto i = size_type{}; i < lhs.size(); ++i) { if (lhs[i] != rhs[i]) { return false; } } return true; } #if __cpp_impl_three_way_comparison < 201907L [[nodiscard]] friend constexpr auto operator!=(cx_vector const &lhs, cx_vector const &rhs) -> bool { return not(lhs == rhs); } #endif }; template cx_vector(T, Ts...) -> cx_vector; template auto get(cx_vector &v LIFETIMEBOUND) -> decltype(auto) { return v.template get(); } template auto get(cx_vector const &v LIFETIMEBOUND) -> decltype(auto) { return v.template get(); } template constexpr auto ct_capacity_v> = N; } // namespace v1 } // namespace stdx