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