#pragma once #include namespace hpr { // forward declaration template requires (S > 0) class StaticArray; // type traits template struct is_sequence> : public std::true_type {}; // aliases template using sarray = StaticArray; // class definition template requires (S > 0) class StaticArray : public Sequence { using base = Sequence; public: using difference_type = std::ptrdiff_t; using value_type = T; using size_type = Size; using pointer = T*; using reference = T&; using iterator = Iterator; using const_pointer = T const*; using const_reference = T const&; using const_iterator = Iterator; public: friend constexpr void swap(StaticArray& main, StaticArray& other) noexcept { using std::swap; swap(static_cast(main), static_cast(other)); } //! Default constructor constexpr StaticArray() noexcept : base {S, S, new value_type[S] {}} {} constexpr explicit StaticArray(const base& b) noexcept : base {b} {} //! Copy constructor constexpr StaticArray(const StaticArray& arr) noexcept : base {static_cast(arr)} {} //! Move constructor constexpr StaticArray(StaticArray&& arr) noexcept : base {std::forward(static_cast(arr))} {} constexpr StaticArray(typename base::iterator start, typename base::iterator end) : base {start, end} {} constexpr StaticArray(typename base::const_iterator start, typename base::const_iterator end) : base {start, end} {} constexpr StaticArray(typename base::iterator start, typename base::iterator end, size_type capacity) : base {start, end, capacity} {} constexpr StaticArray(typename base::const_iterator start, typename base::const_iterator end, size_type capacity) : base {start, end, capacity} {} constexpr StaticArray(std::initializer_list list) : base {list.begin(), list.end()} {} template ... Args> constexpr explicit StaticArray(const value_type& v, const Args& ...args) requires (1 + sizeof...(args) == S) : StaticArray {std::initializer_list({v, static_cast(args)...})} {} template ... Args> constexpr explicit StaticArray(value_type&& v, Args&& ...args) requires (1 + sizeof...(args) == S) : StaticArray {std::initializer_list({std::forward(v), std::forward(static_cast(args))...})} {} template ... Args> constexpr StaticArray(const StaticArray& subArr, const value_type& v, const Args& ...args) noexcept requires (SS + 1 + sizeof...(args) == S) : base {S, S, new value_type[S] {}} { std::copy(subArr.begin(), subArr.end(), base::begin()); std::initializer_list list {v, static_cast(args)...}; std::copy(list.begin(), list.end(), base::begin() + subArr.size()); } constexpr StaticArray& operator=(StaticArray other) { swap(*this, other); return *this; } constexpr StaticArray& operator=(StaticArray&& other) noexcept { swap(*this, other); return *this; } virtual ~StaticArray() = default; }; } // end namespace hpr