forked from OctaForge/libostd
use new type aliases + refactoring + namespacing
parent
06dc966f19
commit
ea42a5e841
28
octa/array.h
28
octa/array.h
|
@ -14,23 +14,23 @@
|
||||||
|
|
||||||
namespace octa {
|
namespace octa {
|
||||||
|
|
||||||
template<typename T, size_t N>
|
template<typename T, octa::Size N>
|
||||||
struct Array {
|
struct Array {
|
||||||
using Size = size_t;
|
using Size = octa::Size;
|
||||||
using Difference = ptrdiff_t;
|
using Difference = octa::Ptrdiff;
|
||||||
using Value = T;
|
using Value = T;
|
||||||
using Reference = T &;
|
using Reference = T &;
|
||||||
using ConstReference = const T &;
|
using ConstReference = const T &;
|
||||||
using Pointer = T *;
|
using Pointer = T *;
|
||||||
using ConstPointer = const T *;
|
using ConstPointer = const T *;
|
||||||
using Range = PointerRange<T>;
|
using Range = octa::PointerRange<T>;
|
||||||
using ConstRange = PointerRange<const T>;
|
using ConstRange = octa::PointerRange<const T>;
|
||||||
|
|
||||||
T &operator[](size_t i) { return p_buf[i]; }
|
T &operator[](Size i) { return p_buf[i]; }
|
||||||
const T &operator[](size_t i) const { return p_buf[i]; }
|
const T &operator[](Size i) const { return p_buf[i]; }
|
||||||
|
|
||||||
T &at(size_t i) { return p_buf[i]; }
|
T &at(Size i) { return p_buf[i]; }
|
||||||
const T &at(size_t i) const { return p_buf[i]; }
|
const T &at(Size i) const { return p_buf[i]; }
|
||||||
|
|
||||||
T &front() { return p_buf[0]; }
|
T &front() { return p_buf[0]; }
|
||||||
const T &front() const { return p_buf[0]; }
|
const T &front() const { return p_buf[0]; }
|
||||||
|
@ -38,12 +38,12 @@ struct Array {
|
||||||
T &back() { return p_buf[(N > 0) ? (N - 1) : 0]; }
|
T &back() { return p_buf[(N > 0) ? (N - 1) : 0]; }
|
||||||
const T &back() const { return p_buf[(N > 0) ? (N - 1) : 0]; }
|
const T &back() const { return p_buf[(N > 0) ? (N - 1) : 0]; }
|
||||||
|
|
||||||
size_t size() const { return N; }
|
Size size() const { return N; }
|
||||||
|
|
||||||
bool empty() const { return N == 0; }
|
bool empty() const { return N == 0; }
|
||||||
|
|
||||||
bool in_range(size_t idx) { return idx < N; }
|
bool in_range(Size idx) { return idx < N; }
|
||||||
bool in_range(int idx) { return idx >= 0 && size_t(idx) < N; }
|
bool in_range(int idx) { return idx >= 0 && Size(idx) < N; }
|
||||||
bool in_range(const T *ptr) {
|
bool in_range(const T *ptr) {
|
||||||
return ptr >= &p_buf[0] && ptr < &p_buf[N];
|
return ptr >= &p_buf[0] && ptr < &p_buf[N];
|
||||||
}
|
}
|
||||||
|
@ -52,10 +52,10 @@ struct Array {
|
||||||
const T *data() const { return p_buf; }
|
const T *data() const { return p_buf; }
|
||||||
|
|
||||||
Range each() {
|
Range each() {
|
||||||
return octa::PointerRange<T>(p_buf, p_buf + N);
|
return Range(p_buf, p_buf + N);
|
||||||
}
|
}
|
||||||
ConstRange each() const {
|
ConstRange each() const {
|
||||||
return octa::PointerRange<const T>(p_buf, p_buf + N);
|
return ConstRange(p_buf, p_buf + N);
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(Array &v) {
|
void swap(Array &v) {
|
||||||
|
|
928
octa/atomic.h
928
octa/atomic.h
|
@ -115,7 +115,7 @@ namespace detail {
|
||||||
__atomic_signal_fence(to_gcc_order(ord));
|
__atomic_signal_fence(to_gcc_order(ord));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool atomic_is_lock_free(size_t size) {
|
static inline bool atomic_is_lock_free(octa::Size size) {
|
||||||
/* return __atomic_is_lock_free(size, 0); cannot be used on some platforms */
|
/* return __atomic_is_lock_free(size, 0); cannot be used on some platforms */
|
||||||
return size <= sizeof(void *);
|
return size <= sizeof(void *);
|
||||||
}
|
}
|
||||||
|
@ -201,13 +201,13 @@ namespace detail {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct SkipAmt { static constexpr size_t value = 1; };
|
struct SkipAmt { static constexpr octa::Size value = 1; };
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct SkipAmt<T *> { static constexpr size_t value = sizeof(T); };
|
struct SkipAmt<T *> { static constexpr octa::Size value = sizeof(T); };
|
||||||
|
|
||||||
template<typename T> struct SkipAmt<T[]> {};
|
template<typename T> struct SkipAmt<T[]> {};
|
||||||
template<typename T, size_t N> struct SkipAmt<T[N]> {};
|
template<typename T, octa::Size N> struct SkipAmt<T[N]> {};
|
||||||
|
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
static inline T atomic_fetch_add(volatile AtomicBase<T> *a,
|
static inline T atomic_fetch_add(volatile AtomicBase<T> *a,
|
||||||
|
@ -450,494 +450,528 @@ namespace detail {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Atomic: octa::detail::Atomic<T> {
|
struct Atomic: octa::detail::Atomic<T> {
|
||||||
using Base = octa::detail::Atomic<T>;
|
using Base = octa::detail::Atomic<T>;
|
||||||
|
|
||||||
Atomic() = default;
|
Atomic() = default;
|
||||||
|
|
||||||
constexpr Atomic(T v): Base(v) {}
|
constexpr Atomic(T v): Base(v) {}
|
||||||
|
|
||||||
T operator=(T v) volatile {
|
T operator=(T v) volatile {
|
||||||
Base::store(v); return v;
|
Base::store(v); return v;
|
||||||
}
|
|
||||||
|
|
||||||
T operator=(T v) {
|
|
||||||
Base::store(v); return v;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct Atomic<T *>: octa::detail::Atomic<T *> {
|
|
||||||
using Base = octa::detail::Atomic<T *>;
|
|
||||||
|
|
||||||
Atomic() = default;
|
|
||||||
|
|
||||||
constexpr Atomic(T *v): Base(v) {}
|
|
||||||
|
|
||||||
T *operator=(T *v) volatile {
|
|
||||||
Base::store(v); return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
T *operator=(T *v) {
|
|
||||||
Base::store(v); return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
T *fetch_add(ptrdiff_t op, MemoryOrder ord = MemoryOrder::seq_cst)
|
|
||||||
volatile {
|
|
||||||
return octa::detail::atomic_fetch_add(&this->p_a, op, ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
T *fetch_add(ptrdiff_t op, MemoryOrder ord = MemoryOrder::seq_cst) {
|
|
||||||
return octa::detail::atomic_fetch_add(&this->p_a, op, ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
T *fetch_sub(ptrdiff_t op, MemoryOrder ord = MemoryOrder::seq_cst)
|
|
||||||
volatile {
|
|
||||||
return octa::detail::atomic_fetch_sub(&this->p_a, op, ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
T *fetch_sub(ptrdiff_t op, MemoryOrder ord = MemoryOrder::seq_cst) {
|
|
||||||
return octa::detail::atomic_fetch_sub(&this->p_a, op, ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
T *operator++(int) volatile { return fetch_add(1); }
|
|
||||||
T *operator++(int) { return fetch_add(1); }
|
|
||||||
T *operator--(int) volatile { return fetch_sub(1); }
|
|
||||||
T *operator--(int) { return fetch_sub(1); }
|
|
||||||
T *operator++( ) volatile { return fetch_add(1) + 1; }
|
|
||||||
T *operator++( ) { return fetch_add(1) + 1; }
|
|
||||||
T *operator--( ) volatile { return fetch_sub(1) - 1; }
|
|
||||||
T *operator--( ) { return fetch_sub(1) - 1; }
|
|
||||||
|
|
||||||
T *operator+=(ptrdiff_t op) volatile { return fetch_add(op) + op; }
|
|
||||||
T *operator+=(ptrdiff_t op) { return fetch_add(op) + op; }
|
|
||||||
T *operator-=(ptrdiff_t op) volatile { return fetch_sub(op) - op; }
|
|
||||||
T *operator-=(ptrdiff_t op) { return fetch_sub(op) - op; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline bool atomic_is_lock_free(const volatile Atomic<T> *a) {
|
|
||||||
return a->is_lock_free();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
T operator=(T v) {
|
||||||
inline bool atomic_is_lock_free(const Atomic<T> *a) {
|
Base::store(v); return v;
|
||||||
return a->is_lock_free();
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct Atomic<T *>: octa::detail::Atomic<T *> {
|
||||||
|
using Base = octa::detail::Atomic<T *>;
|
||||||
|
|
||||||
|
Atomic() = default;
|
||||||
|
|
||||||
|
constexpr Atomic(T *v): Base(v) {}
|
||||||
|
|
||||||
|
T *operator=(T *v) volatile {
|
||||||
|
Base::store(v); return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
T *operator=(T *v) {
|
||||||
inline void atomic_init(volatile Atomic<T> *a, T v) {
|
Base::store(v); return v;
|
||||||
octa::detail::atomic_init(&a->p_a, v);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
T *fetch_add(octa::Ptrdiff op, MemoryOrder ord = MemoryOrder::seq_cst)
|
||||||
inline void atomic_init(Atomic<T> *a, T v) {
|
volatile {
|
||||||
octa::detail::atomic_init(&a->p_a, v);
|
return octa::detail::atomic_fetch_add(&this->p_a, op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
T *fetch_add(octa::Ptrdiff op, MemoryOrder ord = MemoryOrder::seq_cst) {
|
||||||
inline void atomic_store(volatile Atomic<T> *a, T v) {
|
return octa::detail::atomic_fetch_add(&this->p_a, op, ord);
|
||||||
a->store(v);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
T *fetch_sub(octa::Ptrdiff op, MemoryOrder ord = MemoryOrder::seq_cst)
|
||||||
inline void atomic_store(Atomic<T> *a, T v) {
|
volatile {
|
||||||
a->store(v);
|
return octa::detail::atomic_fetch_sub(&this->p_a, op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
T *fetch_sub(octa::Ptrdiff op, MemoryOrder ord = MemoryOrder::seq_cst) {
|
||||||
inline void atomic_store_explicit(volatile Atomic<T> *a, T v,
|
return octa::detail::atomic_fetch_sub(&this->p_a, op, ord);
|
||||||
MemoryOrder ord) {
|
|
||||||
a->store(v, ord);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline void atomic_store_explicit(Atomic<T> *a, T v,
|
|
||||||
MemoryOrder ord) {
|
|
||||||
a->store(v, ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
T *operator++(int) volatile { return fetch_add(1); }
|
||||||
inline T atomic_load(const volatile Atomic<T> *a) {
|
T *operator++(int) { return fetch_add(1); }
|
||||||
return a->load();
|
T *operator--(int) volatile { return fetch_sub(1); }
|
||||||
}
|
T *operator--(int) { return fetch_sub(1); }
|
||||||
|
T *operator++( ) volatile { return fetch_add(1) + 1; }
|
||||||
|
T *operator++( ) { return fetch_add(1) + 1; }
|
||||||
|
T *operator--( ) volatile { return fetch_sub(1) - 1; }
|
||||||
|
T *operator--( ) { return fetch_sub(1) - 1; }
|
||||||
|
|
||||||
template <typename T>
|
T *operator+=(octa::Ptrdiff op) volatile { return fetch_add(op) + op; }
|
||||||
inline T atomic_load(const Atomic<T> *a) {
|
T *operator+=(octa::Ptrdiff op) { return fetch_add(op) + op; }
|
||||||
return a->load();
|
T *operator-=(octa::Ptrdiff op) volatile { return fetch_sub(op) - op; }
|
||||||
}
|
T *operator-=(octa::Ptrdiff op) { return fetch_sub(op) - op; }
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
inline T atomic_load_explicit(const volatile Atomic<T> *a,
|
inline bool atomic_is_lock_free(const volatile Atomic<T> *a) {
|
||||||
|
return a->is_lock_free();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline bool atomic_is_lock_free(const Atomic<T> *a) {
|
||||||
|
return a->is_lock_free();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline void atomic_init(volatile Atomic<T> *a, T v) {
|
||||||
|
octa::detail::atomic_init(&a->p_a, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline void atomic_init(Atomic<T> *a, T v) {
|
||||||
|
octa::detail::atomic_init(&a->p_a, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void atomic_store(volatile Atomic<T> *a, T v) {
|
||||||
|
a->store(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void atomic_store(Atomic<T> *a, T v) {
|
||||||
|
a->store(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void atomic_store_explicit(volatile Atomic<T> *a, T v,
|
||||||
|
MemoryOrder ord) {
|
||||||
|
a->store(v, ord);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void atomic_store_explicit(Atomic<T> *a, T v,
|
||||||
|
MemoryOrder ord) {
|
||||||
|
a->store(v, ord);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T atomic_load(const volatile Atomic<T> *a) {
|
||||||
|
return a->load();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T atomic_load(const Atomic<T> *a) {
|
||||||
|
return a->load();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T atomic_load_explicit(const volatile Atomic<T> *a,
|
||||||
|
MemoryOrder ord) {
|
||||||
|
return a->load(ord);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T atomic_load_explicit(const Atomic<T> *a, MemoryOrder ord) {
|
||||||
|
return a->load(ord);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T atomic_exchange(volatile Atomic<T> *a, T v) {
|
||||||
|
return a->exchange(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T atomic_exchange(Atomic<T> *a, T v) {
|
||||||
|
return a->exchange(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T atomic_exchange_explicit(volatile Atomic<T> *a, T v,
|
||||||
|
MemoryOrder ord) {
|
||||||
|
return a->exchange(v, ord);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T atomic_exchange_explicit(Atomic<T> *a, T v,
|
||||||
MemoryOrder ord) {
|
MemoryOrder ord) {
|
||||||
return a->load(ord);
|
return a->exchange(v, ord);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool atomic_compare_exchange_weak(volatile Atomic<T> *a,
|
||||||
|
T *e, T v) {
|
||||||
|
return a->compare_exchange_weak(*e, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool atomic_compare_exchange_weak(Atomic<T> *a, T *e, T v) {
|
||||||
|
return a->compare_exchange_weak(*e, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool atomic_compare_exchange_strong(volatile Atomic<T> *a,
|
||||||
|
T *e, T v) {
|
||||||
|
return a->compare_exchange_strong(*e, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool atomic_compare_exchange_strong(Atomic<T> *a, T *e, T v) {
|
||||||
|
return a->compare_exchange_strong(*e, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool atomic_compare_exchange_weak_explicit(volatile Atomic<T> *a,
|
||||||
|
T *e, T v,
|
||||||
|
MemoryOrder s,
|
||||||
|
MemoryOrder f) {
|
||||||
|
return a->compare_exchange_weak(*e, v, s, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool atomic_compare_exchange_weak_explicit(Atomic<T> *a, T *e,
|
||||||
|
T v,
|
||||||
|
MemoryOrder s,
|
||||||
|
MemoryOrder f) {
|
||||||
|
return a->compare_exchange_weak(*e, v, s, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool atomic_compare_exchange_strong_explicit(volatile Atomic<T> *a,
|
||||||
|
T *e, T v,
|
||||||
|
MemoryOrder s,
|
||||||
|
MemoryOrder f) {
|
||||||
|
return a->compare_exchange_strong(*e, v, s, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool atomic_compare_exchange_strong_explicit(Atomic<T> *a, T *e,
|
||||||
|
T v,
|
||||||
|
MemoryOrder s,
|
||||||
|
MemoryOrder f) {
|
||||||
|
return a->compare_exchange_strong(*e, v, s, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
||||||
|
!octa::IsSame<T, bool>::value, T>
|
||||||
|
atomic_fetch_add(volatile Atomic<T> *a, T op) {
|
||||||
|
return a->fetch_add(op);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
||||||
|
!octa::IsSame<T, bool>::value, T>
|
||||||
|
atomic_fetch_add(Atomic<T> *a, T op) {
|
||||||
|
return a->fetch_add(op);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T *atomic_fetch_add(volatile Atomic<T *> *a, octa::Ptrdiff op) {
|
||||||
|
return a->fetch_add(op);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T *atomic_fetch_add(Atomic<T *> *a, octa::Ptrdiff op) {
|
||||||
|
return a->fetch_add(op);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
||||||
|
!octa::IsSame<T, bool>::value, T>
|
||||||
|
atomic_fetch_add_explicit(volatile Atomic<T> *a, T op,
|
||||||
|
MemoryOrder ord) {
|
||||||
|
return a->fetch_add(op, ord);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
||||||
|
!octa::IsSame<T, bool>::value, T>
|
||||||
|
atomic_fetch_add_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
||||||
|
return a->fetch_add(op, ord);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T *atomic_fetch_add_explicit(volatile Atomic<T *> *a,
|
||||||
|
octa::Ptrdiff op, MemoryOrder ord) {
|
||||||
|
return a->fetch_add(op, ord);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T *atomic_fetch_add_explicit(Atomic<T *> *a, octa::Ptrdiff op,
|
||||||
|
MemoryOrder ord) {
|
||||||
|
return a->fetch_add(op, ord);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
||||||
|
!octa::IsSame<T, bool>::value, T>
|
||||||
|
atomic_fetch_sub(volatile Atomic<T> *a, T op) {
|
||||||
|
return a->fetch_sub(op);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
||||||
|
!octa::IsSame<T, bool>::value, T>
|
||||||
|
atomic_fetch_sub(Atomic<T> *a, T op) {
|
||||||
|
return a->fetch_sub(op);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T *atomic_fetch_sub(volatile Atomic<T *> *a, octa::Ptrdiff op) {
|
||||||
|
return a->fetch_sub(op);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T *atomic_fetch_sub(Atomic<T *> *a, octa::Ptrdiff op) {
|
||||||
|
return a->fetch_sub(op);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
||||||
|
!octa::IsSame<T, bool>::value, T>
|
||||||
|
atomic_fetch_sub_explicit(volatile Atomic<T> *a, T op,
|
||||||
|
MemoryOrder ord) {
|
||||||
|
return a->fetch_sub(op, ord);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
||||||
|
!octa::IsSame<T, bool>::value, T>
|
||||||
|
atomic_fetch_sub_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
||||||
|
return a->fetch_sub(op, ord);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T *atomic_fetch_sub_explicit(volatile Atomic<T *> *a,
|
||||||
|
octa::Ptrdiff op, MemoryOrder ord) {
|
||||||
|
return a->fetch_sub(op, ord);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T *atomic_fetch_sub_explicit(Atomic<T *> *a, octa::Ptrdiff op,
|
||||||
|
MemoryOrder ord) {
|
||||||
|
return a->fetch_sub(op, ord);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
||||||
|
!octa::IsSame<T, bool>::value, T>
|
||||||
|
atomic_fetch_and(volatile Atomic<T> *a, T op) {
|
||||||
|
return a->fetch_and(op);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
||||||
|
!octa::IsSame<T, bool>::value, T>
|
||||||
|
atomic_fetch_and(Atomic<T> *a, T op) {
|
||||||
|
return a->fetch_and(op);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
||||||
|
!octa::IsSame<T, bool>::value, T>
|
||||||
|
atomic_fetch_and_explicit(volatile Atomic<T> *a, T op,
|
||||||
|
MemoryOrder ord) {
|
||||||
|
return a->fetch_and(op, ord);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
||||||
|
!octa::IsSame<T, bool>::value, T>
|
||||||
|
atomic_fetch_and_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
||||||
|
return a->fetch_and(op, ord);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
||||||
|
!octa::IsSame<T, bool>::value, T>
|
||||||
|
atomic_fetch_or(volatile Atomic<T> *a, T op) {
|
||||||
|
return a->fetch_or(op);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
||||||
|
!octa::IsSame<T, bool>::value, T>
|
||||||
|
atomic_fetch_or(Atomic<T> *a, T op) {
|
||||||
|
return a->fetch_or(op);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
||||||
|
!octa::IsSame<T, bool>::value, T>
|
||||||
|
atomic_fetch_or_explicit(volatile Atomic<T> *a, T op,
|
||||||
|
MemoryOrder ord) {
|
||||||
|
return a->fetch_or(op, ord);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
||||||
|
!octa::IsSame<T, bool>::value, T>
|
||||||
|
atomic_fetch_or_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
||||||
|
return a->fetch_or(op, ord);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
||||||
|
!octa::IsSame<T, bool>::value, T>
|
||||||
|
atomic_fetch_xor(volatile Atomic<T> *a, T op) {
|
||||||
|
return a->fetch_xor(op);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
||||||
|
!octa::IsSame<T, bool>::value, T>
|
||||||
|
atomic_fetch_xor(Atomic<T> *a, T op) {
|
||||||
|
return a->fetch_xor(op);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
||||||
|
!octa::IsSame<T, bool>::value, T>
|
||||||
|
atomic_fetch_xor_explicit(volatile Atomic<T> *a, T op,
|
||||||
|
MemoryOrder ord) {
|
||||||
|
return a->fetch_xor(op, ord);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
||||||
|
!octa::IsSame<T, bool>::value, T>
|
||||||
|
atomic_fetch_xor_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
||||||
|
return a->fetch_xor(op, ord);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AtomicFlag {
|
||||||
|
octa::detail::AtomicBase<bool> p_a;
|
||||||
|
|
||||||
|
AtomicFlag() = default;
|
||||||
|
|
||||||
|
AtomicFlag(bool b): p_a(b) {}
|
||||||
|
|
||||||
|
AtomicFlag(const AtomicFlag &) = delete;
|
||||||
|
|
||||||
|
AtomicFlag &operator=(const AtomicFlag &) = delete;
|
||||||
|
AtomicFlag &operator=(const AtomicFlag &) volatile = delete;
|
||||||
|
|
||||||
|
bool test_and_set(MemoryOrder ord = MemoryOrder::seq_cst) volatile {
|
||||||
|
return octa::detail::atomic_exchange(&p_a, true, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
bool test_and_set(MemoryOrder ord = MemoryOrder::seq_cst) {
|
||||||
inline T atomic_load_explicit(const Atomic<T> *a, MemoryOrder ord) {
|
return octa::detail::atomic_exchange(&p_a, true, ord);
|
||||||
return a->load(ord);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
void clear(MemoryOrder ord = MemoryOrder::seq_cst) volatile {
|
||||||
inline T atomic_exchange(volatile Atomic<T> *a, T v) {
|
octa::detail::atomic_store(&p_a, false, ord);
|
||||||
return a->exchange(v);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
void clear(MemoryOrder ord = MemoryOrder::seq_cst) {
|
||||||
inline T atomic_exchange(Atomic<T> *a, T v) {
|
octa::detail::atomic_store(&p_a, false, ord);
|
||||||
return a->exchange(v);
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T>
|
inline bool atomic_flag_test_and_set(volatile AtomicFlag *a) {
|
||||||
inline T atomic_exchange_explicit(volatile Atomic<T> *a, T v,
|
return a->test_and_set();
|
||||||
MemoryOrder ord) {
|
}
|
||||||
return a->exchange(v, ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
inline bool atomic_flag_test_and_set(AtomicFlag *a) {
|
||||||
inline T atomic_exchange_explicit(Atomic<T> *a, T v,
|
return a->test_and_set();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool atomic_flag_test_and_set_explicit(volatile AtomicFlag *a,
|
||||||
|
MemoryOrder ord) {
|
||||||
|
return a->test_and_set(ord);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool atomic_flag_test_and_set_explicit(AtomicFlag *a,
|
||||||
|
MemoryOrder ord) {
|
||||||
|
return a->test_and_set(ord);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void atomic_flag_clear(volatile AtomicFlag *a) {
|
||||||
|
a->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void atomic_flag_clear(AtomicFlag *a) {
|
||||||
|
a->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void atomic_flag_clear_explicit(volatile AtomicFlag *a,
|
||||||
MemoryOrder ord) {
|
MemoryOrder ord) {
|
||||||
return a->exchange(v, ord);
|
a->clear(ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
inline void atomic_flag_clear_explicit(AtomicFlag *a, MemoryOrder ord) {
|
||||||
inline bool atomic_compare_exchange_weak(volatile Atomic<T> *a,
|
a->clear(ord);
|
||||||
T *e, T v) {
|
}
|
||||||
return a->compare_exchange_weak(*e, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
inline void atomic_thread_fence(MemoryOrder ord) {
|
||||||
inline bool atomic_compare_exchange_weak(Atomic<T> *a, T *e, T v) {
|
octa::detail::atomic_thread_fence(ord);
|
||||||
return a->compare_exchange_weak(*e, v);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
inline void atomic_signal_fence(MemoryOrder ord) {
|
||||||
inline bool atomic_compare_exchange_strong(volatile Atomic<T> *a,
|
octa::detail::atomic_signal_fence(ord);
|
||||||
T *e, T v) {
|
}
|
||||||
return a->compare_exchange_strong(*e, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
using AtomicBool = Atomic<bool>;
|
||||||
inline bool atomic_compare_exchange_strong(Atomic<T> *a, T *e, T v) {
|
using AtomicChar = Atomic<char>;
|
||||||
return a->compare_exchange_strong(*e, v);
|
using AtomicShort = Atomic<short>;
|
||||||
}
|
using AtomicInt = Atomic<int>;
|
||||||
|
using AtomicLong = Atomic<long>;
|
||||||
|
using AtomicSchar = Atomic<octa::schar>;
|
||||||
|
using AtomicUchar = Atomic<octa::uchar>;
|
||||||
|
using AtomicUshort = Atomic<octa::ushort>;
|
||||||
|
using AtomicUint = Atomic<octa::uint>;
|
||||||
|
using AtomicUlong = Atomic<octa::ulong>;
|
||||||
|
using AtomicLlong = Atomic<octa::llong>;
|
||||||
|
using AtomicUllong = Atomic<octa::ullong>;
|
||||||
|
|
||||||
template <typename T>
|
using AtomicChar16 = Atomic<octa::Char16>;
|
||||||
inline bool atomic_compare_exchange_weak_explicit(volatile Atomic<T> *a,
|
using AtomicChar32 = Atomic<octa::Char32>;
|
||||||
T *e, T v,
|
using AtomicWchar = Atomic<octa::Wchar>;
|
||||||
MemoryOrder s,
|
|
||||||
MemoryOrder f) {
|
|
||||||
return a->compare_exchange_weak(*e, v, s, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
using AtomicPtrdiff = Atomic<octa::Ptrdiff>;
|
||||||
inline bool atomic_compare_exchange_weak_explicit(Atomic<T> *a, T *e,
|
using AtomicSize = Atomic<octa::Size>;
|
||||||
T v,
|
|
||||||
MemoryOrder s,
|
|
||||||
MemoryOrder f) {
|
|
||||||
return a->compare_exchange_weak(*e, v, s, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
using AtomicIntmax = Atomic<octa::Intmax>;
|
||||||
inline bool atomic_compare_exchange_strong_explicit(volatile Atomic<T> *a,
|
using AtomicUintmax = Atomic<octa::Uintmax>;
|
||||||
T *e, T v,
|
|
||||||
MemoryOrder s,
|
|
||||||
MemoryOrder f) {
|
|
||||||
return a->compare_exchange_strong(*e, v, s, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
using AtomicIntptr = Atomic<octa::Intptr>;
|
||||||
inline bool atomic_compare_exchange_strong_explicit(Atomic<T> *a, T *e,
|
using AtomicUintptr = Atomic<octa::Uintptr>;
|
||||||
T v,
|
|
||||||
MemoryOrder s,
|
|
||||||
MemoryOrder f) {
|
|
||||||
return a->compare_exchange_strong(*e, v, s, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
using AtomicInt8 = Atomic<octa::Int8>;
|
||||||
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
using AtomicInt16 = Atomic<octa::Int16>;
|
||||||
!octa::IsSame<T, bool>::value, T>
|
using AtomicInt32 = Atomic<octa::Int32>;
|
||||||
atomic_fetch_add(volatile Atomic<T> *a, T op) {
|
using AtomicInt64 = Atomic<octa::Int64>;
|
||||||
return a->fetch_add(op);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
using AtomicUint8 = Atomic<octa::Uint8>;
|
||||||
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
using AtomicUint16 = Atomic<octa::Uint16>;
|
||||||
!octa::IsSame<T, bool>::value, T>
|
using AtomicUint32 = Atomic<octa::Uint32>;
|
||||||
atomic_fetch_add(Atomic<T> *a, T op) {
|
using AtomicUint64 = Atomic<octa::Uint64>;
|
||||||
return a->fetch_add(op);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
using AtomicIntLeast8 = Atomic<octa::IntLeast8>;
|
||||||
inline T *atomic_fetch_add(volatile Atomic<T *> *a, ptrdiff_t op) {
|
using AtomicIntLeast16 = Atomic<octa::IntLeast16>;
|
||||||
return a->fetch_add(op);
|
using AtomicIntLeast32 = Atomic<octa::IntLeast32>;
|
||||||
}
|
using AtomicIntLeast64 = Atomic<octa::IntLeast64>;
|
||||||
|
|
||||||
template <typename T>
|
using AtomicUintLeast8 = Atomic<octa::UintLeast8>;
|
||||||
inline T *atomic_fetch_add(Atomic<T *> *a, ptrdiff_t op) {
|
using AtomicUintLeast16 = Atomic<octa::UintLeast16>;
|
||||||
return a->fetch_add(op);
|
using AtomicUintLeast32 = Atomic<octa::UintLeast32>;
|
||||||
}
|
using AtomicUintLeast64 = Atomic<octa::UintLeast64>;
|
||||||
|
|
||||||
template <typename T>
|
using AtomicIntFast8 = Atomic<octa::IntFast8>;
|
||||||
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
using AtomicIntFast16 = Atomic<octa::IntFast16>;
|
||||||
!octa::IsSame<T, bool>::value, T>
|
using AtomicIntFast32 = Atomic<octa::IntFast32>;
|
||||||
atomic_fetch_add_explicit(volatile Atomic<T> *a, T op,
|
using AtomicIntFast64 = Atomic<octa::IntFast64>;
|
||||||
MemoryOrder ord) {
|
|
||||||
return a->fetch_add(op, ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
using AtomicUintFast8 = Atomic<octa::UintFast8>;
|
||||||
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
using AtomicUintFast16 = Atomic<octa::UintFast16>;
|
||||||
!octa::IsSame<T, bool>::value, T>
|
using AtomicUintFast32 = Atomic<octa::UintFast32>;
|
||||||
atomic_fetch_add_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
using AtomicUintFast64 = Atomic<octa::UintFast64>;
|
||||||
return a->fetch_add(op, ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline T *atomic_fetch_add_explicit(volatile Atomic<T *> *a,
|
|
||||||
ptrdiff_t op, MemoryOrder ord) {
|
|
||||||
return a->fetch_add(op, ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline T *atomic_fetch_add_explicit(Atomic<T *> *a, ptrdiff_t op,
|
|
||||||
MemoryOrder ord) {
|
|
||||||
return a->fetch_add(op, ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
|
||||||
!octa::IsSame<T, bool>::value, T>
|
|
||||||
atomic_fetch_sub(volatile Atomic<T> *a, T op) {
|
|
||||||
return a->fetch_sub(op);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
|
||||||
!octa::IsSame<T, bool>::value, T>
|
|
||||||
atomic_fetch_sub(Atomic<T> *a, T op) {
|
|
||||||
return a->fetch_sub(op);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline T *atomic_fetch_sub(volatile Atomic<T *> *a, ptrdiff_t op) {
|
|
||||||
return a->fetch_sub(op);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline T *atomic_fetch_sub(Atomic<T *> *a, ptrdiff_t op) {
|
|
||||||
return a->fetch_sub(op);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
|
||||||
!octa::IsSame<T, bool>::value, T>
|
|
||||||
atomic_fetch_sub_explicit(volatile Atomic<T> *a, T op,
|
|
||||||
MemoryOrder ord) {
|
|
||||||
return a->fetch_sub(op, ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
|
||||||
!octa::IsSame<T, bool>::value, T>
|
|
||||||
atomic_fetch_sub_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
|
||||||
return a->fetch_sub(op, ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline T *atomic_fetch_sub_explicit(volatile Atomic<T *> *a,
|
|
||||||
ptrdiff_t op, MemoryOrder ord) {
|
|
||||||
return a->fetch_sub(op, ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline T *atomic_fetch_sub_explicit(Atomic<T *> *a, ptrdiff_t op,
|
|
||||||
MemoryOrder ord) {
|
|
||||||
return a->fetch_sub(op, ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
|
||||||
!octa::IsSame<T, bool>::value, T>
|
|
||||||
atomic_fetch_and(volatile Atomic<T> *a, T op) {
|
|
||||||
return a->fetch_and(op);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
|
||||||
!octa::IsSame<T, bool>::value, T>
|
|
||||||
atomic_fetch_and(Atomic<T> *a, T op) {
|
|
||||||
return a->fetch_and(op);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
|
||||||
!octa::IsSame<T, bool>::value, T>
|
|
||||||
atomic_fetch_and_explicit(volatile Atomic<T> *a, T op,
|
|
||||||
MemoryOrder ord) {
|
|
||||||
return a->fetch_and(op, ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
|
||||||
!octa::IsSame<T, bool>::value, T>
|
|
||||||
atomic_fetch_and_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
|
||||||
return a->fetch_and(op, ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
|
||||||
!octa::IsSame<T, bool>::value, T>
|
|
||||||
atomic_fetch_or(volatile Atomic<T> *a, T op) {
|
|
||||||
return a->fetch_or(op);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
|
||||||
!octa::IsSame<T, bool>::value, T>
|
|
||||||
atomic_fetch_or(Atomic<T> *a, T op) {
|
|
||||||
return a->fetch_or(op);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
|
||||||
!octa::IsSame<T, bool>::value, T>
|
|
||||||
atomic_fetch_or_explicit(volatile Atomic<T> *a, T op,
|
|
||||||
MemoryOrder ord) {
|
|
||||||
return a->fetch_or(op, ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
|
||||||
!octa::IsSame<T, bool>::value, T>
|
|
||||||
atomic_fetch_or_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
|
||||||
return a->fetch_or(op, ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
|
||||||
!octa::IsSame<T, bool>::value, T>
|
|
||||||
atomic_fetch_xor(volatile Atomic<T> *a, T op) {
|
|
||||||
return a->fetch_xor(op);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
|
||||||
!octa::IsSame<T, bool>::value, T>
|
|
||||||
atomic_fetch_xor(Atomic<T> *a, T op) {
|
|
||||||
return a->fetch_xor(op);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
|
||||||
!octa::IsSame<T, bool>::value, T>
|
|
||||||
atomic_fetch_xor_explicit(volatile Atomic<T> *a, T op,
|
|
||||||
MemoryOrder ord) {
|
|
||||||
return a->fetch_xor(op, ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline octa::EnableIf<octa::IsIntegral<T>::value &&
|
|
||||||
!octa::IsSame<T, bool>::value, T>
|
|
||||||
atomic_fetch_xor_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
|
||||||
return a->fetch_xor(op, ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct AtomicFlag {
|
|
||||||
octa::detail::AtomicBase<bool> p_a;
|
|
||||||
|
|
||||||
AtomicFlag() = default;
|
|
||||||
|
|
||||||
AtomicFlag(bool b): p_a(b) {}
|
|
||||||
|
|
||||||
AtomicFlag(const AtomicFlag &) = delete;
|
|
||||||
|
|
||||||
AtomicFlag &operator=(const AtomicFlag &) = delete;
|
|
||||||
AtomicFlag &operator=(const AtomicFlag &) volatile = delete;
|
|
||||||
|
|
||||||
bool test_and_set(MemoryOrder ord = MemoryOrder::seq_cst) volatile {
|
|
||||||
return octa::detail::atomic_exchange(&p_a, true, ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool test_and_set(MemoryOrder ord = MemoryOrder::seq_cst) {
|
|
||||||
return octa::detail::atomic_exchange(&p_a, true, ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear(MemoryOrder ord = MemoryOrder::seq_cst) volatile {
|
|
||||||
octa::detail::atomic_store(&p_a, false, ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear(MemoryOrder ord = MemoryOrder::seq_cst) {
|
|
||||||
octa::detail::atomic_store(&p_a, false, ord);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
inline bool atomic_flag_test_and_set(volatile AtomicFlag *a) {
|
|
||||||
return a->test_and_set();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool atomic_flag_test_and_set(AtomicFlag *a) {
|
|
||||||
return a->test_and_set();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool atomic_flag_test_and_set_explicit(volatile AtomicFlag *a,
|
|
||||||
MemoryOrder ord) {
|
|
||||||
return a->test_and_set(ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool atomic_flag_test_and_set_explicit(AtomicFlag *a,
|
|
||||||
MemoryOrder ord) {
|
|
||||||
return a->test_and_set(ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void atomic_flag_clear(volatile AtomicFlag *a) {
|
|
||||||
a->clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void atomic_flag_clear(AtomicFlag *a) {
|
|
||||||
a->clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void atomic_flag_clear_explicit(volatile AtomicFlag *a,
|
|
||||||
MemoryOrder ord) {
|
|
||||||
a->clear(ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void atomic_flag_clear_explicit(AtomicFlag *a, MemoryOrder ord) {
|
|
||||||
a->clear(ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void atomic_thread_fence(MemoryOrder ord) {
|
|
||||||
octa::detail::atomic_thread_fence(ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void atomic_signal_fence(MemoryOrder ord) {
|
|
||||||
octa::detail::atomic_signal_fence(ord);
|
|
||||||
}
|
|
||||||
|
|
||||||
using AtomicBool = Atomic<bool>;
|
|
||||||
using AtomicChar = Atomic<char>;
|
|
||||||
using AtomicSchar = Atomic<schar>;
|
|
||||||
using AtomicUchar = Atomic<uchar>;
|
|
||||||
using AtomicShort = Atomic<short>;
|
|
||||||
using AtomicUshort = Atomic<ushort>;
|
|
||||||
using AtomicInt = Atomic<int>;
|
|
||||||
using AtomicUint = Atomic<uint>;
|
|
||||||
using AtomicLong = Atomic<long>;
|
|
||||||
using AtomicUlong = Atomic<ulong>;
|
|
||||||
using AtomicLlong = Atomic<llong>;
|
|
||||||
using AtomicUllong = Atomic<ullong>;
|
|
||||||
|
|
||||||
using AtomicChar16 = Atomic<char16_t>;
|
|
||||||
using AtomicChar32 = Atomic<char32_t>;
|
|
||||||
using AtomicWchar = Atomic<wchar_t>;
|
|
||||||
|
|
||||||
using AtomicIntptr = Atomic<intptr_t>;
|
|
||||||
using AtomicUintptr = Atomic<uintptr_t>;
|
|
||||||
using AtomicSize = Atomic<size_t>;
|
|
||||||
using AtomicPtrdiff = Atomic<ptrdiff_t>;
|
|
||||||
|
|
||||||
#define ATOMIC_FLAG_INIT {false}
|
#define ATOMIC_FLAG_INIT {false}
|
||||||
#define ATOMIC_VAR_INIT(v) {v}
|
#define ATOMIC_VAR_INIT(v) {v}
|
||||||
|
|
|
@ -98,10 +98,10 @@ template<typename T> struct Hash;
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T> struct HashBase {
|
template<typename T> struct HashBase {
|
||||||
using Argument = T;
|
using Argument = T;
|
||||||
using Result = size_t;
|
using Result = octa::Size;
|
||||||
|
|
||||||
size_t operator()(T v) const {
|
octa::Size operator()(T v) const {
|
||||||
return size_t(v);
|
return octa::Size(v);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -110,37 +110,39 @@ namespace detail {
|
||||||
|
|
||||||
OCTA_HASH_BASIC(bool)
|
OCTA_HASH_BASIC(bool)
|
||||||
OCTA_HASH_BASIC(char)
|
OCTA_HASH_BASIC(char)
|
||||||
OCTA_HASH_BASIC(schar)
|
|
||||||
OCTA_HASH_BASIC(uchar)
|
|
||||||
OCTA_HASH_BASIC(char16_t)
|
|
||||||
OCTA_HASH_BASIC(char32_t)
|
|
||||||
OCTA_HASH_BASIC(wchar_t)
|
|
||||||
OCTA_HASH_BASIC(short)
|
OCTA_HASH_BASIC(short)
|
||||||
OCTA_HASH_BASIC(ushort)
|
|
||||||
OCTA_HASH_BASIC(int)
|
OCTA_HASH_BASIC(int)
|
||||||
OCTA_HASH_BASIC(uint)
|
|
||||||
OCTA_HASH_BASIC(long)
|
OCTA_HASH_BASIC(long)
|
||||||
OCTA_HASH_BASIC(ulong)
|
|
||||||
|
OCTA_HASH_BASIC(octa::schar)
|
||||||
|
OCTA_HASH_BASIC(octa::uchar)
|
||||||
|
OCTA_HASH_BASIC(octa::ushort)
|
||||||
|
OCTA_HASH_BASIC(octa::uint)
|
||||||
|
OCTA_HASH_BASIC(octa::ulong)
|
||||||
|
|
||||||
|
OCTA_HASH_BASIC(octa::Char16)
|
||||||
|
OCTA_HASH_BASIC(octa::Char32)
|
||||||
|
OCTA_HASH_BASIC(octa::Wchar)
|
||||||
|
|
||||||
#undef OCTA_HASH_BASIC
|
#undef OCTA_HASH_BASIC
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
static inline size_t mem_hash(const void *p, size_t l) {
|
static inline Size mem_hash(const void *p, octa::Size l) {
|
||||||
const uchar *d = (const uchar *)p;
|
const octa::uchar *d = (const octa::uchar *)p;
|
||||||
size_t h = 5381;
|
octa::Size h = 5381;
|
||||||
for (size_t i = 0; i < l; ++i) h = ((h << 5) + h) ^ d[i];
|
for (Size i = 0; i < l; ++i) h = ((h << 5) + h) ^ d[i];
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, size_t = sizeof(T) / sizeof(size_t)>
|
template<typename T, octa::Size = sizeof(T) / sizeof(octa::Size)>
|
||||||
struct ScalarHash;
|
struct ScalarHash;
|
||||||
|
|
||||||
template<typename T> struct ScalarHash<T, 0> {
|
template<typename T> struct ScalarHash<T, 0> {
|
||||||
using Argument = T;
|
using Argument = T;
|
||||||
using Result = size_t;
|
using Result = octa::Size;
|
||||||
|
|
||||||
size_t operator()(T v) const {
|
octa::Size operator()(T v) const {
|
||||||
union { T v; size_t h; } u;
|
union { T v; octa::Size h; } u;
|
||||||
u.h = 0;
|
u.h = 0;
|
||||||
u.v = v;
|
u.v = v;
|
||||||
return u.h;
|
return u.h;
|
||||||
|
@ -149,10 +151,10 @@ namespace detail {
|
||||||
|
|
||||||
template<typename T> struct ScalarHash<T, 1> {
|
template<typename T> struct ScalarHash<T, 1> {
|
||||||
using Argument = T;
|
using Argument = T;
|
||||||
using Result = size_t;
|
using Result = octa::Size;
|
||||||
|
|
||||||
size_t operator()(T v) const {
|
octa::Size operator()(T v) const {
|
||||||
union { T v; size_t h; } u;
|
union { T v; octa::Size h; } u;
|
||||||
u.v = v;
|
u.v = v;
|
||||||
return u.h;
|
return u.h;
|
||||||
}
|
}
|
||||||
|
@ -160,10 +162,10 @@ namespace detail {
|
||||||
|
|
||||||
template<typename T> struct ScalarHash<T, 2> {
|
template<typename T> struct ScalarHash<T, 2> {
|
||||||
using Argument = T;
|
using Argument = T;
|
||||||
using Result = size_t;
|
using Result = octa::Size;
|
||||||
|
|
||||||
size_t operator()(T v) const {
|
octa::Size operator()(T v) const {
|
||||||
union { T v; struct { size_t h1, h2; }; } u;
|
union { T v; struct { octa::Size h1, h2; }; } u;
|
||||||
u.v = v;
|
u.v = v;
|
||||||
return mem_hash((const void *)&u, sizeof(u));
|
return mem_hash((const void *)&u, sizeof(u));
|
||||||
}
|
}
|
||||||
|
@ -171,10 +173,10 @@ namespace detail {
|
||||||
|
|
||||||
template<typename T> struct ScalarHash<T, 3> {
|
template<typename T> struct ScalarHash<T, 3> {
|
||||||
using Argument = T;
|
using Argument = T;
|
||||||
using Result = size_t;
|
using Result = octa::Size;
|
||||||
|
|
||||||
size_t operator()(T v) const {
|
octa::Size operator()(T v) const {
|
||||||
union { T v; struct { size_t h1, h2, h3; }; } u;
|
union { T v; struct { octa::Size h1, h2, h3; }; } u;
|
||||||
u.v = v;
|
u.v = v;
|
||||||
return mem_hash((const void *)&u, sizeof(u));
|
return mem_hash((const void *)&u, sizeof(u));
|
||||||
}
|
}
|
||||||
|
@ -182,49 +184,49 @@ namespace detail {
|
||||||
|
|
||||||
template<typename T> struct ScalarHash<T, 4> {
|
template<typename T> struct ScalarHash<T, 4> {
|
||||||
using Argument = T;
|
using Argument = T;
|
||||||
using Result = size_t;
|
using Result = octa::Size;
|
||||||
|
|
||||||
size_t operator()(T v) const {
|
octa::Size operator()(T v) const {
|
||||||
union { T v; struct { size_t h1, h2, h3, h4; }; } u;
|
union { T v; struct { octa::Size h1, h2, h3, h4; }; } u;
|
||||||
u.v = v;
|
u.v = v;
|
||||||
return mem_hash((const void *)&u, sizeof(u));
|
return mem_hash((const void *)&u, sizeof(u));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} /* namespace detail */
|
} /* namespace detail */
|
||||||
|
|
||||||
template<> struct Hash<llong>: octa::detail::ScalarHash<llong> {};
|
template<> struct Hash<octa::llong>: octa::detail::ScalarHash<octa::llong> {};
|
||||||
template<> struct Hash<ullong>: octa::detail::ScalarHash<ullong> {};
|
template<> struct Hash<octa::ullong>: octa::detail::ScalarHash<octa::ullong> {};
|
||||||
|
|
||||||
template<> struct Hash<float>: octa::detail::ScalarHash<float> {
|
template<> struct Hash<float>: octa::detail::ScalarHash<float> {
|
||||||
size_t operator()(float v) const {
|
octa::Size operator()(float v) const {
|
||||||
if (v == 0) return 0;
|
if (v == 0) return 0;
|
||||||
return octa::detail::ScalarHash<float>::operator()(v);
|
return octa::detail::ScalarHash<float>::operator()(v);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<> struct Hash<double>: octa::detail::ScalarHash<double> {
|
template<> struct Hash<double>: octa::detail::ScalarHash<double> {
|
||||||
size_t operator()(double v) const {
|
octa::Size operator()(double v) const {
|
||||||
if (v == 0) return 0;
|
if (v == 0) return 0;
|
||||||
return octa::detail::ScalarHash<double>::operator()(v);
|
return octa::detail::ScalarHash<double>::operator()(v);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<> struct Hash<ldouble>: octa::detail::ScalarHash<ldouble> {
|
template<> struct Hash<octa::ldouble>: octa::detail::ScalarHash<octa::ldouble> {
|
||||||
size_t operator()(ldouble v) const {
|
octa::Size operator()(octa::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 { octa::ldouble v; struct { octa::Size h1, h2, h3, h4; }; } u;
|
||||||
u.h1 = u.h2 = u.h3 = u.h4 = 0;
|
u.h1 = u.h2 = u.h3 = u.h4 = 0;
|
||||||
u.v = v;
|
u.v = v;
|
||||||
return (u.h1 ^ u.h2 ^ u.h3 ^ u.h4);
|
return (u.h1 ^ u.h2 ^ u.h3 ^ u.h4);
|
||||||
#else
|
#else
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
union { ldouble v; struct { size_t h1, h2; }; } u;
|
union { octa::ldouble v; struct { octa::Size h1, h2; }; } u;
|
||||||
u.h1 = u.h2 = 0;
|
u.h1 = u.h2 = 0;
|
||||||
u.v = v;
|
u.v = v;
|
||||||
return (u.h1 ^ u.h2);
|
return (u.h1 ^ u.h2);
|
||||||
#else
|
#else
|
||||||
return octa::detail::ScalarHash<ldouble>::operator()(v);
|
return octa::detail::ScalarHash<octa::ldouble>::operator()(v);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -232,10 +234,10 @@ template<> struct Hash<ldouble>: octa::detail::ScalarHash<ldouble> {
|
||||||
|
|
||||||
template<typename T> struct Hash<T *> {
|
template<typename T> struct Hash<T *> {
|
||||||
using Argument = T *;
|
using Argument = T *;
|
||||||
using Result = size_t;
|
using Result = octa::Size;
|
||||||
|
|
||||||
size_t operator()(T *v) const {
|
octa::Size operator()(T *v) const {
|
||||||
union { T *v; size_t h; } u;
|
union { T *v; octa::Size h; } u;
|
||||||
u.v = v;
|
u.v = v;
|
||||||
return octa::detail::mem_hash((const void *)&u, sizeof(u));
|
return octa::detail::mem_hash((const void *)&u, sizeof(u));
|
||||||
}
|
}
|
||||||
|
@ -591,8 +593,8 @@ namespace detail {
|
||||||
|
|
||||||
template<typename R, typename ...Args>
|
template<typename R, typename ...Args>
|
||||||
struct Function<R(Args...)>: octa::detail::FunctionBase<R, Args...> {
|
struct Function<R(Args...)>: octa::detail::FunctionBase<R, Args...> {
|
||||||
Function( ) { init_empty(); }
|
Function( ) { init_empty(); }
|
||||||
Function(Nullptr) { init_empty(); }
|
Function(octa::Nullptr) { init_empty(); }
|
||||||
|
|
||||||
Function(Function &&f) {
|
Function(Function &&f) {
|
||||||
init_empty();
|
init_empty();
|
||||||
|
@ -619,7 +621,7 @@ struct Function<R(Args...)>: octa::detail::FunctionBase<R, Args...> {
|
||||||
Function(octa::AllocatorArg, const A &) { init_empty(); }
|
Function(octa::AllocatorArg, const A &) { init_empty(); }
|
||||||
|
|
||||||
template<typename A>
|
template<typename A>
|
||||||
Function(octa::AllocatorArg, const A &, Nullptr) { init_empty(); }
|
Function(octa::AllocatorArg, const A &, octa::Nullptr) { init_empty(); }
|
||||||
|
|
||||||
template<typename A>
|
template<typename A>
|
||||||
Function(octa::AllocatorArg, const A &, Function &&f) {
|
Function(octa::AllocatorArg, const A &, Function &&f) {
|
||||||
|
@ -739,16 +741,16 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator==(Nullptr, const Function<T> &rhs) { return !rhs; }
|
bool operator==(octa::Nullptr, const Function<T> &rhs) { return !rhs; }
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator==(const Function<T> &lhs, Nullptr) { return !lhs; }
|
bool operator==(const Function<T> &lhs, octa::Nullptr) { return !lhs; }
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator!=(Nullptr, const Function<T> &rhs) { return rhs; }
|
bool operator!=(octa::Nullptr, const Function<T> &rhs) { return rhs; }
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator!=(const Function<T> &lhs, Nullptr) { return lhs; }
|
bool operator!=(const Function<T> &lhs, octa::Nullptr) { return lhs; }
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename F>
|
template<typename F>
|
||||||
|
|
|
@ -17,13 +17,13 @@ namespace std {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class initializer_list {
|
class initializer_list {
|
||||||
const T *p_buf;
|
const T *p_buf;
|
||||||
size_t p_len;
|
octa::Size p_len;
|
||||||
|
|
||||||
initializer_list(const T *v, size_t n): p_buf(v), p_len(n) {}
|
initializer_list(const T *v, octa::Size n): p_buf(v), p_len(n) {}
|
||||||
public:
|
public:
|
||||||
initializer_list(): p_buf(nullptr), p_len(0) {}
|
initializer_list(): p_buf(nullptr), p_len(0) {}
|
||||||
|
|
||||||
size_t size() const { return p_len; }
|
octa::Size size() const { return p_len; }
|
||||||
|
|
||||||
const T *begin() const { return p_buf; }
|
const T *begin() const { return p_buf; }
|
||||||
const T *end() const { return p_buf + p_len; }
|
const T *end() const { return p_buf + p_len; }
|
||||||
|
|
|
@ -68,7 +68,7 @@ namespace detail {
|
||||||
|
|
||||||
template<typename T, bool = HasDifference<T>::value>
|
template<typename T, bool = HasDifference<T>::value>
|
||||||
struct PointerDifferenceBase {
|
struct PointerDifferenceBase {
|
||||||
using Type = ptrdiff_t;
|
using Type = octa::Ptrdiff;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T> struct PointerDifferenceBase<T, true> {
|
template<typename T> struct PointerDifferenceBase<T, true> {
|
||||||
|
@ -82,7 +82,7 @@ namespace detail {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct PointerDifferenceType<T *> {
|
struct PointerDifferenceType<T *> {
|
||||||
using Type = ptrdiff_t;
|
using Type = octa::Ptrdiff;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
|
@ -284,7 +284,7 @@ public:
|
||||||
static_assert(!octa::IsPointer<D>::value,
|
static_assert(!octa::IsPointer<D>::value,
|
||||||
"Box constructed with null fptr deleter");
|
"Box constructed with null fptr deleter");
|
||||||
}
|
}
|
||||||
constexpr Box(Nullptr): p_stor(nullptr, D()) {
|
constexpr Box(octa::Nullptr): p_stor(nullptr, D()) {
|
||||||
static_assert(!octa::IsPointer<D>::value,
|
static_assert(!octa::IsPointer<D>::value,
|
||||||
"Box constructed with null fptr deleter");
|
"Box constructed with null fptr deleter");
|
||||||
}
|
}
|
||||||
|
@ -330,7 +330,7 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Box &operator=(Nullptr) {
|
Box &operator=(octa::Nullptr) {
|
||||||
reset();
|
reset();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -403,7 +403,7 @@ public:
|
||||||
static_assert(!octa::IsPointer<D>::value,
|
static_assert(!octa::IsPointer<D>::value,
|
||||||
"Box constructed with null fptr deleter");
|
"Box constructed with null fptr deleter");
|
||||||
}
|
}
|
||||||
constexpr Box(Nullptr): p_stor(nullptr, D()) {
|
constexpr Box(octa::Nullptr): p_stor(nullptr, D()) {
|
||||||
static_assert(!octa::IsPointer<D>::value,
|
static_assert(!octa::IsPointer<D>::value,
|
||||||
"Box constructed with null fptr deleter");
|
"Box constructed with null fptr deleter");
|
||||||
}
|
}
|
||||||
|
@ -421,7 +421,7 @@ public:
|
||||||
> d, octa::EnableIf<octa::detail::SameOrLessCvQualified<U, Pointer>::value,
|
> d, octa::EnableIf<octa::detail::SameOrLessCvQualified<U, Pointer>::value,
|
||||||
Nat> = Nat()): p_stor(p, d) {}
|
Nat> = Nat()): p_stor(p, d) {}
|
||||||
|
|
||||||
Box(Nullptr, octa::Conditional<octa::IsReference<D>::value,
|
Box(octa::Nullptr, octa::Conditional<octa::IsReference<D>::value,
|
||||||
D, AddLvalueReference<const D>
|
D, AddLvalueReference<const D>
|
||||||
> d): p_stor(nullptr, d) {}
|
> d): p_stor(nullptr, d) {}
|
||||||
|
|
||||||
|
@ -433,7 +433,7 @@ public:
|
||||||
"rvalue deleter cannot be a ref");
|
"rvalue deleter cannot be a ref");
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(Nullptr, octa::RemoveReference<D> &&d):
|
Box(octa::Nullptr, octa::RemoveReference<D> &&d):
|
||||||
p_stor(nullptr, octa::move(d)) {
|
p_stor(nullptr, octa::move(d)) {
|
||||||
static_assert(!octa::IsReference<D>::value,
|
static_assert(!octa::IsReference<D>::value,
|
||||||
"rvalue deleter cannot be a ref");
|
"rvalue deleter cannot be a ref");
|
||||||
|
@ -468,14 +468,14 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Box &operator=(Nullptr) {
|
Box &operator=(octa::Nullptr) {
|
||||||
reset();
|
reset();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
~Box() { reset(); }
|
~Box() { reset(); }
|
||||||
|
|
||||||
octa::AddLvalueReference<T> operator[](size_t idx) const {
|
octa::AddLvalueReference<T> operator[](octa::Size idx) const {
|
||||||
return p_stor.p_ptr[idx];
|
return p_stor.p_ptr[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -502,7 +502,7 @@ public:
|
||||||
if (tmp) p_stor.get_deleter()(tmp);
|
if (tmp) p_stor.get_deleter()(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset(Nullptr) {
|
void reset(octa::Nullptr) {
|
||||||
Pointer tmp = p_stor.p_ptr;
|
Pointer tmp = p_stor.p_ptr;
|
||||||
p_stor.p_ptr = nullptr;
|
p_stor.p_ptr = nullptr;
|
||||||
if (tmp) p_stor.get_deleter()(tmp);
|
if (tmp) p_stor.get_deleter()(tmp);
|
||||||
|
@ -529,7 +529,7 @@ namespace detail {
|
||||||
using BoxUnknownSize = octa::Box<T[]>;
|
using BoxUnknownSize = octa::Box<T[]>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, size_t N> struct BoxIf<T[N]> {
|
template<typename T, octa::Size N> struct BoxIf<T[N]> {
|
||||||
using BoxKnownSize = void;
|
using BoxKnownSize = void;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -540,7 +540,7 @@ typename octa::detail::BoxIf<T>::Box make_box(A &&...args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
typename octa::detail::BoxIf<T>::BoxUnknownSize make_box(size_t n) {
|
typename octa::detail::BoxIf<T>::BoxUnknownSize make_box(octa::Size n) {
|
||||||
return Box<T>(new octa::RemoveExtent<T>[n]());
|
return Box<T>(new octa::RemoveExtent<T>[n]());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,8 +568,8 @@ template<> struct Allocator<const void> {
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T> struct Allocator {
|
template<typename T> struct Allocator {
|
||||||
using Size = size_t;
|
using Size = octa::Size;
|
||||||
using Difference = ptrdiff_t;
|
using Difference = octa::Ptrdiff;
|
||||||
using Value = T;
|
using Value = T;
|
||||||
using Reference = T &;
|
using Reference = T &;
|
||||||
using ConstReference = const T &;
|
using ConstReference = const T &;
|
||||||
|
@ -588,10 +588,10 @@ template<typename T> struct Allocator {
|
||||||
Size max_size() const { return Size(~0) / sizeof(T); }
|
Size max_size() const { return Size(~0) / sizeof(T); }
|
||||||
|
|
||||||
Pointer allocate(Size n, Allocator<void>::ConstPointer = nullptr) {
|
Pointer allocate(Size n, Allocator<void>::ConstPointer = nullptr) {
|
||||||
return (Pointer) ::new uchar[n * sizeof(T)];
|
return (Pointer) ::new octa::uchar[n * sizeof(T)];
|
||||||
}
|
}
|
||||||
|
|
||||||
void deallocate(Pointer p, Size) { ::delete[] (uchar *) p; }
|
void deallocate(Pointer p, Size) { ::delete[] (octa::uchar *) p; }
|
||||||
|
|
||||||
template<typename U, typename ...A>
|
template<typename U, typename ...A>
|
||||||
void construct(U *p, A &&...args) {
|
void construct(U *p, A &&...args) {
|
||||||
|
@ -602,8 +602,8 @@ template<typename T> struct Allocator {
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T> struct Allocator<const T> {
|
template<typename T> struct Allocator<const T> {
|
||||||
using Size = size_t;
|
using Size = octa::Size;
|
||||||
using Difference = ptrdiff_t;
|
using Difference = octa::Ptrdiff;
|
||||||
using Value = const T;
|
using Value = const T;
|
||||||
using Reference = const T &;
|
using Reference = const T &;
|
||||||
using ConstReference = const T &;
|
using ConstReference = const T &;
|
||||||
|
@ -619,10 +619,10 @@ template<typename T> struct Allocator<const T> {
|
||||||
Size max_size() const { return Size(~0) / sizeof(T); }
|
Size max_size() const { return Size(~0) / sizeof(T); }
|
||||||
|
|
||||||
Pointer allocate(Size n, Allocator<void>::ConstPointer = nullptr) {
|
Pointer allocate(Size n, Allocator<void>::ConstPointer = nullptr) {
|
||||||
return (Pointer) ::new uchar[n * sizeof(T)];
|
return (Pointer) ::new octa::uchar[n * sizeof(T)];
|
||||||
}
|
}
|
||||||
|
|
||||||
void deallocate(Pointer p, Size) { ::delete[] (uchar *) p; }
|
void deallocate(Pointer p, Size) { ::delete[] (octa::uchar *) p; }
|
||||||
|
|
||||||
template<typename U, typename ...A>
|
template<typename U, typename ...A>
|
||||||
void construct(U *p, A &&...args) {
|
void construct(U *p, A &&...args) {
|
||||||
|
|
|
@ -6,11 +6,11 @@
|
||||||
#ifndef OCTA_NEW_H
|
#ifndef OCTA_NEW_H
|
||||||
#define OCTA_NEW_H
|
#define OCTA_NEW_H
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#ifndef OCTA_ALLOW_CXXSTD
|
#ifndef OCTA_ALLOW_CXXSTD
|
||||||
inline void *operator new (size_t, void *p) { return p; }
|
#include "octa/types.h"
|
||||||
inline void *operator new [](size_t, void *p) { return p; }
|
|
||||||
|
inline void *operator new (octa::Size, void *p) { return p; }
|
||||||
|
inline void *operator new [](octa::Size, void *p) { return p; }
|
||||||
inline void operator delete (void *, void *) {}
|
inline void operator delete (void *, void *) {}
|
||||||
inline void operator delete[](void *, void *) {}
|
inline void operator delete[](void *, void *) {}
|
||||||
#else
|
#else
|
||||||
|
|
32
octa/range.h
32
octa/range.h
|
@ -285,7 +285,7 @@ namespace detail {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename B, typename C, typename V, typename R = V &,
|
template<typename B, typename C, typename V, typename R = V &,
|
||||||
typename S = size_t, typename D = ptrdiff_t
|
typename S = octa::Size, typename D = octa::Ptrdiff
|
||||||
> struct InputRange {
|
> struct InputRange {
|
||||||
using Category = C;
|
using Category = C;
|
||||||
using Size = S;
|
using Size = S;
|
||||||
|
@ -325,8 +325,8 @@ template<typename B, typename C, typename V, typename R = V &,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename V, typename R = V &, typename S = size_t,
|
template<typename V, typename R = V &, typename S = octa::Size,
|
||||||
typename D = ptrdiff_t
|
typename D = octa::Ptrdiff
|
||||||
> struct OutputRange {
|
> struct OutputRange {
|
||||||
using Category = OutputRangeTag;
|
using Category = OutputRangeTag;
|
||||||
using Size = S;
|
using Size = S;
|
||||||
|
@ -541,7 +541,7 @@ struct PointerRange: InputRange<PointerRange<T>, FiniteRandomAccessRangeTag, T>
|
||||||
PointerRange(const PointerRange &v): 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): p_beg(beg), p_end(end) {}
|
PointerRange(T *beg, T *end): p_beg(beg), p_end(end) {}
|
||||||
PointerRange(T *beg, size_t n): p_beg(beg), p_end(beg + n) {}
|
PointerRange(T *beg, octa::Size n): p_beg(beg), p_end(beg + n) {}
|
||||||
|
|
||||||
PointerRange &operator=(const PointerRange &v) {
|
PointerRange &operator=(const PointerRange &v) {
|
||||||
p_beg = v.p_beg;
|
p_beg = v.p_beg;
|
||||||
|
@ -561,8 +561,8 @@ struct PointerRange: InputRange<PointerRange<T>, FiniteRandomAccessRangeTag, T>
|
||||||
--p_beg; return true;
|
--p_beg; return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pop_front_n(size_t n) {
|
octa::Size pop_front_n(octa::Size n) {
|
||||||
size_t olen = p_end - p_beg;
|
octa::Size olen = p_end - p_beg;
|
||||||
p_beg += n;
|
p_beg += n;
|
||||||
if (p_beg > p_end) {
|
if (p_beg > p_end) {
|
||||||
p_beg = p_end;
|
p_beg = p_end;
|
||||||
|
@ -571,7 +571,7 @@ struct PointerRange: InputRange<PointerRange<T>, FiniteRandomAccessRangeTag, T>
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t push_front_n(size_t n) {
|
octa::Size push_front_n(octa::Size n) {
|
||||||
p_beg -= n; return true;
|
p_beg -= n; return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,7 +581,7 @@ struct PointerRange: InputRange<PointerRange<T>, FiniteRandomAccessRangeTag, T>
|
||||||
return p_beg == range.p_beg;
|
return p_beg == range.p_beg;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptrdiff_t distance_front(const PointerRange &range) const {
|
octa::Ptrdiff distance_front(const PointerRange &range) const {
|
||||||
return range.p_beg - p_beg;
|
return range.p_beg - p_beg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -595,8 +595,8 @@ struct PointerRange: InputRange<PointerRange<T>, FiniteRandomAccessRangeTag, T>
|
||||||
++p_end; return true;
|
++p_end; return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pop_back_n(size_t n) {
|
octa::Size pop_back_n(octa::Size n) {
|
||||||
size_t olen = p_end - p_beg;
|
octa::Size olen = p_end - p_beg;
|
||||||
p_end -= n;
|
p_end -= n;
|
||||||
if (p_end < p_beg) {
|
if (p_end < p_beg) {
|
||||||
p_end = p_beg;
|
p_end = p_beg;
|
||||||
|
@ -605,7 +605,7 @@ struct PointerRange: InputRange<PointerRange<T>, FiniteRandomAccessRangeTag, T>
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t push_back_n(size_t n) {
|
octa::Size push_back_n(octa::Size n) {
|
||||||
p_end += n; return true;
|
p_end += n; return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -615,18 +615,18 @@ struct PointerRange: InputRange<PointerRange<T>, FiniteRandomAccessRangeTag, T>
|
||||||
return p_end == range.p_end;
|
return p_end == range.p_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptrdiff_t distance_back(const PointerRange &range) const {
|
octa::Ptrdiff distance_back(const PointerRange &range) const {
|
||||||
return range.p_end - p_end;
|
return range.p_end - p_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* satisfy FiniteRandomAccessRange */
|
/* satisfy FiniteRandomAccessRange */
|
||||||
size_t size() const { return p_end - p_beg; }
|
octa::Size size() const { return p_end - p_beg; }
|
||||||
|
|
||||||
PointerRange slice(size_t start, size_t end) const {
|
PointerRange slice(octa::Size start, octa::Size end) const {
|
||||||
return PointerRange(p_beg + start, p_beg + end);
|
return PointerRange(p_beg + start, p_beg + end);
|
||||||
}
|
}
|
||||||
|
|
||||||
T &operator[](size_t i) const { return p_beg[i]; }
|
T &operator[](octa::Size i) const { return p_beg[i]; }
|
||||||
|
|
||||||
/* satisfy OutputRange */
|
/* satisfy OutputRange */
|
||||||
void put(const T &v) {
|
void put(const T &v) {
|
||||||
|
@ -864,7 +864,7 @@ auto each(const T &r) -> decltype(r.each()) {
|
||||||
return r.each();
|
return r.each();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, size_t N>
|
template<typename T, octa::Size N>
|
||||||
PointerRange<T> each(T (&array)[N]) {
|
PointerRange<T> each(T (&array)[N]) {
|
||||||
return PointerRange<T>(array, N);
|
return PointerRange<T>(array, N);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include "octa/vector.h"
|
#include "octa/vector.h"
|
||||||
|
|
||||||
namespace octa {
|
namespace octa {
|
||||||
static constexpr size_t npos = -1;
|
static constexpr octa::Size npos = -1;
|
||||||
|
|
||||||
template<typename T, typename A = octa::Allocator<T>>
|
template<typename T, typename A = octa::Allocator<T>>
|
||||||
class StringBase {
|
class StringBase {
|
||||||
|
@ -25,15 +25,15 @@ class StringBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using Size = size_t;
|
using Size = octa::Size;
|
||||||
using Difference = ptrdiff_t;
|
using Difference = octa::Ptrdiff;
|
||||||
using Value = T;
|
using Value = T;
|
||||||
using Reference = T &;
|
using Reference = T &;
|
||||||
using ConstReference = const T &;
|
using ConstReference = const T &;
|
||||||
using Pointer = T *;
|
using Pointer = T *;
|
||||||
using ConstPointer = const T *;
|
using ConstPointer = const T *;
|
||||||
using Range = PointerRange<T>;
|
using Range = octa::PointerRange<T>;
|
||||||
using ConstRange = PointerRange<const T>;
|
using ConstRange = octa::PointerRange<const T>;
|
||||||
using Allocator = A;
|
using Allocator = A;
|
||||||
|
|
||||||
StringBase(const A &a = A()): p_buf(1, '\0', a) {}
|
StringBase(const A &a = A()): p_buf(1, '\0', a) {}
|
||||||
|
@ -45,7 +45,7 @@ public:
|
||||||
StringBase(StringBase &&s, const A &a):
|
StringBase(StringBase &&s, const A &a):
|
||||||
p_buf(octa::move(s.p_buf), a) {}
|
p_buf(octa::move(s.p_buf), a) {}
|
||||||
|
|
||||||
StringBase(const StringBase &s, size_t pos, size_t len = npos,
|
StringBase(const StringBase &s, octa::Size pos, octa::Size len = npos,
|
||||||
const A &a = A()):
|
const A &a = A()):
|
||||||
p_buf(s.p_buf.each().slice(pos,
|
p_buf(s.p_buf.each().slice(pos,
|
||||||
(len == npos) ? s.p_buf.size() : (pos + len)), a) {
|
(len == npos) ? s.p_buf.size() : (pos + len)), a) {
|
||||||
|
@ -76,21 +76,21 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void resize(size_t n, T v = T()) {
|
void resize(octa::Size n, T v = T()) {
|
||||||
p_buf.pop();
|
p_buf.pop();
|
||||||
p_buf.resize(n, v);
|
p_buf.resize(n, v);
|
||||||
terminate();
|
terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void reserve(size_t n) {
|
void reserve(octa::Size n) {
|
||||||
p_buf.reserve(n + 1);
|
p_buf.reserve(n + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
T &operator[](size_t i) { return p_buf[i]; }
|
T &operator[](octa::Size i) { return p_buf[i]; }
|
||||||
const T &operator[](size_t i) const { return p_buf[i]; }
|
const T &operator[](octa::Size i) const { return p_buf[i]; }
|
||||||
|
|
||||||
T &at(size_t i) { return p_buf[i]; }
|
T &at(octa::Size i) { return p_buf[i]; }
|
||||||
const T &at(size_t i) const { return p_buf[i]; }
|
const T &at(octa::Size i) const { return p_buf[i]; }
|
||||||
|
|
||||||
T &front() { return p_buf[0]; }
|
T &front() { return p_buf[0]; }
|
||||||
const T &front() const { return p_buf[0]; };
|
const T &front() const { return p_buf[0]; };
|
||||||
|
@ -101,11 +101,11 @@ public:
|
||||||
T *data() { return p_buf.data(); }
|
T *data() { return p_buf.data(); }
|
||||||
const T *data() const { return p_buf.data(); }
|
const T *data() const { return p_buf.data(); }
|
||||||
|
|
||||||
size_t size() const {
|
octa::Size size() const {
|
||||||
return p_buf.size() - 1;
|
return p_buf.size() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t capacity() const {
|
octa::Size capacity() const {
|
||||||
return p_buf.capacity() - 1;
|
return p_buf.capacity() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,9 +122,9 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBase<T> &append(const StringBase &s, size_t idx, size_t len) {
|
StringBase<T> &append(const StringBase &s, octa::Size idx, octa::Size len) {
|
||||||
p_buf.pop();
|
p_buf.pop();
|
||||||
p_buf.insert_range(p_buf.size(), octa::PointerRange<T>(&s[idx],
|
p_buf.insert_range(p_buf.size(), Range(&s[idx],
|
||||||
(len == npos) ? (s.size() - idx) : len));
|
(len == npos) ? (s.size() - idx) : len));
|
||||||
terminate();
|
terminate();
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -137,9 +137,9 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBase<T> &append(size_t n, T c) {
|
StringBase<T> &append(octa::Size n, T c) {
|
||||||
p_buf.pop();
|
p_buf.pop();
|
||||||
for (size_t i = 0; i < n; ++i) p_buf.push(c);
|
for (octa::Size i = 0; i < n; ++i) p_buf.push(c);
|
||||||
p_buf.push('\0');
|
p_buf.push('\0');
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -281,7 +281,7 @@ namespace detail {
|
||||||
n = 0;
|
n = 0;
|
||||||
*(s->data()) = '\0';
|
*(s->data()) = '\0';
|
||||||
}
|
}
|
||||||
*(((size_t *)s) + 1) = n + 1;
|
*(((octa::Size *)s) + 1) = n + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,14 +316,15 @@ template<> struct ToString<T> { \
|
||||||
|
|
||||||
OCTA_TOSTR_NUM(int, "%d")
|
OCTA_TOSTR_NUM(int, "%d")
|
||||||
OCTA_TOSTR_NUM(int &, "%d")
|
OCTA_TOSTR_NUM(int &, "%d")
|
||||||
OCTA_TOSTR_NUM(uint, "%u")
|
|
||||||
OCTA_TOSTR_NUM(long, "%ld")
|
OCTA_TOSTR_NUM(long, "%ld")
|
||||||
OCTA_TOSTR_NUM(ulong, "%lu")
|
|
||||||
OCTA_TOSTR_NUM(llong, "%lld")
|
|
||||||
OCTA_TOSTR_NUM(ullong, "%llu")
|
|
||||||
OCTA_TOSTR_NUM(float, "%f")
|
OCTA_TOSTR_NUM(float, "%f")
|
||||||
OCTA_TOSTR_NUM(double, "%f")
|
OCTA_TOSTR_NUM(double, "%f")
|
||||||
OCTA_TOSTR_NUM(ldouble, "%Lf")
|
|
||||||
|
OCTA_TOSTR_NUM(octa::uint, "%u")
|
||||||
|
OCTA_TOSTR_NUM(octa::ulong, "%lu")
|
||||||
|
OCTA_TOSTR_NUM(octa::llong, "%lld")
|
||||||
|
OCTA_TOSTR_NUM(octa::ullong, "%llu")
|
||||||
|
OCTA_TOSTR_NUM(octa::ldouble, "%Lf")
|
||||||
|
|
||||||
#undef OCTA_TOSTR_NUM
|
#undef OCTA_TOSTR_NUM
|
||||||
|
|
||||||
|
|
|
@ -80,8 +80,8 @@ namespace detail {
|
||||||
/* is null pointer */
|
/* is null pointer */
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename> struct IsNullPointerBase : False {};
|
template<typename> struct IsNullPointerBase : False {};
|
||||||
template< > struct IsNullPointerBase<Nullptr>: True {};
|
template< > struct IsNullPointerBase<octa::Nullptr>: True {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> struct IsNullPointer:
|
template<typename T> struct IsNullPointer:
|
||||||
|
@ -94,20 +94,21 @@ namespace detail {
|
||||||
|
|
||||||
template<> struct IsIntegralBase<bool >: True {};
|
template<> struct IsIntegralBase<bool >: True {};
|
||||||
template<> struct IsIntegralBase<char >: True {};
|
template<> struct IsIntegralBase<char >: True {};
|
||||||
template<> struct IsIntegralBase<uchar >: True {};
|
|
||||||
template<> struct IsIntegralBase<schar >: True {};
|
|
||||||
template<> struct IsIntegralBase<short >: True {};
|
template<> struct IsIntegralBase<short >: True {};
|
||||||
template<> struct IsIntegralBase<ushort>: True {};
|
|
||||||
template<> struct IsIntegralBase<int >: True {};
|
template<> struct IsIntegralBase<int >: True {};
|
||||||
template<> struct IsIntegralBase<uint >: True {};
|
|
||||||
template<> struct IsIntegralBase<long >: True {};
|
template<> struct IsIntegralBase<long >: True {};
|
||||||
template<> struct IsIntegralBase<ulong >: True {};
|
|
||||||
template<> struct IsIntegralBase<llong >: True {};
|
|
||||||
template<> struct IsIntegralBase<ullong>: True {};
|
|
||||||
|
|
||||||
template<> struct IsIntegralBase<char16_t>: True {};
|
template<> struct IsIntegralBase<octa::uchar >: True {};
|
||||||
template<> struct IsIntegralBase<char32_t>: True {};
|
template<> struct IsIntegralBase<octa::schar >: True {};
|
||||||
template<> struct IsIntegralBase< wchar_t>: True {};
|
template<> struct IsIntegralBase<octa::ushort>: True {};
|
||||||
|
template<> struct IsIntegralBase<octa::uint >: True {};
|
||||||
|
template<> struct IsIntegralBase<octa::ulong >: True {};
|
||||||
|
template<> struct IsIntegralBase<octa::llong >: True {};
|
||||||
|
template<> struct IsIntegralBase<octa::ullong>: True {};
|
||||||
|
|
||||||
|
template<> struct IsIntegralBase<octa::Char16>: True {};
|
||||||
|
template<> struct IsIntegralBase<octa::Char32>: True {};
|
||||||
|
template<> struct IsIntegralBase<octa::Wchar >: True {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -118,9 +119,10 @@ struct IsIntegral: octa::detail::IsIntegralBase<RemoveCv<T>> {};
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T> struct IsFloatingPointBase: False {};
|
template<typename T> struct IsFloatingPointBase: False {};
|
||||||
|
|
||||||
template<> struct IsFloatingPointBase<float >: True {};
|
template<> struct IsFloatingPointBase<float >: True {};
|
||||||
template<> struct IsFloatingPointBase<double >: True {};
|
template<> struct IsFloatingPointBase<double>: True {};
|
||||||
template<> struct IsFloatingPointBase<ldouble>: True {};
|
|
||||||
|
template<> struct IsFloatingPointBase<octa::ldouble>: True {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -128,9 +130,9 @@ struct IsFloatingPoint: octa::detail::IsFloatingPointBase<RemoveCv<T>> {};
|
||||||
|
|
||||||
/* is array */
|
/* is array */
|
||||||
|
|
||||||
template<typename > struct IsArray : False {};
|
template<typename > struct IsArray : False {};
|
||||||
template<typename T > struct IsArray<T[] >: True {};
|
template<typename T > struct IsArray<T[] >: True {};
|
||||||
template<typename T, size_t N> struct IsArray<T[N]>: True {};
|
template<typename T, octa::Size N> struct IsArray<T[N]>: True {};
|
||||||
|
|
||||||
/* is pointer */
|
/* is pointer */
|
||||||
|
|
||||||
|
@ -412,11 +414,11 @@ namespace detail {
|
||||||
> {};
|
> {};
|
||||||
|
|
||||||
/* array types are default constructible if their element type is */
|
/* array types are default constructible if their element type is */
|
||||||
template<typename T, size_t N>
|
template<typename T, octa::Size N>
|
||||||
struct CtibleCore<false, T[N]>: Ctible<octa::RemoveAllExtents<T>> {};
|
struct CtibleCore<false, T[N]>: Ctible<octa::RemoveAllExtents<T>> {};
|
||||||
|
|
||||||
/* otherwise array types are not constructible by this syntax */
|
/* otherwise array types are not constructible by this syntax */
|
||||||
template<typename T, size_t N, typename ...A>
|
template<typename T, octa::Size N, typename ...A>
|
||||||
struct CtibleCore<false, T[N], A...>: False {};
|
struct CtibleCore<false, T[N], A...>: False {};
|
||||||
|
|
||||||
/* incomplete array types are not constructible */
|
/* incomplete array types are not constructible */
|
||||||
|
@ -646,30 +648,30 @@ template<typename T > struct IsSame<T, T>: True {};
|
||||||
|
|
||||||
/* extent */
|
/* extent */
|
||||||
|
|
||||||
template<typename T, uint I = 0>
|
template<typename T, octa::uint I = 0>
|
||||||
struct Extent: IntegralConstant<size_t, 0> {};
|
struct Extent: IntegralConstant<octa::Size, 0> {};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Extent<T[], 0>: IntegralConstant<size_t, 0> {};
|
struct Extent<T[], 0>: IntegralConstant<octa::Size, 0> {};
|
||||||
|
|
||||||
template<typename T, uint I>
|
template<typename T, octa::uint I>
|
||||||
struct Extent<T[], I>: IntegralConstant<size_t, Extent<T, I - 1>::value> {};
|
struct Extent<T[], I>: IntegralConstant<octa::Size, Extent<T, I - 1>::value> {};
|
||||||
|
|
||||||
template<typename T, size_t N>
|
template<typename T, octa::Size N>
|
||||||
struct Extent<T[N], 0>: IntegralConstant<size_t, N> {};
|
struct Extent<T[N], 0>: IntegralConstant<octa::Size, N> {};
|
||||||
|
|
||||||
template<typename T, size_t N, uint I>
|
template<typename T, octa::Size N, octa::uint I>
|
||||||
struct Extent<T[N], I>: IntegralConstant<size_t, Extent<T, I - 1>::value> {};
|
struct Extent<T[N], I>: IntegralConstant<octa::Size, Extent<T, I - 1>::value> {};
|
||||||
|
|
||||||
/* rank */
|
/* rank */
|
||||||
|
|
||||||
template<typename T> struct Rank: IntegralConstant<size_t, 0> {};
|
template<typename T> struct Rank: IntegralConstant<octa::Size, 0> {};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Rank<T[]>: IntegralConstant<size_t, Rank<T>::value + 1> {};
|
struct Rank<T[]>: IntegralConstant<octa::Size, Rank<T>::value + 1> {};
|
||||||
|
|
||||||
template<typename T, size_t N>
|
template<typename T, octa::Size N>
|
||||||
struct Rank<T[N]>: IntegralConstant<size_t, Rank<T>::value + 1> {};
|
struct Rank<T[N]>: IntegralConstant<octa::Size, Rank<T>::value + 1> {};
|
||||||
|
|
||||||
/* remove const, volatile, cv */
|
/* remove const, volatile, cv */
|
||||||
|
|
||||||
|
@ -825,7 +827,7 @@ namespace detail {
|
||||||
struct RemoveExtentBase { using Type = T; };
|
struct RemoveExtentBase { using Type = T; };
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct RemoveExtentBase<T[ ]> { using Type = T; };
|
struct RemoveExtentBase<T[ ]> { using Type = T; };
|
||||||
template<typename T, size_t N>
|
template<typename T, octa::Size N>
|
||||||
struct RemoveExtentBase<T[N]> { using Type = T; };
|
struct RemoveExtentBase<T[N]> { using Type = T; };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -841,7 +843,7 @@ namespace detail {
|
||||||
using Type = RemoveAllExtentsBase<T>;
|
using Type = RemoveAllExtentsBase<T>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, size_t N> struct RemoveAllExtentsBase<T[N]> {
|
template<typename T, octa::Size N> struct RemoveAllExtentsBase<T[N]> {
|
||||||
using Type = RemoveAllExtentsBase<T>;
|
using Type = RemoveAllExtentsBase<T>;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -866,27 +868,27 @@ namespace detail {
|
||||||
~TlNat() = delete;
|
~TlNat() = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
using Stypes = TypeList<schar,
|
using Stypes = TypeList<octa::schar,
|
||||||
TypeList<short,
|
TypeList<short,
|
||||||
TypeList<int,
|
TypeList<int,
|
||||||
TypeList<long,
|
TypeList<long,
|
||||||
TypeList<llong, TlNat>>>>>;
|
TypeList<octa::llong, TlNat>>>>>;
|
||||||
|
|
||||||
using Utypes = TypeList<uchar,
|
using Utypes = TypeList<octa::uchar,
|
||||||
TypeList<ushort,
|
TypeList<octa::ushort,
|
||||||
TypeList<uint,
|
TypeList<octa::uint,
|
||||||
TypeList<ulong,
|
TypeList<octa::ulong,
|
||||||
TypeList<ullong, TlNat>>>>>;
|
TypeList<octa::ullong, TlNat>>>>>;
|
||||||
|
|
||||||
template<typename T, size_t N, bool = (N <= sizeof(typename T::First))>
|
template<typename T, octa::Size N, bool = (N <= sizeof(typename T::First))>
|
||||||
struct TypeFindFirst;
|
struct TypeFindFirst;
|
||||||
|
|
||||||
template<typename T, typename U, size_t N>
|
template<typename T, typename U, octa::Size N>
|
||||||
struct TypeFindFirst<TypeList<T, U>, N, true> {
|
struct TypeFindFirst<TypeList<T, U>, N, true> {
|
||||||
using Type = T;
|
using Type = T;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename U, size_t N>
|
template<typename T, typename U, octa::Size N>
|
||||||
struct TypeFindFirst<TypeList<T, U>, N, false> {
|
struct TypeFindFirst<TypeList<T, U>, N, false> {
|
||||||
using Type = typename TypeFindFirst<U, N>::Type;
|
using Type = typename TypeFindFirst<U, N>::Type;
|
||||||
};
|
};
|
||||||
|
@ -947,28 +949,30 @@ namespace detail {
|
||||||
};
|
};
|
||||||
|
|
||||||
template<> struct MakeSigned<bool , true> {};
|
template<> struct MakeSigned<bool , true> {};
|
||||||
template<> struct MakeSigned<schar , true> { using Type = schar; };
|
|
||||||
template<> struct MakeSigned<uchar , true> { using Type = schar; };
|
|
||||||
template<> struct MakeSigned<short , true> { using Type = short; };
|
template<> struct MakeSigned<short , true> { using Type = short; };
|
||||||
template<> struct MakeSigned<ushort, true> { using Type = short; };
|
|
||||||
template<> struct MakeSigned<int , true> { using Type = int; };
|
template<> struct MakeSigned<int , true> { using Type = int; };
|
||||||
template<> struct MakeSigned<uint , true> { using Type = int; };
|
|
||||||
template<> struct MakeSigned<long , true> { using Type = long; };
|
template<> struct MakeSigned<long , true> { using Type = long; };
|
||||||
template<> struct MakeSigned<ulong , true> { using Type = long; };
|
|
||||||
template<> struct MakeSigned<llong , true> { using Type = llong; };
|
template<> struct MakeSigned<octa::schar , true> { using Type = octa::schar; };
|
||||||
template<> struct MakeSigned<ullong, true> { using Type = llong; };
|
template<> struct MakeSigned<octa::uchar , true> { using Type = octa::schar; };
|
||||||
|
template<> struct MakeSigned<octa::ushort, true> { using Type = short; };
|
||||||
|
template<> struct MakeSigned<octa::uint , true> { using Type = int; };
|
||||||
|
template<> struct MakeSigned<octa::ulong , true> { using Type = long; };
|
||||||
|
template<> struct MakeSigned<octa::llong , true> { using Type = octa::llong; };
|
||||||
|
template<> struct MakeSigned<octa::ullong, true> { using Type = octa::llong; };
|
||||||
|
|
||||||
template<> struct MakeUnsigned<bool , true> {};
|
template<> struct MakeUnsigned<bool , true> {};
|
||||||
template<> struct MakeUnsigned<schar , true> { using Type = uchar; };
|
template<> struct MakeUnsigned<short , true> { using Type = octa::ushort; };
|
||||||
template<> struct MakeUnsigned<uchar , true> { using Type = uchar; };
|
template<> struct MakeUnsigned<int , true> { using Type = octa::uint; };
|
||||||
template<> struct MakeUnsigned<short , true> { using Type = ushort; };
|
template<> struct MakeUnsigned<long , true> { using Type = octa::ulong; };
|
||||||
template<> struct MakeUnsigned<ushort, true> { using Type = ushort; };
|
|
||||||
template<> struct MakeUnsigned<int , true> { using Type = uint; };
|
template<> struct MakeUnsigned<octa::schar , true> { using Type = octa::uchar; };
|
||||||
template<> struct MakeUnsigned<uint , true> { using Type = uint; };
|
template<> struct MakeUnsigned<octa::uchar , true> { using Type = octa::uchar; };
|
||||||
template<> struct MakeUnsigned<long , true> { using Type = ulong; };
|
template<> struct MakeUnsigned<octa::ushort, true> { using Type = octa::ushort; };
|
||||||
template<> struct MakeUnsigned<ulong , true> { using Type = ulong; };
|
template<> struct MakeUnsigned<octa::uint , true> { using Type = octa::uint; };
|
||||||
template<> struct MakeUnsigned<llong , true> { using Type = ullong; };
|
template<> struct MakeUnsigned<octa::ulong , true> { using Type = octa::ulong; };
|
||||||
template<> struct MakeUnsigned<ullong, true> { using Type = ullong; };
|
template<> struct MakeUnsigned<octa::llong , true> { using Type = octa::ullong; };
|
||||||
|
template<> struct MakeUnsigned<octa::ullong, true> { using Type = octa::ullong; };
|
||||||
|
|
||||||
template<typename T> struct MakeSignedBase {
|
template<typename T> struct MakeSignedBase {
|
||||||
using Type = typename ApplyCv<T,
|
using Type = typename ApplyCv<T,
|
||||||
|
@ -1111,55 +1115,55 @@ using CommonType = typename octa::detail::CommonTypeBase<T, U, V...>::Type;
|
||||||
/* aligned storage */
|
/* aligned storage */
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<size_t N> struct AlignedTest {
|
template<octa::Size N> struct AlignedTest {
|
||||||
union type {
|
union type {
|
||||||
uchar data[N];
|
octa::uchar data[N];
|
||||||
octa::MaxAlign align;
|
octa::MaxAlign align;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
template<size_t N, size_t A> struct AlignedStorageBase {
|
template<octa::Size N, octa::Size A> struct AlignedStorageBase {
|
||||||
struct type {
|
struct type {
|
||||||
alignas(A) uchar data[N];
|
alignas(A) octa::uchar data[N];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t N, size_t A
|
template<octa::Size N, octa::Size A
|
||||||
= alignof(typename octa::detail::AlignedTest<N>::Type)
|
= alignof(typename octa::detail::AlignedTest<N>::Type)
|
||||||
> using AlignedStorage = typename octa::detail::AlignedStorageBase<N, A>::Type;
|
> using AlignedStorage = typename octa::detail::AlignedStorageBase<N, A>::Type;
|
||||||
|
|
||||||
/* aligned union */
|
/* aligned union */
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<size_t ...N> struct AlignMax;
|
template<octa::Size ...N> struct AlignMax;
|
||||||
|
|
||||||
template<size_t N> struct AlignMax<N> {
|
template<octa::Size N> struct AlignMax<N> {
|
||||||
static constexpr size_t value = N;
|
static constexpr octa::Size value = N;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<size_t N1, size_t N2> struct AlignMax<N1, N2> {
|
template<octa::Size N1, octa::Size N2> struct AlignMax<N1, N2> {
|
||||||
static constexpr size_t value = (N1 > N2) ? N1 : N2;
|
static constexpr octa::Size value = (N1 > N2) ? N1 : N2;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<size_t N1, size_t N2, size_t ...N>
|
template<octa::Size N1, octa::Size N2, octa::Size ...N>
|
||||||
struct AlignMax<N1, N2, N...> {
|
struct AlignMax<N1, N2, N...> {
|
||||||
static constexpr size_t value
|
static constexpr octa::Size value
|
||||||
= AlignMax<AlignMax<N1, N2>::value, N...>::value;
|
= AlignMax<AlignMax<N1, N2>::value, N...>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<size_t N, typename ...T> struct AlignedUnionBase {
|
template<octa::Size N, typename ...T> struct AlignedUnionBase {
|
||||||
static constexpr size_t alignment_value
|
static constexpr octa::Size alignment_value
|
||||||
= AlignMax<alignof(T)...>::value;
|
= AlignMax<alignof(T)...>::value;
|
||||||
|
|
||||||
struct type {
|
struct type {
|
||||||
alignas(alignment_value) uchar data[AlignMax<N,
|
alignas(alignment_value) octa::uchar data[AlignMax<N,
|
||||||
sizeof(T)...>::value];
|
sizeof(T)...>::value];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} /* namespace detail */
|
} /* namespace detail */
|
||||||
|
|
||||||
template<size_t N, typename ...T>
|
template<octa::Size N, typename ...T>
|
||||||
using AlignedUnion = typename octa::detail::AlignedUnionBase<N, T...>::Type;
|
using AlignedUnion = typename octa::detail::AlignedUnionBase<N, T...>::Type;
|
||||||
|
|
||||||
/* underlying type */
|
/* underlying type */
|
||||||
|
|
|
@ -23,6 +23,12 @@ using llong = long long;
|
||||||
|
|
||||||
using ldouble = long double;
|
using ldouble = long double;
|
||||||
|
|
||||||
|
/* keywords in c++, but aliased */
|
||||||
|
|
||||||
|
using Wchar = wchar_t;
|
||||||
|
using Char16 = char16_t;
|
||||||
|
using Char32 = char32_t;
|
||||||
|
|
||||||
/* nullptr type */
|
/* nullptr type */
|
||||||
|
|
||||||
using Nullptr = decltype(nullptr);
|
using Nullptr = decltype(nullptr);
|
||||||
|
|
|
@ -74,8 +74,8 @@ template<typename T> void swap(T &a, T &b) {
|
||||||
octa::detail::swap(a, b);
|
octa::detail::swap(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, size_t N> void swap(T (&a)[N], T (&b)[N]) {
|
template<typename T, octa::Size N> void swap(T (&a)[N], T (&b)[N]) {
|
||||||
for (size_t i = 0; i < N; ++i) {
|
for (octa::Size i = 0; i < N; ++i) {
|
||||||
octa::swap(a[i], b[i]);
|
octa::swap(a[i], b[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,12 +62,12 @@ class Vector {
|
||||||
using VecPair = octa::detail::VectorPair<T, A>;
|
using VecPair = octa::detail::VectorPair<T, A>;
|
||||||
|
|
||||||
VecPair p_buf;
|
VecPair p_buf;
|
||||||
size_t p_len, p_cap;
|
octa::Size p_len, p_cap;
|
||||||
|
|
||||||
void insert_base(size_t idx, size_t n) {
|
void insert_base(octa::Size idx, octa::Size n) {
|
||||||
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 (octa::Size i = p_len - 1; i > idx + n - 1; --i) {
|
||||||
p_buf.p_ptr[i] = octa::move(p_buf.p_ptr[i - n]);
|
p_buf.p_ptr[i] = octa::move(p_buf.p_ptr[i - n]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ class Vector {
|
||||||
octa::RangeSize<R> l = range.size();
|
octa::RangeSize<R> l = range.size();
|
||||||
reserve(l);
|
reserve(l);
|
||||||
p_len = l;
|
p_len = l;
|
||||||
for (size_t i = 0; !range.empty(); range.pop_front()) {
|
for (octa::Size i = 0; !range.empty(); range.pop_front()) {
|
||||||
octa::allocator_construct(p_buf.get_alloc(),
|
octa::allocator_construct(p_buf.get_alloc(),
|
||||||
&p_buf.p_ptr[i], range.front());
|
&p_buf.p_ptr[i], range.front());
|
||||||
++i;
|
++i;
|
||||||
|
@ -90,7 +90,7 @@ class Vector {
|
||||||
void ctor_from_range(R &range, EnableIf<
|
void ctor_from_range(R &range, EnableIf<
|
||||||
!octa::IsFiniteRandomAccessRange<R>::value, bool
|
!octa::IsFiniteRandomAccessRange<R>::value, bool
|
||||||
> = true) {
|
> = true) {
|
||||||
size_t i = 0;
|
octa::Size i = 0;
|
||||||
for (; !range.empty(); range.pop_front()) {
|
for (; !range.empty(); range.pop_front()) {
|
||||||
reserve(i + 1);
|
reserve(i + 1);
|
||||||
octa::allocator_construct(p_buf.get_alloc(),
|
octa::allocator_construct(p_buf.get_alloc(),
|
||||||
|
@ -114,20 +114,20 @@ class Vector {
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using Size = size_t;
|
using Size = octa::Size;
|
||||||
using Difference = ptrdiff_t;
|
using Difference = octa::Ptrdiff;
|
||||||
using Value = T;
|
using Value = T;
|
||||||
using Reference = T &;
|
using Reference = T &;
|
||||||
using ConstReference = const T &;
|
using ConstReference = const T &;
|
||||||
using Pointer = T *;
|
using Pointer = T *;
|
||||||
using ConstPointer = const T *;
|
using ConstPointer = const T *;
|
||||||
using Range = PointerRange<T>;
|
using Range = octa::PointerRange<T>;
|
||||||
using ConstRange = PointerRange<const T>;
|
using ConstRange = octa::PointerRange<const T>;
|
||||||
using Allocator = A;
|
using Allocator = A;
|
||||||
|
|
||||||
Vector(const A &a = A()): p_buf(nullptr, a), p_len(0), p_cap(0) {}
|
Vector(const A &a = A()): p_buf(nullptr, a), p_len(0), p_cap(0) {}
|
||||||
|
|
||||||
explicit Vector(size_t n, const T &val = T(),
|
explicit Vector(Size n, const T &val = T(),
|
||||||
const A &al = A()): Vector(al) {
|
const A &al = A()): Vector(al) {
|
||||||
p_buf.p_ptr = octa::allocator_allocate(p_buf.get_alloc(), n);
|
p_buf.p_ptr = octa::allocator_allocate(p_buf.get_alloc(), n);
|
||||||
p_len = p_cap = n;
|
p_len = p_cap = n;
|
||||||
|
@ -183,10 +183,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector(InitializerList<T> v, const A &a = A()): Vector(a) {
|
Vector(InitializerList<T> v, const A &a = A()): Vector(a) {
|
||||||
size_t l = v.end() - v.begin();
|
Size l = v.end() - v.begin();
|
||||||
const T *ptr = v.begin();
|
const T *ptr = v.begin();
|
||||||
reserve(l);
|
reserve(l);
|
||||||
for (size_t i = 0; i < l; ++i)
|
for (Size i = 0; i < l; ++i)
|
||||||
octa::allocator_construct(p_buf.get_alloc(),
|
octa::allocator_construct(p_buf.get_alloc(),
|
||||||
&p_buf.p_ptr[i], ptr[i]);
|
&p_buf.p_ptr[i], ptr[i]);
|
||||||
p_len = l;
|
p_len = l;
|
||||||
|
@ -232,7 +232,7 @@ public:
|
||||||
|
|
||||||
Vector &operator=(InitializerList<T> il) {
|
Vector &operator=(InitializerList<T> il) {
|
||||||
clear();
|
clear();
|
||||||
size_t ilen = il.end() - il.begin();
|
Size ilen = il.end() - il.begin();
|
||||||
reserve(ilen);
|
reserve(ilen);
|
||||||
if (octa::IsPod<T>()) {
|
if (octa::IsPod<T>()) {
|
||||||
memcpy(p_buf.p_ptr, il.begin(), ilen);
|
memcpy(p_buf.p_ptr, il.begin(), ilen);
|
||||||
|
@ -254,12 +254,12 @@ public:
|
||||||
ctor_from_range(range);
|
ctor_from_range(range);
|
||||||
}
|
}
|
||||||
|
|
||||||
void resize(size_t n, const T &v = T()) {
|
void resize(Size n, const T &v = T()) {
|
||||||
size_t l = p_len;
|
Size l = p_len;
|
||||||
reserve(n);
|
reserve(n);
|
||||||
p_len = n;
|
p_len = n;
|
||||||
if (octa::IsPod<T>()) {
|
if (octa::IsPod<T>()) {
|
||||||
for (size_t i = l; i < p_len; ++i) {
|
for (Size i = l; i < p_len; ++i) {
|
||||||
p_buf.p_ptr[i] = T(v);
|
p_buf.p_ptr[i] = T(v);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -270,11 +270,11 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void reserve(size_t n) {
|
void reserve(Size n) {
|
||||||
if (n <= p_cap) return;
|
if (n <= p_cap) return;
|
||||||
size_t oc = p_cap;
|
Size oc = p_cap;
|
||||||
if (!oc) {
|
if (!oc) {
|
||||||
p_cap = octa::max(n, size_t(8));
|
p_cap = octa::max(n, Size(8));
|
||||||
} else {
|
} else {
|
||||||
while (p_cap < n) p_cap *= 2;
|
while (p_cap < n) p_cap *= 2;
|
||||||
}
|
}
|
||||||
|
@ -297,11 +297,11 @@ public:
|
||||||
p_buf.p_ptr = tmp;
|
p_buf.p_ptr = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
T &operator[](size_t i) { return p_buf.p_ptr[i]; }
|
T &operator[](Size i) { return p_buf.p_ptr[i]; }
|
||||||
const T &operator[](size_t i) const { return p_buf.p_ptr[i]; }
|
const T &operator[](Size i) const { return p_buf.p_ptr[i]; }
|
||||||
|
|
||||||
T &at(size_t i) { return p_buf.p_ptr[i]; }
|
T &at(Size i) { return p_buf.p_ptr[i]; }
|
||||||
const T &at(size_t i) const { return p_buf.p_ptr[i]; }
|
const T &at(Size i) const { return p_buf.p_ptr[i]; }
|
||||||
|
|
||||||
T &push(const T &v) {
|
T &push(const T &v) {
|
||||||
if (p_len == p_cap) reserve(p_len + 1);
|
if (p_len == p_cap) reserve(p_len + 1);
|
||||||
|
@ -342,13 +342,13 @@ public:
|
||||||
T *data() { return p_buf.p_ptr; }
|
T *data() { return p_buf.p_ptr; }
|
||||||
const T *data() const { return p_buf.p_ptr; }
|
const T *data() const { return p_buf.p_ptr; }
|
||||||
|
|
||||||
size_t size() const { return p_len; }
|
Size size() const { return p_len; }
|
||||||
size_t capacity() const { return p_cap; }
|
Size capacity() const { return p_cap; }
|
||||||
|
|
||||||
bool empty() const { return (p_len == 0); }
|
bool empty() const { return (p_len == 0); }
|
||||||
|
|
||||||
bool in_range(size_t idx) { return idx < p_len; }
|
bool in_range(Size idx) { return idx < p_len; }
|
||||||
bool in_range(int idx) { return idx >= 0 && size_t(idx) < p_len; }
|
bool in_range(int idx) { return idx >= 0 && Size(idx) < p_len; }
|
||||||
bool in_range(const T *ptr) {
|
bool in_range(const T *ptr) {
|
||||||
return ptr >= p_buf.p_ptr && ptr < &p_buf.p_ptr[p_len];
|
return ptr >= p_buf.p_ptr && ptr < &p_buf.p_ptr[p_len];
|
||||||
}
|
}
|
||||||
|
@ -360,38 +360,38 @@ public:
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
T *insert(size_t idx, T &&v) {
|
T *insert(Size idx, T &&v) {
|
||||||
insert_base(idx, 1);
|
insert_base(idx, 1);
|
||||||
p_buf.p_ptr[idx] = octa::move(v);
|
p_buf.p_ptr[idx] = octa::move(v);
|
||||||
return &p_buf.p_ptr[idx];
|
return &p_buf.p_ptr[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
T *insert(size_t idx, const T &v) {
|
T *insert(Size idx, const T &v) {
|
||||||
insert_base(idx, 1);
|
insert_base(idx, 1);
|
||||||
p_buf.p_ptr[idx] = v;
|
p_buf.p_ptr[idx] = v;
|
||||||
return &p_buf.p_ptr[idx];
|
return &p_buf.p_ptr[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
T *insert(size_t idx, size_t n, const T &v) {
|
T *insert(Size idx, Size n, const T &v) {
|
||||||
insert_base(idx, n);
|
insert_base(idx, n);
|
||||||
for (size_t i = 0; i < n; ++i) {
|
for (Size i = 0; i < n; ++i) {
|
||||||
p_buf.p_ptr[idx + i] = v;
|
p_buf.p_ptr[idx + i] = v;
|
||||||
}
|
}
|
||||||
return &p_buf.p_ptr[idx];
|
return &p_buf.p_ptr[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
T *insert_range(size_t idx, U range) {
|
T *insert_range(Size idx, U range) {
|
||||||
size_t l = range.size();
|
Size l = range.size();
|
||||||
insert_base(idx, l);
|
insert_base(idx, l);
|
||||||
for (size_t i = 0; i < l; ++i) {
|
for (Size i = 0; i < l; ++i) {
|
||||||
p_buf.p_ptr[idx + i] = range.front();
|
p_buf.p_ptr[idx + i] = range.front();
|
||||||
range.pop_front();
|
range.pop_front();
|
||||||
}
|
}
|
||||||
return &p_buf.p_ptr[idx];
|
return &p_buf.p_ptr[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
T *insert(size_t idx, InitializerList<T> il) {
|
T *insert(Size idx, InitializerList<T> il) {
|
||||||
return insert_range(idx, octa::each(il));
|
return insert_range(idx, octa::each(il));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,15 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
void *operator new(size_t size) {
|
#include "octa/types.h"
|
||||||
|
|
||||||
|
void *operator new(octa::Size size) {
|
||||||
void *p = malloc(size);
|
void *p = malloc(size);
|
||||||
if (!p) abort();
|
if (!p) abort();
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *operator new[](size_t size) {
|
void *operator new[](octa::Size size) {
|
||||||
void *p = malloc(size);
|
void *p = malloc(size);
|
||||||
if (!p) abort();
|
if (!p) abort();
|
||||||
return p;
|
return p;
|
||||||
|
|
Loading…
Reference in New Issue