use new type aliases + refactoring + namespacing

master
Daniel Kolesa 2015-06-08 21:20:12 +01:00
parent 06dc966f19
commit ea42a5e841
13 changed files with 744 additions and 695 deletions

View File

@ -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) {

View File

@ -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}

View File

@ -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>

View File

@ -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; }

View File

@ -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) {

View File

@ -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

View File

@ -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);
} }

View File

@ -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

View File

@ -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 */

View File

@ -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);

View File

@ -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]);
} }
} }

View File

@ -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));
} }

View File

@ -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;