// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- // vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi #ifndef CTL_ARRAY_H_ #define CTL_ARRAY_H_ #include "initializer_list.h" #include "out_of_range.h" #include "reverse_iterator.h" namespace ctl { template struct array { using value_type = T; using size_type = size_t; using difference_type = ptrdiff_t; using reference = value_type&; using const_reference = const value_type&; using pointer = value_type*; using const_pointer = const value_type*; using iterator = value_type*; using const_iterator = const value_type*; using reverse_iterator = ctl::reverse_iterator; using const_reverse_iterator = ctl::reverse_iterator; T elems[N]; constexpr array() = default; constexpr array(std::initializer_list init) { auto it = init.begin(); for (size_t i = 0; i < N && it != init.end(); ++i, ++it) elems[i] = *it; } constexpr reference at(size_type pos) { if (pos >= N) throw ctl::out_of_range("out of range"); return elems[pos]; } constexpr const_reference at(size_type pos) const { if (pos >= N) throw ctl::out_of_range("out of range"); return elems[pos]; } constexpr reference operator[](size_type pos) { return elems[pos]; } constexpr const_reference operator[](size_type pos) const { return elems[pos]; } constexpr reference front() { return elems[0]; } constexpr const_reference front() const { return elems[0]; } constexpr reference back() { return elems[N - 1]; } constexpr const_reference back() const { return elems[N - 1]; } constexpr T* data() noexcept { return elems; } constexpr const T* data() const noexcept { return elems; } constexpr iterator begin() noexcept { return elems; } constexpr const_iterator begin() const noexcept { return elems; } constexpr iterator end() noexcept { return elems + N; } constexpr const_iterator end() const noexcept { return elems + N; } constexpr reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } constexpr const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } constexpr reverse_iterator rend() noexcept { return reverse_iterator(begin()); } constexpr const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } constexpr const_iterator cbegin() const noexcept { return begin(); } constexpr const_iterator cend() const noexcept { return end(); } constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); } constexpr const_reverse_iterator crend() const noexcept { return rend(); } constexpr bool empty() const noexcept { return N == 0; } constexpr size_type size() const noexcept { return N; } constexpr size_type max_size() const noexcept { return N; } void fill(const T& value) { for (size_type i = 0; i < N; ++i) { elems[i] = value; } } void swap(array& other) noexcept { for (size_type i = 0; i < N; ++i) { T temp = elems[i]; elems[i] = other.elems[i]; other.elems[i] = temp; } } }; template bool operator==(const array& lhs, const array& rhs) { for (size_t i = 0; i < N; ++i) { if (!(lhs[i] == rhs[i])) return false; } return true; } template bool operator!=(const array& lhs, const array& rhs) { return !(lhs == rhs); } template bool operator<(const array& lhs, const array& rhs) { for (size_t i = 0; i < N; ++i) { if (lhs[i] < rhs[i]) return true; if (rhs[i] < lhs[i]) return false; } return false; } template bool operator<=(const array& lhs, const array& rhs) { return !(rhs < lhs); } template bool operator>(const array& lhs, const array& rhs) { return rhs < lhs; } template bool operator>=(const array& lhs, const array& rhs) { return !(lhs < rhs); } template void swap(array& lhs, array& rhs) noexcept { lhs.swap(rhs); } } // namespace ctl #endif // CTL_ARRAY_H_