mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
This change introduces accumulate, addressof, advance, all_of, distance, array, enable_if, allocator_traits, back_inserter, bad_alloc, is_signed, any_of, copy, exception, fill, fill_n, is_same, is_same_v, out_of_range, lexicographical_compare, is_integral, uninitialized_fill_n, is_unsigned, numeric_limits, uninitialized_fill, iterator_traits, move_backward, min, max, iterator_tag, move_iterator, reverse_iterator, uninitialized_move_n This change experiments with rewriting the ctl::vector class to make the CTL design more similar to the STL. So far it has not slowed things down to have 42 #include lines rather than 2, since it's still almost nothing compared to LLVM's code. In fact the closer we can flirt with being just like libcxx, the better chance we might have of discovering exactly what makes it so slow to compile. It would be an enormous discovery if we can find one simple trick to solving the issue there instead. This also fixes a bug in `ctl::string(const string &s)` when `s` is big.
243 lines
4.7 KiB
C++
243 lines
4.7 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 "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)
|
|
__builtin_trap();
|
|
return elems[pos];
|
|
}
|
|
|
|
constexpr const_reference at(size_type pos) const
|
|
{
|
|
if (pos >= N)
|
|
__builtin_trap();
|
|
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_
|