y3c-stl 0.3.3
Friendly C++ STL wrapper with automatic stacktrace
Loading...
Searching...
No Matches
array.h
Go to the documentation of this file.
1#pragma once
2#include "y3c/terminate.h"
3#include "y3c/wrap.h"
4#include "y3c/typename.h"
5#include "y3c/iterator.h"
6#include <array>
7
8namespace y3c {
9
19template <typename T, std::size_t N>
20class array {
21 std::array<T, N> base_;
22 internal::life elems_life_;
23 internal::life life_;
24
25 const std::string &type_name() const {
26 return internal::get_type_name<array>();
27 }
28 const std::string &iter_name() const {
29 static std::string name =
30 internal::get_type_name<array>() + "::iterator";
31 return name;
32 }
33
34 public:
39 : base_(), elems_life_(N == 0 ? nullptr : &base_[0],
40 N == 0 ? nullptr : &base_[0] + N),
41 life_(this) {}
45 array(const array &other)
46 : base_(other.base_), elems_life_(N == 0 ? nullptr : &base_[0],
47 N == 0 ? nullptr : &base_[0] + N),
48 life_(this) {}
52 array &operator=(const array &other) {
53 this->base_ = other.base_;
54 return *this;
55 }
59 array(array &&other)
60 : base_(std::move(other.base_)),
61 elems_life_(N == 0 ? nullptr : &base_[0],
62 N == 0 ? nullptr : &base_[0] + N),
63 life_(this) {}
67 array &operator=(array &&other) {
68 if (this != std::addressof(other)) {
69 this->base_ = std::move(other.base_);
70 }
71 return *this;
72 }
73
80 template <typename... Args,
81 typename std::enable_if<(sizeof...(Args) == N),
82 std::nullptr_t>::type = nullptr>
83 array(Args &&...args)
84 : array(std::array<T, N>{std::forward<Args>(args)...}) {}
88 array(const std::array<T, N> &elems)
89 : base_(elems), elems_life_(N == 0 ? nullptr : &base_[0],
90 N == 0 ? nullptr : &base_[0] + N),
91 life_(this) {}
95 array(std::array<T, N> &&elems)
96 : base_(std::move(elems)),
97 elems_life_(N == 0 ? nullptr : &base_[0],
98 N == 0 ? nullptr : &base_[0] + N),
99 life_(this) {}
103 array &operator=(const std::array<T, N> &elems) {
104 this->base_ = elems;
105 return *this;
106 }
110 array &operator=(std::array<T, N> &&elems) {
111 this->base_ = std::move(elems);
112 return *this;
113 }
114
119 // using reverse_iterator = std::reverse_iterator<iterator>;
120 // using const_reverse_iterator = std::reverse_iterator<const_iterator>;
121 using size_type = std::size_t;
122 using difference_type = std::ptrdiff_t;
125 using value_type = T;
126
134 if (n >= N) {
135 static std::string func = type_name() + "::at()";
136 throw y3c::out_of_range(func, N, static_cast<std::ptrdiff_t>(n));
137 }
138 return reference(&this->base_[n], this->elems_life_.observer());
139 }
147 if (n >= N) {
148 static std::string func = type_name() + "::at()";
149 throw y3c::out_of_range(func, N, static_cast<std::ptrdiff_t>(n));
150 }
151 return const_reference(&this->base_[n], this->elems_life_.observer());
152 }
159 template <typename = internal::skip_trace_tag>
161 if (n >= N) {
162 static std::string func = type_name() + "::operator[]()";
164 func, N, static_cast<std::ptrdiff_t>(n));
165 }
166 return reference(&this->base_[n], this->elems_life_.observer());
167 }
174 template <typename = internal::skip_trace_tag>
176 if (n >= N) {
177 static std::string func = type_name() + "::operator[]()";
179 func, N, static_cast<std::ptrdiff_t>(n));
180 }
181 return const_reference(&this->base_[n], this->elems_life_.observer());
182 }
183
191 if (N == 0) {
192 static std::string func = type_name() + "::front()";
194 }
195 return reference(&this->base_.front(), this->elems_life_.observer());
196 }
204 if (N == 0) {
205 static std::string func = type_name() + "::front()";
207 }
208 return const_reference(&this->base_.front(),
209 this->elems_life_.observer());
210 }
218 if (N == 0) {
219 static std::string func = type_name() + "::back()";
221 }
222 return reference(&this->base_.back(), this->elems_life_.observer());
223 }
231 if (N == 0) {
232 static std::string func = type_name() + "::back()";
234 }
235 return const_reference(&this->base_.back(),
236 this->elems_life_.observer());
237 }
238
246 if (N == 0) {
247 return pointer(nullptr, this->elems_life_.observer());
248 }
249 return pointer(&this->base_[0], this->elems_life_.observer());
250 }
258 if (N == 0) {
259 return const_pointer(nullptr, this->elems_life_.observer());
260 }
261 return const_pointer(&this->base_[0], this->elems_life_.observer());
262 }
263
271 if (N == 0) {
272 return iterator(nullptr, this->elems_life_.observer(),
273 &iter_name());
274 }
275 return iterator(&this->base_.front(), this->elems_life_.observer(),
276 &iter_name());
277 }
285 if (N == 0) {
286 return const_iterator(nullptr, this->elems_life_.observer(),
287 &iter_name());
288 }
289 return const_iterator(&this->base_.front(),
290 this->elems_life_.observer(), &iter_name());
291 }
298 const_iterator cbegin() const { return begin(); }
305 iterator end() { return begin() + N; }
312 const_iterator end() const { return begin() + N; }
319 const_iterator cend() const { return begin() + N; }
320
325 bool empty() const noexcept { return N == 0; }
330 size_type size() const noexcept { return N; }
335 size_type max_size() const noexcept { return N; }
336
340 void fill(const T &value) { this->base_.fill(value); }
344 void swap(array &other) { this->base_.swap(other); }
345
349 operator std::array<T, N>&() noexcept {
350 return base_;
351 }
355 operator const std::array<T, N>&() const noexcept {
356 return base_;
357 }
358
359 operator wrap<array &>() noexcept {
360 return wrap<array &>(this, life_.observer());
361 }
362 operator wrap<const array &>() const noexcept {
363 return wrap<const array &>(this, life_.observer());
364 }
365 wrap<array *> operator&() { return wrap<array *>(this, life_.observer()); }
367 return wrap<const array *>(this, life_.observer());
368 }
369};
370
371template <typename T, std::size_t N>
372std::array<T, N> &unwrap(array<T, N> &wrapper) noexcept {
373 return static_cast<std::array<T, N> &>(wrapper);
374}
375template <typename T, std::size_t N>
376const std::array<T, N> &unwrap(const array<T, N> &wrapper) noexcept {
377 return static_cast<const std::array<T, N> &>(wrapper);
378}
379
380template <typename T, std::size_t N>
381void swap(array<T, N> &lhs, array<T, N> &rhs) {
382 lhs.swap(rhs);
383}
384
385template <typename T, std::size_t N>
386bool operator==(const array<T, N> &lhs, const array<T, N> &rhs) {
387 return unwrap(lhs) == unwrap(rhs);
388}
389template <typename T, std::size_t N>
390bool operator!=(const array<T, N> &lhs, const array<T, N> &rhs) {
391 return unwrap(lhs) != unwrap(rhs);
392}
393template <typename T, std::size_t N>
394bool operator<(const array<T, N> &lhs, const array<T, N> &rhs) {
395 return unwrap(lhs) < unwrap(rhs);
396}
397template <typename T, std::size_t N>
398bool operator<=(const array<T, N> &lhs, const array<T, N> &rhs) {
399 return unwrap(lhs) <= unwrap(rhs);
400}
401template <typename T, std::size_t N>
402bool operator>(const array<T, N> &lhs, const array<T, N> &rhs) {
403 return unwrap(lhs) > unwrap(rhs);
404}
405template <typename T, std::size_t N>
406bool operator>=(const array<T, N> &lhs, const array<T, N> &rhs) {
407 return unwrap(lhs) >= unwrap(rhs);
408}
409
410} // namespace y3c
固定長配列 (std::array)
Definition array.h:20
wrap< const array * > operator&() const
Definition array.h:366
size_type size() const noexcept
配列のサイズを取得
Definition array.h:330
array(const std::array< T, N > &elems)
std::arrayからのコピー
Definition array.h:88
const_reference at(size_type n, internal::skip_trace_tag={}) const
要素アクセス(const)
Definition array.h:146
array & operator=(const array &other)
コピー代入
Definition array.h:52
const_iterator begin() const
先頭要素を指すconstイテレータを取得
Definition array.h:284
array(Args &&...args)
要素で初期化
Definition array.h:83
reference front(internal::skip_trace_tag={})
先頭の要素へのアクセス
Definition array.h:190
const_pointer data() const
先頭要素へのconstポインタを取得
Definition array.h:257
pointer data()
先頭要素へのポインタを取得
Definition array.h:245
reference operator[](size_type n)
要素アクセス
Definition array.h:160
const_iterator cbegin() const
先頭要素を指すconstイテレータを取得
Definition array.h:298
reference at(size_type n, internal::skip_trace_tag={})
要素アクセス
Definition array.h:133
bool empty() const noexcept
sizeが0かどうかを返す
Definition array.h:325
internal::contiguous_iterator< T > iterator
Definition array.h:117
array(const array &other)
コピーコンストラクタ
Definition array.h:45
const_iterator cend() const
末尾要素を指すconstイテレータを取得
Definition array.h:319
array & operator=(std::array< T, N > &&elems)
std::arrayからのムーブ
Definition array.h:110
array()
デフォルトコンストラクタ: 各要素をデフォルト値で初期化
Definition array.h:38
array & operator=(array &&other)
ムーブ代入
Definition array.h:67
wrap_ref< T > reference
Definition array.h:115
reference back(internal::skip_trace_tag={})
末尾の要素へのアクセス
Definition array.h:217
size_type max_size() const noexcept
配列の最大サイズを取得
Definition array.h:335
ptr< T > pointer
Definition array.h:123
const_reference back(internal::skip_trace_tag={}) const
末尾の要素へのアクセス
Definition array.h:230
const_ptr< T > const_pointer
Definition array.h:124
internal::contiguous_iterator< const T > const_iterator
Definition array.h:118
iterator end()
末尾要素を指すイテレータを取得
Definition array.h:305
const_iterator end() const
末尾要素を指すconstイテレータを取得
Definition array.h:312
std::ptrdiff_t difference_type
Definition array.h:122
iterator begin()
先頭要素を指すイテレータを取得
Definition array.h:270
const_wrap_ref< T > const_reference
Definition array.h:116
wrap< array * > operator&()
Definition array.h:365
array(std::array< T, N > &&elems)
std::arrayからのムーブ
Definition array.h:95
array & operator=(const std::array< T, N > &elems)
std::arrayからのコピー
Definition array.h:103
void swap(array &other)
別のarrayと要素を入れ替える
Definition array.h:344
const_reference front(internal::skip_trace_tag={}) const
先頭の要素へのアクセス(const)
Definition array.h:203
void fill(const T &value)
コンテナを要素で埋める
Definition array.h:340
const_reference operator[](size_type n) const
要素アクセス(const)
Definition array.h:175
std::size_t size_type
Definition array.h:121
array(array &&other)
ムーブコンストラクタ
Definition array.h:59
T value_type
Definition array.h:125
array, vector など各種コンテナのイテレータ
Definition iterator.h:26
オブジェクトのライフタイムを管理するクラス
Definition life.h:207
life_observer observer() const
Definition life.h:233
Definition terminate.h:179
ポインタ型wrap: element_type型のデータへのポインタと、 このポインタ自体の生存状態を管理するクラス
Definition wrap.h:318
参照型wrap: element_type型のデータへの参照を持つクラス
Definition wrap.h:168
値型wrap: base_type型のデータと、このデータの生存状態を管理するクラス
Definition wrap.h:26
void terminate_ub_out_of_range(std::string func, Args &&...args)
Definition terminate.h:132
Definition array.h:8
bool operator!=(const array< T, N > &lhs, const array< T, N > &rhs)
Definition array.h:390
bool operator<=(const array< T, N > &lhs, const array< T, N > &rhs)
Definition array.h:398
void swap(array< T, N > &lhs, array< T, N > &rhs)
Definition array.h:381
bool operator==(const array< T, N > &lhs, const array< T, N > &rhs)
Definition array.h:386
std::array< T, N > & unwrap(array< T, N > &wrapper) noexcept
Definition array.h:372
bool operator>(const array< T, N > &lhs, const array< T, N > &rhs)
Definition array.h:402
bool operator<(const array< T, N > &lhs, const array< T, N > &rhs)
Definition array.h:394
bool operator>=(const array< T, N > &lhs, const array< T, N > &rhs)
Definition array.h:406
Definition terminate.h:27