array.h
Go to the documentation of this file.
#ifndef __utl_container_array_h__
#define __utl_container_array_h__
#include <utl/core/impl.h>
#include <algorithm>
namespace utl {
template<typename _Tp, size_t _Nm>
struct array_traits {
typedef _Tp type[_Nm];
static constexpr _Tp& Ref (const type& t, size_t n) noexcept {
return const_cast<_Tp&>(t[n]);
}
static constexpr _Tp* Ptr(const type& t) noexcept {
return const_cast<_Tp*>(t);
}
};
template<typename _Tp>
struct array_traits<_Tp, 0> {
struct type { };
static constexpr _Tp& Ref(const type&, size_t) noexcept {
return *static_cast<_Tp*>(nullptr);
}
static constexpr _Tp* Ptr(const type&) noexcept {
return nullptr;
}
};
template <typename _Tp, size_t _Nm>
struct array {
using value_type = _Tp;
using pointer = value_type*;
using const_pointer = const value_type*;
using reference = value_type&;
using const_reference = const value_type&;
using iterator = value_type*;
using const_iterator = const value_type*;
using size_type = size_t;
using difference_type = ptrdiff_t;
using reverse_iterator = std::reverse_iterator <iterator>;
using const_reverse_iterator
= std::reverse_iterator <const_iterator>;
// type and data
//using empty_t = array_traits<_Tp, 0>;
using array_t = array_traits<_Tp, _Nm>;
typename array_t::type _data;
// No explicit construct/copy/destroy for aggregate type.
// DR 776.
void fill (const value_type& v) { std::fill_n (begin(), size(), v); }
void swap (array& other) noexcept {
std::swap_ranges (begin(), end(), other.begin());
}
iterator begin() noexcept { return iterator (data()); }
const_iterator begin() const noexcept { return const_iterator (data()); }
iterator end() noexcept { return iterator (data() + _Nm); }
const_iterator end() const noexcept { return const_iterator (data() + _Nm); }
const_iterator cbegin() const noexcept { return const_iterator (data()); }
const_iterator cend() const noexcept { return const_iterator (data() + _Nm); }
reverse_iterator rbegin() noexcept { return reverse_iterator (end()); }
reverse_iterator rend() noexcept { return reverse_iterator (begin()); }
const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator (end()); }
const_reverse_iterator rend() const noexcept { return const_reverse_iterator (begin()); }
const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator (end()); }
const_reverse_iterator crend() const noexcept { return const_reverse_iterator (begin()); }
constexpr size_type size() const noexcept { return _Nm; }
constexpr size_type max_size() const noexcept { return _Nm; }
constexpr bool empty() const noexcept { return size() == 0; }
reference operator[] (size_type n) noexcept {
return array_t::Ref(_data, n);
}
constexpr const_reference operator[](size_type n) const noexcept {
return array_t::Ref(_data, n);
}
reference at (size_type n) noexcept {
if (n < _Nm)
return array_t::Ref(_data, n);
else
abort (); //XXX: Throw here
}
constexpr const_reference at (size_type n) const noexcept {
static_assert ((n < _Nm), "array::at: out of range");
return array_t::Ref(_data, n);
}
// first item
reference front () noexcept {
return *begin ();
}
constexpr const_reference front() const noexcept {
return array_t::Ref(_data, 0);
}
// Last item
reference back () noexcept {
return _Nm ? *(end() - 1) : *end();
}
constexpr const_reference back () const noexcept {
return _Nm ? array_t::Ref(_data, _Nm - 1)
: array_t::Ref(_data, 0);
}
// Pointer to data
pointer data () noexcept { return array_t::Ptr(_data); }
const_pointer data () const noexcept { return array_t::Ptr(_data); }
};
template<typename _Tp, size_t _Nm>
inline bool operator== (const array<_Tp, _Nm>& lhs, const array<_Tp, _Nm>& rhs) {
return std::equal (lhs.begin(), lhs.end(), rhs.begin());
}
template<typename _Tp, size_t _Nm>
inline bool operator!= (const array<_Tp, _Nm>& lhs, const array<_Tp, _Nm>& rhs) {
return !(lhs == rhs);
}
template<typename _Tp, size_t _Nm>
inline bool operator< (const array<_Tp, _Nm>& lhs, const array<_Tp, _Nm>& rhs) {
return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}
template<typename _Tp, size_t _Nm>
inline bool operator> (const array<_Tp, _Nm>& lhs, const array<_Tp, _Nm>& rhs) {
return rhs < lhs;
}
template<typename _Tp, size_t _Nm>
inline bool operator<= (const array<_Tp, _Nm>& lhs, const array<_Tp, _Nm>& rhs) {
return !(lhs > rhs);
}
template<typename _Tp, size_t _Nm>
inline bool
operator>= (const array<_Tp, _Nm>& lhs, const array<_Tp, _Nm>& rhs) {
return !(lhs < rhs);
}
// Specialized algorithms.
template<typename _Tp, size_t _Nm>
inline void swap (array<_Tp, _Nm>& lhs, array<_Tp, _Nm>& rhs)
noexcept (noexcept (lhs.swap(rhs))) {
lhs.swap (rhs);
}
template<size_t _Int, typename _Tp, size_t _Nm>
constexpr _Tp& get (array<_Tp, _Nm>& arr) noexcept {
static_assert(_Int < _Nm, "Index is out of bounds");
return array_traits<_Tp, _Nm>::Ref(arr._data, _Int);
}
template<size_t _Int, typename _Tp, size_t _Nm>
constexpr _Tp&& get (array<_Tp, _Nm>&& arr) noexcept {
static_assert(_Int < _Nm, "Index is out of bounds");
return std::move(std::get<_Int>(arr));
}
template<size_t _Int, typename _Tp, size_t _Nm>
constexpr const _Tp& get (const array<_Tp, _Nm>& arr) noexcept {
static_assert(_Int < _Nm, "Index is out of bounds");
return array_traits<_Tp, _Nm>::Ref(arr._data, _Int);
}
} // namespace utl
#endif /* __utl_continer_array_h__ */
utl::array::cend
const_iterator cend() const noexcept
Definition: array.h:112
utl::operator==
bool operator==(const array< _Tp, _Nm > &lhs, const array< _Tp, _Nm > &rhs)
Definition: array.h:181
utl::array::front
reference front() noexcept
Definition: array.h:156
utl::array::difference_type
ptrdiff_t difference_type
Definition: array.h:86
utl::array
A standard container for storing a fixed size sequence of elements.
Definition: array.h:77
utl::array::operator[]
constexpr const_reference operator[](size_type n) const noexcept
Operator [] for const.
Definition: array.h:136
utl::array::rend
reverse_iterator rend() noexcept
Definition: array.h:115
utl::array::_data
array_t::type _data
Definition: array.h:94
utl::array::pointer
value_type * pointer
Definition: array.h:79
utl::array_traits< _Tp, 0 >::Ref
static constexpr _Tp & Ref(const type &, size_t) noexcept
Definition: array.h:52
utl::array::end
const_iterator end() const noexcept
Definition: array.h:110
utl::array::data
const_pointer data() const noexcept
Definition: array.h:174
utl::array::empty
constexpr bool empty() const noexcept
Definition: array.h:125
utl::array::data
pointer data() noexcept
Definition: array.h:173
utl::array::swap
void swap(array &other) noexcept
Definition: array.h:101
utl::array::rbegin
const_reverse_iterator rbegin() const noexcept
Definition: array.h:116
utl::array::end
iterator end() noexcept
Definition: array.h:109
utl::array::back
reference back() noexcept
Definition: array.h:164
utl::array::crbegin
const_reverse_iterator crbegin() const noexcept
Definition: array.h:118
utl::array::rend
const_reverse_iterator rend() const noexcept
Definition: array.h:117
utl::ptrdiff_t
std::ptrdiff_t ptrdiff_t
Definition: types.h:40
utl::array::const_iterator
const value_type * const_iterator
Definition: array.h:84
utl::array_traits
array container traits helper
Definition: array.h:36
utl::array::const_reverse_iterator
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: array.h:89
utl::array::const_pointer
const value_type * const_pointer
Definition: array.h:80
utl::operator>=
bool operator>=(const array< _Tp, _Nm > &lhs, const array< _Tp, _Nm > &rhs)
Definition: array.h:207
utl::array::reverse_iterator
std::reverse_iterator< iterator > reverse_iterator
Definition: array.h:87
utl::array_traits< _Tp, 0 >::Ptr
static constexpr _Tp * Ptr(const type &) noexcept
Definition: array.h:56
utl::size_t
std::size_t size_t
Definition: types.h:37
utl::array::back
constexpr const_reference back() const noexcept
Definition: array.h:167
utl
STL&#39;s core language concepts.
Definition: _1wire.h:30
utl::array::value_type
_Tp value_type
Definition: array.h:78
utl::array::at
reference at(size_type n) noexcept
Definition: array.h:144
utl::array::operator[]
reference operator[](size_type n) noexcept
Operator [].
Definition: array.h:132
utl::array::fill
void fill(const value_type &v)
Definition: array.h:99
utl::operator>
bool operator>(const array< _Tp, _Nm > &lhs, const array< _Tp, _Nm > &rhs)
Definition: array.h:196
utl::array::at
constexpr const_reference at(size_type n) const noexcept
Compile time boundary check dereference operator.
Definition: array.h:151
utl::array::rbegin
reverse_iterator rbegin() noexcept
Definition: array.h:114
utl::array_traits::Ptr
static constexpr _Tp * Ptr(const type &t) noexcept
Definition: array.h:43
utl::array::size
constexpr size_type size() const noexcept
Definition: array.h:123
utl::array::reference
value_type & reference
Definition: array.h:81
utl::array::crend
const_reverse_iterator crend() const noexcept
Definition: array.h:119
utl::array::begin
iterator begin() noexcept
Definition: array.h:107
utl::operator!=
bool operator!=(const array< _Tp, _Nm > &lhs, const array< _Tp, _Nm > &rhs)
Definition: array.h:186
utl::array::front
constexpr const_reference front() const noexcept
Definition: array.h:159
utl::array::cbegin
const_iterator cbegin() const noexcept
Definition: array.h:111
utl::array::size_type
size_t size_type
Definition: array.h:85
utl::array::max_size
constexpr size_type max_size() const noexcept
Definition: array.h:124
utl::array::begin
const_iterator begin() const noexcept
Definition: array.h:108
utl::array_traits::type
_Tp type[_Nm]
Definition: array.h:37
utl::swap
void swap(array< _Tp, _Nm > &lhs, array< _Tp, _Nm > &rhs) noexcept(noexcept(lhs.swap(rhs)))
Definition: array.h:214
utl::array::const_reference
const value_type & const_reference
Definition: array.h:82
utl::array::iterator
value_type * iterator
Definition: array.h:83
impl.h
Implementation detail main forward header.
utl::array_traits::Ref
static constexpr _Tp & Ref(const type &t, size_t n) noexcept
Definition: array.h:39