uTL
micro Template library
array.h
Go to the documentation of this file.
1 
21 #ifndef __utl_container_array_h__
22 #define __utl_container_array_h__
23 
24 #include <utl/core/impl.h>
25 #include <algorithm>
26 
27 namespace utl {
28 
34  template<typename _Tp, size_t _Nm>
36  struct array_traits {
37  typedef _Tp type[_Nm];
38 
39  static constexpr _Tp& Ref (const type& t, size_t n) noexcept {
40  return const_cast<_Tp&>(t[n]);
41  }
42 
43  static constexpr _Tp* Ptr(const type& t) noexcept {
44  return const_cast<_Tp*>(t);
45  }
46  };
47 
48  template<typename _Tp>
49  struct array_traits<_Tp, 0> {
50  struct type { };
51 
52  static constexpr _Tp& Ref(const type&, size_t) noexcept {
53  return *static_cast<_Tp*>(nullptr);
54  }
55 
56  static constexpr _Tp* Ptr(const type&) noexcept {
57  return nullptr;
58  }
59  };
61 
76  template <typename _Tp, size_t _Nm>
77  struct array {
78  using value_type = _Tp;
79  using pointer = value_type*;
80  using const_pointer = const value_type*;
82  using const_reference = const value_type&;
83  using iterator = value_type*;
84  using const_iterator = const value_type*;
85  using size_type = size_t;
87  using reverse_iterator = std::reverse_iterator <iterator>;
89  = std::reverse_iterator <const_iterator>;
90 
91  // type and data
92  //using empty_t = array_traits<_Tp, 0>;
94  typename array_t::type _data;
95 
96  // No explicit construct/copy/destroy for aggregate type.
97 
98  // DR 776.
99  void fill (const value_type& v) { std::fill_n (begin(), size(), v); }
100 
101  void swap (array& other) noexcept {
102  std::swap_ranges (begin(), end(), other.begin());
103  }
104 
107  iterator begin() noexcept { return iterator (data()); }
108  const_iterator begin() const noexcept { return const_iterator (data()); }
109  iterator end() noexcept { return iterator (data() + _Nm); }
110  const_iterator end() const noexcept { return const_iterator (data() + _Nm); }
111  const_iterator cbegin() const noexcept { return const_iterator (data()); }
112  const_iterator cend() const noexcept { return const_iterator (data() + _Nm); }
113 
114  reverse_iterator rbegin() noexcept { return reverse_iterator (end()); }
115  reverse_iterator rend() noexcept { return reverse_iterator (begin()); }
116  const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator (end()); }
117  const_reverse_iterator rend() const noexcept { return const_reverse_iterator (begin()); }
118  const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator (end()); }
119  const_reverse_iterator crend() const noexcept { return const_reverse_iterator (begin()); }
123  constexpr size_type size() const noexcept { return _Nm; }
124  constexpr size_type max_size() const noexcept { return _Nm; }
125  constexpr bool empty() const noexcept { return size() == 0; }
127 
130 
133  return array_t::Ref(_data, n);
134  }
136  constexpr const_reference operator[](size_type n) const noexcept {
137  return array_t::Ref(_data, n);
138  }
139 
144  reference at (size_type n) noexcept {
145  if (n < _Nm)
146  return array_t::Ref(_data, n);
147  else
148  abort (); //XXX: Throw here
149  }
151  constexpr const_reference at (size_type n) const noexcept {
152  static_assert ((n < _Nm), "array::at: out of range");
153  return array_t::Ref(_data, n);
154  }
155  // first item
156  reference front () noexcept {
157  return *begin ();
158  }
159  constexpr const_reference front() const noexcept {
160  return array_t::Ref(_data, 0);
161  }
162 
163  // Last item
164  reference back () noexcept {
165  return _Nm ? *(end() - 1) : *end();
166  }
167  constexpr const_reference back () const noexcept {
168  return _Nm ? array_t::Ref(_data, _Nm - 1)
169  : array_t::Ref(_data, 0);
170  }
171 
172  // Pointer to data
173  pointer data () noexcept { return array_t::Ptr(_data); }
174  const_pointer data () const noexcept { return array_t::Ptr(_data); }
176  };
177 
180  template<typename _Tp, size_t _Nm>
181  inline bool operator== (const array<_Tp, _Nm>& lhs, const array<_Tp, _Nm>& rhs) {
182  return std::equal (lhs.begin(), lhs.end(), rhs.begin());
183  }
184 
185  template<typename _Tp, size_t _Nm>
186  inline bool operator!= (const array<_Tp, _Nm>& lhs, const array<_Tp, _Nm>& rhs) {
187  return !(lhs == rhs);
188  }
189 
190  template<typename _Tp, size_t _Nm>
191  inline bool operator< (const array<_Tp, _Nm>& lhs, const array<_Tp, _Nm>& rhs) {
192  return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
193  }
194 
195  template<typename _Tp, size_t _Nm>
196  inline bool operator> (const array<_Tp, _Nm>& lhs, const array<_Tp, _Nm>& rhs) {
197  return rhs < lhs;
198  }
199 
200  template<typename _Tp, size_t _Nm>
201  inline bool operator<= (const array<_Tp, _Nm>& lhs, const array<_Tp, _Nm>& rhs) {
202  return !(lhs > rhs);
203  }
204 
205  template<typename _Tp, size_t _Nm>
206  inline bool
207  operator>= (const array<_Tp, _Nm>& lhs, const array<_Tp, _Nm>& rhs) {
208  return !(lhs < rhs);
209  }
211 
212  // Specialized algorithms.
213  template<typename _Tp, size_t _Nm>
214  inline void swap (array<_Tp, _Nm>& lhs, array<_Tp, _Nm>& rhs)
215  noexcept (noexcept (lhs.swap(rhs))) {
216  lhs.swap (rhs);
217  }
218 
219  template<size_t _Int, typename _Tp, size_t _Nm>
220  constexpr _Tp& get (array<_Tp, _Nm>& arr) noexcept {
221  static_assert(_Int < _Nm, "Index is out of bounds");
222  return array_traits<_Tp, _Nm>::Ref(arr._data, _Int);
223  }
224 
225  template<size_t _Int, typename _Tp, size_t _Nm>
226  constexpr _Tp&& get (array<_Tp, _Nm>&& arr) noexcept {
227  static_assert(_Int < _Nm, "Index is out of bounds");
228  return std::move(std::get<_Int>(arr));
229  }
230 
231  template<size_t _Int, typename _Tp, size_t _Nm>
232  constexpr const _Tp& get (const array<_Tp, _Nm>& arr) noexcept {
233  static_assert(_Int < _Nm, "Index is out of bounds");
234  return array_traits<_Tp, _Nm>::Ref(arr._data, _Int);
235  }
236 
237 } // namespace utl
238 
239 
240 #endif /* __utl_continer_array_h__ */
const_iterator cend() const noexcept
Definition: array.h:112
bool operator==(const array< _Tp, _Nm > &lhs, const array< _Tp, _Nm > &rhs)
Definition: array.h:181
reference front() noexcept
Definition: array.h:156
ptrdiff_t difference_type
Definition: array.h:86
A standard container for storing a fixed size sequence of elements.
Definition: array.h:77
constexpr const_reference operator[](size_type n) const noexcept
Operator [] for const.
Definition: array.h:136
reverse_iterator rend() noexcept
Definition: array.h:115
array_t::type _data
Definition: array.h:94
value_type * pointer
Definition: array.h:79
static constexpr _Tp & Ref(const type &, size_t) noexcept
Definition: array.h:52
const_iterator end() const noexcept
Definition: array.h:110
const_pointer data() const noexcept
Definition: array.h:174
constexpr bool empty() const noexcept
Definition: array.h:125
pointer data() noexcept
Definition: array.h:173
void swap(array &other) noexcept
Definition: array.h:101
const_reverse_iterator rbegin() const noexcept
Definition: array.h:116
iterator end() noexcept
Definition: array.h:109
reference back() noexcept
Definition: array.h:164
const_reverse_iterator crbegin() const noexcept
Definition: array.h:118
const_reverse_iterator rend() const noexcept
Definition: array.h:117
std::ptrdiff_t ptrdiff_t
Definition: types.h:40
const value_type * const_iterator
Definition: array.h:84
array container traits helper
Definition: array.h:36
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: array.h:89
const value_type * const_pointer
Definition: array.h:80
bool operator>=(const array< _Tp, _Nm > &lhs, const array< _Tp, _Nm > &rhs)
Definition: array.h:207
std::reverse_iterator< iterator > reverse_iterator
Definition: array.h:87
static constexpr _Tp * Ptr(const type &) noexcept
Definition: array.h:56
std::size_t size_t
Definition: types.h:37
constexpr const_reference back() const noexcept
Definition: array.h:167
STL&#39;s core language concepts.
Definition: _1wire.h:30
_Tp value_type
Definition: array.h:78
reference at(size_type n) noexcept
Definition: array.h:144
reference operator[](size_type n) noexcept
Operator [].
Definition: array.h:132
void fill(const value_type &v)
Definition: array.h:99
bool operator>(const array< _Tp, _Nm > &lhs, const array< _Tp, _Nm > &rhs)
Definition: array.h:196
constexpr const_reference at(size_type n) const noexcept
Compile time boundary check dereference operator.
Definition: array.h:151
reverse_iterator rbegin() noexcept
Definition: array.h:114
static constexpr _Tp * Ptr(const type &t) noexcept
Definition: array.h:43
constexpr size_type size() const noexcept
Definition: array.h:123
value_type & reference
Definition: array.h:81
const_reverse_iterator crend() const noexcept
Definition: array.h:119
iterator begin() noexcept
Definition: array.h:107
bool operator!=(const array< _Tp, _Nm > &lhs, const array< _Tp, _Nm > &rhs)
Definition: array.h:186
constexpr const_reference front() const noexcept
Definition: array.h:159
const_iterator cbegin() const noexcept
Definition: array.h:111
size_t size_type
Definition: array.h:85
constexpr size_type max_size() const noexcept
Definition: array.h:124
const_iterator begin() const noexcept
Definition: array.h:108
_Tp type[_Nm]
Definition: array.h:37
void swap(array< _Tp, _Nm > &lhs, array< _Tp, _Nm > &rhs) noexcept(noexcept(lhs.swap(rhs)))
Definition: array.h:214
const value_type & const_reference
Definition: array.h:82
value_type * iterator
Definition: array.h:83
Implementation detail main forward header.
static constexpr _Tp & Ref(const type &t, size_t n) noexcept
Definition: array.h:39