forked from OctaForge/libostd
remove the noexcept stuff; nothing in octastd ever throws
parent
25fb30b524
commit
64810e4006
38
octa/array.h
38
octa/array.h
|
@ -23,39 +23,39 @@ namespace octa {
|
||||||
typedef PointerRange< T> RangeType;
|
typedef PointerRange< T> RangeType;
|
||||||
typedef PointerRange<const T> ConstRangeType;
|
typedef PointerRange<const T> ConstRangeType;
|
||||||
|
|
||||||
T &operator[](size_t i) noexcept { return p_buf[i]; }
|
T &operator[](size_t i) { return p_buf[i]; }
|
||||||
const T &operator[](size_t i) const noexcept { return p_buf[i]; }
|
const T &operator[](size_t i) const { return p_buf[i]; }
|
||||||
|
|
||||||
T &at(size_t i) noexcept { return p_buf[i]; }
|
T &at(size_t i) { return p_buf[i]; }
|
||||||
const T &at(size_t i) const noexcept { return p_buf[i]; }
|
const T &at(size_t i) const { return p_buf[i]; }
|
||||||
|
|
||||||
T &first() noexcept { return p_buf[0]; }
|
T &first() { return p_buf[0]; }
|
||||||
const T &first() const noexcept { return p_buf[0]; }
|
const T &first() const { return p_buf[0]; }
|
||||||
|
|
||||||
T &last() noexcept { return p_buf[N - 1]; }
|
T &last() { return p_buf[N - 1]; }
|
||||||
const T &last() const noexcept { return p_buf[N - 1]; }
|
const T &last() const { return p_buf[N - 1]; }
|
||||||
|
|
||||||
size_t length() const noexcept { return N; }
|
size_t length() const { return N; }
|
||||||
|
|
||||||
bool empty() const noexcept { return N == 0; }
|
bool empty() const { return N == 0; }
|
||||||
|
|
||||||
bool in_range(size_t idx) noexcept { return idx < N; }
|
bool in_range(size_t idx) { return idx < N; }
|
||||||
bool in_range(int idx) noexcept { return idx >= 0 && idx < N; }
|
bool in_range(int idx) { return idx >= 0 && idx < N; }
|
||||||
bool in_range(const T *ptr) noexcept {
|
bool in_range(const T *ptr) {
|
||||||
return ptr >= &p_buf[0] && ptr < &p_buf[N];
|
return ptr >= &p_buf[0] && ptr < &p_buf[N];
|
||||||
}
|
}
|
||||||
|
|
||||||
T *get() noexcept { return p_buf; }
|
T *get() { return p_buf; }
|
||||||
const T *get() const noexcept { return p_buf; }
|
const T *get() const { return p_buf; }
|
||||||
|
|
||||||
void swap(Array &v) noexcept(swap(declval<T &>(), declval<T &>())) {
|
void swap(Array &v)(swap(declval<T &>(), declval<T &>())) {
|
||||||
swap(p_buf, v.p_buf);
|
swap(p_buf, v.p_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
RangeType each() noexcept {
|
RangeType each() {
|
||||||
return PointerRange<T>(p_buf, p_buf + N);
|
return PointerRange<T>(p_buf, p_buf + N);
|
||||||
}
|
}
|
||||||
ConstRangeType each() const noexcept {
|
ConstRangeType each() const {
|
||||||
return PointerRange<const T>(p_buf, p_buf + N);
|
return PointerRange<const T>(p_buf, p_buf + N);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ namespace octa {
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, size_t N>
|
template<typename T, size_t N>
|
||||||
void swap(Array<T, N> &a, Array<T, N> &b) noexcept(noexcept(a.swap(b))) {
|
void swap(Array<T, N> &a, Array<T, N> &b) {
|
||||||
a.swap(b);
|
a.swap(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
379
octa/atomic.h
379
octa/atomic.h
|
@ -24,8 +24,8 @@ namespace octa {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct __OctaAtomicBase {
|
struct __OctaAtomicBase {
|
||||||
__OctaAtomicBase() noexcept {}
|
__OctaAtomicBase() {}
|
||||||
explicit __OctaAtomicBase(T v) noexcept: value(v) {}
|
explicit __OctaAtomicBase(T v): value(v) {}
|
||||||
T value;
|
T value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -112,8 +112,7 @@ namespace octa {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct __OctaMsvcAtomicStore<T, 1> {
|
struct __OctaMsvcAtomicStore<T, 1> {
|
||||||
static inline void store(volatile T *dst, T src, MemoryOrder ord)
|
static inline void store(volatile T *dst, T src, MemoryOrder ord) {
|
||||||
noexcept {
|
|
||||||
if (ord == MemoryOrder::seq_cst)
|
if (ord == MemoryOrder::seq_cst)
|
||||||
InterlockedExchange8((volatile int8_t *)dst, (int8_t)src);
|
InterlockedExchange8((volatile int8_t *)dst, (int8_t)src);
|
||||||
else *dst = src;
|
else *dst = src;
|
||||||
|
@ -122,8 +121,7 @@ namespace octa {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct __OctaMsvcAtomicStore<T, 2> {
|
struct __OctaMsvcAtomicStore<T, 2> {
|
||||||
static inline void store(volatile T *dst, T src, MemoryOrder ord)
|
static inline void store(volatile T *dst, T src, MemoryOrder ord) {
|
||||||
noexcept {
|
|
||||||
if (ord == MemoryOrder::seq_cst)
|
if (ord == MemoryOrder::seq_cst)
|
||||||
InterlockedExchange16((volatile int16_t *)dst, (int16_t)src);
|
InterlockedExchange16((volatile int16_t *)dst, (int16_t)src);
|
||||||
else *dst = src;
|
else *dst = src;
|
||||||
|
@ -132,8 +130,7 @@ namespace octa {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct __OctaMsvcAtomicStore<T, 4> {
|
struct __OctaMsvcAtomicStore<T, 4> {
|
||||||
static inline void store(volatile T *dst, T src, MemoryOrder ord)
|
static inline void store(volatile T *dst, T src, MemoryOrder ord) {
|
||||||
noexcept {
|
|
||||||
if (ord == MemoryOrder::seq_cst)
|
if (ord == MemoryOrder::seq_cst)
|
||||||
InterlockedExchange((volatile int32_t *)dst, (int32_t)src);
|
InterlockedExchange((volatile int32_t *)dst, (int32_t)src);
|
||||||
else *dst = src;
|
else *dst = src;
|
||||||
|
@ -142,8 +139,7 @@ namespace octa {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct __OctaMsvcAtomicStore<T, 8> {
|
struct __OctaMsvcAtomicStore<T, 8> {
|
||||||
static inline void store(volatile T *dst, T src, MemoryOrder ord)
|
static inline void store(volatile T *dst, T src, MemoryOrder ord) {
|
||||||
noexcept {
|
|
||||||
if (ord == MemoryOrder::relaxed)
|
if (ord == MemoryOrder::relaxed)
|
||||||
InterlockedExchangeNoFence64((volatile int64_t *)dst, (int64_t)src);
|
InterlockedExchangeNoFence64((volatile int64_t *)dst, (int64_t)src);
|
||||||
else
|
else
|
||||||
|
@ -168,26 +164,22 @@ namespace octa {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct __OctaMsvcAtomicLoad<T, 1> {
|
struct __OctaMsvcAtomicLoad<T, 1> {
|
||||||
static inline void load(volatile T *src, T *dst)
|
static inline void load(volatile T *src, T *dst) { *dst = *src; }
|
||||||
noexcept { *dst = *src; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct __OctaMsvcAtomicLoad<T, 2> {
|
struct __OctaMsvcAtomicLoad<T, 2> {
|
||||||
static inline void load(volatile T *src, T *dst)
|
static inline void load(volatile T *src, T *dst) { *dst = *src; }
|
||||||
noexcept { *dst = *src; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct __OctaMsvcAtomicLoad<T, 4> {
|
struct __OctaMsvcAtomicLoad<T, 4> {
|
||||||
static inline void load(volatile T *src, T *dst)
|
static inline void load(volatile T *src, T *dst) { *dst = *src; }
|
||||||
noexcept { *dst = *src; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct __OctaMsvcAtomicLoad<T, 8> {
|
struct __OctaMsvcAtomicLoad<T, 8> {
|
||||||
static inline void load(volatile T *src, T *dst)
|
static inline void load(volatile T *src, T *dst) {
|
||||||
noexcept {
|
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable:4047)
|
#pragma warning(disable:4047)
|
||||||
*dst = InterlockedOr64((volatile int64_t *)(src), 0);
|
*dst = InterlockedOr64((volatile int64_t *)(src), 0);
|
||||||
|
@ -216,32 +208,28 @@ namespace octa {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct __OctaMsvcAtomicExchange<T, 1> {
|
struct __OctaMsvcAtomicExchange<T, 1> {
|
||||||
static inline void exchange(volatile T *dst, T src, T *ret)
|
static inline void exchange(volatile T *dst, T src, T *ret) {
|
||||||
noexcept {
|
|
||||||
*ret = InterlockedExchange8((volatile int8_t *)dst, (int8_t)src);
|
*ret = InterlockedExchange8((volatile int8_t *)dst, (int8_t)src);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct __OctaMsvcAtomicExchange<T, 2> {
|
struct __OctaMsvcAtomicExchange<T, 2> {
|
||||||
static inline void exchange(volatile T *dst, T src, T *ret)
|
static inline void exchange(volatile T *dst, T src, T *ret) {
|
||||||
noexcept {
|
|
||||||
*ret = InterlockedExchange16((volatile int16_t *)dst, (int16_t)src);
|
*ret = InterlockedExchange16((volatile int16_t *)dst, (int16_t)src);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct __OctaMsvcAtomicExchange<T, 4> {
|
struct __OctaMsvcAtomicExchange<T, 4> {
|
||||||
static inline void exchange(volatile T *dst, T src, T *ret)
|
static inline void exchange(volatile T *dst, T src, T *ret) {
|
||||||
noexcept {
|
|
||||||
*ret = InterlockedExchange((volatile int32_t *)dst, (int32_t)src);
|
*ret = InterlockedExchange((volatile int32_t *)dst, (int32_t)src);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct __OctaMsvcAtomicExchange<T, 8> {
|
struct __OctaMsvcAtomicExchange<T, 8> {
|
||||||
static inline void exchange(volatile T *dst, T src, T *ret)
|
static inline void exchange(volatile T *dst, T src, T *ret) {
|
||||||
noexcept {
|
|
||||||
*ret = InterlockedExchange64((volatile int64_t *)dst, (int64_t)src);
|
*ret = InterlockedExchange64((volatile int64_t *)dst, (int64_t)src);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -267,8 +255,7 @@ namespace octa {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct __OctaMsvcAtomicCompareExchange<T, 1> {
|
struct __OctaMsvcAtomicCompareExchange<T, 1> {
|
||||||
static inline bool exchange(volatile T *dst, T *exp, T src)
|
static inline bool exchange(volatile T *dst, T *exp, T src) {
|
||||||
noexcept {
|
|
||||||
int8_t prev = _InterlockedCompareExchange8((volatile int8_t *)dst,
|
int8_t prev = _InterlockedCompareExchange8((volatile int8_t *)dst,
|
||||||
(int8_t)src, (int8_t)*exp);
|
(int8_t)src, (int8_t)*exp);
|
||||||
if (prev == (int8_t)*exp) return true;
|
if (prev == (int8_t)*exp) return true;
|
||||||
|
@ -278,8 +265,7 @@ namespace octa {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct __OctaMsvcAtomicCompareExchange<T, 2> {
|
struct __OctaMsvcAtomicCompareExchange<T, 2> {
|
||||||
static inline bool exchange(volatile T *dst, T *exp, T src)
|
static inline bool exchange(volatile T *dst, T *exp, T src) {
|
||||||
noexcept {
|
|
||||||
int16_t prev = _InterlockedCompareExchange16((volatile int16_t *)dst,
|
int16_t prev = _InterlockedCompareExchange16((volatile int16_t *)dst,
|
||||||
(int16_t)src, (int16_t)*exp);
|
(int16_t)src, (int16_t)*exp);
|
||||||
if (prev == (int16_t)*exp) return true;
|
if (prev == (int16_t)*exp) return true;
|
||||||
|
@ -289,8 +275,7 @@ namespace octa {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct __OctaMsvcAtomicCompareExchange<T, 4> {
|
struct __OctaMsvcAtomicCompareExchange<T, 4> {
|
||||||
static inline bool exchange(volatile T *dst, T *exp, T src)
|
static inline bool exchange(volatile T *dst, T *exp, T src) {
|
||||||
noexcept {
|
|
||||||
int32_t prev = _InterlockedCompareExchange((volatile int32_t *)dst,
|
int32_t prev = _InterlockedCompareExchange((volatile int32_t *)dst,
|
||||||
(int32_t)src, (int32_t)*exp);
|
(int32_t)src, (int32_t)*exp);
|
||||||
if (prev == (int32_t)*exp) return true;
|
if (prev == (int32_t)*exp) return true;
|
||||||
|
@ -300,8 +285,7 @@ namespace octa {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct __OctaMsvcAtomicCompareExchange<T, 8> {
|
struct __OctaMsvcAtomicCompareExchange<T, 8> {
|
||||||
static inline bool exchange(volatile T *dst, T *exp, T src)
|
static inline bool exchange(volatile T *dst, T *exp, T src) {
|
||||||
noexcept {
|
|
||||||
int64_t prev = _InterlockedCompareExchange64((volatile int64_t *)dst,
|
int64_t prev = _InterlockedCompareExchange64((volatile int64_t *)dst,
|
||||||
(int64_t)src, (int64_t)*exp);
|
(int64_t)src, (int64_t)*exp);
|
||||||
if (prev == (int64_t)*exp) return true;
|
if (prev == (int64_t)*exp) return true;
|
||||||
|
@ -668,7 +652,7 @@ namespace octa {
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename T> inline T kill_dependency(T v) noexcept {
|
template <typename T> inline T kill_dependency(T v) {
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,93 +660,87 @@ namespace octa {
|
||||||
struct __OctaAtomic {
|
struct __OctaAtomic {
|
||||||
mutable __OctaAtomicBase<T> p_a;
|
mutable __OctaAtomicBase<T> p_a;
|
||||||
|
|
||||||
__OctaAtomic() noexcept = default;
|
__OctaAtomic() = default;
|
||||||
|
|
||||||
constexpr __OctaAtomic(T v) noexcept: p_a(v) {}
|
constexpr __OctaAtomic(T v): p_a(v) {}
|
||||||
|
|
||||||
__OctaAtomic(const __OctaAtomic &) = delete;
|
__OctaAtomic(const __OctaAtomic &) = delete;
|
||||||
|
|
||||||
__OctaAtomic &operator=(const __OctaAtomic &) = delete;
|
__OctaAtomic &operator=(const __OctaAtomic &) = delete;
|
||||||
__OctaAtomic &operator=(const __OctaAtomic &) volatile = delete;
|
__OctaAtomic &operator=(const __OctaAtomic &) volatile = delete;
|
||||||
|
|
||||||
bool is_lock_free() const volatile noexcept {
|
bool is_lock_free() const volatile {
|
||||||
return __octa_atomic_is_lock_free(sizeof(T));
|
return __octa_atomic_is_lock_free(sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_lock_free() const noexcept {
|
bool is_lock_free() const {
|
||||||
return __octa_atomic_is_lock_free(sizeof(T));
|
return __octa_atomic_is_lock_free(sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
void store(T v, MemoryOrder ord = MemoryOrder::seq_cst)
|
void store(T v, MemoryOrder ord = MemoryOrder::seq_cst) volatile {
|
||||||
volatile noexcept {
|
|
||||||
__octa_atomic_store(&p_a, v, ord);
|
__octa_atomic_store(&p_a, v, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
void store(T v, MemoryOrder ord = MemoryOrder::seq_cst) noexcept {
|
void store(T v, MemoryOrder ord = MemoryOrder::seq_cst) {
|
||||||
__octa_atomic_store(&p_a, v, ord);
|
__octa_atomic_store(&p_a, v, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
T load(MemoryOrder ord = MemoryOrder::seq_cst) const volatile noexcept {
|
T load(MemoryOrder ord = MemoryOrder::seq_cst) const volatile {
|
||||||
return __octa_atomic_load(&p_a, ord);
|
return __octa_atomic_load(&p_a, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
T load(MemoryOrder ord = MemoryOrder::seq_cst) const noexcept {
|
T load(MemoryOrder ord = MemoryOrder::seq_cst) const {
|
||||||
return __octa_atomic_load(&p_a, ord);
|
return __octa_atomic_load(&p_a, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
operator T() const volatile noexcept { return load(); }
|
operator T() const volatile { return load(); }
|
||||||
operator T() const noexcept { return load(); }
|
operator T() const { return load(); }
|
||||||
|
|
||||||
T exchange(T v, MemoryOrder ord = MemoryOrder::seq_cst)
|
T exchange(T v, MemoryOrder ord = MemoryOrder::seq_cst) volatile {
|
||||||
volatile noexcept {
|
|
||||||
return __octa_atomic_exchange(&p_a, v, ord);
|
return __octa_atomic_exchange(&p_a, v, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
T exchange(T v, MemoryOrder ord = MemoryOrder::seq_cst) noexcept {
|
T exchange(T v, MemoryOrder ord = MemoryOrder::seq_cst) {
|
||||||
return __octa_atomic_exchange(&p_a, v, ord);
|
return __octa_atomic_exchange(&p_a, v, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compare_exchange_weak(T &e, T v, MemoryOrder s, MemoryOrder f)
|
bool compare_exchange_weak(T &e, T v, MemoryOrder s, MemoryOrder f)
|
||||||
volatile noexcept {
|
volatile {
|
||||||
return __octa_atomic_compare_exchange_weak(&p_a, &e, v, s, f);
|
return __octa_atomic_compare_exchange_weak(&p_a, &e, v, s, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compare_exchange_weak(T& e, T v, MemoryOrder s, MemoryOrder f)
|
bool compare_exchange_weak(T& e, T v, MemoryOrder s, MemoryOrder f) {
|
||||||
noexcept {
|
|
||||||
return __octa_atomic_compare_exchange_weak(&p_a, &e, v, s, f);
|
return __octa_atomic_compare_exchange_weak(&p_a, &e, v, s, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compare_exchange_strong(T& e, T v, MemoryOrder s, MemoryOrder f)
|
bool compare_exchange_strong(T& e, T v, MemoryOrder s, MemoryOrder f)
|
||||||
volatile noexcept {
|
volatile {
|
||||||
return __octa_atomic_compare_exchange_strong(&p_a, &e, v, s, f);
|
return __octa_atomic_compare_exchange_strong(&p_a, &e, v, s, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compare_exchange_strong(T& e, T v, MemoryOrder s, MemoryOrder f)
|
bool compare_exchange_strong(T& e, T v, MemoryOrder s, MemoryOrder f) {
|
||||||
noexcept {
|
|
||||||
return __octa_atomic_compare_exchange_strong(&p_a, &e, v, s, f);
|
return __octa_atomic_compare_exchange_strong(&p_a, &e, v, s, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compare_exchange_weak(T& e, T v, MemoryOrder ord
|
bool compare_exchange_weak(T& e, T v, MemoryOrder ord
|
||||||
= MemoryOrder::seq_cst)
|
= MemoryOrder::seq_cst)
|
||||||
volatile noexcept {
|
volatile {
|
||||||
return __octa_atomic_compare_exchange_weak(&p_a, &e, v, ord, ord);
|
return __octa_atomic_compare_exchange_weak(&p_a, &e, v, ord, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compare_exchange_weak(T& e, T v, MemoryOrder ord
|
bool compare_exchange_weak(T& e, T v, MemoryOrder ord
|
||||||
= MemoryOrder::seq_cst)
|
= MemoryOrder::seq_cst) {
|
||||||
noexcept {
|
|
||||||
return __octa_atomic_compare_exchange_weak(&p_a, &e, v, ord, ord);
|
return __octa_atomic_compare_exchange_weak(&p_a, &e, v, ord, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compare_exchange_strong(T& e, T v, MemoryOrder ord
|
bool compare_exchange_strong(T& e, T v, MemoryOrder ord
|
||||||
= MemoryOrder::seq_cst)
|
= MemoryOrder::seq_cst)
|
||||||
volatile noexcept {
|
volatile {
|
||||||
return __octa_atomic_compare_exchange_strong(&p_a, &e, v, ord, ord);
|
return __octa_atomic_compare_exchange_strong(&p_a, &e, v, ord, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compare_exchange_strong(T& e, T v, MemoryOrder ord
|
bool compare_exchange_strong(T& e, T v, MemoryOrder ord
|
||||||
= MemoryOrder::seq_cst)
|
= MemoryOrder::seq_cst) {
|
||||||
noexcept {
|
|
||||||
return __octa_atomic_compare_exchange_strong(&p_a, &e, v, ord, ord);
|
return __octa_atomic_compare_exchange_strong(&p_a, &e, v, ord, ord);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -771,89 +749,84 @@ namespace octa {
|
||||||
struct __OctaAtomic<T, true>: __OctaAtomic<T, false> {
|
struct __OctaAtomic<T, true>: __OctaAtomic<T, false> {
|
||||||
typedef __OctaAtomic<T, false> base_t;
|
typedef __OctaAtomic<T, false> base_t;
|
||||||
|
|
||||||
__OctaAtomic() noexcept = default;
|
__OctaAtomic() = default;
|
||||||
|
|
||||||
constexpr __OctaAtomic(T v) noexcept: base_t(v) {}
|
constexpr __OctaAtomic(T v): base_t(v) {}
|
||||||
|
|
||||||
T fetch_add(T op, MemoryOrder ord = MemoryOrder::seq_cst)
|
T fetch_add(T op, MemoryOrder ord = MemoryOrder::seq_cst) volatile {
|
||||||
volatile noexcept {
|
|
||||||
return __octa_atomic_fetch_add(&this->p_a, op, ord);
|
return __octa_atomic_fetch_add(&this->p_a, op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
T fetch_add(T op, MemoryOrder ord = MemoryOrder::seq_cst) noexcept {
|
T fetch_add(T op, MemoryOrder ord = MemoryOrder::seq_cst) {
|
||||||
return __octa_atomic_fetch_add(&this->p_a, op, ord);
|
return __octa_atomic_fetch_add(&this->p_a, op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
T fetch_sub(T op, MemoryOrder ord = MemoryOrder::seq_cst)
|
T fetch_sub(T op, MemoryOrder ord = MemoryOrder::seq_cst) volatile {
|
||||||
volatile noexcept {
|
|
||||||
return __octa_atomic_fetch_sub(&this->p_a, op, ord);
|
return __octa_atomic_fetch_sub(&this->p_a, op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
T fetch_sub(T op, MemoryOrder ord = MemoryOrder::seq_cst) noexcept {
|
T fetch_sub(T op, MemoryOrder ord = MemoryOrder::seq_cst) {
|
||||||
return __octa_atomic_fetch_sub(&this->p_a, op, ord);
|
return __octa_atomic_fetch_sub(&this->p_a, op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
T fetch_and(T op, MemoryOrder ord = MemoryOrder::seq_cst)
|
T fetch_and(T op, MemoryOrder ord = MemoryOrder::seq_cst) volatile {
|
||||||
volatile noexcept {
|
|
||||||
return __octa_atomic_fetch_and(&this->p_a, op, ord);
|
return __octa_atomic_fetch_and(&this->p_a, op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
T fetch_and(T op, MemoryOrder ord = MemoryOrder::seq_cst) noexcept {
|
T fetch_and(T op, MemoryOrder ord = MemoryOrder::seq_cst) {
|
||||||
return __octa_atomic_fetch_and(&this->p_a, op, ord);
|
return __octa_atomic_fetch_and(&this->p_a, op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
T fetch_or(T op, MemoryOrder ord = MemoryOrder::seq_cst)
|
T fetch_or(T op, MemoryOrder ord = MemoryOrder::seq_cst) volatile {
|
||||||
volatile noexcept {
|
|
||||||
return __octa_atomic_fetch_or(&this->p_a, op, ord);
|
return __octa_atomic_fetch_or(&this->p_a, op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
T fetch_or(T op, MemoryOrder ord = MemoryOrder::seq_cst) noexcept {
|
T fetch_or(T op, MemoryOrder ord = MemoryOrder::seq_cst) {
|
||||||
return __octa_atomic_fetch_or(&this->p_a, op, ord);
|
return __octa_atomic_fetch_or(&this->p_a, op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
T fetch_xor(T op, MemoryOrder ord = MemoryOrder::seq_cst)
|
T fetch_xor(T op, MemoryOrder ord = MemoryOrder::seq_cst) volatile {
|
||||||
volatile noexcept {
|
|
||||||
return __octa_atomic_fetch_xor(&this->p_a, op, ord);
|
return __octa_atomic_fetch_xor(&this->p_a, op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
T fetch_xor(T op, MemoryOrder ord = MemoryOrder::seq_cst) noexcept {
|
T fetch_xor(T op, MemoryOrder ord = MemoryOrder::seq_cst) {
|
||||||
return __octa_atomic_fetch_xor(&this->p_a, op, ord);
|
return __octa_atomic_fetch_xor(&this->p_a, op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
T operator++(int) volatile noexcept { return fetch_add(T(1)); }
|
T operator++(int) volatile { return fetch_add(T(1)); }
|
||||||
T operator++(int) noexcept { return fetch_add(T(1)); }
|
T operator++(int) { return fetch_add(T(1)); }
|
||||||
T operator--(int) volatile noexcept { return fetch_sub(T(1)); }
|
T operator--(int) volatile { return fetch_sub(T(1)); }
|
||||||
T operator--(int) noexcept { return fetch_sub(T(1)); }
|
T operator--(int) { return fetch_sub(T(1)); }
|
||||||
T operator++( ) volatile noexcept { return fetch_add(T(1)) + T(1); }
|
T operator++( ) volatile { return fetch_add(T(1)) + T(1); }
|
||||||
T operator++( ) noexcept { return fetch_add(T(1)) + T(1); }
|
T operator++( ) { return fetch_add(T(1)) + T(1); }
|
||||||
T operator--( ) volatile noexcept { return fetch_sub(T(1)) - T(1); }
|
T operator--( ) volatile { return fetch_sub(T(1)) - T(1); }
|
||||||
T operator--( ) noexcept { return fetch_sub(T(1)) - T(1); }
|
T operator--( ) { return fetch_sub(T(1)) - T(1); }
|
||||||
|
|
||||||
T operator+=(T op) volatile noexcept { return fetch_add(op) + op; }
|
T operator+=(T op) volatile { return fetch_add(op) + op; }
|
||||||
T operator+=(T op) noexcept { return fetch_add(op) + op; }
|
T operator+=(T op) { return fetch_add(op) + op; }
|
||||||
T operator-=(T op) volatile noexcept { return fetch_sub(op) - op; }
|
T operator-=(T op) volatile { return fetch_sub(op) - op; }
|
||||||
T operator-=(T op) noexcept { return fetch_sub(op) - op; }
|
T operator-=(T op) { return fetch_sub(op) - op; }
|
||||||
T operator&=(T op) volatile noexcept { return fetch_and(op) & op; }
|
T operator&=(T op) volatile { return fetch_and(op) & op; }
|
||||||
T operator&=(T op) noexcept { return fetch_and(op) & op; }
|
T operator&=(T op) { return fetch_and(op) & op; }
|
||||||
T operator|=(T op) volatile noexcept { return fetch_or (op) | op; }
|
T operator|=(T op) volatile { return fetch_or (op) | op; }
|
||||||
T operator|=(T op) noexcept { return fetch_or (op) | op; }
|
T operator|=(T op) { return fetch_or (op) | op; }
|
||||||
T operator^=(T op) volatile noexcept { return fetch_xor(op) ^ op; }
|
T operator^=(T op) volatile { return fetch_xor(op) ^ op; }
|
||||||
T operator^=(T op) noexcept { return fetch_xor(op) ^ op; }
|
T operator^=(T op) { return fetch_xor(op) ^ op; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Atomic: __OctaAtomic<T> {
|
struct Atomic: __OctaAtomic<T> {
|
||||||
typedef __OctaAtomic<T> base_t;
|
typedef __OctaAtomic<T> base_t;
|
||||||
|
|
||||||
Atomic() noexcept = default;
|
Atomic() = default;
|
||||||
|
|
||||||
constexpr Atomic(T v) noexcept: base_t(v) {}
|
constexpr Atomic(T v): base_t(v) {}
|
||||||
|
|
||||||
T operator=(T v) volatile noexcept {
|
T operator=(T v) volatile {
|
||||||
base_t::store(v); return v;
|
base_t::store(v); return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
T operator=(T v) noexcept {
|
T operator=(T v) {
|
||||||
base_t::store(v); return v;
|
base_t::store(v); return v;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -862,163 +835,152 @@ namespace octa {
|
||||||
struct Atomic<T *>: __OctaAtomic<T *> {
|
struct Atomic<T *>: __OctaAtomic<T *> {
|
||||||
typedef __OctaAtomic<T *> base_t;
|
typedef __OctaAtomic<T *> base_t;
|
||||||
|
|
||||||
Atomic() noexcept = default;
|
Atomic() = default;
|
||||||
|
|
||||||
constexpr Atomic(T *v) noexcept: base_t(v) {}
|
constexpr Atomic(T *v): base_t(v) {}
|
||||||
|
|
||||||
T *operator=(T *v) volatile noexcept {
|
T *operator=(T *v) volatile {
|
||||||
base_t::store(v); return v;
|
base_t::store(v); return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
T *operator=(T *v) noexcept {
|
T *operator=(T *v) {
|
||||||
base_t::store(v); return v;
|
base_t::store(v); return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
T *fetch_add(ptrdiff_t op, MemoryOrder ord = MemoryOrder::seq_cst)
|
T *fetch_add(ptrdiff_t op, MemoryOrder ord = MemoryOrder::seq_cst)
|
||||||
volatile noexcept {
|
volatile {
|
||||||
return __octa_atomic_fetch_add(&this->p_a, op, ord);
|
return __octa_atomic_fetch_add(&this->p_a, op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
T *fetch_add(ptrdiff_t op, MemoryOrder ord = MemoryOrder::seq_cst)
|
T *fetch_add(ptrdiff_t op, MemoryOrder ord = MemoryOrder::seq_cst) {
|
||||||
noexcept {
|
|
||||||
return __octa_atomic_fetch_add(&this->p_a, op, ord);
|
return __octa_atomic_fetch_add(&this->p_a, op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
T *fetch_sub(ptrdiff_t op, MemoryOrder ord = MemoryOrder::seq_cst)
|
T *fetch_sub(ptrdiff_t op, MemoryOrder ord = MemoryOrder::seq_cst)
|
||||||
volatile noexcept {
|
volatile {
|
||||||
return __octa_atomic_fetch_sub(&this->p_a, op, ord);
|
return __octa_atomic_fetch_sub(&this->p_a, op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
T *fetch_sub(ptrdiff_t op, MemoryOrder ord = MemoryOrder::seq_cst)
|
T *fetch_sub(ptrdiff_t op, MemoryOrder ord = MemoryOrder::seq_cst) {
|
||||||
noexcept {
|
|
||||||
return __octa_atomic_fetch_sub(&this->p_a, op, ord);
|
return __octa_atomic_fetch_sub(&this->p_a, op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
T *operator++(int) volatile noexcept { return fetch_add(1); }
|
T *operator++(int) volatile { return fetch_add(1); }
|
||||||
T *operator++(int) noexcept { return fetch_add(1); }
|
T *operator++(int) { return fetch_add(1); }
|
||||||
T *operator--(int) volatile noexcept { return fetch_sub(1); }
|
T *operator--(int) volatile { return fetch_sub(1); }
|
||||||
T *operator--(int) noexcept { return fetch_sub(1); }
|
T *operator--(int) { return fetch_sub(1); }
|
||||||
T *operator++( ) volatile noexcept { return fetch_add(1) + 1; }
|
T *operator++( ) volatile { return fetch_add(1) + 1; }
|
||||||
T *operator++( ) noexcept { return fetch_add(1) + 1; }
|
T *operator++( ) { return fetch_add(1) + 1; }
|
||||||
T *operator--( ) volatile noexcept { return fetch_sub(1) - 1; }
|
T *operator--( ) volatile { return fetch_sub(1) - 1; }
|
||||||
T *operator--( ) noexcept { return fetch_sub(1) - 1; }
|
T *operator--( ) { return fetch_sub(1) - 1; }
|
||||||
|
|
||||||
T *operator+=(ptrdiff_t op) volatile noexcept { return fetch_add(op) + op; }
|
T *operator+=(ptrdiff_t op) volatile { return fetch_add(op) + op; }
|
||||||
T *operator+=(ptrdiff_t op) noexcept { return fetch_add(op) + op; }
|
T *operator+=(ptrdiff_t op) { return fetch_add(op) + op; }
|
||||||
T *operator-=(ptrdiff_t op) volatile noexcept { return fetch_sub(op) - op; }
|
T *operator-=(ptrdiff_t op) volatile { return fetch_sub(op) - op; }
|
||||||
T *operator-=(ptrdiff_t op) noexcept { return fetch_sub(op) - op; }
|
T *operator-=(ptrdiff_t op) { return fetch_sub(op) - op; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline bool atomic_is_lock_free(const volatile Atomic<T> *a) noexcept {
|
inline bool atomic_is_lock_free(const volatile Atomic<T> *a) {
|
||||||
return a->is_lock_free();
|
return a->is_lock_free();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline bool atomic_is_lock_free(const Atomic<T> *a) noexcept {
|
inline bool atomic_is_lock_free(const Atomic<T> *a) {
|
||||||
return a->is_lock_free();
|
return a->is_lock_free();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline void atomic_init(volatile Atomic<T> *a, T v) noexcept {
|
inline void atomic_init(volatile Atomic<T> *a, T v) {
|
||||||
__octa_atomic_init(&a->p_a, v);
|
__octa_atomic_init(&a->p_a, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline void atomic_init(Atomic<T> *a, T v) noexcept {
|
inline void atomic_init(Atomic<T> *a, T v) {
|
||||||
__octa_atomic_init(&a->p_a, v);
|
__octa_atomic_init(&a->p_a, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void atomic_store(volatile Atomic<T> *a, T v) noexcept {
|
inline void atomic_store(volatile Atomic<T> *a, T v) {
|
||||||
a->store(v);
|
a->store(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void atomic_store(Atomic<T> *a, T v) noexcept {
|
inline void atomic_store(Atomic<T> *a, T v) {
|
||||||
a->store(v);
|
a->store(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void atomic_store_explicit(volatile Atomic<T> *a, T v,
|
inline void atomic_store_explicit(volatile Atomic<T> *a, T v,
|
||||||
MemoryOrder ord)
|
MemoryOrder ord) {
|
||||||
noexcept {
|
|
||||||
a->store(v, ord);
|
a->store(v, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void atomic_store_explicit(Atomic<T> *a, T v, MemoryOrder ord)
|
inline void atomic_store_explicit(Atomic<T> *a, T v, MemoryOrder ord) {
|
||||||
noexcept {
|
|
||||||
a->store(v, ord);
|
a->store(v, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T atomic_load(const volatile Atomic<T> *a) noexcept {
|
inline T atomic_load(const volatile Atomic<T> *a) {
|
||||||
return a->load();
|
return a->load();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T atomic_load(const Atomic<T> *a) noexcept {
|
inline T atomic_load(const Atomic<T> *a) {
|
||||||
return a->load();
|
return a->load();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T atomic_load_explicit(const volatile Atomic<T> *a,
|
inline T atomic_load_explicit(const volatile Atomic<T> *a,
|
||||||
MemoryOrder ord)
|
MemoryOrder ord) {
|
||||||
noexcept {
|
|
||||||
return a->load(ord);
|
return a->load(ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T atomic_load_explicit(const Atomic<T> *a, MemoryOrder ord)
|
inline T atomic_load_explicit(const Atomic<T> *a, MemoryOrder ord) {
|
||||||
noexcept {
|
|
||||||
return a->load(ord);
|
return a->load(ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T atomic_exchange(volatile Atomic<T> *a, T v) noexcept {
|
inline T atomic_exchange(volatile Atomic<T> *a, T v) {
|
||||||
return a->exchange(v);
|
return a->exchange(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T atomic_exchange(Atomic<T> *a, T v) noexcept {
|
inline T atomic_exchange(Atomic<T> *a, T v) {
|
||||||
return a->exchange(v);
|
return a->exchange(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T atomic_exchange_explicit(volatile Atomic<T> *a, T v,
|
inline T atomic_exchange_explicit(volatile Atomic<T> *a, T v,
|
||||||
MemoryOrder ord)
|
MemoryOrder ord) {
|
||||||
noexcept {
|
|
||||||
return a->exchange(v, ord);
|
return a->exchange(v, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T atomic_exchange_explicit(Atomic<T> *a, T v, MemoryOrder ord)
|
inline T atomic_exchange_explicit(Atomic<T> *a, T v, MemoryOrder ord) {
|
||||||
noexcept {
|
|
||||||
return a->exchange(v, ord);
|
return a->exchange(v, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool atomic_compare_exchange_weak(volatile Atomic<T> *a, T *e, T v)
|
inline bool atomic_compare_exchange_weak(volatile Atomic<T> *a, T *e, T v) {
|
||||||
noexcept {
|
|
||||||
return a->compare_exchange_weak(*e, v);
|
return a->compare_exchange_weak(*e, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool atomic_compare_exchange_weak(Atomic<T> *a, T *e, T v) noexcept {
|
inline bool atomic_compare_exchange_weak(Atomic<T> *a, T *e, T v) {
|
||||||
return a->compare_exchange_weak(*e, v);
|
return a->compare_exchange_weak(*e, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool atomic_compare_exchange_strong(volatile Atomic<T> *a, T *e, T v)
|
inline bool atomic_compare_exchange_strong(volatile Atomic<T> *a, T *e, T v) {
|
||||||
noexcept {
|
|
||||||
return a->compare_exchange_strong(*e, v);
|
return a->compare_exchange_strong(*e, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool atomic_compare_exchange_strong(Atomic<T> *a, T *e, T v)
|
inline bool atomic_compare_exchange_strong(Atomic<T> *a, T *e, T v) {
|
||||||
noexcept {
|
|
||||||
return a->compare_exchange_strong(*e, v);
|
return a->compare_exchange_strong(*e, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1026,16 +988,14 @@ namespace octa {
|
||||||
inline bool atomic_compare_exchange_weak_explicit(volatile Atomic<T> *a,
|
inline bool atomic_compare_exchange_weak_explicit(volatile Atomic<T> *a,
|
||||||
T *e, T v,
|
T *e, T v,
|
||||||
MemoryOrder s,
|
MemoryOrder s,
|
||||||
MemoryOrder f)
|
MemoryOrder f) {
|
||||||
noexcept {
|
|
||||||
return a->compare_exchange_weak(*e, v, s, f);
|
return a->compare_exchange_weak(*e, v, s, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool atomic_compare_exchange_weak_explicit(Atomic<T> *a, T *e, T v,
|
inline bool atomic_compare_exchange_weak_explicit(Atomic<T> *a, T *e, T v,
|
||||||
MemoryOrder s,
|
MemoryOrder s,
|
||||||
MemoryOrder f)
|
MemoryOrder f) {
|
||||||
noexcept {
|
|
||||||
return a->compare_exchange_weak(*e, v, s, f);
|
return a->compare_exchange_weak(*e, v, s, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1043,267 +1003,250 @@ namespace octa {
|
||||||
inline bool atomic_compare_exchange_strong_explicit(volatile Atomic<T> *a,
|
inline bool atomic_compare_exchange_strong_explicit(volatile Atomic<T> *a,
|
||||||
T *e, T v,
|
T *e, T v,
|
||||||
MemoryOrder s,
|
MemoryOrder s,
|
||||||
MemoryOrder f)
|
MemoryOrder f) {
|
||||||
noexcept {
|
|
||||||
return a->compare_exchange_strong(*e, v, s, f);
|
return a->compare_exchange_strong(*e, v, s, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool atomic_compare_exchange_strong_explicit(Atomic<T> *a, T *e, T v,
|
inline bool atomic_compare_exchange_strong_explicit(Atomic<T> *a, T *e, T v,
|
||||||
MemoryOrder s,
|
MemoryOrder s,
|
||||||
MemoryOrder f)
|
MemoryOrder f) {
|
||||||
noexcept {
|
|
||||||
return a->compare_exchange_strong(*e, v, s, f);
|
return a->compare_exchange_strong(*e, v, s, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_add(volatile Atomic<T> *a, T op) noexcept {
|
atomic_fetch_add(volatile Atomic<T> *a, T op) {
|
||||||
return a->fetch_add(op);
|
return a->fetch_add(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_add(Atomic<T> *a, T op) noexcept {
|
atomic_fetch_add(Atomic<T> *a, T op) {
|
||||||
return a->fetch_add(op);
|
return a->fetch_add(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T *atomic_fetch_add(volatile Atomic<T *> *a, ptrdiff_t op) noexcept {
|
inline T *atomic_fetch_add(volatile Atomic<T *> *a, ptrdiff_t op) {
|
||||||
return a->fetch_add(op);
|
return a->fetch_add(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T *atomic_fetch_add(Atomic<T *> *a, ptrdiff_t op) noexcept {
|
inline T *atomic_fetch_add(Atomic<T *> *a, ptrdiff_t op) {
|
||||||
return a->fetch_add(op);
|
return a->fetch_add(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_add_explicit(volatile Atomic<T> *a, T op, MemoryOrder ord)
|
atomic_fetch_add_explicit(volatile Atomic<T> *a, T op, MemoryOrder ord) {
|
||||||
noexcept {
|
|
||||||
return a->fetch_add(op, ord);
|
return a->fetch_add(op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_add_explicit(Atomic<T> *a, T op, MemoryOrder ord) noexcept {
|
atomic_fetch_add_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
||||||
return a->fetch_add(op, ord);
|
return a->fetch_add(op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T *atomic_fetch_add_explicit(volatile Atomic<T *> *a, ptrdiff_t op,
|
inline T *atomic_fetch_add_explicit(volatile Atomic<T *> *a, ptrdiff_t op,
|
||||||
MemoryOrder ord)
|
MemoryOrder ord) {
|
||||||
noexcept {
|
|
||||||
return a->fetch_add(op, ord);
|
return a->fetch_add(op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T *atomic_fetch_add_explicit(Atomic<T *> *a, ptrdiff_t op,
|
inline T *atomic_fetch_add_explicit(Atomic<T *> *a, ptrdiff_t op,
|
||||||
MemoryOrder ord)
|
MemoryOrder ord) {
|
||||||
noexcept {
|
|
||||||
return a->fetch_add(op, ord);
|
return a->fetch_add(op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_sub(volatile Atomic<T> *a, T op) noexcept {
|
atomic_fetch_sub(volatile Atomic<T> *a, T op) {
|
||||||
return a->fetch_sub(op);
|
return a->fetch_sub(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_sub(Atomic<T> *a, T op) noexcept {
|
atomic_fetch_sub(Atomic<T> *a, T op) {
|
||||||
return a->fetch_sub(op);
|
return a->fetch_sub(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T *atomic_fetch_sub(volatile Atomic<T *> *a, ptrdiff_t op) noexcept {
|
inline T *atomic_fetch_sub(volatile Atomic<T *> *a, ptrdiff_t op) {
|
||||||
return a->fetch_sub(op);
|
return a->fetch_sub(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T *atomic_fetch_sub(Atomic<T *> *a, ptrdiff_t op) noexcept {
|
inline T *atomic_fetch_sub(Atomic<T *> *a, ptrdiff_t op) {
|
||||||
return a->fetch_sub(op);
|
return a->fetch_sub(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_sub_explicit(volatile Atomic<T> *a, T op, MemoryOrder ord)
|
atomic_fetch_sub_explicit(volatile Atomic<T> *a, T op, MemoryOrder ord) {
|
||||||
noexcept {
|
|
||||||
return a->fetch_sub(op, ord);
|
return a->fetch_sub(op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_sub_explicit(Atomic<T> *a, T op, MemoryOrder ord) noexcept {
|
atomic_fetch_sub_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
||||||
return a->fetch_sub(op, ord);
|
return a->fetch_sub(op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T *atomic_fetch_sub_explicit(volatile Atomic<T *> *a, ptrdiff_t op,
|
inline T *atomic_fetch_sub_explicit(volatile Atomic<T *> *a, ptrdiff_t op,
|
||||||
MemoryOrder ord)
|
MemoryOrder ord) {
|
||||||
noexcept {
|
|
||||||
return a->fetch_sub(op, ord);
|
return a->fetch_sub(op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T *atomic_fetch_sub_explicit(Atomic<T *> *a, ptrdiff_t op,
|
inline T *atomic_fetch_sub_explicit(Atomic<T *> *a, ptrdiff_t op,
|
||||||
MemoryOrder ord)
|
MemoryOrder ord) {
|
||||||
noexcept {
|
|
||||||
return a->fetch_sub(op, ord);
|
return a->fetch_sub(op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_and(volatile Atomic<T> *a, T op) noexcept {
|
atomic_fetch_and(volatile Atomic<T> *a, T op) {
|
||||||
return a->fetch_and(op);
|
return a->fetch_and(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_and(Atomic<T> *a, T op) noexcept {
|
atomic_fetch_and(Atomic<T> *a, T op) {
|
||||||
return a->fetch_and(op);
|
return a->fetch_and(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_and_explicit(volatile Atomic<T> *a, T op, MemoryOrder ord)
|
atomic_fetch_and_explicit(volatile Atomic<T> *a, T op, MemoryOrder ord) {
|
||||||
noexcept {
|
|
||||||
return a->fetch_and(op, ord);
|
return a->fetch_and(op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_and_explicit(Atomic<T> *a, T op, MemoryOrder ord) noexcept {
|
atomic_fetch_and_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
||||||
return a->fetch_and(op, ord);
|
return a->fetch_and(op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_or(volatile Atomic<T> *a, T op) noexcept {
|
atomic_fetch_or(volatile Atomic<T> *a, T op) {
|
||||||
return a->fetch_or(op);
|
return a->fetch_or(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_or(Atomic<T> *a, T op) noexcept {
|
atomic_fetch_or(Atomic<T> *a, T op) {
|
||||||
return a->fetch_or(op);
|
return a->fetch_or(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_or_explicit(volatile Atomic<T> *a, T op, MemoryOrder ord)
|
atomic_fetch_or_explicit(volatile Atomic<T> *a, T op, MemoryOrder ord) {
|
||||||
noexcept {
|
|
||||||
return a->fetch_or(op, ord);
|
return a->fetch_or(op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_or_explicit(Atomic<T> *a, T op, MemoryOrder ord) noexcept {
|
atomic_fetch_or_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
||||||
return a->fetch_or(op, ord);
|
return a->fetch_or(op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_xor(volatile Atomic<T> *a, T op) noexcept {
|
atomic_fetch_xor(volatile Atomic<T> *a, T op) {
|
||||||
return a->fetch_xor(op);
|
return a->fetch_xor(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_xor(Atomic<T> *a, T op) noexcept {
|
atomic_fetch_xor(Atomic<T> *a, T op) {
|
||||||
return a->fetch_xor(op);
|
return a->fetch_xor(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_xor_explicit(volatile Atomic<T> *a, T op, MemoryOrder ord)
|
atomic_fetch_xor_explicit(volatile Atomic<T> *a, T op, MemoryOrder ord) {
|
||||||
noexcept {
|
|
||||||
return a->fetch_xor(op, ord);
|
return a->fetch_xor(op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_xor_explicit(Atomic<T> *a, T op, MemoryOrder ord) noexcept {
|
atomic_fetch_xor_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
||||||
return a->fetch_xor(op, ord);
|
return a->fetch_xor(op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AtomicFlag {
|
struct AtomicFlag {
|
||||||
__OctaAtomicBase<bool> p_a;
|
__OctaAtomicBase<bool> p_a;
|
||||||
|
|
||||||
AtomicFlag() noexcept = default;
|
AtomicFlag() = default;
|
||||||
|
|
||||||
AtomicFlag(bool b) noexcept: p_a(b) {}
|
AtomicFlag(bool b): p_a(b) {}
|
||||||
|
|
||||||
AtomicFlag(const AtomicFlag &) = delete;
|
AtomicFlag(const AtomicFlag &) = delete;
|
||||||
|
|
||||||
AtomicFlag &operator=(const AtomicFlag &) = delete;
|
AtomicFlag &operator=(const AtomicFlag &) = delete;
|
||||||
AtomicFlag &operator=(const AtomicFlag &) volatile = delete;
|
AtomicFlag &operator=(const AtomicFlag &) volatile = delete;
|
||||||
|
|
||||||
bool test_and_set(MemoryOrder ord = MemoryOrder::seq_cst)
|
bool test_and_set(MemoryOrder ord = MemoryOrder::seq_cst) volatile {
|
||||||
volatile noexcept {
|
|
||||||
return __octa_atomic_exchange(&p_a, true, ord);
|
return __octa_atomic_exchange(&p_a, true, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_and_set(MemoryOrder ord = MemoryOrder::seq_cst) noexcept {
|
bool test_and_set(MemoryOrder ord = MemoryOrder::seq_cst) {
|
||||||
return __octa_atomic_exchange(&p_a, true, ord);
|
return __octa_atomic_exchange(&p_a, true, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear(MemoryOrder ord = MemoryOrder::seq_cst) volatile noexcept {
|
void clear(MemoryOrder ord = MemoryOrder::seq_cst) volatile {
|
||||||
__octa_atomic_store(&p_a, false, ord);
|
__octa_atomic_store(&p_a, false, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear(MemoryOrder ord = MemoryOrder::seq_cst) noexcept {
|
void clear(MemoryOrder ord = MemoryOrder::seq_cst) {
|
||||||
__octa_atomic_store(&p_a, false, ord);
|
__octa_atomic_store(&p_a, false, ord);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool atomic_flag_test_and_set(volatile AtomicFlag *a)
|
inline bool atomic_flag_test_and_set(volatile AtomicFlag *a) {
|
||||||
noexcept {
|
|
||||||
return a->test_and_set();
|
return a->test_and_set();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool atomic_flag_test_and_set(AtomicFlag *a) noexcept {
|
inline bool atomic_flag_test_and_set(AtomicFlag *a) {
|
||||||
return a->test_and_set();
|
return a->test_and_set();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool atomic_flag_test_and_set_explicit(volatile AtomicFlag *a,
|
inline bool atomic_flag_test_and_set_explicit(volatile AtomicFlag *a,
|
||||||
MemoryOrder ord)
|
MemoryOrder ord) {
|
||||||
noexcept {
|
|
||||||
return a->test_and_set(ord);
|
return a->test_and_set(ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool atomic_flag_test_and_set_explicit(AtomicFlag *a,
|
inline bool atomic_flag_test_and_set_explicit(AtomicFlag *a,
|
||||||
MemoryOrder ord)
|
MemoryOrder ord) {
|
||||||
noexcept {
|
|
||||||
return a->test_and_set(ord);
|
return a->test_and_set(ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void atomic_flag_clear(volatile AtomicFlag *a) noexcept {
|
inline void atomic_flag_clear(volatile AtomicFlag *a) {
|
||||||
a->clear();
|
a->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void atomic_flag_clear(AtomicFlag *a) noexcept {
|
inline void atomic_flag_clear(AtomicFlag *a) {
|
||||||
a->clear();
|
a->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void atomic_flag_clear_explicit(volatile AtomicFlag *a,
|
inline void atomic_flag_clear_explicit(volatile AtomicFlag *a,
|
||||||
MemoryOrder ord)
|
MemoryOrder ord) {
|
||||||
noexcept {
|
|
||||||
a->clear(ord);
|
a->clear(ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void atomic_flag_clear_explicit(AtomicFlag *a, MemoryOrder ord)
|
inline void atomic_flag_clear_explicit(AtomicFlag *a, MemoryOrder ord) {
|
||||||
noexcept {
|
|
||||||
a->clear(ord);
|
a->clear(ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void atomic_thread_fence(MemoryOrder ord) noexcept {
|
inline void atomic_thread_fence(MemoryOrder ord) {
|
||||||
__octa_atomic_thread_fence(ord);
|
__octa_atomic_thread_fence(ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void atomic_signal_fence(MemoryOrder ord) noexcept {
|
inline void atomic_signal_fence(MemoryOrder ord) {
|
||||||
__octa_atomic_signal_fence(ord);
|
__octa_atomic_signal_fence(ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,7 @@ namespace octa {
|
||||||
|
|
||||||
#define __OCTA_DEFINE_BINARY_OP(name, op, rettype) \
|
#define __OCTA_DEFINE_BINARY_OP(name, op, rettype) \
|
||||||
template<typename T> struct name { \
|
template<typename T> struct name { \
|
||||||
bool operator()(const T &x, const T &y) const noexcept( \
|
bool operator()(const T &x, const T &y) const { return x op y; } \
|
||||||
noexcept(x op y) \
|
|
||||||
) { return x op y; } \
|
|
||||||
typedef T FirstArgType; \
|
typedef T FirstArgType; \
|
||||||
typedef T SecondArgType; \
|
typedef T SecondArgType; \
|
||||||
typedef rettype ResultType; \
|
typedef rettype ResultType; \
|
||||||
|
@ -44,13 +42,13 @@ namespace octa {
|
||||||
#undef __OCTA_DEFINE_BINARY_OP
|
#undef __OCTA_DEFINE_BINARY_OP
|
||||||
|
|
||||||
template<typename T> struct LogicalNot {
|
template<typename T> struct LogicalNot {
|
||||||
bool operator()(const T &x) const noexcept(noexcept(!x)) { return !x; }
|
bool operator()(const T &x) const { return !x; }
|
||||||
typedef T ArgType;
|
typedef T ArgType;
|
||||||
typedef bool ResultType;
|
typedef bool ResultType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T> struct Negate {
|
template<typename T> struct Negate {
|
||||||
bool operator()(const T &x) const noexcept(noexcept(-x)) { return -x; }
|
bool operator()(const T &x) const { return -x; }
|
||||||
typedef T ArgType;
|
typedef T ArgType;
|
||||||
typedef T ResultType;
|
typedef T ResultType;
|
||||||
};
|
};
|
||||||
|
@ -60,14 +58,10 @@ namespace octa {
|
||||||
typedef typename T::SecondArgType SecondArgType;
|
typedef typename T::SecondArgType SecondArgType;
|
||||||
typedef bool ResultType;
|
typedef bool ResultType;
|
||||||
|
|
||||||
explicit BinaryNegate(const T &f) noexcept(
|
explicit BinaryNegate(const T &f): p_fn(f) {}
|
||||||
IsNothrowCopyConstructible<T>::value
|
|
||||||
): p_fn(f) {}
|
|
||||||
|
|
||||||
bool operator()(const FirstArgType &x,
|
bool operator()(const FirstArgType &x,
|
||||||
const SecondArgType &y) noexcept(
|
const SecondArgType &y) {
|
||||||
noexcept(p_fn(x, y))
|
|
||||||
) {
|
|
||||||
return !p_fn(x, y);
|
return !p_fn(x, y);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
@ -78,25 +72,19 @@ namespace octa {
|
||||||
typedef typename T::ArgType ArgType;
|
typedef typename T::ArgType ArgType;
|
||||||
typedef bool ResultType;
|
typedef bool ResultType;
|
||||||
|
|
||||||
explicit UnaryNegate(const T &f) noexcept(
|
explicit UnaryNegate(const T &f): p_fn(f) {}
|
||||||
IsNothrowCopyConstructible<T>::value
|
bool operator()(const ArgType &x) {
|
||||||
): p_fn(f) {}
|
|
||||||
bool operator()(const ArgType &x) noexcept(noexcept(p_fn(x))) {
|
|
||||||
return !p_fn(x);
|
return !p_fn(x);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
T p_fn;
|
T p_fn;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T> UnaryNegate<T> not1(const T &fn) noexcept(
|
template<typename T> UnaryNegate<T> not1(const T &fn) {
|
||||||
IsNothrowCopyConstructible<UnaryNegate<T>>::value
|
|
||||||
) {
|
|
||||||
return UnaryNegate<T>(fn);
|
return UnaryNegate<T>(fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> BinaryNegate<T> not2(const T &fn) noexcept(
|
template<typename T> BinaryNegate<T> not2(const T &fn) {
|
||||||
IsNothrowCopyConstructible<BinaryNegate<T>>::value
|
|
||||||
) {
|
|
||||||
return BinaryNegate<T>(fn);
|
return BinaryNegate<T>(fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +96,7 @@ namespace octa {
|
||||||
typedef T ArgType;
|
typedef T ArgType;
|
||||||
typedef size_t ResultType;
|
typedef size_t ResultType;
|
||||||
|
|
||||||
size_t operator()(T v) const noexcept {
|
size_t operator()(T v) const {
|
||||||
return (size_t)v;
|
return (size_t)v;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -145,7 +133,7 @@ namespace octa {
|
||||||
typedef T ArgType;
|
typedef T ArgType;
|
||||||
typedef size_t ResultType;
|
typedef size_t ResultType;
|
||||||
|
|
||||||
size_t operator()(T v) const noexcept {
|
size_t operator()(T v) const {
|
||||||
union { T v; size_t h; } u;
|
union { T v; size_t h; } u;
|
||||||
u.h = 0;
|
u.h = 0;
|
||||||
u.v = v;
|
u.v = v;
|
||||||
|
@ -157,7 +145,7 @@ namespace octa {
|
||||||
typedef T ArgType;
|
typedef T ArgType;
|
||||||
typedef size_t ResultType;
|
typedef size_t ResultType;
|
||||||
|
|
||||||
size_t operator()(T v) const noexcept {
|
size_t operator()(T v) const {
|
||||||
union { T v; size_t h; } u;
|
union { T v; size_t h; } u;
|
||||||
u.v = v;
|
u.v = v;
|
||||||
return u.h;
|
return u.h;
|
||||||
|
@ -168,7 +156,7 @@ namespace octa {
|
||||||
typedef T ArgType;
|
typedef T ArgType;
|
||||||
typedef size_t ResultType;
|
typedef size_t ResultType;
|
||||||
|
|
||||||
size_t operator()(T v) const noexcept {
|
size_t operator()(T v) const {
|
||||||
union { T v; struct { size_t h1, h2; }; } u;
|
union { T v; struct { size_t h1, h2; }; } u;
|
||||||
u.v = v;
|
u.v = v;
|
||||||
return __octa_mem_hash((const void *)&u, sizeof(u));
|
return __octa_mem_hash((const void *)&u, sizeof(u));
|
||||||
|
@ -179,7 +167,7 @@ namespace octa {
|
||||||
typedef T ArgType;
|
typedef T ArgType;
|
||||||
typedef size_t ResultType;
|
typedef size_t ResultType;
|
||||||
|
|
||||||
size_t operator()(T v) const noexcept {
|
size_t operator()(T v) const {
|
||||||
union { T v; struct { size_t h1, h2, h3; }; } u;
|
union { T v; struct { size_t h1, h2, h3; }; } u;
|
||||||
u.v = v;
|
u.v = v;
|
||||||
return __octa_mem_hash((const void *)&u, sizeof(u));
|
return __octa_mem_hash((const void *)&u, sizeof(u));
|
||||||
|
@ -190,7 +178,7 @@ namespace octa {
|
||||||
typedef T ArgType;
|
typedef T ArgType;
|
||||||
typedef size_t ResultType;
|
typedef size_t ResultType;
|
||||||
|
|
||||||
size_t operator()(T v) const noexcept {
|
size_t operator()(T v) const {
|
||||||
union { T v; struct { size_t h1, h2, h3, h4; }; } u;
|
union { T v; struct { size_t h1, h2, h3, h4; }; } u;
|
||||||
u.v = v;
|
u.v = v;
|
||||||
return __octa_mem_hash((const void *)&u, sizeof(u));
|
return __octa_mem_hash((const void *)&u, sizeof(u));
|
||||||
|
@ -201,21 +189,21 @@ namespace octa {
|
||||||
template<> struct Hash<ullong>: __OctaScalarHash<ullong> {};
|
template<> struct Hash<ullong>: __OctaScalarHash<ullong> {};
|
||||||
|
|
||||||
template<> struct Hash<float>: __OctaScalarHash<float> {
|
template<> struct Hash<float>: __OctaScalarHash<float> {
|
||||||
size_t operator()(float v) const noexcept {
|
size_t operator()(float v) const {
|
||||||
if (v == 0) return 0;
|
if (v == 0) return 0;
|
||||||
return __OctaScalarHash<float>::operator()(v);
|
return __OctaScalarHash<float>::operator()(v);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<> struct Hash<double>: __OctaScalarHash<double> {
|
template<> struct Hash<double>: __OctaScalarHash<double> {
|
||||||
size_t operator()(double v) const noexcept {
|
size_t operator()(double v) const {
|
||||||
if (v == 0) return 0;
|
if (v == 0) return 0;
|
||||||
return __OctaScalarHash<double>::operator()(v);
|
return __OctaScalarHash<double>::operator()(v);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<> struct Hash<ldouble>: __OctaScalarHash<ldouble> {
|
template<> struct Hash<ldouble>: __OctaScalarHash<ldouble> {
|
||||||
size_t operator()(ldouble v) const noexcept {
|
size_t operator()(ldouble v) const {
|
||||||
if (v == 0) return 0;
|
if (v == 0) return 0;
|
||||||
#ifdef __i386__
|
#ifdef __i386__
|
||||||
union { ldouble v; struct { size_t h1, h2, h3, h4; }; } u;
|
union { ldouble v; struct { size_t h1, h2, h3, h4; }; } u;
|
||||||
|
@ -239,7 +227,7 @@ namespace octa {
|
||||||
typedef T *ArgType;
|
typedef T *ArgType;
|
||||||
typedef size_t ResultType;
|
typedef size_t ResultType;
|
||||||
|
|
||||||
size_t operator()(T *v) const noexcept {
|
size_t operator()(T *v) const {
|
||||||
union { T *v; size_t h; } u;
|
union { T *v; size_t h; } u;
|
||||||
u.v = v;
|
u.v = v;
|
||||||
return __octa_mem_hash((const void *)&u, sizeof(u));
|
return __octa_mem_hash((const void *)&u, sizeof(u));
|
||||||
|
@ -252,7 +240,7 @@ namespace octa {
|
||||||
struct ReferenceWrapper {
|
struct ReferenceWrapper {
|
||||||
typedef T type;
|
typedef T type;
|
||||||
|
|
||||||
ReferenceWrapper(T &v) noexcept: p_ptr(address_of(v)) {}
|
ReferenceWrapper(T &v): p_ptr(address_of(v)) {}
|
||||||
ReferenceWrapper(const ReferenceWrapper &) = default;
|
ReferenceWrapper(const ReferenceWrapper &) = default;
|
||||||
ReferenceWrapper(T &&) = delete;
|
ReferenceWrapper(T &&) = delete;
|
||||||
|
|
||||||
|
@ -266,21 +254,21 @@ namespace octa {
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ReferenceWrapper<T> ref(T &v) noexcept {
|
ReferenceWrapper<T> ref(T &v) {
|
||||||
return ReferenceWrapper<T>(v);
|
return ReferenceWrapper<T>(v);
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ReferenceWrapper<T> ref(ReferenceWrapper<T> v) noexcept {
|
ReferenceWrapper<T> ref(ReferenceWrapper<T> v) {
|
||||||
return ReferenceWrapper<T>(v);
|
return ReferenceWrapper<T>(v);
|
||||||
}
|
}
|
||||||
template<typename T> void ref(const T &&) = delete;
|
template<typename T> void ref(const T &&) = delete;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ReferenceWrapper<const T> cref(const T &v) noexcept {
|
ReferenceWrapper<const T> cref(const T &v) {
|
||||||
return ReferenceWrapper<T>(v);
|
return ReferenceWrapper<T>(v);
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ReferenceWrapper<const T> cref(ReferenceWrapper<T> v) noexcept {
|
ReferenceWrapper<const T> cref(ReferenceWrapper<T> v) {
|
||||||
return ReferenceWrapper<T>(v);
|
return ReferenceWrapper<T>(v);
|
||||||
}
|
}
|
||||||
template<typename T> void cref(const T &&) = delete;
|
template<typename T> void cref(const T &&) = delete;
|
||||||
|
@ -339,7 +327,7 @@ namespace octa {
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename R, typename T>
|
template<typename R, typename T>
|
||||||
__OctaMemFn<R, T> mem_fn(R T:: *ptr) noexcept {
|
__OctaMemFn<R, T> mem_fn(R T:: *ptr) {
|
||||||
return __OctaMemFn<R, T>(ptr);
|
return __OctaMemFn<R, T>(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,7 +345,7 @@ namespace octa {
|
||||||
struct __OctaFunctorInPlace {
|
struct __OctaFunctorInPlace {
|
||||||
static constexpr bool value = sizeof(T) <= sizeof(__OctaFunctorData)
|
static constexpr bool value = sizeof(T) <= sizeof(__OctaFunctorData)
|
||||||
&& (alignof(__OctaFunctorData) % alignof(T)) == 0
|
&& (alignof(__OctaFunctorData) % alignof(T)) == 0
|
||||||
&& octa::IsNothrowMoveConstructible<T>();
|
&& octa::IsMoveConstructible<T>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename E = void>
|
template<typename T, typename E = void>
|
||||||
|
@ -371,15 +359,15 @@ namespace octa {
|
||||||
new (&get_ref(s)) T(forward<T>(v));
|
new (&get_ref(s)) T(forward<T>(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void move_f(__OctaFunctorData &lhs, __OctaFunctorData &&rhs) noexcept {
|
static void move_f(__OctaFunctorData &lhs, __OctaFunctorData &&rhs) {
|
||||||
new (&get_ref(lhs)) T(move(get_ref(rhs)));
|
new (&get_ref(lhs)) T(move(get_ref(rhs)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroy_f(__OctaFunctorData &s) noexcept {
|
static void destroy_f(__OctaFunctorData &s) {
|
||||||
get_ref(s).~T();
|
get_ref(s).~T();
|
||||||
}
|
}
|
||||||
|
|
||||||
static T &get_ref(const __OctaFunctorData &s) noexcept {
|
static T &get_ref(const __OctaFunctorData &s) {
|
||||||
return (T &)s;
|
return (T &)s;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -395,27 +383,27 @@ namespace octa {
|
||||||
new (&get_ptr_ref(s)) T *(new T(forward<T>(v)));
|
new (&get_ptr_ref(s)) T *(new T(forward<T>(v)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void move_f(__OctaFunctorData &lhs, __OctaFunctorData &&rhs) noexcept {
|
static void move_f(__OctaFunctorData &lhs, __OctaFunctorData &&rhs) {
|
||||||
new (&get_ptr_ref(lhs)) T *(get_ptr_ref(rhs));
|
new (&get_ptr_ref(lhs)) T *(get_ptr_ref(rhs));
|
||||||
get_ptr_ref(rhs) = nullptr;
|
get_ptr_ref(rhs) = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroy_f(__OctaFunctorData &s) noexcept {
|
static void destroy_f(__OctaFunctorData &s) {
|
||||||
T *&ptr = get_ptr_ref(s);
|
T *&ptr = get_ptr_ref(s);
|
||||||
if (!ptr) return;
|
if (!ptr) return;
|
||||||
delete ptr;
|
delete ptr;
|
||||||
ptr = nullptr;
|
ptr = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static T &get_ref(const __OctaFunctorData &s) noexcept {
|
static T &get_ref(const __OctaFunctorData &s) {
|
||||||
return *get_ptr_ref(s);
|
return *get_ptr_ref(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static T *&get_ptr_ref(__OctaFunctorData &s) noexcept {
|
static T *&get_ptr_ref(__OctaFunctorData &s) {
|
||||||
return (T *&)s;
|
return (T *&)s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static T *&get_ptr_ref(const __OctaFunctorData &s) noexcept {
|
static T *&get_ptr_ref(const __OctaFunctorData &s) {
|
||||||
return (T *&)s;
|
return (T *&)s;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -537,22 +525,21 @@ namespace octa {
|
||||||
|
|
||||||
template<typename R, typename ...A>
|
template<typename R, typename ...A>
|
||||||
struct Function<R(A...)>: __OctaFunction<R, A...> {
|
struct Function<R(A...)>: __OctaFunction<R, A...> {
|
||||||
Function( ) noexcept { initialize_empty(); }
|
Function( ) { initialize_empty(); }
|
||||||
Function(nullptr_t) noexcept { initialize_empty(); }
|
Function(nullptr_t) { initialize_empty(); }
|
||||||
|
|
||||||
Function(Function &&f) noexcept {
|
Function(Function &&f) {
|
||||||
initialize_empty();
|
initialize_empty();
|
||||||
swap(f);
|
swap(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
Function(const Function &f) noexcept: p_call(f.p_call) {
|
Function(const Function &f): p_call(f.p_call) {
|
||||||
f.p_stor.manager->call_copy(p_stor, f.p_stor);
|
f.p_stor.manager->call_copy(p_stor, f.p_stor);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Function(T f, EnableIf<IsValidFunctor<T, R(A...)>::value, __OctaEmpty>
|
Function(T f, EnableIf<IsValidFunctor<T, R(A...)>::value, __OctaEmpty>
|
||||||
= __OctaEmpty())
|
= __OctaEmpty()) {
|
||||||
noexcept(__OctaFunctorInPlace<T>::value) {
|
|
||||||
if (func_is_null(f)) {
|
if (func_is_null(f)) {
|
||||||
initialize_empty();
|
initialize_empty();
|
||||||
return;
|
return;
|
||||||
|
@ -564,13 +551,13 @@ namespace octa {
|
||||||
p_stor.manager->call_destroy(p_stor);
|
p_stor.manager->call_destroy(p_stor);
|
||||||
}
|
}
|
||||||
|
|
||||||
Function &operator=(Function &&f) noexcept {
|
Function &operator=(Function &&f) {
|
||||||
p_stor.manager->call_destroy(p_stor);
|
p_stor.manager->call_destroy(p_stor);
|
||||||
swap(f);
|
swap(f);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Function &operator=(const Function &f) noexcept {
|
Function &operator=(const Function &f) {
|
||||||
p_stor.manager->call_destroy(p_stor);
|
p_stor.manager->call_destroy(p_stor);
|
||||||
f.p_stor.manager->call_copy(p_stor, f.p_stor);
|
f.p_stor.manager->call_copy(p_stor, f.p_stor);
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -580,12 +567,11 @@ namespace octa {
|
||||||
return p_call(p_stor.data, forward<A>(args)...);
|
return p_call(p_stor.data, forward<A>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F>
|
template<typename F> void assign(F &&f) {
|
||||||
void assign(F &&f) noexcept(__OctaFunctorInPlace<F>::value) {
|
|
||||||
Function(forward<F>(f)).swap(*this);
|
Function(forward<F>(f)).swap(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(Function &f) noexcept {
|
void swap(Function &f) {
|
||||||
__OctaFmStorage tmp;
|
__OctaFmStorage tmp;
|
||||||
f.p_stor.manager->call_move_and_destroy(tmp, move(f.p_stor));
|
f.p_stor.manager->call_move_and_destroy(tmp, move(f.p_stor));
|
||||||
p_stor.manager->call_move_and_destroy(f.p_stor, move(p_stor));
|
p_stor.manager->call_move_and_destroy(f.p_stor, move(p_stor));
|
||||||
|
@ -593,7 +579,7 @@ namespace octa {
|
||||||
octa::swap(p_call, f.p_call);
|
octa::swap(p_call, f.p_call);
|
||||||
}
|
}
|
||||||
|
|
||||||
operator bool() const noexcept { return p_call != nullptr; }
|
operator bool() const { return p_call != nullptr; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
__OctaFmStorage p_stor;
|
__OctaFmStorage p_stor;
|
||||||
|
@ -606,7 +592,7 @@ namespace octa {
|
||||||
__OctaFunctorDataManager<T>::store_f(p_stor.data, forward<T>(f));
|
__OctaFunctorDataManager<T>::store_f(p_stor.data, forward<T>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
void initialize_empty() noexcept {
|
void initialize_empty() {
|
||||||
typedef R(*emptyf)(A...);
|
typedef R(*emptyf)(A...);
|
||||||
p_call = nullptr;
|
p_call = nullptr;
|
||||||
p_stor.manager = &__octa_get_default_fm<emptyf>();
|
p_stor.manager = &__octa_get_default_fm<emptyf>();
|
||||||
|
@ -632,21 +618,21 @@ namespace octa {
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void swap(Function<T> &a, Function<T> &b) noexcept {
|
void swap(Function<T> &a, Function<T> &b) {
|
||||||
a.swap(b);
|
a.swap(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator==(nullptr_t, const Function<T> &rhs) noexcept { return !rhs; }
|
bool operator==(nullptr_t, const Function<T> &rhs) { return !rhs; }
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator==(const Function<T> &lhs, nullptr_t) noexcept { return !lhs; }
|
bool operator==(const Function<T> &lhs, nullptr_t) { return !lhs; }
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator!=(nullptr_t, const Function<T> &rhs) noexcept { return rhs; }
|
bool operator!=(nullptr_t, const Function<T> &rhs) { return rhs; }
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator!=(const Function<T> &lhs, nullptr_t) noexcept { return lhs; }
|
bool operator!=(const Function<T> &lhs, nullptr_t) { return lhs; }
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -17,7 +17,7 @@ namespace std {
|
||||||
const T *p_buf;
|
const T *p_buf;
|
||||||
size_t p_len;
|
size_t p_len;
|
||||||
|
|
||||||
initializer_list(const T *v, size_t n) noexcept: p_buf(v), p_len(n) {}
|
initializer_list(const T *v, size_t n): p_buf(v), p_len(n) {}
|
||||||
public:
|
public:
|
||||||
typedef size_t SizeType;
|
typedef size_t SizeType;
|
||||||
typedef ptrdiff_t DiffType;
|
typedef ptrdiff_t DiffType;
|
||||||
|
@ -27,13 +27,13 @@ namespace std {
|
||||||
typedef T *PtrType;
|
typedef T *PtrType;
|
||||||
typedef const T *ConstPtrType;
|
typedef const T *ConstPtrType;
|
||||||
|
|
||||||
initializer_list() noexcept: p_buf(nullptr), p_len(0) {}
|
initializer_list(): p_buf(nullptr), p_len(0) {}
|
||||||
|
|
||||||
size_t length() const noexcept { return p_len; }
|
size_t length() const { return p_len; }
|
||||||
|
|
||||||
const T *get() const noexcept { return p_buf; }
|
const T *get() const { return p_buf; }
|
||||||
|
|
||||||
octa::PointerRange<const T> range() noexcept {
|
octa::PointerRange<const T> range() {
|
||||||
return octa::PointerRange<const T>(p_buf, p_len);
|
return octa::PointerRange<const T>(p_buf, p_len);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
129
octa/memory.h
129
octa/memory.h
|
@ -15,7 +15,7 @@
|
||||||
namespace octa {
|
namespace octa {
|
||||||
/* address of */
|
/* address of */
|
||||||
|
|
||||||
template<typename T> constexpr T *address_of(T &v) noexcept {
|
template<typename T> constexpr T *address_of(T &v) {
|
||||||
return reinterpret_cast<T *>(&const_cast<char &>
|
return reinterpret_cast<T *>(&const_cast<char &>
|
||||||
(reinterpret_cast<const volatile char &>(v)));
|
(reinterpret_cast<const volatile char &>(v)));
|
||||||
}
|
}
|
||||||
|
@ -156,15 +156,15 @@ namespace octa {
|
||||||
struct __OctaPtrTraitsPointerTo {
|
struct __OctaPtrTraitsPointerTo {
|
||||||
static T pointer_to(Conditional<IsVoid<PointerElement<T>>::value,
|
static T pointer_to(Conditional<IsVoid<PointerElement<T>>::value,
|
||||||
__OctaPtrTraitsNat, PointerElement<T>
|
__OctaPtrTraitsNat, PointerElement<T>
|
||||||
> &r) noexcept(noexcept(T::pointer_to(r))) {
|
> &r) {
|
||||||
return T::pointer_to(r);
|
return T::pointer_to(r);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct __OctaPtrTraitsPointerTo<T *> {
|
struct __OctaPtrTraitsPointerTo<T *> {
|
||||||
static T pointer_to(Conditional<IsVoid<T>::value, __OctaPtrTraitsNat, T> &r)
|
static T pointer_to(Conditional<IsVoid<T>::value, __OctaPtrTraitsNat, T
|
||||||
noexcept {
|
> &r) {
|
||||||
return octa::address_of(r);
|
return octa::address_of(r);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -172,7 +172,7 @@ namespace octa {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static T pointer_to(Conditional<IsVoid<PointerElement<T>>::value,
|
static T pointer_to(Conditional<IsVoid<PointerElement<T>>::value,
|
||||||
__OctaPtrTraitsNat, PointerElement<T>
|
__OctaPtrTraitsNat, PointerElement<T>
|
||||||
> &r) noexcept(noexcept(__OctaPtrTraitsPointerTo<T>::pointer_to(r))) {
|
> &r) {
|
||||||
return __OctaPtrTraitsPointerTo<T>::pointer_to(r);
|
return __OctaPtrTraitsPointerTo<T>::pointer_to(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ namespace octa {
|
||||||
|
|
||||||
template<typename U> DefaultDelete(const DefaultDelete<U> &) {};
|
template<typename U> DefaultDelete(const DefaultDelete<U> &) {};
|
||||||
|
|
||||||
void operator()(T *p) const noexcept {
|
void operator()(T *p) const {
|
||||||
delete p;
|
delete p;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -195,7 +195,7 @@ namespace octa {
|
||||||
|
|
||||||
template<typename U> DefaultDelete(const DefaultDelete<U[]> &) {};
|
template<typename U> DefaultDelete(const DefaultDelete<U[]> &) {};
|
||||||
|
|
||||||
void operator()(T *p) const noexcept {
|
void operator()(T *p) const {
|
||||||
delete[] p;
|
delete[] p;
|
||||||
}
|
}
|
||||||
template<typename U> void operator()(U *) const = delete;
|
template<typename U> void operator()(U *) const = delete;
|
||||||
|
@ -214,13 +214,12 @@ namespace octa {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<typename D>
|
template<typename D>
|
||||||
__OctaBoxPair(T *ptr, D &&dltr) noexcept:
|
__OctaBoxPair(T *ptr, D &&dltr): i_ptr(ptr), p_del(forward<D>(dltr)) {}
|
||||||
i_ptr(ptr), p_del(forward<D>(dltr)) {}
|
|
||||||
|
|
||||||
U &get_deleter() noexcept { return p_del; }
|
U &get_deleter() { return p_del; }
|
||||||
const U &get_deleter() const noexcept { return p_del; }
|
const U &get_deleter() const { return p_del; }
|
||||||
|
|
||||||
void swap(__OctaBoxPair &v) noexcept {
|
void swap(__OctaBoxPair &v) {
|
||||||
octa::swap(i_ptr, v.i_ptr);
|
octa::swap(i_ptr, v.i_ptr);
|
||||||
octa::swap(p_del, v.p_del);
|
octa::swap(p_del, v.p_del);
|
||||||
}
|
}
|
||||||
|
@ -231,13 +230,12 @@ namespace octa {
|
||||||
T *i_ptr;
|
T *i_ptr;
|
||||||
|
|
||||||
template<typename D>
|
template<typename D>
|
||||||
__OctaBoxPair(T *ptr, D &&dltr) noexcept:
|
__OctaBoxPair(T *ptr, D &&dltr): U(forward<D>(dltr)), i_ptr(ptr) {}
|
||||||
U(forward<D>(dltr)), i_ptr(ptr) {}
|
|
||||||
|
|
||||||
U &get_deleter() noexcept { return *this; }
|
U &get_deleter() { return *this; }
|
||||||
const U &get_deleter() const noexcept { return *this; }
|
const U &get_deleter() const { return *this; }
|
||||||
|
|
||||||
void swap(__OctaBoxPair &v) noexcept {
|
void swap(__OctaBoxPair &v) {
|
||||||
octa::swap(i_ptr, v.i_ptr);
|
octa::swap(i_ptr, v.i_ptr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -277,40 +275,39 @@ namespace octa {
|
||||||
typedef const RemoveReference<D> &D_cref;
|
typedef const RemoveReference<D> &D_cref;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr Box() noexcept: p_stor(nullptr, D()) {
|
constexpr Box(): p_stor(nullptr, D()) {
|
||||||
static_assert(!IsPointer<D>::value,
|
static_assert(!IsPointer<D>::value,
|
||||||
"Box constructed with null fptr deleter");
|
"Box constructed with null fptr deleter");
|
||||||
}
|
}
|
||||||
constexpr Box(nullptr_t) noexcept: p_stor(nullptr, D()) {
|
constexpr Box(nullptr_t): p_stor(nullptr, D()) {
|
||||||
static_assert(!IsPointer<D>::value,
|
static_assert(!IsPointer<D>::value,
|
||||||
"Box constructed with null fptr deleter");
|
"Box constructed with null fptr deleter");
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit Box(PtrType p) noexcept: p_stor(p, D()) {
|
explicit Box(PtrType p): p_stor(p, D()) {
|
||||||
static_assert(!IsPointer<D>::value,
|
static_assert(!IsPointer<D>::value,
|
||||||
"Box constructed with null fptr deleter");
|
"Box constructed with null fptr deleter");
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(PtrType p, Conditional<IsReference<D>::value,
|
Box(PtrType p, Conditional<IsReference<D>::value,
|
||||||
D, AddLvalueReference<const D>
|
D, AddLvalueReference<const D>
|
||||||
> d) noexcept: p_stor(p, d) {}
|
> d): p_stor(p, d) {}
|
||||||
|
|
||||||
Box(PtrType p, RemoveReference<D> &&d) noexcept: p_stor(p, move(d)) {
|
Box(PtrType p, RemoveReference<D> &&d): p_stor(p, move(d)) {
|
||||||
static_assert(!IsReference<D>::value,
|
static_assert(!IsReference<D>::value,
|
||||||
"rvalue deleter cannot be a ref");
|
"rvalue deleter cannot be a ref");
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(Box &&u) noexcept: p_stor(u.release(), forward<D>(u.get_deleter())) {}
|
Box(Box &&u): p_stor(u.release(), forward<D>(u.get_deleter())) {}
|
||||||
|
|
||||||
template<typename TT, typename DD>
|
template<typename TT, typename DD>
|
||||||
Box(Box<TT, DD> &&u, EnableIf<!IsArray<TT>::value
|
Box(Box<TT, DD> &&u, EnableIf<!IsArray<TT>::value
|
||||||
&& IsConvertible<typename Box<TT, DD>::PtrType, PtrType>::value
|
&& IsConvertible<typename Box<TT, DD>::PtrType, PtrType>::value
|
||||||
&& IsConvertible<DD, D>::value
|
&& IsConvertible<DD, D>::value
|
||||||
&& (!IsReference<D>::value || IsSame<D, DD>::value)
|
&& (!IsReference<D>::value || IsSame<D, DD>::value)
|
||||||
> = __OctaNat()) noexcept: p_stor(u.release(),
|
> = __OctaNat()): p_stor(u.release(), forward<DD>(u.get_deleter())) {}
|
||||||
forward<DD>(u.get_deleter())) {}
|
|
||||||
|
|
||||||
Box &operator=(Box &&u) noexcept {
|
Box &operator=(Box &&u) {
|
||||||
reset(u.release());
|
reset(u.release());
|
||||||
p_stor.get_deleter() = forward<D>(u.get_deleter());
|
p_stor.get_deleter() = forward<D>(u.get_deleter());
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -321,13 +318,13 @@ namespace octa {
|
||||||
&& IsConvertible<typename Box<TT, DD>::PtrType, PtrType>::value
|
&& IsConvertible<typename Box<TT, DD>::PtrType, PtrType>::value
|
||||||
&& IsAssignable<D &, DD &&>::value,
|
&& IsAssignable<D &, DD &&>::value,
|
||||||
Box &
|
Box &
|
||||||
> operator=(Box<TT, DD> &&u) noexcept {
|
> operator=(Box<TT, DD> &&u) {
|
||||||
reset(u.release());
|
reset(u.release());
|
||||||
p_stor.get_deleter() = forward<DD>(u.get_deleter());
|
p_stor.get_deleter() = forward<DD>(u.get_deleter());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Box &operator=(nullptr_t) noexcept {
|
Box &operator=(nullptr_t) {
|
||||||
reset();
|
reset();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -335,30 +332,30 @@ namespace octa {
|
||||||
~Box() { reset(); }
|
~Box() { reset(); }
|
||||||
|
|
||||||
AddLvalueReference<T> operator*() const { return *p_stor.i_ptr; }
|
AddLvalueReference<T> operator*() const { return *p_stor.i_ptr; }
|
||||||
PtrType operator->() const noexcept { return p_stor.i_ptr; }
|
PtrType operator->() const { return p_stor.i_ptr; }
|
||||||
|
|
||||||
explicit operator bool() const noexcept {
|
explicit operator bool() const {
|
||||||
return p_stor.i_ptr != nullptr;
|
return p_stor.i_ptr != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
PtrType get() const noexcept { return p_stor.i_ptr; }
|
PtrType get() const { return p_stor.i_ptr; }
|
||||||
|
|
||||||
D_ref get_deleter() noexcept { return p_stor.get_deleter(); }
|
D_ref get_deleter() { return p_stor.get_deleter(); }
|
||||||
D_cref get_deleter() const noexcept { return p_stor.get_deleter(); }
|
D_cref get_deleter() const { return p_stor.get_deleter(); }
|
||||||
|
|
||||||
PtrType release() noexcept {
|
PtrType release() {
|
||||||
PtrType p = p_stor.i_ptr;
|
PtrType p = p_stor.i_ptr;
|
||||||
p_stor.i_ptr = nullptr;
|
p_stor.i_ptr = nullptr;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset(PtrType p = nullptr) noexcept {
|
void reset(PtrType p = nullptr) {
|
||||||
PtrType tmp = p_stor.i_ptr;
|
PtrType tmp = p_stor.i_ptr;
|
||||||
p_stor.i_ptr = p;
|
p_stor.i_ptr = p;
|
||||||
if (tmp) p_stor.get_deleter()(tmp);
|
if (tmp) p_stor.get_deleter()(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(Box &u) noexcept {
|
void swap(Box &u) {
|
||||||
p_stor.swap(u.p_stor);
|
p_stor.swap(u.p_stor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,18 +391,18 @@ namespace octa {
|
||||||
typedef const RemoveReference<D> &D_cref;
|
typedef const RemoveReference<D> &D_cref;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr Box() noexcept: p_stor(nullptr, D()) {
|
constexpr Box(): p_stor(nullptr, D()) {
|
||||||
static_assert(!IsPointer<D>::value,
|
static_assert(!IsPointer<D>::value,
|
||||||
"Box constructed with null fptr deleter");
|
"Box constructed with null fptr deleter");
|
||||||
}
|
}
|
||||||
constexpr Box(nullptr_t) noexcept: p_stor(nullptr, D()) {
|
constexpr Box(nullptr_t): p_stor(nullptr, D()) {
|
||||||
static_assert(!IsPointer<D>::value,
|
static_assert(!IsPointer<D>::value,
|
||||||
"Box constructed with null fptr deleter");
|
"Box constructed with null fptr deleter");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U> explicit Box(U p, EnableIf<
|
template<typename U> explicit Box(U p, EnableIf<
|
||||||
__OctaSameOrLessCvQualified<U, PtrType>::value, __OctaNat
|
__OctaSameOrLessCvQualified<U, PtrType>::value, __OctaNat
|
||||||
> = __OctaNat()) noexcept: p_stor(p, D()) {
|
> = __OctaNat()): p_stor(p, D()) {
|
||||||
static_assert(!IsPointer<D>::value,
|
static_assert(!IsPointer<D>::value,
|
||||||
"Box constructed with null fptr deleter");
|
"Box constructed with null fptr deleter");
|
||||||
}
|
}
|
||||||
|
@ -413,25 +410,25 @@ namespace octa {
|
||||||
template<typename U> Box(U p, Conditional<IsReference<D>::value,
|
template<typename U> Box(U p, Conditional<IsReference<D>::value,
|
||||||
D, AddLvalueReference<const D>
|
D, AddLvalueReference<const D>
|
||||||
> d, EnableIf<__OctaSameOrLessCvQualified<U, PtrType>::value, __OctaNat
|
> d, EnableIf<__OctaSameOrLessCvQualified<U, PtrType>::value, __OctaNat
|
||||||
> = __OctaNat()) noexcept: p_stor(p, d) {}
|
> = __OctaNat()): p_stor(p, d) {}
|
||||||
|
|
||||||
Box(nullptr_t, Conditional<IsReference<D>::value,
|
Box(nullptr_t, Conditional<IsReference<D>::value,
|
||||||
D, AddLvalueReference<const D>
|
D, AddLvalueReference<const D>
|
||||||
> d) noexcept: p_stor(nullptr, d) {}
|
> d): p_stor(nullptr, d) {}
|
||||||
|
|
||||||
template<typename U> Box(U p, RemoveReference<D> &&d, EnableIf<
|
template<typename U> Box(U p, RemoveReference<D> &&d, EnableIf<
|
||||||
__OctaSameOrLessCvQualified<U, PtrType>::value, __OctaNat
|
__OctaSameOrLessCvQualified<U, PtrType>::value, __OctaNat
|
||||||
> = __OctaNat()) noexcept: p_stor(p, move(d)) {
|
> = __OctaNat()): p_stor(p, move(d)) {
|
||||||
static_assert(!IsReference<D>::value,
|
static_assert(!IsReference<D>::value,
|
||||||
"rvalue deleter cannot be a ref");
|
"rvalue deleter cannot be a ref");
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(nullptr_t, RemoveReference<D> &&d) noexcept: p_stor(nullptr, move(d)) {
|
Box(nullptr_t, RemoveReference<D> &&d): p_stor(nullptr, move(d)) {
|
||||||
static_assert(!IsReference<D>::value,
|
static_assert(!IsReference<D>::value,
|
||||||
"rvalue deleter cannot be a ref");
|
"rvalue deleter cannot be a ref");
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(Box &&u) noexcept: p_stor(u.release(), forward<D>(u.get_deleter())) {}
|
Box(Box &&u): p_stor(u.release(), forward<D>(u.get_deleter())) {}
|
||||||
|
|
||||||
template<typename TT, typename DD>
|
template<typename TT, typename DD>
|
||||||
Box(Box<TT, DD> &&u, EnableIf<IsArray<TT>::value
|
Box(Box<TT, DD> &&u, EnableIf<IsArray<TT>::value
|
||||||
|
@ -439,9 +436,9 @@ namespace octa {
|
||||||
PtrType>::value
|
PtrType>::value
|
||||||
&& IsConvertible<DD, D>::value
|
&& IsConvertible<DD, D>::value
|
||||||
&& (!IsReference<D>::value || IsSame<D, DD>::value)> = __OctaNat()
|
&& (!IsReference<D>::value || IsSame<D, DD>::value)> = __OctaNat()
|
||||||
) noexcept: p_stor(u.release(), forward<DD>(u.get_deleter())) {}
|
): p_stor(u.release(), forward<DD>(u.get_deleter())) {}
|
||||||
|
|
||||||
Box &operator=(Box &&u) noexcept {
|
Box &operator=(Box &&u) {
|
||||||
reset(u.release());
|
reset(u.release());
|
||||||
p_stor.get_deleter() = forward<D>(u.get_deleter());
|
p_stor.get_deleter() = forward<D>(u.get_deleter());
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -453,13 +450,13 @@ namespace octa {
|
||||||
PtrType>::value
|
PtrType>::value
|
||||||
&& IsAssignable<D &, DD &&>::value,
|
&& IsAssignable<D &, DD &&>::value,
|
||||||
Box &
|
Box &
|
||||||
> operator=(Box<TT, DD> &&u) noexcept {
|
> operator=(Box<TT, DD> &&u) {
|
||||||
reset(u.release());
|
reset(u.release());
|
||||||
p_stor.get_deleter() = forward<DD>(u.get_deleter());
|
p_stor.get_deleter() = forward<DD>(u.get_deleter());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Box &operator=(nullptr_t) noexcept {
|
Box &operator=(nullptr_t) {
|
||||||
reset();
|
reset();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -470,16 +467,16 @@ namespace octa {
|
||||||
return p_stor.i_ptr[idx];
|
return p_stor.i_ptr[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit operator bool() const noexcept {
|
explicit operator bool() const {
|
||||||
return p_stor.i_ptr != nullptr;
|
return p_stor.i_ptr != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
PtrType get() const noexcept { return p_stor.i_ptr; }
|
PtrType get() const { return p_stor.i_ptr; }
|
||||||
|
|
||||||
D_ref get_deleter() noexcept { return p_stor.get_deleter(); }
|
D_ref get_deleter() { return p_stor.get_deleter(); }
|
||||||
D_cref get_deleter() const noexcept { return p_stor.get_deleter(); }
|
D_cref get_deleter() const { return p_stor.get_deleter(); }
|
||||||
|
|
||||||
PtrType release() noexcept {
|
PtrType release() {
|
||||||
PtrType p = p_stor.i_ptr;
|
PtrType p = p_stor.i_ptr;
|
||||||
p_stor.i_ptr = nullptr;
|
p_stor.i_ptr = nullptr;
|
||||||
return p;
|
return p;
|
||||||
|
@ -487,23 +484,23 @@ namespace octa {
|
||||||
|
|
||||||
template<typename U> EnableIf<
|
template<typename U> EnableIf<
|
||||||
__OctaSameOrLessCvQualified<U, PtrType>::value, void
|
__OctaSameOrLessCvQualified<U, PtrType>::value, void
|
||||||
> reset(U p) noexcept {
|
> reset(U p) {
|
||||||
PtrType tmp = p_stor.i_ptr;
|
PtrType tmp = p_stor.i_ptr;
|
||||||
p_stor.i_ptr = p;
|
p_stor.i_ptr = p;
|
||||||
if (tmp) p_stor.get_deleter()(tmp);
|
if (tmp) p_stor.get_deleter()(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset(nullptr_t) noexcept {
|
void reset(nullptr_t) {
|
||||||
PtrType tmp = p_stor.i_ptr;
|
PtrType tmp = p_stor.i_ptr;
|
||||||
p_stor.i_ptr = nullptr;
|
p_stor.i_ptr = nullptr;
|
||||||
if (tmp) p_stor.get_deleter()(tmp);
|
if (tmp) p_stor.get_deleter()(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() noexcept {
|
void reset() {
|
||||||
reset(nullptr);
|
reset(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(Box &u) noexcept {
|
void swap(Box &u) {
|
||||||
p_stor.swap(u.p_stor);
|
p_stor.swap(u.p_stor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -567,16 +564,16 @@ namespace octa {
|
||||||
|
|
||||||
template<typename U> using Rebind = Allocator<U>;
|
template<typename U> using Rebind = Allocator<U>;
|
||||||
|
|
||||||
PtrType address(RefType v) const noexcept {
|
PtrType address(RefType v) const {
|
||||||
return address_of(v);
|
return address_of(v);
|
||||||
};
|
};
|
||||||
ConstPtrType address(ConstRefType v) const noexcept {
|
ConstPtrType address(ConstRefType v) const {
|
||||||
return address_of(v);
|
return address_of(v);
|
||||||
};
|
};
|
||||||
|
|
||||||
SizeType max_size() const noexcept { return SizeType(~0) / sizeof(T); }
|
SizeType max_size() const { return SizeType(~0) / sizeof(T); }
|
||||||
|
|
||||||
PtrType allocate(SizeType n, Allocator<void>::ConstPtrType = nullptr) noexcept {
|
PtrType allocate(SizeType n, Allocator<void>::ConstPtrType = nullptr) {
|
||||||
return (PtrType) ::new uchar[n * sizeof(T)];
|
return (PtrType) ::new uchar[n * sizeof(T)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -601,13 +598,13 @@ namespace octa {
|
||||||
|
|
||||||
template<typename U> using Rebind = Allocator<U>;
|
template<typename U> using Rebind = Allocator<U>;
|
||||||
|
|
||||||
ConstPtrType address(ConstRefType v) const noexcept {
|
ConstPtrType address(ConstRefType v) const {
|
||||||
return address_of(v);
|
return address_of(v);
|
||||||
};
|
};
|
||||||
|
|
||||||
SizeType max_size() const noexcept { return SizeType(~0) / sizeof(T); }
|
SizeType max_size() const { return SizeType(~0) / sizeof(T); }
|
||||||
|
|
||||||
PtrType allocate(SizeType n, Allocator<void>::ConstPtrType = nullptr) noexcept {
|
PtrType allocate(SizeType n, Allocator<void>::ConstPtrType = nullptr) {
|
||||||
return (PtrType) ::new uchar[n * sizeof(T)];
|
return (PtrType) ::new uchar[n * sizeof(T)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -622,12 +619,12 @@ namespace octa {
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
bool operator==(const Allocator<T> &, const Allocator<U> &) noexcept {
|
bool operator==(const Allocator<T> &, const Allocator<U> &) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
bool operator!=(const Allocator<T> &, const Allocator<U> &) noexcept {
|
bool operator!=(const Allocator<T> &, const Allocator<U> &) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
261
octa/range.h
261
octa/range.h
|
@ -26,7 +26,6 @@ namespace octa {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct __OctaRangeIterator {
|
struct __OctaRangeIterator {
|
||||||
/* no need to mark noexcept as it's never instantiated directly */
|
|
||||||
__OctaRangeIterator(): p_range() {}
|
__OctaRangeIterator(): p_range() {}
|
||||||
explicit __OctaRangeIterator(const T &range): p_range(range) {}
|
explicit __OctaRangeIterator(const T &range): p_range(range) {}
|
||||||
__OctaRangeIterator &operator++() {
|
__OctaRangeIterator &operator++() {
|
||||||
|
@ -52,14 +51,10 @@ namespace octa {
|
||||||
typedef V ValType;
|
typedef V ValType;
|
||||||
typedef R RefType;
|
typedef R RefType;
|
||||||
|
|
||||||
__OctaRangeIterator<B> begin() noexcept(
|
__OctaRangeIterator<B> begin() {
|
||||||
IsNothrowCopyConstructible<B>::value
|
|
||||||
) {
|
|
||||||
return __OctaRangeIterator<B>((const B &)*this);
|
return __OctaRangeIterator<B>((const B &)*this);
|
||||||
}
|
}
|
||||||
__OctaRangeIterator<B> end() noexcept(
|
__OctaRangeIterator<B> end() {
|
||||||
IsNothrowDefaultConstructible<B>::value
|
|
||||||
) {
|
|
||||||
return __OctaRangeIterator<B>();
|
return __OctaRangeIterator<B>();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -83,106 +78,82 @@ namespace octa {
|
||||||
T p_range;
|
T p_range;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ReverseRange() noexcept(IsNothrowDefaultConstructible<T>::value):
|
ReverseRange(): p_range() {}
|
||||||
p_range() {}
|
|
||||||
|
|
||||||
ReverseRange(const T &range) noexcept(
|
ReverseRange(const T &range): p_range(range) {}
|
||||||
IsNothrowCopyConstructible<T>::value
|
|
||||||
): p_range(range) {}
|
|
||||||
|
|
||||||
ReverseRange(const ReverseRange &it) noexcept(
|
ReverseRange(const ReverseRange &it): p_range(it.p_range) {}
|
||||||
IsNothrowCopyConstructible<T>::value
|
|
||||||
): p_range(it.p_range) {}
|
|
||||||
|
|
||||||
ReverseRange(ReverseRange &&it) noexcept(
|
ReverseRange(ReverseRange &&it): p_range(move(it.p_range)) {}
|
||||||
IsNothrowMoveConstructible<T>::value
|
|
||||||
): p_range(move(it.p_range)) {}
|
|
||||||
|
|
||||||
ReverseRange &operator=(const ReverseRange &v) noexcept(
|
ReverseRange &operator=(const ReverseRange &v) {
|
||||||
IsNothrowCopyAssignable<T>::value
|
|
||||||
) {
|
|
||||||
p_range = v.p_range;
|
p_range = v.p_range;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
ReverseRange &operator=(ReverseRange &&v) noexcept(
|
ReverseRange &operator=(ReverseRange &&v) {
|
||||||
IsNothrowMoveAssignable<T>::value
|
|
||||||
) {
|
|
||||||
p_range = move(v.p_range);
|
p_range = move(v.p_range);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
ReverseRange &operator=(const T &v) noexcept(
|
ReverseRange &operator=(const T &v) {
|
||||||
IsNothrowCopyAssignable<T>::value
|
|
||||||
) {
|
|
||||||
p_range = v;
|
p_range = v;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
ReverseRange &operator=(T &&v) noexcept(
|
ReverseRange &operator=(T &&v) {
|
||||||
IsNothrowMoveAssignable<T>::value
|
|
||||||
) {
|
|
||||||
p_range = move(v);
|
p_range = move(v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool empty() const noexcept(noexcept(p_range.empty())) {
|
bool empty() const {
|
||||||
return p_range.empty();
|
return p_range.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
r_size length() const noexcept(noexcept(p_range.length())) {
|
r_size length() const {
|
||||||
return p_range.length();
|
return p_range.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop_first() noexcept(noexcept(p_range.pop_last())) {
|
void pop_first() {
|
||||||
p_range.pop_last();
|
p_range.pop_last();
|
||||||
}
|
}
|
||||||
void pop_last() noexcept(noexcept(p_range.pop_first())) {
|
void pop_last() {
|
||||||
p_range.pop_first();
|
p_range.pop_first();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const ReverseRange &v) const noexcept(
|
bool operator==(const ReverseRange &v) const {
|
||||||
noexcept(p_range == v.p_range)
|
|
||||||
) {
|
|
||||||
return p_range == v.p_range;
|
return p_range == v.p_range;
|
||||||
}
|
}
|
||||||
bool operator!=(const ReverseRange &v) const noexcept(
|
bool operator!=(const ReverseRange &v) const {
|
||||||
noexcept(p_range != v.p_range)
|
|
||||||
) {
|
|
||||||
return p_range != v.p_range;
|
return p_range != v.p_range;
|
||||||
}
|
}
|
||||||
|
|
||||||
r_ref first() noexcept(noexcept(p_range.last())) {
|
r_ref first() {
|
||||||
return p_range.last();
|
return p_range.last();
|
||||||
}
|
}
|
||||||
r_ref first() const noexcept(noexcept(p_range.last())) {
|
r_ref first() const {
|
||||||
return p_range.last();
|
return p_range.last();
|
||||||
}
|
}
|
||||||
|
|
||||||
r_ref last() noexcept(noexcept(p_range.first())) {
|
r_ref last() {
|
||||||
return p_range.first();
|
return p_range.first();
|
||||||
}
|
}
|
||||||
r_ref last() const noexcept(noexcept(p_range.first())) {
|
r_ref last() const {
|
||||||
return p_range.first();
|
return p_range.first();
|
||||||
}
|
}
|
||||||
|
|
||||||
r_ref operator[](r_size i) noexcept(noexcept(p_range[0])) {
|
r_ref operator[](r_size i) {
|
||||||
return p_range[length() - i - 1];
|
return p_range[length() - i - 1];
|
||||||
}
|
}
|
||||||
r_ref operator[](r_size i) const noexcept(noexcept(p_range[0])) {
|
r_ref operator[](r_size i) const {
|
||||||
return p_range[length() - i - 1];
|
return p_range[length() - i - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
ReverseRange<T> slice(r_size start, r_size end) noexcept(
|
ReverseRange<T> slice(r_size start, r_size end) {
|
||||||
noexcept(ReverseRange<T>(p_range.slice(0, 0)))
|
|
||||||
&& noexcept(p_range.length())
|
|
||||||
) {
|
|
||||||
r_size len = p_range.length();
|
r_size len = p_range.length();
|
||||||
return ReverseRange<T>(p_range.slice(len - end, len - start));
|
return ReverseRange<T>(p_range.slice(len - end, len - start));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ReverseRange<T> make_reverse_range(const T &it) noexcept(
|
ReverseRange<T> make_reverse_range(const T &it) {
|
||||||
noexcept(ReverseRange<T>(it))
|
|
||||||
) {
|
|
||||||
return ReverseRange<T>(it);
|
return ReverseRange<T>(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,193 +169,170 @@ namespace octa {
|
||||||
T p_range;
|
T p_range;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MoveRange() noexcept(IsNothrowDefaultConstructible<T>::value):
|
MoveRange(): p_range() {}
|
||||||
p_range() {}
|
|
||||||
|
|
||||||
MoveRange(const T &range) noexcept(
|
MoveRange(const T &range): p_range(range) {}
|
||||||
IsNothrowCopyConstructible<T>::value
|
|
||||||
): p_range(range) {}
|
|
||||||
|
|
||||||
MoveRange(const MoveRange &it) noexcept(
|
MoveRange(const MoveRange &it): p_range(it.p_range) {}
|
||||||
IsNothrowCopyConstructible<T>::value
|
|
||||||
): p_range(it.p_range) {}
|
|
||||||
|
|
||||||
MoveRange(MoveRange &&it) noexcept(
|
MoveRange(MoveRange &&it): p_range(move(it.p_range)) {}
|
||||||
IsNothrowMoveConstructible<T>::value
|
|
||||||
): p_range(move(it.p_range)) {}
|
|
||||||
|
|
||||||
MoveRange &operator=(const MoveRange &v) noexcept(
|
MoveRange &operator=(const MoveRange &v) {
|
||||||
IsNothrowCopyAssignable<T>::value
|
|
||||||
) {
|
|
||||||
p_range = v.p_range;
|
p_range = v.p_range;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
MoveRange &operator=(MoveRange &&v) noexcept(
|
MoveRange &operator=(MoveRange &&v) {
|
||||||
IsNothrowMoveAssignable<T>::value
|
|
||||||
) {
|
|
||||||
p_range = move(v.p_range);
|
p_range = move(v.p_range);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
MoveRange &operator=(const T &v) noexcept(
|
MoveRange &operator=(const T &v) {
|
||||||
IsNothrowCopyAssignable<T>::value
|
|
||||||
) {
|
|
||||||
p_range = v;
|
p_range = v;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
MoveRange &operator=(T &&v) noexcept(
|
MoveRange &operator=(T &&v) {
|
||||||
IsNothrowMoveAssignable<T>::value
|
|
||||||
) {
|
|
||||||
p_range = move(v);
|
p_range = move(v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool empty() const noexcept(noexcept(p_range.empty())) {
|
bool empty() const {
|
||||||
return p_range.empty();
|
return p_range.empty();
|
||||||
}
|
}
|
||||||
r_size length() const noexcept(noexcept(p_range.length())) {
|
r_size length() const {
|
||||||
return p_range.length();
|
return p_range.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop_first() noexcept(noexcept(p_range.pop_first())) {
|
void pop_first() {
|
||||||
p_range.pop_first();
|
p_range.pop_first();
|
||||||
}
|
}
|
||||||
void pop_last() noexcept(noexcept(p_range.pop_last())) {
|
void pop_last() {
|
||||||
p_range.pop_last();
|
p_range.pop_last();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const MoveRange &v) const noexcept(
|
bool operator==(const MoveRange &v) const {
|
||||||
noexcept(p_range == v.p_range)
|
|
||||||
) {
|
|
||||||
return p_range == v.p_range;
|
return p_range == v.p_range;
|
||||||
}
|
}
|
||||||
bool operator!=(const MoveRange &v) const noexcept(
|
bool operator!=(const MoveRange &v) const {
|
||||||
noexcept(p_range != v.p_range)
|
|
||||||
) {
|
|
||||||
return p_range != v.p_range;
|
return p_range != v.p_range;
|
||||||
}
|
}
|
||||||
|
|
||||||
r_ref first() noexcept(noexcept(p_range.first())) {
|
r_ref first() {
|
||||||
return move(p_range.first());
|
return move(p_range.first());
|
||||||
}
|
}
|
||||||
r_ref last() noexcept(noexcept(p_range.last())) {
|
r_ref last() {
|
||||||
return move(p_range.last());
|
return move(p_range.last());
|
||||||
}
|
}
|
||||||
|
|
||||||
r_ref operator[](r_size i) noexcept(noexcept(p_range[0])) {
|
r_ref operator[](r_size i) {
|
||||||
return move(p_range[i]);
|
return move(p_range[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
MoveRange<T> slice(r_size start, r_size end) noexcept(
|
MoveRange<T> slice(r_size start, r_size end) {
|
||||||
noexcept(MoveRange<T>(p_range.slice(start, end)))
|
|
||||||
) {
|
|
||||||
return MoveRange<T>(p_range.slice(start, end));
|
return MoveRange<T>(p_range.slice(start, end));
|
||||||
}
|
}
|
||||||
|
|
||||||
void put(const r_val &v) noexcept(noexcept(p_range.put(v))) {
|
void put(const r_val &v) {
|
||||||
p_range.put(v);
|
p_range.put(v);
|
||||||
}
|
}
|
||||||
void put(r_val &&v) noexcept(noexcept(p_range.put(move(v)))) {
|
void put(r_val &&v) {
|
||||||
p_range.put(move(v));
|
p_range.put(move(v));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
MoveRange<T> make_move_range(const T &it) noexcept(
|
MoveRange<T> make_move_range(const T &it) {
|
||||||
noexcept(MoveRange<T>(it))
|
|
||||||
) {
|
|
||||||
return MoveRange<T>(it);
|
return MoveRange<T>(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct NumberRange: InputRange<NumberRange<T>, ForwardRangeTag, T> {
|
struct NumberRange: InputRange<NumberRange<T>, ForwardRangeTag, T> {
|
||||||
NumberRange() noexcept: p_a(0), p_b(0), p_step(0) {}
|
NumberRange(): p_a(0), p_b(0), p_step(0) {}
|
||||||
NumberRange(const NumberRange &it) noexcept: p_a(it.p_a), p_b(it.p_b),
|
NumberRange(const NumberRange &it): p_a(it.p_a), p_b(it.p_b),
|
||||||
p_step(it.p_step) {}
|
p_step(it.p_step) {}
|
||||||
NumberRange(T a, T b, T step = T(1)) noexcept: p_a(a), p_b(b),
|
NumberRange(T a, T b, T step = T(1)): p_a(a), p_b(b),
|
||||||
p_step(step) {}
|
p_step(step) {}
|
||||||
NumberRange(T v) noexcept: p_a(0), p_b(v), p_step(1) {}
|
NumberRange(T v): p_a(0), p_b(v), p_step(1) {}
|
||||||
|
|
||||||
bool operator==(const NumberRange &v) const noexcept {
|
bool operator==(const NumberRange &v) const {
|
||||||
return p_a == v.p_a && p_b == v.p_b && p_step == v.p_step;
|
return p_a == v.p_a && p_b == v.p_b && p_step == v.p_step;
|
||||||
}
|
}
|
||||||
bool operator!=(const NumberRange &v) const noexcept {
|
bool operator!=(const NumberRange &v) const {
|
||||||
return p_a != v.p_a || p_b != v.p_b || p_step != v.p_step;
|
return p_a != v.p_a || p_b != v.p_b || p_step != v.p_step;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool empty() const noexcept { return p_a * p_step >= p_b * p_step; }
|
bool empty() const { return p_a * p_step >= p_b * p_step; }
|
||||||
void pop_first() noexcept { p_a += p_step; }
|
void pop_first() { p_a += p_step; }
|
||||||
T &first() noexcept { return p_a; }
|
T &first() { return p_a; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T p_a, p_b, p_step;
|
T p_a, p_b, p_step;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NumberRange<T> range(T a, T b, T step = T(1)) noexcept {
|
NumberRange<T> range(T a, T b, T step = T(1)) {
|
||||||
return NumberRange<T>(a, b, step);
|
return NumberRange<T>(a, b, step);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NumberRange<T> range(T v) noexcept {
|
NumberRange<T> range(T v) {
|
||||||
return NumberRange<T>(v);
|
return NumberRange<T>(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct PointerRange: InputRange<PointerRange<T>, RandomAccessRangeTag, T> {
|
struct PointerRange: InputRange<PointerRange<T>, RandomAccessRangeTag, T> {
|
||||||
PointerRange() noexcept: p_beg(nullptr), p_end(nullptr) {}
|
PointerRange(): p_beg(nullptr), p_end(nullptr) {}
|
||||||
PointerRange(const PointerRange &v) noexcept: p_beg(v.p_beg),
|
PointerRange(const PointerRange &v): p_beg(v.p_beg),
|
||||||
p_end(v.p_end) {}
|
p_end(v.p_end) {}
|
||||||
PointerRange(T *beg, T *end) noexcept: p_beg(beg), p_end(end) {}
|
PointerRange(T *beg, T *end): p_beg(beg), p_end(end) {}
|
||||||
PointerRange(T *beg, size_t n) noexcept: p_beg(beg), p_end(beg + n) {}
|
PointerRange(T *beg, size_t n): p_beg(beg), p_end(beg + n) {}
|
||||||
|
|
||||||
PointerRange &operator=(const PointerRange &v) noexcept {
|
PointerRange &operator=(const PointerRange &v) {
|
||||||
p_beg = v.p_beg;
|
p_beg = v.p_beg;
|
||||||
p_end = v.p_end;
|
p_end = v.p_end;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const PointerRange &v) const noexcept {
|
bool operator==(const PointerRange &v) const {
|
||||||
return p_beg == v.p_beg && p_end == v.p_end;
|
return p_beg == v.p_beg && p_end == v.p_end;
|
||||||
}
|
}
|
||||||
bool operator!=(const PointerRange &v) const noexcept {
|
bool operator!=(const PointerRange &v) const {
|
||||||
return p_beg != v.p_beg || p_end != v.p_end;
|
return p_beg != v.p_beg || p_end != v.p_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* satisfy InputRange / ForwardRange */
|
/* satisfy InputRange / ForwardRange */
|
||||||
bool empty() const noexcept { return p_beg == nullptr; }
|
bool empty() const { return p_beg == nullptr; }
|
||||||
|
|
||||||
void pop_first() noexcept {
|
void pop_first() {
|
||||||
if (p_beg == nullptr) return;
|
if (p_beg == nullptr) return;
|
||||||
if (++p_beg == p_end) p_beg = p_end = nullptr;
|
if (++p_beg == p_end) p_beg = p_end = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
T &first() noexcept { return *p_beg; }
|
T &first() { return *p_beg; }
|
||||||
const T &first() const noexcept { return *p_beg; }
|
const T &first() const { return *p_beg; }
|
||||||
|
|
||||||
/* satisfy BidirectionalRange */
|
/* satisfy BidirectionalRange */
|
||||||
void pop_last() noexcept {
|
void pop_last() {
|
||||||
if (p_end-- == p_beg) { p_end = nullptr; return; }
|
if (p_end-- == p_beg) { p_end = nullptr; return; }
|
||||||
if (p_end == p_beg) p_beg = p_end = nullptr;
|
if (p_end == p_beg) p_beg = p_end = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
T &last() noexcept { return *(p_end - 1); }
|
T &last() { return *(p_end - 1); }
|
||||||
const T &last() const noexcept { return *(p_end - 1); }
|
const T &last() const { return *(p_end - 1); }
|
||||||
|
|
||||||
/* satisfy RandomAccessRange */
|
/* satisfy RandomAccessRange */
|
||||||
size_t length() const noexcept { return p_end - p_beg; }
|
size_t length() const { return p_end - p_beg; }
|
||||||
|
|
||||||
PointerRange slice(size_t start, size_t end) noexcept {
|
PointerRange slice(size_t start, size_t end) {
|
||||||
return PointerRange(p_beg + start, p_beg + end);
|
return PointerRange(p_beg + start, p_beg + end);
|
||||||
}
|
}
|
||||||
|
|
||||||
T &operator[](size_t i) noexcept { return p_beg[i]; }
|
T &operator[](size_t i) { return p_beg[i]; }
|
||||||
const T &operator[](size_t i) const noexcept { return p_beg[i]; }
|
const T &operator[](size_t i) const { return p_beg[i]; }
|
||||||
|
|
||||||
/* satisfy OutputRange */
|
/* satisfy OutputRange */
|
||||||
void put(const T &v) noexcept(IsNothrowCopyAssignable<T>::value) {
|
void put(const T &v) {
|
||||||
*(p_beg++) = v;
|
*(p_beg++) = v;
|
||||||
}
|
}
|
||||||
void put(T &&v) noexcept(IsNothrowMoveAssignable<T>::value) {
|
void put(T &&v) {
|
||||||
*(p_beg++) = move(v);
|
*(p_beg++) = move(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,85 +360,62 @@ namespace octa {
|
||||||
r_size p_index;
|
r_size p_index;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EnumeratedRange() noexcept(IsNothrowDefaultConstructible<T>::value):
|
EnumeratedRange(): p_range(), p_index(0) {}
|
||||||
p_range(), p_index(0) {}
|
|
||||||
|
|
||||||
EnumeratedRange(const T &range) noexcept(
|
EnumeratedRange(const T &range): p_range(range), p_index(0) {}
|
||||||
IsNothrowCopyConstructible<T>::value
|
|
||||||
): p_range(range), p_index(0) {}
|
|
||||||
|
|
||||||
EnumeratedRange(const EnumeratedRange &it) noexcept(
|
EnumeratedRange(const EnumeratedRange &it):
|
||||||
IsNothrowCopyConstructible<T>::value
|
p_range(it.p_range), p_index(it.p_index) {}
|
||||||
): p_range(it.p_range), p_index(it.p_index) {}
|
|
||||||
|
|
||||||
EnumeratedRange(EnumeratedRange &&it) noexcept(
|
EnumeratedRange(EnumeratedRange &&it):
|
||||||
IsNothrowMoveConstructible<T>::value
|
p_range(move(it.p_range)), p_index(it.p_index) {}
|
||||||
): p_range(move(it.p_range)), p_index(it.p_index) {}
|
|
||||||
|
|
||||||
EnumeratedRange &operator=(const EnumeratedRange &v) noexcept(
|
EnumeratedRange &operator=(const EnumeratedRange &v) {
|
||||||
IsNothrowCopyAssignable<T>::value
|
|
||||||
) {
|
|
||||||
p_range = v.p_range;
|
p_range = v.p_range;
|
||||||
p_index = v.p_index;
|
p_index = v.p_index;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
EnumeratedRange &operator=(EnumeratedRange &&v) noexcept(
|
EnumeratedRange &operator=(EnumeratedRange &&v) {
|
||||||
IsNothrowMoveAssignable<T>::value
|
|
||||||
) {
|
|
||||||
p_range = move(v.p_range);
|
p_range = move(v.p_range);
|
||||||
p_index = v.p_index;
|
p_index = v.p_index;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
EnumeratedRange &operator=(const T &v) noexcept(
|
EnumeratedRange &operator=(const T &v) {
|
||||||
IsNothrowCopyAssignable<T>::value
|
|
||||||
) {
|
|
||||||
p_range = v;
|
p_range = v;
|
||||||
p_index = 0;
|
p_index = 0;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
EnumeratedRange &operator=(T &&v) noexcept(
|
EnumeratedRange &operator=(T &&v) {
|
||||||
IsNothrowMoveAssignable<T>::value
|
|
||||||
) {
|
|
||||||
p_range = move(v);
|
p_range = move(v);
|
||||||
p_index = 0;
|
p_index = 0;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool empty() const noexcept(noexcept(p_range.empty())) {
|
bool empty() const {
|
||||||
return p_range.empty();
|
return p_range.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop_first() noexcept(noexcept(p_range.pop_last())) {
|
void pop_first() {
|
||||||
++p_index; p_range.pop_first();
|
++p_index; p_range.pop_first();
|
||||||
}
|
}
|
||||||
|
|
||||||
EnumeratedValue<r_ref, r_size> first() noexcept(
|
EnumeratedValue<r_ref, r_size> first() {
|
||||||
noexcept(p_range.first())
|
|
||||||
) {
|
|
||||||
return EnumeratedValue<r_ref, r_size> { p_index, p_range.first() };
|
return EnumeratedValue<r_ref, r_size> { p_index, p_range.first() };
|
||||||
}
|
}
|
||||||
EnumeratedValue<r_ref, r_size> first() const noexcept(
|
EnumeratedValue<r_ref, r_size> first() const {
|
||||||
noexcept(p_range.first())
|
|
||||||
) {
|
|
||||||
return EnumeratedValue<r_ref, r_size> { p_index, p_range.first() };
|
return EnumeratedValue<r_ref, r_size> { p_index, p_range.first() };
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const EnumeratedRange &v) const noexcept(
|
bool operator==(const EnumeratedRange &v) const {
|
||||||
noexcept(p_range == v.p_range)
|
|
||||||
) {
|
|
||||||
return p_range == v.p_range;
|
return p_range == v.p_range;
|
||||||
}
|
}
|
||||||
bool operator!=(const EnumeratedRange &v) const noexcept(
|
bool operator!=(const EnumeratedRange &v) const {
|
||||||
noexcept(p_range != v.p_range)
|
|
||||||
) {
|
|
||||||
return p_range != v.p_range;
|
return p_range != v.p_range;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
EnumeratedRange<T> enumerate(const T &it) noexcept(
|
EnumeratedRange<T> enumerate(const T &it) {
|
||||||
noexcept(EnumeratedRange<T>(it))
|
|
||||||
) {
|
|
||||||
return EnumeratedRange<T>(it);
|
return EnumeratedRange<T>(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -325,7 +325,7 @@ namespace octa {
|
||||||
decltype(__OCTA_MOVE(T(__octa_declval<A>()...))), True
|
decltype(__OCTA_MOVE(T(__octa_declval<A>()...))), True
|
||||||
>::Type __octa_is_ctible_test(T &&, A &&...);
|
>::Type __octa_is_ctible_test(T &&, A &&...);
|
||||||
|
|
||||||
#undef __OCTA_MOVE
|
//#undef __OCTA_MOVE
|
||||||
|
|
||||||
template<typename ...A> False __octa_is_ctible_test(__OctaAny, A &&...);
|
template<typename ...A> False __octa_is_ctible_test(__OctaAny, A &&...);
|
||||||
|
|
||||||
|
@ -578,115 +578,6 @@ namespace octa {
|
||||||
__has_trivial_destructor(T)
|
__has_trivial_destructor(T)
|
||||||
> {};
|
> {};
|
||||||
|
|
||||||
/* is nothrow constructible */
|
|
||||||
|
|
||||||
template<typename T, typename ...A>
|
|
||||||
struct IsNothrowConstructible: False {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsNothrowConstructible<T>: IntegralConstant<bool,
|
|
||||||
__has_nothrow_constructor(T)
|
|
||||||
> {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsNothrowConstructible<T, T &>: IntegralConstant<bool,
|
|
||||||
__has_nothrow_copy(T)
|
|
||||||
> {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsNothrowConstructible<T, const T &>: IntegralConstant<bool,
|
|
||||||
__has_nothrow_copy(T)
|
|
||||||
> {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsNothrowConstructible<T, T &&>: IntegralConstant<bool,
|
|
||||||
__has_nothrow_copy(T)
|
|
||||||
> {};
|
|
||||||
|
|
||||||
/* is nothrow default constructible */
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsNothrowDefaultConstructible: IsNothrowConstructible<T> {};
|
|
||||||
|
|
||||||
/* is nothrow copy constructible */
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsNothrowCopyConstructible: IsNothrowConstructible<T,
|
|
||||||
AddLvalueReference<const T>
|
|
||||||
> {};
|
|
||||||
|
|
||||||
/* is nothrow move constructible */
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsNothrowMoveConstructible: IsNothrowConstructible<T,
|
|
||||||
AddRvalueReference<T>
|
|
||||||
> {};
|
|
||||||
|
|
||||||
/* is nothrow assignable */
|
|
||||||
|
|
||||||
template<typename T, typename ...A>
|
|
||||||
struct IsNothrowAssignable: False {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsNothrowAssignable<T>: IntegralConstant<bool,
|
|
||||||
__has_nothrow_assign(T)
|
|
||||||
> {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsNothrowAssignable<T, T &>: IntegralConstant<bool,
|
|
||||||
__has_nothrow_copy(T)
|
|
||||||
> {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsNothrowAssignable<T, const T &>: IntegralConstant<bool,
|
|
||||||
__has_nothrow_copy(T)
|
|
||||||
> {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsNothrowAssignable<T, T &&>: IntegralConstant<bool,
|
|
||||||
__has_nothrow_copy(T)
|
|
||||||
> {};
|
|
||||||
|
|
||||||
/* is nothrow copy assignable */
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsNothrowCopyAssignable: IsNothrowAssignable<T,
|
|
||||||
AddLvalueReference<const T>
|
|
||||||
> {};
|
|
||||||
|
|
||||||
/* is nothrow move assignable */
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsNothrowMoveAssignable: IsNothrowAssignable<T,
|
|
||||||
AddRvalueReference<T>
|
|
||||||
> {};
|
|
||||||
|
|
||||||
/* is nothrow destructible */
|
|
||||||
|
|
||||||
template<typename, bool> struct __OctaIsNothrowDtible;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct __OctaIsNothrowDtible<T, false>: False {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct __OctaIsNothrowDtible<T, true>: IntegralConstant<bool,
|
|
||||||
(IsScalar<T>::value || noexcept(__octa_declval<T>().~T()))
|
|
||||||
> {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsNothrowDestructible: __OctaIsNothrowDtible<T,
|
|
||||||
IsDestructible<T>::value
|
|
||||||
> {};
|
|
||||||
|
|
||||||
template<typename T, size_t N>
|
|
||||||
struct IsNothrowDestructible<T[N]>: IsNothrowDestructible<T> {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsNothrowDestructible<T &>: IsNothrowDestructible<T> {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsNothrowDestructible<T &&>: IsNothrowDestructible<T> {};
|
|
||||||
|
|
||||||
/* is base of */
|
/* is base of */
|
||||||
|
|
||||||
template<typename B, typename D>
|
template<typename B, typename D>
|
||||||
|
@ -1127,11 +1018,11 @@ namespace octa {
|
||||||
template<typename ...T> struct __OctaCommonType;
|
template<typename ...T> struct __OctaCommonType;
|
||||||
|
|
||||||
template<typename T> struct __OctaCommonType<T> {
|
template<typename T> struct __OctaCommonType<T> {
|
||||||
typedef __OctaDecay<T> Type;
|
typedef Decay<T> Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename U> struct __OctaCommonType<T, U> {
|
template<typename T, typename U> struct __OctaCommonType<T, U> {
|
||||||
typedef __OctaDecay<decltype(true ? __octa_declval<T>()
|
typedef Decay<decltype(true ? __octa_declval<T>()
|
||||||
: __octa_declval<U>())> Type;
|
: __octa_declval<U>())> Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -14,22 +14,19 @@ namespace octa {
|
||||||
/* move */
|
/* move */
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static inline constexpr RemoveReference<T> &&
|
static inline constexpr RemoveReference<T> &&move(T &&v) {
|
||||||
move(T &&v) noexcept {
|
|
||||||
return static_cast<RemoveReference<T> &&>(v);
|
return static_cast<RemoveReference<T> &&>(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* forward */
|
/* forward */
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static inline constexpr T &&
|
static inline constexpr T &&forward(RemoveReference<T> &v) {
|
||||||
forward(RemoveReference<T> &v) noexcept {
|
|
||||||
return static_cast<T &&>(v);
|
return static_cast<T &&>(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static inline constexpr T &&
|
static inline constexpr T &&forward(RemoveReference<T> &&v) {
|
||||||
forward(RemoveReference<T> &&v) noexcept {
|
|
||||||
return static_cast<T &&>(v);
|
return static_cast<T &&>(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,18 +36,13 @@ namespace octa {
|
||||||
|
|
||||||
/* swap */
|
/* swap */
|
||||||
|
|
||||||
template<typename T> void swap(T &a, T &b) noexcept(
|
template<typename T> void swap(T &a, T &b) {
|
||||||
IsNothrowMoveConstructible<T>::value
|
|
||||||
&& IsNothrowMoveAssignable<T>::value
|
|
||||||
) {
|
|
||||||
T c(move(a));
|
T c(move(a));
|
||||||
a = move(b);
|
a = move(b);
|
||||||
b = move(c);
|
b = move(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, size_t N> void swap(T (&a)[N], T (&b)[N]) noexcept(
|
template<typename T, size_t N> void swap(T (&a)[N], T (&b)[N]) {
|
||||||
noexcept(swap(*a, *b))
|
|
||||||
) {
|
|
||||||
for (size_t i = 0; i < N; ++i) {
|
for (size_t i = 0; i < N; ++i) {
|
||||||
swap(a[i], b[i]);
|
swap(a[i], b[i]);
|
||||||
}
|
}
|
||||||
|
@ -63,64 +55,37 @@ namespace octa {
|
||||||
T first;
|
T first;
|
||||||
U second;
|
U second;
|
||||||
|
|
||||||
Pair() noexcept(
|
Pair() = default;
|
||||||
IsNothrowDefaultConstructible<T>::value
|
|
||||||
&& IsNothrowDefaultConstructible<U>::value
|
|
||||||
) = default;
|
|
||||||
~Pair() = default;
|
~Pair() = default;
|
||||||
|
|
||||||
Pair(const Pair &) noexcept(
|
Pair(const Pair &) = default;
|
||||||
IsNothrowCopyConstructible<T>::value
|
Pair(Pair &&) = default;
|
||||||
&& IsNothrowCopyConstructible<U>::value
|
|
||||||
) = default;
|
|
||||||
Pair(Pair &&) noexcept(
|
|
||||||
IsNothrowMoveConstructible<T>::value
|
|
||||||
&& IsNothrowMoveConstructible<U>::value
|
|
||||||
) = default;
|
|
||||||
|
|
||||||
Pair(const T &x, const U &y) noexcept(
|
Pair(const T &x, const U &y): first(x), second(y) {}
|
||||||
IsNothrowCopyConstructible<T>::value
|
|
||||||
&& IsNothrowCopyConstructible<U>::value
|
|
||||||
): first(x), second(y) {}
|
|
||||||
|
|
||||||
template<typename TT, typename UU>
|
template<typename TT, typename UU>
|
||||||
Pair(TT &&x, UU &&y): first(forward<TT>(x)), second(forward<UU>(y)) {}
|
Pair(TT &&x, UU &&y): first(forward<TT>(x)), second(forward<UU>(y)) {}
|
||||||
|
|
||||||
template<typename TT, typename UU>
|
template<typename TT, typename UU>
|
||||||
Pair(const Pair<TT, UU> &v) noexcept(
|
Pair(const Pair<TT, UU> &v): first(v.first), second(v.second) {}
|
||||||
IsNothrowCopyConstructible<T>::value
|
|
||||||
&& IsNothrowCopyConstructible<U>::value
|
|
||||||
): first(v.first), second(v.second) {}
|
|
||||||
|
|
||||||
template<typename TT, typename UU>
|
template<typename TT, typename UU>
|
||||||
Pair(Pair<TT, UU> &&v) noexcept(
|
Pair(Pair<TT, UU> &&v): first(move(v.first)), second(move(v.second)) {}
|
||||||
IsNothrowMoveConstructible<T>::value
|
|
||||||
&& IsNothrowMoveConstructible<U>::value
|
|
||||||
): first(move(v.first)), second(move(v.second)) {}
|
|
||||||
|
|
||||||
Pair &operator=(const Pair &v) noexcept(
|
Pair &operator=(const Pair &v) {
|
||||||
IsNothrowCopyAssignable<T>::value
|
|
||||||
&& IsNothrowCopyAssignable<U>::value
|
|
||||||
) {
|
|
||||||
first = v.first;
|
first = v.first;
|
||||||
second = v.second;
|
second = v.second;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TT, typename UU>
|
template<typename TT, typename UU>
|
||||||
Pair &operator=(const Pair<TT, UU> &v) noexcept(
|
Pair &operator=(const Pair<TT, UU> &v) {
|
||||||
IsNothrowCopyAssignable<T>::value
|
|
||||||
&& IsNothrowCopyAssignable<U>::value
|
|
||||||
) {
|
|
||||||
first = v.first;
|
first = v.first;
|
||||||
second = v.second;
|
second = v.second;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pair &operator=(Pair &&v) noexcept(
|
Pair &operator=(Pair &&v) {
|
||||||
IsNothrowMoveAssignable<T>::value
|
|
||||||
&& IsNothrowMoveAssignable<U>::value
|
|
||||||
) {
|
|
||||||
first = move(v.first);
|
first = move(v.first);
|
||||||
second = move(v.second);
|
second = move(v.second);
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -133,17 +98,14 @@ namespace octa {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(Pair &v) noexcept(
|
void swap(Pair &v) {
|
||||||
noexcept(octa::swap(first, v.first))
|
|
||||||
&& noexcept(octa::swap(second, v.second))
|
|
||||||
) {
|
|
||||||
octa::swap(first, v.first);
|
octa::swap(first, v.first);
|
||||||
octa::swap(second, v.second);
|
octa::swap(second, v.second);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
void swap(Pair<T, U> &a, Pair<T, U> &b) noexcept(noexcept(a.swap(b))) {
|
void swap(Pair<T, U> &a, Pair<T, U> &b) {
|
||||||
a.swap(b);
|
a.swap(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
140
octa/vector.h
140
octa/vector.h
|
@ -22,11 +22,7 @@ namespace octa {
|
||||||
T *p_buf;
|
T *p_buf;
|
||||||
size_t p_len, p_cap;
|
size_t p_len, p_cap;
|
||||||
|
|
||||||
void insert_base(size_t idx, size_t n) noexcept(
|
void insert_base(size_t idx, size_t n) {
|
||||||
IsNothrowDestructible<T>::value
|
|
||||||
&& IsNothrowMoveConstructible<T>::value
|
|
||||||
&& IsNothrowMoveAssignable<T>::value
|
|
||||||
) {
|
|
||||||
if (p_len + n > p_cap) reserve(p_len + n);
|
if (p_len + n > p_cap) reserve(p_len + n);
|
||||||
p_len += n;
|
p_len += n;
|
||||||
for (size_t i = p_len - 1; i > idx + n - 1; --i) {
|
for (size_t i = p_len - 1; i > idx + n - 1; --i) {
|
||||||
|
@ -47,33 +43,25 @@ namespace octa {
|
||||||
typedef PointerRange< T> RangeType;
|
typedef PointerRange< T> RangeType;
|
||||||
typedef PointerRange<const T> ConstRangeType;
|
typedef PointerRange<const T> ConstRangeType;
|
||||||
|
|
||||||
Vector() noexcept: p_buf(nullptr), p_len(0), p_cap(0) {}
|
Vector(): p_buf(nullptr), p_len(0), p_cap(0) {}
|
||||||
|
|
||||||
explicit Vector(size_t n, const T &val = T()) noexcept(
|
explicit Vector(size_t n, const T &val = T()): Vector() {
|
||||||
IsNothrowCopyConstructible<T>::value
|
|
||||||
): Vector() {
|
|
||||||
p_buf = new uchar[n * sizeof(T)];
|
p_buf = new uchar[n * sizeof(T)];
|
||||||
p_len = p_cap = n;
|
p_len = p_cap = n;
|
||||||
T *cur = p_buf, *last = p_buf + n;
|
T *cur = p_buf, *last = p_buf + n;
|
||||||
while (cur != last) new (cur++) T(val);
|
while (cur != last) new (cur++) T(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector(const Vector &v) noexcept(
|
Vector(const Vector &v): Vector() {
|
||||||
IsNothrowDestructible<T>::value
|
|
||||||
&& IsNothrowCopyConstructible<T>::value
|
|
||||||
): Vector() {
|
|
||||||
*this = v;
|
*this = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector(Vector &&v) noexcept: p_buf(v.p_buf), p_len(v.p_len),
|
Vector(Vector &&v): p_buf(v.p_buf), p_len(v.p_len), p_cap(v.p_cap) {
|
||||||
p_cap(v.p_cap) {
|
|
||||||
v.p_buf = nullptr;
|
v.p_buf = nullptr;
|
||||||
v.p_len = v.p_cap = 0;
|
v.p_len = v.p_cap = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector(InitializerList<T> v) noexcept(
|
Vector(InitializerList<T> v): Vector() {
|
||||||
IsNothrowCopyConstructible<T>::value
|
|
||||||
): Vector() {
|
|
||||||
size_t len = v.length();
|
size_t len = v.length();
|
||||||
const T *ptr = v.get();
|
const T *ptr = v.get();
|
||||||
reserve(len);
|
reserve(len);
|
||||||
|
@ -82,14 +70,14 @@ namespace octa {
|
||||||
p_len = len;
|
p_len = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
~Vector() noexcept(IsNothrowDestructible<T>::value) {
|
~Vector() {
|
||||||
clear();
|
clear();
|
||||||
delete[] (uchar *)p_buf;
|
delete[] (uchar *)p_buf;
|
||||||
p_buf = nullptr;
|
p_buf = nullptr;
|
||||||
p_cap = 0;
|
p_cap = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() noexcept(IsNothrowDestructible<T>::value) {
|
void clear() {
|
||||||
if (p_len > 0 && !octa::IsPod<T>()) {
|
if (p_len > 0 && !octa::IsPod<T>()) {
|
||||||
T *cur = p_buf, *last = p_buf + p_len;
|
T *cur = p_buf, *last = p_buf + p_len;
|
||||||
while (cur != last) (*cur++).~T();
|
while (cur != last) (*cur++).~T();
|
||||||
|
@ -97,10 +85,7 @@ namespace octa {
|
||||||
p_len = 0;
|
p_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<T> &operator=(const Vector<T> &v) noexcept(
|
Vector<T> &operator=(const Vector<T> &v) {
|
||||||
IsNothrowDestructible<T>::value
|
|
||||||
&& IsNothrowCopyConstructible<T>::value
|
|
||||||
) {
|
|
||||||
if (this == &v) return *this;
|
if (this == &v) return *this;
|
||||||
clear();
|
clear();
|
||||||
reserve(v.p_cap);
|
reserve(v.p_cap);
|
||||||
|
@ -117,9 +102,7 @@ namespace octa {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<T> &operator=(Vector<T> &&v) noexcept(
|
Vector<T> &operator=(Vector<T> &&v) {
|
||||||
IsNothrowDestructible<T>::value
|
|
||||||
) {
|
|
||||||
clear();
|
clear();
|
||||||
delete[] (uchar *)p_buf;
|
delete[] (uchar *)p_buf;
|
||||||
p_len = v.p_len;
|
p_len = v.p_len;
|
||||||
|
@ -128,10 +111,7 @@ namespace octa {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<T> &operator=(InitializerList<T> il) noexcept(
|
Vector<T> &operator=(InitializerList<T> il) {
|
||||||
IsNothrowDestructible<T>::value &&
|
|
||||||
IsNothrowCopyConstructible<T>::value
|
|
||||||
) {
|
|
||||||
clear();
|
clear();
|
||||||
size_t ilen = il.length();
|
size_t ilen = il.length();
|
||||||
reserve(ilen);
|
reserve(ilen);
|
||||||
|
@ -147,11 +127,7 @@ namespace octa {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void resize(size_t n, const T &v = T()) noexcept(
|
void resize(size_t n, const T &v = T()) {
|
||||||
IsNothrowDestructible<T>::value
|
|
||||||
&& IsNothrowMoveConstructible<T>::value
|
|
||||||
&& IsNothrowCopyConstructible<T>::value
|
|
||||||
) {
|
|
||||||
size_t len = p_len;
|
size_t len = p_len;
|
||||||
reserve(n);
|
reserve(n);
|
||||||
p_len = n;
|
p_len = n;
|
||||||
|
@ -166,10 +142,7 @@ namespace octa {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void reserve(size_t n) noexcept(
|
void reserve(size_t n) {
|
||||||
IsNothrowDestructible<T>::value
|
|
||||||
&& IsNothrowMoveConstructible<T>::value
|
|
||||||
) {
|
|
||||||
if (n <= p_len) {
|
if (n <= p_len) {
|
||||||
if (n == p_len) return;
|
if (n == p_len) return;
|
||||||
while (p_len > n) pop();
|
while (p_len > n) pop();
|
||||||
|
@ -198,25 +171,19 @@ namespace octa {
|
||||||
p_buf = tmp;
|
p_buf = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
T &operator[](size_t i) noexcept { return p_buf[i]; }
|
T &operator[](size_t i) { return p_buf[i]; }
|
||||||
const T &operator[](size_t i) const noexcept { return p_buf[i]; }
|
const T &operator[](size_t i) const { return p_buf[i]; }
|
||||||
|
|
||||||
T &at(size_t i) noexcept { return p_buf[i]; }
|
T &at(size_t i) { return p_buf[i]; }
|
||||||
const T &at(size_t i) const noexcept { return p_buf[i]; }
|
const T &at(size_t i) const { return p_buf[i]; }
|
||||||
|
|
||||||
T &push(const T &v) noexcept(
|
T &push(const T &v) {
|
||||||
noexcept(noexcept(reserve(0))) &&
|
|
||||||
IsNothrowCopyConstructible<T>::value
|
|
||||||
) {
|
|
||||||
if (p_len == p_cap) reserve(p_len + 1);
|
if (p_len == p_cap) reserve(p_len + 1);
|
||||||
new (&p_buf[p_len]) T(v);
|
new (&p_buf[p_len]) T(v);
|
||||||
return p_buf[p_len++];
|
return p_buf[p_len++];
|
||||||
}
|
}
|
||||||
|
|
||||||
T &push() noexcept(
|
T &push() {
|
||||||
noexcept(noexcept(reserve(0))) &&
|
|
||||||
IsNothrowDefaultConstructible<T>::value
|
|
||||||
) {
|
|
||||||
if (p_len == p_cap) reserve(p_len + 1);
|
if (p_len == p_cap) reserve(p_len + 1);
|
||||||
new (&p_buf[p_len]) T;
|
new (&p_buf[p_len]) T;
|
||||||
return p_buf[p_len++];
|
return p_buf[p_len++];
|
||||||
|
@ -229,7 +196,7 @@ namespace octa {
|
||||||
return p_buf[p_len++];
|
return p_buf[p_len++];
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop() noexcept(IsNothrowDestructible<T>::value) {
|
void pop() {
|
||||||
if (!octa::IsPod<T>()) {
|
if (!octa::IsPod<T>()) {
|
||||||
p_buf[--p_len].~T();
|
p_buf[--p_len].~T();
|
||||||
} else {
|
} else {
|
||||||
|
@ -237,60 +204,46 @@ namespace octa {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
T &first() noexcept { return p_buf[0]; }
|
T &first() { return p_buf[0]; }
|
||||||
const T &first() const noexcept { return p_buf[0]; };
|
const T &first() const { return p_buf[0]; };
|
||||||
|
|
||||||
T &last() noexcept { return p_buf[p_len - 1]; }
|
T &last() { return p_buf[p_len - 1]; }
|
||||||
const T &last() const noexcept { return p_buf[p_len - 1]; }
|
const T &last() const { return p_buf[p_len - 1]; }
|
||||||
|
|
||||||
T *get() noexcept { return p_buf; }
|
T *get() { return p_buf; }
|
||||||
const T *get() const noexcept { return p_buf; }
|
const T *get() const { return p_buf; }
|
||||||
|
|
||||||
size_t length() const noexcept { return p_len; }
|
size_t length() const { return p_len; }
|
||||||
size_t capacity() const noexcept { return p_cap; }
|
size_t capacity() const { return p_cap; }
|
||||||
|
|
||||||
bool empty() const noexcept { return (p_len == 0); }
|
bool empty() const { return (p_len == 0); }
|
||||||
|
|
||||||
bool in_range(size_t idx) noexcept { return idx < p_len; }
|
bool in_range(size_t idx) { return idx < p_len; }
|
||||||
bool in_range(int idx) noexcept { return idx >= 0 && idx < p_len; }
|
bool in_range(int idx) { return idx >= 0 && idx < p_len; }
|
||||||
bool in_range(const T *ptr) noexcept {
|
bool in_range(const T *ptr) {
|
||||||
return ptr >= p_buf && ptr < &p_buf[p_len];
|
return ptr >= p_buf && ptr < &p_buf[p_len];
|
||||||
}
|
}
|
||||||
|
|
||||||
T *disown() noexcept {
|
T *disown() {
|
||||||
T *r = p_buf;
|
T *r = p_buf;
|
||||||
p_buf = nullptr;
|
p_buf = nullptr;
|
||||||
p_len = p_cap = 0;
|
p_len = p_cap = 0;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
T *insert(size_t idx, T &&v) noexcept(
|
T *insert(size_t idx, T &&v) {
|
||||||
IsNothrowDestructible<T>::value
|
|
||||||
&& IsNothrowMoveConstructible<T>::value
|
|
||||||
&& IsNothrowMoveAssignable<T>::value
|
|
||||||
) {
|
|
||||||
insert_base(idx, 1);
|
insert_base(idx, 1);
|
||||||
p_buf[idx] = move(v);
|
p_buf[idx] = move(v);
|
||||||
return &p_buf[idx];
|
return &p_buf[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
T *insert(size_t idx, const T &v) noexcept(
|
T *insert(size_t idx, const T &v) {
|
||||||
IsNothrowDestructible<T>::value
|
|
||||||
&& IsNothrowMoveConstructible<T>::value
|
|
||||||
&& IsNothrowMoveAssignable<T>::value
|
|
||||||
&& IsNothrowCopyAssignable<T>::value
|
|
||||||
) {
|
|
||||||
insert_base(idx, 1);
|
insert_base(idx, 1);
|
||||||
p_buf[idx] = v;
|
p_buf[idx] = v;
|
||||||
return &p_buf[idx];
|
return &p_buf[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
T *insert(size_t idx, size_t n, const T &v) noexcept(
|
T *insert(size_t idx, size_t n, const T &v) {
|
||||||
IsNothrowDestructible<T>::value
|
|
||||||
&& IsNothrowMoveConstructible<T>::value
|
|
||||||
&& IsNothrowMoveAssignable<T>::value
|
|
||||||
&& IsNothrowCopyAssignable<T>::value
|
|
||||||
) {
|
|
||||||
insert_base(idx, n);
|
insert_base(idx, n);
|
||||||
for (size_t i = 0; i < n; ++i) {
|
for (size_t i = 0; i < n; ++i) {
|
||||||
p_buf[idx + i] = v;
|
p_buf[idx + i] = v;
|
||||||
|
@ -299,14 +252,7 @@ namespace octa {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
T *insert_range(size_t idx, U range) noexcept(
|
T *insert_range(size_t idx, U range) {
|
||||||
IsNothrowDestructible<T>::value
|
|
||||||
&& IsNothrowMoveConstructible<T>::value
|
|
||||||
&& IsNothrowMoveAssignable<T>::value
|
|
||||||
&& noexcept(range.first())
|
|
||||||
&& noexcept(range.pop_first())
|
|
||||||
&& noexcept((*p_buf = range.first()))
|
|
||||||
) {
|
|
||||||
size_t len = range.length();
|
size_t len = range.length();
|
||||||
insert_base(idx, len);
|
insert_base(idx, len);
|
||||||
for (size_t i = 0; i < len; ++i) {
|
for (size_t i = 0; i < len; ++i) {
|
||||||
|
@ -316,20 +262,18 @@ namespace octa {
|
||||||
return &p_buf[idx];
|
return &p_buf[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
T *insert(size_t idx, InitializerList<T> il) noexcept(
|
T *insert(size_t idx, InitializerList<T> il) {
|
||||||
noexcept(declval<Vector<T>>().insert_range(idx, il.range()))
|
|
||||||
) {
|
|
||||||
return insert_range(idx, il.range());
|
return insert_range(idx, il.range());
|
||||||
}
|
}
|
||||||
|
|
||||||
RangeType each() noexcept {
|
RangeType each() {
|
||||||
return PointerRange<T>(p_buf, p_buf + p_len);
|
return PointerRange<T>(p_buf, p_buf + p_len);
|
||||||
}
|
}
|
||||||
ConstRangeType each() const noexcept {
|
ConstRangeType each() const {
|
||||||
return PointerRange<const T>(p_buf, p_buf + p_len);
|
return PointerRange<const T>(p_buf, p_buf + p_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(Vector &v) noexcept {
|
void swap(Vector &v) {
|
||||||
swap(p_len, v.p_len);
|
swap(p_len, v.p_len);
|
||||||
swap(p_cap, v.p_cap);
|
swap(p_cap, v.p_cap);
|
||||||
swap(p_buf, v.p_buf);
|
swap(p_buf, v.p_buf);
|
||||||
|
@ -337,7 +281,7 @@ namespace octa {
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void swap(Vector<T> &a, Vector<T> &b) noexcept {
|
void swap(Vector<T> &a, Vector<T> &b) {
|
||||||
a.swap(b);
|
a.swap(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue