mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
244 lines
4.8 KiB
C++
244 lines
4.8 KiB
C++
// -*-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<typename T, size_t N>
|
|
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<iterator>;
|
|
using const_reverse_iterator = ctl::reverse_iterator<const_iterator>;
|
|
|
|
T elems[N];
|
|
|
|
constexpr array() = default;
|
|
|
|
constexpr array(std::initializer_list<T> 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<typename T, size_t N>
|
|
bool
|
|
operator==(const array<T, N>& lhs, const array<T, N>& rhs)
|
|
{
|
|
for (size_t i = 0; i < N; ++i) {
|
|
if (!(lhs[i] == rhs[i]))
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
template<typename T, size_t N>
|
|
bool
|
|
operator!=(const array<T, N>& lhs, const array<T, N>& rhs)
|
|
{
|
|
return !(lhs == rhs);
|
|
}
|
|
|
|
template<typename T, size_t N>
|
|
bool
|
|
operator<(const array<T, N>& lhs, const array<T, N>& 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<typename T, size_t N>
|
|
bool
|
|
operator<=(const array<T, N>& lhs, const array<T, N>& rhs)
|
|
{
|
|
return !(rhs < lhs);
|
|
}
|
|
|
|
template<typename T, size_t N>
|
|
bool
|
|
operator>(const array<T, N>& lhs, const array<T, N>& rhs)
|
|
{
|
|
return rhs < lhs;
|
|
}
|
|
|
|
template<typename T, size_t N>
|
|
bool
|
|
operator>=(const array<T, N>& lhs, const array<T, N>& rhs)
|
|
{
|
|
return !(lhs < rhs);
|
|
}
|
|
|
|
template<typename T, size_t N>
|
|
void
|
|
swap(array<T, N>& lhs, array<T, N>& rhs) noexcept
|
|
{
|
|
lhs.swap(rhs);
|
|
}
|
|
|
|
} // namespace ctl
|
|
|
|
#endif // CTL_ARRAY_H_
|