get rid of full namespace where unambiguous resolution is guaranteed

master
Daniel Kolesa 2015-07-05 23:59:36 +01:00
parent d2aba4d5b6
commit 1654ee84db
18 changed files with 1333 additions and 1418 deletions

View File

@ -42,25 +42,25 @@ bool is_partitioned(R range, P pred) {
namespace detail {
template<typename R, typename C>
void insort(R range, C compare) {
octa::RangeSize<R> rlen = range.size();
for (octa::RangeSize<R> i = 1; i < rlen; ++i) {
octa::RangeSize<R> j = i;
octa::RangeValue<R> v(octa::move(range[i]));
RangeSize<R> rlen = range.size();
for (RangeSize<R> i = 1; i < rlen; ++i) {
RangeSize<R> j = i;
RangeValue<R> v(move(range[i]));
while (j > 0 && !compare(range[j - 1], v)) {
range[j] = range[j - 1];
--j;
}
range[j] = octa::move(v);
range[j] = move(v);
}
}
template<typename R, typename C>
void hs_sift_down(R range, octa::RangeSize<R> s,
octa::RangeSize<R> e, C compare) {
octa::RangeSize<R> r = s;
void hs_sift_down(R range, RangeSize<R> s,
RangeSize<R> e, C compare) {
RangeSize<R> r = s;
while ((r * 2 + 1) <= e) {
octa::RangeSize<R> ch = r * 2 + 1;
octa::RangeSize<R> sw = r;
RangeSize<R> ch = r * 2 + 1;
RangeSize<R> sw = r;
if (compare(range[sw], range[ch]))
sw = ch;
if (((ch + 1) <= e) && compare(range[sw], range[ch + 1]))
@ -74,32 +74,32 @@ namespace detail {
template<typename R, typename C>
void heapsort(R range, C compare) {
octa::RangeSize<R> len = range.size();
octa::RangeSize<R> st = (len - 2) / 2;
RangeSize<R> len = range.size();
RangeSize<R> st = (len - 2) / 2;
for (;;) {
octa::detail::hs_sift_down(range, st, len - 1, compare);
detail::hs_sift_down(range, st, len - 1, compare);
if (st-- == 0) break;
}
octa::RangeSize<R> e = len - 1;
RangeSize<R> e = len - 1;
while (e > 0) {
octa::swap(range[e], range[0]);
--e;
octa::detail::hs_sift_down(range, 0, e, compare);
detail::hs_sift_down(range, 0, e, compare);
}
}
template<typename R, typename C>
void introloop(R range, C compare, RangeSize<R> depth) {
if (range.size() <= 10) {
octa::detail::insort(range, compare);
detail::insort(range, compare);
return;
}
if (depth == 0) {
octa::detail::heapsort(range, compare);
detail::heapsort(range, compare);
return;
}
octa::swap(range[range.size() / 2], range.back());
octa::RangeSize<R> pi = 0;
RangeSize<R> pi = 0;
R pr = range;
pr.pop_back();
for (; !pr.empty(); pr.pop_front()) {
@ -107,26 +107,26 @@ namespace detail {
octa::swap(pr.front(), range[pi++]);
}
octa::swap(range[pi], range.back());
octa::detail::introloop(range.slice(0, pi), compare, depth - 1);
octa::detail::introloop(range.slice(pi + 1, range.size()), compare,
detail::introloop(range.slice(0, pi), compare, depth - 1);
detail::introloop(range.slice(pi + 1, range.size()), compare,
depth - 1);
}
template<typename R, typename C>
void introsort(R range, C compare) {
octa::detail::introloop(range, compare, octa::RangeSize<R>(2
detail::introloop(range, compare, RangeSize<R>(2
* (log(range.size()) / log(2))));
}
} /* namespace detail */
template<typename R, typename C>
void sort(R range, C compare) {
octa::detail::introsort(range, compare);
detail::introsort(range, compare);
}
template<typename R>
void sort(R range) {
sort(range, octa::Less<RangeValue<R>>());
sort(range, Less<RangeValue<R>>());
}
/* min/max(_element) */
@ -220,7 +220,7 @@ template<typename R, typename F>
F for_each(R range, F func) {
for (; !range.empty(); range.pop_front())
func(range.front());
return octa::move(func);
return move(func);
}
template<typename R, typename P>
@ -333,7 +333,7 @@ R2 copy_if_not(R1 irange, R2 orange, P pred) {
template<typename R1, typename R2>
R2 move(R1 irange, R2 orange) {
for (; !irange.empty(); irange.pop_front())
orange.put(octa::move(irange.front()));
orange.put(move(irange.front()));
return orange;
}
@ -366,7 +366,7 @@ void generate(R range, F gen) {
}
template<typename R1, typename R2>
octa::Pair<R1, R2> swap_ranges(R1 range1, R2 range2) {
Pair<R1, R2> swap_ranges(R1 range1, R2 range2) {
while (!range1.empty() && !range2.empty()) {
octa::swap(range1.front(), range2.front());
range1.pop_front();
@ -411,11 +411,11 @@ T foldr(R range, T init, F func) {
template<typename T, typename F, typename R>
struct MapRange: InputRange<
MapRange<T, F, R>, octa::RangeCategory<T>, R, R, octa::RangeSize<T>
MapRange<T, F, R>, RangeCategory<T>, R, R, RangeSize<T>
> {
private:
T p_range;
octa::FunctionMakeDefaultConstructible<F> p_func;
FunctionMakeDefaultConstructible<F> p_func;
public:
MapRange() = delete;
@ -438,7 +438,7 @@ public:
}
bool empty() const { return p_range.empty(); }
octa::RangeSize<T> size() const { return p_range.size(); }
RangeSize<T> size() const { return p_range.size(); }
bool equals_front(const MapRange &r) const {
return p_range.equals_front(r.p_range);
@ -447,10 +447,10 @@ public:
return p_range.equals_front(r.p_range);
}
octa::RangeDifference<T> distance_front(const MapRange &r) const {
RangeDifference<T> distance_front(const MapRange &r) const {
return p_range.distance_front(r.p_range);
}
octa::RangeDifference<T> distance_back(const MapRange &r) const {
RangeDifference<T> distance_back(const MapRange &r) const {
return p_range.distance_back(r.p_range);
}
@ -460,54 +460,51 @@ public:
bool push_front() { return p_range.pop_front(); }
bool push_back() { return p_range.push_back(); }
octa::RangeSize<T> pop_front_n(octa::RangeSize<T> n) {
RangeSize<T> pop_front_n(RangeSize<T> n) {
p_range.pop_front_n(n);
}
octa::RangeSize<T> pop_back_n(octa::RangeSize<T> n) {
RangeSize<T> pop_back_n(RangeSize<T> n) {
p_range.pop_back_n(n);
}
octa::RangeSize<T> push_front_n(octa::RangeSize<T> n) {
RangeSize<T> push_front_n(RangeSize<T> n) {
return p_range.push_front_n(n);
}
octa::RangeSize<T> push_back_n(octa::RangeSize<T> n) {
RangeSize<T> push_back_n(RangeSize<T> n) {
return p_range.push_back_n(n);
}
R front() const { return p_func(p_range.front()); }
R back() const { return p_func(p_range.back()); }
R operator[](octa::RangeSize<T> idx) const {
R operator[](RangeSize<T> idx) const {
return p_func(p_range[idx]);
}
MapRange slice(octa::RangeSize<T> start,
octa::RangeSize<T> end) {
MapRange slice(RangeSize<T> start, RangeSize<T> end) {
return MapRange(p_range.slice(start, end), p_func);
}
};
namespace detail {
template<typename R, typename F> using MapReturnType
= decltype(declval<F>()(octa::declval<octa::RangeReference<R>>()));
= decltype(declval<F>()(declval<RangeReference<R>>()));
}
template<typename R, typename F>
MapRange<R, F, octa::detail::MapReturnType<R, F>> map(R range,
F func) {
return octa::MapRange<R, F, octa::detail::MapReturnType<R, F>>(range,
MapRange<R, F, detail::MapReturnType<R, F>> map(R range, F func) {
return MapRange<R, F, detail::MapReturnType<R, F>>(range,
func);
}
template<typename T, typename F>
struct FilterRange: InputRange<
FilterRange<T, F>, octa::CommonType<octa::RangeCategory<T>,
octa::ForwardRangeTag>,
octa::RangeValue<T>, octa::RangeReference<T>, octa::RangeSize<T>
FilterRange<T, F>, CommonType<RangeCategory<T>, ForwardRangeTag>,
RangeValue<T>, RangeReference<T>, RangeSize<T>
> {
private:
T p_range;
octa::FunctionMakeDefaultConstructible<F> p_pred;
FunctionMakeDefaultConstructible<F> p_pred;
void advance_valid() {
while (!p_range.empty() && !p_pred(front())) p_range.pop_front();
@ -554,22 +551,19 @@ public:
return ret;
}
octa::RangeReference<T> front() const { return p_range.front(); }
RangeReference<T> front() const { return p_range.front(); }
};
namespace detail {
template<typename R, typename P> using FilterPred
= octa::EnableIf<IsSame<
decltype(octa::declval<P>()(octa::declval<
octa::RangeReference<R>
>())),
bool
= EnableIf<IsSame<
decltype(declval<P>()(declval<RangeReference<R>>())), bool
>::value, P>;
}
template<typename R, typename P>
FilterRange<R, octa::detail::FilterPred<R, P>> filter(R range, P pred) {
return octa::FilterRange<R, P>(range, pred);
FilterRange<R, detail::FilterPred<R, P>> filter(R range, P pred) {
return FilterRange<R, P>(range, pred);
}
} /* namespace octa */

View File

@ -14,17 +14,17 @@
namespace octa {
template<typename T, octa::Size N>
template<typename T, Size N>
struct Array {
using Size = octa::Size;
using Difference = octa::Ptrdiff;
using Size = Size;
using Difference = Ptrdiff;
using Value = T;
using Reference = T &;
using ConstReference = const T &;
using Pointer = T *;
using ConstPointer = const T *;
using Range = octa::PointerRange<T>;
using ConstRange = octa::PointerRange<const T>;
using Range = PointerRange<T>;
using ConstRange = PointerRange<const T>;
T &operator[](Size i) { return p_buf[i]; }
const T &operator[](Size i) const { return p_buf[i]; }

View File

@ -115,7 +115,7 @@ namespace detail {
__atomic_signal_fence(to_gcc_order(ord));
}
static inline bool atomic_is_lock_free(octa::Size size) {
static inline bool atomic_is_lock_free(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 octa::Size value = 1; };
struct SkipAmt { static constexpr Size value = 1; };
template<typename T>
struct SkipAmt<T *> { static constexpr octa::Size value = sizeof(T); };
struct SkipAmt<T *> { static constexpr Size value = sizeof(T); };
template<typename T> struct SkipAmt<T[]> {};
template<typename T, octa::Size N> struct SkipAmt<T[N]> {};
template<typename T, Size N> struct SkipAmt<T[N]> {};
template<typename T, typename U>
static inline T atomic_fetch_add(volatile AtomicBase<T> *a,
@ -288,8 +288,7 @@ template <typename T> inline T kill_dependency(T v) {
}
namespace detail {
template<typename T, bool = octa::IsIntegral<T>::value &&
!octa::IsSame<T, bool>::value>
template<typename T, bool = IsIntegral<T>::value && !IsSame<T, bool>::value>
struct Atomic {
mutable AtomicBase<T> p_a;
@ -451,8 +450,8 @@ namespace detail {
}
template<typename T>
struct Atomic: octa::detail::Atomic<T> {
using Base = octa::detail::Atomic<T>;
struct Atomic: detail::Atomic<T> {
using Base = detail::Atomic<T>;
Atomic() = default;
@ -468,8 +467,8 @@ struct Atomic: octa::detail::Atomic<T> {
};
template<typename T>
struct Atomic<T *>: octa::detail::Atomic<T *> {
using Base = octa::detail::Atomic<T *>;
struct Atomic<T *>: detail::Atomic<T *> {
using Base = detail::Atomic<T *>;
Atomic() = default;
@ -483,22 +482,22 @@ struct Atomic<T *>: octa::detail::Atomic<T *> {
Base::store(v); return v;
}
T *fetch_add(octa::Ptrdiff op, MemoryOrder ord = MemoryOrder::seq_cst)
T *fetch_add(Ptrdiff op, MemoryOrder ord = MemoryOrder::seq_cst)
volatile {
return octa::detail::atomic_fetch_add(&this->p_a, op, ord);
return detail::atomic_fetch_add(&this->p_a, op, ord);
}
T *fetch_add(octa::Ptrdiff op, MemoryOrder ord = MemoryOrder::seq_cst) {
return octa::detail::atomic_fetch_add(&this->p_a, op, ord);
T *fetch_add(Ptrdiff op, MemoryOrder ord = MemoryOrder::seq_cst) {
return detail::atomic_fetch_add(&this->p_a, op, ord);
}
T *fetch_sub(octa::Ptrdiff op, MemoryOrder ord = MemoryOrder::seq_cst)
T *fetch_sub(Ptrdiff op, MemoryOrder ord = MemoryOrder::seq_cst)
volatile {
return octa::detail::atomic_fetch_sub(&this->p_a, op, ord);
return detail::atomic_fetch_sub(&this->p_a, op, ord);
}
T *fetch_sub(octa::Ptrdiff op, MemoryOrder ord = MemoryOrder::seq_cst) {
return octa::detail::atomic_fetch_sub(&this->p_a, op, ord);
T *fetch_sub(Ptrdiff op, MemoryOrder ord = MemoryOrder::seq_cst) {
return detail::atomic_fetch_sub(&this->p_a, op, ord);
}
@ -511,10 +510,10 @@ struct Atomic<T *>: octa::detail::Atomic<T *> {
T *operator--( ) volatile { return fetch_sub(1) - 1; }
T *operator--( ) { return fetch_sub(1) - 1; }
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; }
T *operator+=(Ptrdiff op) volatile { return fetch_add(op) + op; }
T *operator+=(Ptrdiff op) { return fetch_add(op) + op; }
T *operator-=(Ptrdiff op) volatile { return fetch_sub(op) - op; }
T *operator-=(Ptrdiff op) { return fetch_sub(op) - op; }
};
template<typename T>
@ -529,12 +528,12 @@ inline bool atomic_is_lock_free(const Atomic<T> *a) {
template<typename T>
inline void atomic_init(volatile Atomic<T> *a, T v) {
octa::detail::atomic_init(&a->p_a, v);
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);
detail::atomic_init(&a->p_a, v);
}
template <typename T>
@ -657,196 +656,176 @@ inline bool atomic_compare_exchange_strong_explicit(Atomic<T> *a, T *e,
}
template <typename T>
inline octa::EnableIf<octa::IsIntegral<T>::value &&
!octa::IsSame<T, bool>::value, T>
inline EnableIf<IsIntegral<T>::value && !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>
inline EnableIf<IsIntegral<T>::value && !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) {
inline T *atomic_fetch_add(volatile Atomic<T *> *a, Ptrdiff op) {
return a->fetch_add(op);
}
template <typename T>
inline T *atomic_fetch_add(Atomic<T *> *a, octa::Ptrdiff op) {
inline T *atomic_fetch_add(Atomic<T *> *a, Ptrdiff op) {
return a->fetch_add(op);
}
template <typename T>
inline octa::EnableIf<octa::IsIntegral<T>::value &&
!octa::IsSame<T, bool>::value, T>
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
atomic_fetch_add_explicit(volatile Atomic<T> *a, T op,
MemoryOrder ord) {
return a->fetch_add(op, ord);
}
template <typename T>
inline octa::EnableIf<octa::IsIntegral<T>::value &&
!octa::IsSame<T, bool>::value, T>
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
atomic_fetch_add_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
return a->fetch_add(op, ord);
}
template <typename T>
inline T *atomic_fetch_add_explicit(volatile Atomic<T *> *a,
octa::Ptrdiff op, MemoryOrder ord) {
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,
inline T *atomic_fetch_add_explicit(Atomic<T *> *a, 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>
inline EnableIf<IsIntegral<T>::value && !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>
inline EnableIf<IsIntegral<T>::value && !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) {
inline T *atomic_fetch_sub(volatile Atomic<T *> *a, Ptrdiff op) {
return a->fetch_sub(op);
}
template <typename T>
inline T *atomic_fetch_sub(Atomic<T *> *a, octa::Ptrdiff op) {
inline T *atomic_fetch_sub(Atomic<T *> *a, Ptrdiff op) {
return a->fetch_sub(op);
}
template <typename T>
inline octa::EnableIf<octa::IsIntegral<T>::value &&
!octa::IsSame<T, bool>::value, T>
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
atomic_fetch_sub_explicit(volatile Atomic<T> *a, T op,
MemoryOrder ord) {
return a->fetch_sub(op, ord);
}
template <typename T>
inline octa::EnableIf<octa::IsIntegral<T>::value &&
!octa::IsSame<T, bool>::value, T>
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
atomic_fetch_sub_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
return a->fetch_sub(op, ord);
}
template <typename T>
inline T *atomic_fetch_sub_explicit(volatile Atomic<T *> *a,
octa::Ptrdiff op, MemoryOrder ord) {
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,
inline T *atomic_fetch_sub_explicit(Atomic<T *> *a, 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>
inline EnableIf<IsIntegral<T>::value && !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>
inline EnableIf<IsIntegral<T>::value && !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>
inline EnableIf<IsIntegral<T>::value && !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>
inline EnableIf<IsIntegral<T>::value && !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>
inline EnableIf<IsIntegral<T>::value && !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>
inline EnableIf<IsIntegral<T>::value && !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>
inline EnableIf<IsIntegral<T>::value && !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>
inline EnableIf<IsIntegral<T>::value && !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>
inline EnableIf<IsIntegral<T>::value && !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>
inline EnableIf<IsIntegral<T>::value && !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>
inline EnableIf<IsIntegral<T>::value && !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>
inline EnableIf<IsIntegral<T>::value && !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;
detail::AtomicBase<bool> p_a;
AtomicFlag() = default;
@ -858,19 +837,19 @@ struct AtomicFlag {
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);
return 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);
return detail::atomic_exchange(&p_a, true, ord);
}
void clear(MemoryOrder ord = MemoryOrder::seq_cst) volatile {
octa::detail::atomic_store(&p_a, false, ord);
detail::atomic_store(&p_a, false, ord);
}
void clear(MemoryOrder ord = MemoryOrder::seq_cst) {
octa::detail::atomic_store(&p_a, false, ord);
detail::atomic_store(&p_a, false, ord);
}
};
@ -910,11 +889,11 @@ inline void atomic_flag_clear_explicit(AtomicFlag *a, MemoryOrder ord) {
}
inline void atomic_thread_fence(MemoryOrder ord) {
octa::detail::atomic_thread_fence(ord);
detail::atomic_thread_fence(ord);
}
inline void atomic_signal_fence(MemoryOrder ord) {
octa::detail::atomic_signal_fence(ord);
detail::atomic_signal_fence(ord);
}
using AtomicBool = Atomic<bool>;
@ -922,56 +901,56 @@ using AtomicChar = Atomic<char>;
using AtomicShort = Atomic<short>;
using AtomicInt = Atomic<int>;
using AtomicLong = Atomic<long>;
using AtomicSbyte = Atomic<octa::sbyte>;
using AtomicByte = Atomic<octa::byte>;
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 AtomicSbyte = Atomic<sbyte>;
using AtomicByte = Atomic<byte>;
using AtomicUshort = Atomic<ushort>;
using AtomicUint = Atomic<uint>;
using AtomicUlong = Atomic<ulong>;
using AtomicLlong = Atomic<llong>;
using AtomicUllong = Atomic<ullong>;
using AtomicChar16 = Atomic<octa::Char16>;
using AtomicChar32 = Atomic<octa::Char32>;
using AtomicWchar = Atomic<octa::Wchar>;
using AtomicChar16 = Atomic<Char16>;
using AtomicChar32 = Atomic<Char32>;
using AtomicWchar = Atomic<Wchar>;
using AtomicPtrdiff = Atomic<octa::Ptrdiff>;
using AtomicSize = Atomic<octa::Size>;
using AtomicPtrdiff = Atomic<Ptrdiff>;
using AtomicSize = Atomic<Size>;
using AtomicIntmax = Atomic<octa::Intmax>;
using AtomicUintmax = Atomic<octa::Uintmax>;
using AtomicIntmax = Atomic<Intmax>;
using AtomicUintmax = Atomic<Uintmax>;
using AtomicIntptr = Atomic<octa::Intptr>;
using AtomicUintptr = Atomic<octa::Uintptr>;
using AtomicIntptr = Atomic<Intptr>;
using AtomicUintptr = Atomic<Uintptr>;
using AtomicInt8 = Atomic<octa::Int8>;
using AtomicInt16 = Atomic<octa::Int16>;
using AtomicInt32 = Atomic<octa::Int32>;
using AtomicInt64 = Atomic<octa::Int64>;
using AtomicInt8 = Atomic<Int8>;
using AtomicInt16 = Atomic<Int16>;
using AtomicInt32 = Atomic<Int32>;
using AtomicInt64 = Atomic<Int64>;
using AtomicUint8 = Atomic<octa::Uint8>;
using AtomicUint16 = Atomic<octa::Uint16>;
using AtomicUint32 = Atomic<octa::Uint32>;
using AtomicUint64 = Atomic<octa::Uint64>;
using AtomicUint8 = Atomic<Uint8>;
using AtomicUint16 = Atomic<Uint16>;
using AtomicUint32 = Atomic<Uint32>;
using AtomicUint64 = Atomic<Uint64>;
using AtomicIntLeast8 = Atomic<octa::IntLeast8>;
using AtomicIntLeast16 = Atomic<octa::IntLeast16>;
using AtomicIntLeast32 = Atomic<octa::IntLeast32>;
using AtomicIntLeast64 = Atomic<octa::IntLeast64>;
using AtomicIntLeast8 = Atomic<IntLeast8>;
using AtomicIntLeast16 = Atomic<IntLeast16>;
using AtomicIntLeast32 = Atomic<IntLeast32>;
using AtomicIntLeast64 = Atomic<IntLeast64>;
using AtomicUintLeast8 = Atomic<octa::UintLeast8>;
using AtomicUintLeast16 = Atomic<octa::UintLeast16>;
using AtomicUintLeast32 = Atomic<octa::UintLeast32>;
using AtomicUintLeast64 = Atomic<octa::UintLeast64>;
using AtomicUintLeast8 = Atomic<UintLeast8>;
using AtomicUintLeast16 = Atomic<UintLeast16>;
using AtomicUintLeast32 = Atomic<UintLeast32>;
using AtomicUintLeast64 = Atomic<UintLeast64>;
using AtomicIntFast8 = Atomic<octa::IntFast8>;
using AtomicIntFast16 = Atomic<octa::IntFast16>;
using AtomicIntFast32 = Atomic<octa::IntFast32>;
using AtomicIntFast64 = Atomic<octa::IntFast64>;
using AtomicIntFast8 = Atomic<IntFast8>;
using AtomicIntFast16 = Atomic<IntFast16>;
using AtomicIntFast32 = Atomic<IntFast32>;
using AtomicIntFast64 = Atomic<IntFast64>;
using AtomicUintFast8 = Atomic<octa::UintFast8>;
using AtomicUintFast16 = Atomic<octa::UintFast16>;
using AtomicUintFast32 = Atomic<octa::UintFast32>;
using AtomicUintFast64 = Atomic<octa::UintFast64>;
using AtomicUintFast8 = Atomic<UintFast8>;
using AtomicUintFast16 = Atomic<UintFast16>;
using AtomicUintFast32 = Atomic<UintFast32>;
using AtomicUintFast64 = Atomic<UintFast64>;
#define ATOMIC_FLAG_INIT {false}
#define ATOMIC_VAR_INIT(v) {v}

View File

@ -41,8 +41,8 @@ namespace detail {
return ret;
}
static inline octa::Size read_digits(const char *&fmt, char *buf) {
octa::Size ret = 0;
static inline Size read_digits(const char *&fmt, char *buf) {
Size ret = 0;
for (; isdigit(*fmt); ++ret)
*buf++ = *fmt++;
*buf = '\0';
@ -59,7 +59,7 @@ namespace detail {
* 7 .. string
* 8 .. custom object
*/
static constexpr const octa::byte fmt_specs[] = {
static constexpr const byte fmt_specs[] = {
/* uppercase spec set */
1, 3, 8, 8, /* A B C D */
1, 1, 1, 8, /* E F G H */
@ -107,23 +107,23 @@ namespace detail {
/* retrieve width/precision */
template<typename T>
bool convert_arg_param(const T &val, int &param, octa::EnableIf<
octa::IsIntegral<T>::value, bool
bool convert_arg_param(const T &val, int &param, EnableIf<
IsIntegral<T>::value, bool
> = true) {
param = int(val);
return true;
}
template<typename T>
bool convert_arg_param(const T &, int &, octa::EnableIf<
!octa::IsIntegral<T>::value, bool
bool convert_arg_param(const T &, int &, EnableIf<
!IsIntegral<T>::value, bool
> = true) {
assert(false && "invalid argument for width/precision");
return false;
}
template<typename T>
bool get_arg_param(octa::Size idx, int &param, const T &val) {
bool get_arg_param(Size idx, int &param, const T &val) {
if (idx) {
assert(false && "not enough format args");
return false;
@ -131,7 +131,7 @@ namespace detail {
return convert_arg_param(val, param);
}
template<typename T, typename ...A>
bool get_arg_param(octa::Size idx, int &param, const T &val,
bool get_arg_param(Size idx, int &param, const T &val,
const A &...args) {
if (idx) return get_arg_param(idx - 1, param, args...);
return convert_arg_param(val, param);
@ -144,8 +144,8 @@ struct FormatSpec {
p_nested_escape(escape), p_fmt(fmt) {}
template<typename R>
bool read_until_spec(R &writer, octa::Size *wret) {
octa::Size written = 0;
bool read_until_spec(R &writer, Size *wret) {
Size written = 0;
if (!p_fmt) return false;
while (*p_fmt) {
if (*p_fmt == '%') {
@ -164,8 +164,7 @@ struct FormatSpec {
}
template<typename R>
octa::Size write_spaces(R &writer, octa::Size n,
bool left, char c = ' ') const {
Size write_spaces(R &writer, Size n, bool left, char c = ' ') const {
if (left == bool(p_flags & FMT_FLAG_DASH)) return 0;
int r = p_width - int(n);
for (int w = p_width - int(n); --w >= 0; writer.put(c));
@ -177,7 +176,7 @@ struct FormatSpec {
return p_fmt;
}
void build_spec(char *buf, const char *spec, octa::Size specn) {
void build_spec(char *buf, const char *spec, Size specn) {
*buf++ = '%';
if (p_flags & FMT_FLAG_DASH ) *buf++ = '-';
if (p_flags & FMT_FLAG_ZERO ) *buf++ = '0';
@ -199,36 +198,36 @@ struct FormatSpec {
bool arg_precision() const { return p_arg_precision; }
template<typename ...A>
bool set_width(octa::Size idx, const A &...args) {
return octa::detail::get_arg_param(idx, p_width, args...);
bool set_width(Size idx, const A &...args) {
return detail::get_arg_param(idx, p_width, args...);
}
template<typename ...A>
bool set_precision(octa::Size idx, const A &...args) {
return octa::detail::get_arg_param(idx, p_precision, args...);
bool set_precision(Size idx, const A &...args) {
return detail::get_arg_param(idx, p_precision, args...);
}
int flags() const { return p_flags; }
char spec() const { return p_spec; }
octa::byte index() const { return p_index; }
byte index() const { return p_index; }
const char *nested() const { return p_nested; }
octa::Size nested_len() const { return p_nested_len; }
Size nested_len() const { return p_nested_len; }
const char *nested_sep() const { return p_nested_sep; }
octa::Size nested_sep_len() const { return p_nested_sep_len; }
Size nested_sep_len() const { return p_nested_sep_len; }
bool is_nested() const { return p_is_nested; }
bool nested_escape() const { return p_nested_escape; }
protected:
const char *p_nested = nullptr;
octa::Size p_nested_len = 0;
Size p_nested_len = 0;
const char *p_nested_sep = nullptr;
octa::Size p_nested_sep_len = 0;
Size p_nested_sep_len = 0;
int p_flags = 0;
@ -243,7 +242,7 @@ protected:
char p_spec = '\0';
octa::byte p_index = 0;
byte p_index = 0;
bool p_is_nested = false;
bool p_nested_escape = false;
@ -323,7 +322,7 @@ protected:
if ((*p_fmt == '(') || ((*p_fmt == '-') && (*(p_fmt + 1) == '('))) {
return read_spec_range();
}
octa::Size ndig = octa::detail::read_digits(p_fmt, p_buf);
Size ndig = detail::read_digits(p_fmt, p_buf);
bool havepos = false;
p_index = 0;
@ -332,7 +331,7 @@ protected:
if (ndig <= 0) return false; /* no pos given */
int idx = atoi(p_buf);
if (idx <= 0 || idx > 255) return false; /* bad index */
p_index = octa::byte(idx);
p_index = byte(idx);
++p_fmt;
havepos = true;
}
@ -344,17 +343,17 @@ protected:
/* parse flags */
p_flags = 0;
octa::Size skipd = 0;
Size skipd = 0;
if (havepos || !ndig) {
p_flags = octa::detail::parse_fmt_flags(p_fmt, 0);
p_flags = detail::parse_fmt_flags(p_fmt, 0);
} else {
for (octa::Size i = 0; i < ndig; ++i) {
for (Size i = 0; i < ndig; ++i) {
if (p_buf[i] != '0') break;
++skipd;
}
if (skipd) p_flags = FMT_FLAG_ZERO;
if (skipd == ndig)
p_flags = octa::detail::parse_fmt_flags(p_fmt, p_flags);
p_flags = detail::parse_fmt_flags(p_fmt, p_flags);
}
/* parse width */
@ -364,7 +363,7 @@ protected:
if (!havepos && ndig && (ndig - skipd)) {
p_width = atoi(p_buf + skipd);
p_has_width = true;
} else if (octa::detail::read_digits(p_fmt, p_buf)) {
} else if (detail::read_digits(p_fmt, p_buf)) {
p_width = atoi(p_buf);
p_has_width = true;
} else if (*p_fmt == '*') {
@ -379,7 +378,7 @@ protected:
if (*p_fmt != '.') goto fmtchar;
++p_fmt;
if (octa::detail::read_digits(p_fmt, p_buf)) {
if (detail::read_digits(p_fmt, p_buf)) {
p_precision = atoi(p_buf);
p_has_precision = true;
} else if (*p_fmt == '*') {
@ -391,8 +390,8 @@ protected:
p_spec = *p_fmt++;
/* make sure we're testing on a signed byte - our mapping only
* tests values up to 127 */
octa::sbyte sp = p_spec;
return (sp >= 65) && (octa::detail::fmt_specs[sp - 65] != 0);
sbyte sp = p_spec;
return (sp >= 65) && (detail::fmt_specs[sp - 65] != 0);
}
const char *p_fmt;
@ -401,24 +400,24 @@ protected:
namespace detail {
template<typename R, typename T>
static inline octa::Ptrdiff write_u(R &writer, const FormatSpec *fl,
bool neg, T val) {
static inline Ptrdiff write_u(R &writer, const FormatSpec *fl,
bool neg, T val) {
char buf[20];
octa::Ptrdiff r = 0;
octa::Size n = 0;
Ptrdiff r = 0;
Size n = 0;
char spec = fl->spec();
if (spec == 's') spec = 'd';
octa::byte specn = octa::detail::fmt_specs[spec - 65];
byte specn = detail::fmt_specs[spec - 65];
if (specn <= 2 || specn > 7) {
assert(false && "cannot format integers with the given spec");
return -1;
}
int base = octa::detail::fmt_bases[specn];
int base = detail::fmt_bases[specn];
if (!val) buf[n++] = '0';
for (; val; val /= base)
buf[n++] = octa::detail::fmt_digits[spec >= 'a'][val % base];
buf[n++] = detail::fmt_digits[spec >= 'a'][val % base];
r = n;
int flags = fl->flags();
@ -431,7 +430,7 @@ namespace detail {
const char *pfx = nullptr;
int pfxlen = 0;
if (flags & FMT_FLAG_HASH && spec != 'd') {
pfx = octa::detail::fmt_intpfx[spec >= 'a'][specn - 3];
pfx = detail::fmt_intpfx[spec >= 'a'][specn - 3];
pfxlen = !!pfx[1] + 1;
r += pfxlen;
}
@ -451,52 +450,43 @@ namespace detail {
}
template<typename R, typename ...A>
static octa::Ptrdiff format_impl(R &writer, octa::Size &fmtn,
bool escape, const char *fmt,
const A &...args);
static Ptrdiff format_impl(R &writer, Size &fmtn, bool escape,
const char *fmt, const A &...args);
template<typename T, typename = octa::RangeOf<T>>
static octa::True test_fmt_range(int);
template<typename T, typename = RangeOf<T>>
static True test_fmt_range(int);
template<typename>
static octa::False test_fmt_range(...);
static False test_fmt_range(...);
template<typename T>
using FmtRangeTest = decltype(test_fmt_range<T>(0));
template<typename R, typename T>
static inline octa::Ptrdiff format_ritem(R &writer, octa::Size &fmtn,
bool esc,
const char *fmt,
const T &item) {
static inline Ptrdiff format_ritem(R &writer, Size &fmtn, bool esc,
const char *fmt, const T &item) {
return format_impl(writer, fmtn, esc, fmt, item);
}
template<typename R, typename T, typename U>
static inline octa::Ptrdiff format_ritem(R &writer, octa::Size &fmtn,
bool esc,
const char *fmt,
const octa::Pair<T, U> &pair) {
static inline Ptrdiff format_ritem(R &writer, Size &fmtn, bool esc,
const char *fmt,
const Pair<T, U> &pair) {
return format_impl(writer, fmtn, esc, fmt, pair.first, pair.second);
}
template<typename R, typename T>
static inline octa::Ptrdiff write_range(R &writer,
const FormatSpec *fl,
bool escape,
const char *sep,
octa::Size seplen,
const T &val,
octa::EnableIf<
FmtRangeTest<T>::value,
bool
> = true) {
static inline Ptrdiff write_range(R &writer, const FormatSpec *fl,
bool escape, const char *sep,
Size seplen, const T &val,
EnableIf<FmtRangeTest<T>::value,
bool> = true) {
auto range = octa::iter(val);
if (range.empty()) return 0;
octa::Ptrdiff ret = 0;
octa::Size fmtn = 0;
Ptrdiff ret = 0;
Size fmtn = 0;
/* test first item */
octa::Ptrdiff fret = format_ritem(writer, fmtn, escape,
fl->rest(), range.front());
Ptrdiff fret = format_ritem(writer, fmtn, escape, fl->rest(),
range.front());
if (fret < 0) return fret;
ret += fret;
range.pop_front();
@ -515,21 +505,18 @@ namespace detail {
}
template<typename R, typename T>
static inline octa::Ptrdiff write_range(R &, const FormatSpec *, bool,
const char *, octa::Size,
const T &,
octa::EnableIf<
!FmtRangeTest<T>::value,
bool
> = true) {
static inline Ptrdiff write_range(R &, const FormatSpec *, bool,
const char *, Size, const T &,
EnableIf<!FmtRangeTest<T>::value,
bool> = true) {
assert(false && "invalid value for ranged format");
return -1;
}
template<typename T,
typename = decltype(octa::to_string(octa::declval<T>()))
> static octa::True test_fmt_tostr(int);
template<typename> static octa::False test_fmt_tostr(...);
typename = decltype(octa::to_string(declval<T>()))
> static True test_fmt_tostr(int);
template<typename> static False test_fmt_tostr(...);
template<typename T>
using FmtTostrTest = decltype(test_fmt_tostr<T>(0));
@ -549,15 +536,15 @@ namespace detail {
static inline const char *escape_fmt_char(char v, char quote) {
if ((v >= 0 && v < 0x20) || (v == quote)) {
return fmt_escapes[octa::Size(v)];
return fmt_escapes[Size(v)];
} else if (v == 0x7F) {
return "\\x7F";
}
return nullptr;
}
static inline octa::String escape_fmt_str(const char *val) {
octa::String ret;
static inline String escape_fmt_str(const char *val) {
String ret;
ret.push('"');
while (*val) {
const char *esc = escape_fmt_char(*val, '"');
@ -572,7 +559,7 @@ namespace detail {
}
template<typename R>
struct FmtWriteRange: octa::OutputRange<FmtWriteRange<R>, char> {
struct FmtWriteRange: OutputRange<FmtWriteRange<R>, char> {
FmtWriteRange() = delete;
FmtWriteRange(R &out): p_out(out), p_written(0) {}
bool put(char v) {
@ -580,15 +567,15 @@ namespace detail {
p_written += ret;
return ret;
}
octa::Size put_n(const char *v, octa::Size n) {
octa::Size ret = p_out.put_n(v, n);
Size put_n(const char *v, Size n) {
Size ret = p_out.put_n(v, n);
p_written += ret;
return ret;
}
octa::Size get_written() const { return p_written; }
Size get_written() const { return p_written; }
private:
R &p_out;
octa::Size p_written;
Size p_written;
};
template<typename T, typename U>
@ -602,21 +589,20 @@ namespace detail {
static constexpr bool value = (sizeof(test<T, U>(0)) == sizeof(char));
};
struct WriteSpec: octa::FormatSpec {
WriteSpec(): octa::FormatSpec() {}
WriteSpec(const char *fmt, bool esc): octa::FormatSpec(fmt, esc) {}
struct WriteSpec: FormatSpec {
WriteSpec(): FormatSpec() {}
WriteSpec(const char *fmt, bool esc): FormatSpec(fmt, esc) {}
/* C string */
template<typename R>
octa::Ptrdiff write(R &writer, bool escape, const char *val,
octa::Size n) {
Ptrdiff write(R &writer, bool escape, const char *val, Size n) {
if (escape) {
octa::String esc = escape_fmt_str(val);
String esc = escape_fmt_str(val);
return write(writer, false, (const char *)esc.data(),
esc.size());
}
if (this->precision()) n = this->precision();
octa::Ptrdiff r = n;
Ptrdiff r = n;
r += this->write_spaces(writer, n, true);
writer.put_n(val, n);
r += this->write_spaces(writer, n, false);
@ -624,7 +610,7 @@ namespace detail {
}
template<typename R>
octa::Ptrdiff write(R &writer, bool escape, const char *val) {
Ptrdiff write(R &writer, bool escape, const char *val) {
if (this->spec() != 's') {
assert(false && "cannot print strings with the given spec");
return -1;
@ -634,8 +620,7 @@ namespace detail {
/* OctaSTD string */
template<typename R, typename A>
octa::Ptrdiff write(R &writer, bool escape,
const octa::AnyString<A> &val) {
Ptrdiff write(R &writer, bool escape, const AnyString<A> &val) {
if (this->spec() != 's') {
assert(false && "cannot print strings with the given spec");
return -1;
@ -645,7 +630,7 @@ namespace detail {
/* character */
template<typename R>
octa::Ptrdiff write(R &writer, bool escape, char val) {
Ptrdiff write(R &writer, bool escape, char val) {
if (this->spec() != 's' && this->spec() != 'c') {
assert(false && "cannot print chars with the given spec");
return -1;
@ -655,13 +640,13 @@ namespace detail {
if (esc) {
char buf[6];
buf[0] = '\'';
octa::Size elen = strlen(esc);
Size elen = strlen(esc);
memcpy(buf + 1, esc, elen);
buf[elen + 1] = '\'';
return write(writer, false, (const char *)buf, elen + 2);
}
}
octa::Ptrdiff r = 1 + escape * 2;
Ptrdiff r = 1 + escape * 2;
r += this->write_spaces(writer, 1 + escape * 2, true);
if (escape) {
writer.put('\'');
@ -674,7 +659,7 @@ namespace detail {
/* bool */
template<typename R>
octa::Ptrdiff write(R &writer, bool, bool val) {
Ptrdiff write(R &writer, bool, bool val) {
if (this->spec() == 's')
return write(writer, ("false\0true") + (6 * val));
else
@ -683,32 +668,32 @@ namespace detail {
/* signed integers */
template<typename R, typename T>
octa::Ptrdiff write(R &writer, bool, T val, octa::EnableIf<
octa::IsIntegral<T>::value && octa::IsSigned<T>::value, bool
Ptrdiff write(R &writer, bool, T val, EnableIf<
IsIntegral<T>::value && IsSigned<T>::value, bool
> = true) {
using UT = octa::MakeUnsigned<T>;
return octa::detail::write_u(writer, this, val < 0,
(val < 0) ? UT(-val) : UT(val));
using UT = MakeUnsigned<T>;
return detail::write_u(writer, this, val < 0,
(val < 0) ? (UT)(-val) : (UT)(val));
}
/* unsigned integers */
template<typename R, typename T>
octa::Ptrdiff write(R &writer, bool, T val, octa::EnableIf<
octa::IsIntegral<T>::value && octa::IsUnsigned<T>::value, bool
Ptrdiff write(R &writer, bool, T val, EnableIf<
IsIntegral<T>::value && IsUnsigned<T>::value, bool
> = true) {
return octa::detail::write_u(writer, this, false, val);
return detail::write_u(writer, this, false, val);
}
template<typename R, typename T,
bool Long = octa::IsSame<T, octa::ldouble>::value
> octa::Ptrdiff write(R &writer, bool, T val, octa::EnableIf<
octa::IsFloatingPoint<T>::value, bool
bool Long = IsSame<T, ldouble>::value
> Ptrdiff write(R &writer, bool, T val, EnableIf<
IsFloatingPoint<T>::value, bool
> = true) {
char buf[16], rbuf[128];
char fmtspec[Long + 1];
fmtspec[Long] = this->spec();
octa::byte specn = octa::detail::fmt_specs[this->spec() - 65];
byte specn = detail::fmt_specs[this->spec() - 65];
if (specn != 1 && specn != 7) {
assert(false && "cannot format floats with the given spec");
return -1;
@ -717,12 +702,12 @@ namespace detail {
if (Long) fmtspec[0] = 'L';
this->build_spec(buf, fmtspec, sizeof(fmtspec));
octa::Ptrdiff ret = snprintf(rbuf, sizeof(rbuf), buf,
Ptrdiff ret = snprintf(rbuf, sizeof(rbuf), buf,
this->width(),
this->has_precision() ? this->precision() : 6, val);
char *dbuf = nullptr;
if (octa::Size(ret) >= sizeof(rbuf)) {
if (Size(ret) >= sizeof(rbuf)) {
/* this should typically never happen */
dbuf = (char *)malloc(ret + 1);
ret = snprintf(dbuf, ret + 1, buf, this->width(),
@ -735,18 +720,18 @@ namespace detail {
/* pointer value */
template<typename R, typename T>
octa::Ptrdiff write(R &writer, bool, T *val) {
Ptrdiff write(R &writer, bool, T *val) {
if (this->p_spec == 's') {
this->p_spec = 'x';
this->p_flags |= FMT_FLAG_HASH;
}
return write(writer, false, octa::Size(val));
return write(writer, false, Size(val));
}
/* generic value */
template<typename R, typename T>
octa::Ptrdiff write(R &writer, bool, const T &val, octa::EnableIf<
!octa::IsArithmetic<T>::value && FmtTostrTest<T>::value &&
Ptrdiff write(R &writer, bool, const T &val, EnableIf<
!IsArithmetic<T>::value && FmtTostrTest<T>::value &&
!FmtTofmtTest<T, FmtWriteRange<R>>::value, bool
> = true) {
if (this->spec() != 's') {
@ -758,8 +743,8 @@ namespace detail {
/* custom format case */
template<typename R, typename T>
octa::Ptrdiff write(R &writer, bool, const T &val,
octa::EnableIf<FmtTofmtTest<T, FmtWriteRange<R>>::value, bool
Ptrdiff write(R &writer, bool, const T &val,
EnableIf<FmtTofmtTest<T, FmtWriteRange<R>>::value, bool
> = true) {
FmtWriteRange<R> sink(writer);
if (!val.to_format(sink, *this)) return -1;
@ -768,8 +753,8 @@ namespace detail {
/* generic failure case */
template<typename R, typename T>
octa::Ptrdiff write(R &, bool, const T &, octa::EnableIf<
!octa::IsArithmetic<T>::value && !FmtTostrTest<T>::value, bool
Ptrdiff write(R &, bool, const T &, EnableIf<
!IsArithmetic<T>::value && !FmtTostrTest<T>::value, bool
> = true) {
assert(false && "value cannot be formatted");
return -1;
@ -777,7 +762,7 @@ namespace detail {
/* actual writer */
template<typename R, typename T>
octa::Ptrdiff write_arg(R &writer, octa::Size idx, const T &val) {
Ptrdiff write_arg(R &writer, Size idx, const T &val) {
if (idx) {
assert(false && "not enough format args");
return -1;
@ -786,55 +771,50 @@ namespace detail {
}
template<typename R, typename T, typename ...A>
octa::Ptrdiff write_arg(R &writer, octa::Size idx, const T &val,
const A &...args) {
Ptrdiff write_arg(R &writer, Size idx, const T &val,
const A &...args) {
if (idx) return write_arg(writer, idx - 1, args...);
return write(writer, this->p_nested_escape, val);
}
/* range writer */
template<typename R, typename T>
octa::Ptrdiff write_range(R &writer, octa::Size idx,
const char *sep, octa::Size seplen,
const T &val) {
Ptrdiff write_range(R &writer, Size idx, const char *sep,
Size seplen, const T &val) {
if (idx) {
assert(false && "not enough format args");
return -1;
}
return octa::detail::write_range(writer, this,
this->p_nested_escape, sep, seplen, val);
return detail::write_range(writer, this, this->p_nested_escape,
sep, seplen, val);
}
template<typename R, typename T, typename ...A>
octa::Ptrdiff write_range(R &writer, octa::Size idx,
const char *sep, octa::Size seplen,
const T &val,
const A &...args) {
Ptrdiff write_range(R &writer, Size idx, const char *sep,
Size seplen, const T &val, const A &...args) {
if (idx) return write_range(writer, idx - 1, sep, seplen, args...);
return octa::detail::write_range(writer, this,
return detail::write_range(writer, this,
this->p_nested_escape, sep, seplen, val);
}
};
template<typename R, typename ...A>
static inline octa::Ptrdiff format_impl(R &writer, octa::Size &fmtn,
bool escape,
const char *fmt,
const A &...args) {
octa::Size argidx = 1, retn = 0, twr = 0;
octa::Ptrdiff written = 0;
octa::detail::WriteSpec spec(fmt, escape);
static inline Ptrdiff format_impl(R &writer, Size &fmtn, bool escape,
const char *fmt, const A &...args) {
Size argidx = 1, retn = 0, twr = 0;
Ptrdiff written = 0;
detail::WriteSpec spec(fmt, escape);
while (spec.read_until_spec(writer, &twr)) {
written += twr;
octa::Size argpos = spec.index();
Size argpos = spec.index();
if (spec.is_nested()) {
if (!argpos) argpos = argidx++;
/* FIXME: figure out a better way */
char new_fmt[256];
memcpy(new_fmt, spec.nested(), spec.nested_len());
new_fmt[spec.nested_len()] = '\0';
octa::detail::WriteSpec nspec(new_fmt, spec.nested_escape());
octa::Ptrdiff sw = nspec.write_range(writer, argpos - 1,
detail::WriteSpec nspec(new_fmt, spec.nested_escape());
Ptrdiff sw = nspec.write_range(writer, argpos - 1,
spec.nested_sep(), spec.nested_sep_len(), args...);
if (sw < 0) return sw;
written += sw;
@ -871,7 +851,7 @@ namespace detail {
return -1;
}
}
octa::Ptrdiff sw = spec.write_arg(writer, argpos - 1, args...);
Ptrdiff sw = spec.write_arg(writer, argpos - 1, args...);
if (sw < 0) return sw;
written += sw;
}
@ -881,10 +861,10 @@ namespace detail {
}
template<typename R, typename ...A>
static inline octa::Ptrdiff format_impl(R &writer, octa::Size &fmtn,
bool, const char *fmt) {
octa::Size written = 0;
octa::detail::WriteSpec spec(fmt, false);
static inline Ptrdiff format_impl(R &writer, Size &fmtn, bool,
const char *fmt) {
Size written = 0;
detail::WriteSpec spec(fmt, false);
if (spec.read_until_spec(writer, &written)) return -1;
fmtn = 0;
return written;
@ -892,28 +872,26 @@ namespace detail {
} /* namespace detail */
template<typename R, typename ...A>
static inline octa::Ptrdiff format(R &&writer, octa::Size &fmtn,
const char *fmt, const A &...args) {
return octa::detail::format_impl(writer, fmtn, false, fmt, args...);
static inline Ptrdiff format(R &&writer, Size &fmtn, const char *fmt,
const A &...args) {
return detail::format_impl(writer, fmtn, false, fmt, args...);
}
template<typename R, typename AL, typename ...A>
octa::Ptrdiff format(R &&writer, octa::Size &fmtn,
const octa::AnyString<AL> &fmt,
const A &...args) {
Ptrdiff format(R &&writer, Size &fmtn, const AnyString<AL> &fmt,
const A &...args) {
return format(writer, fmtn, fmt.data(), args...);
}
template<typename R, typename ...A>
octa::Ptrdiff format(R &&writer, const char *fmt, const A &...args) {
octa::Size fmtn = 0;
Ptrdiff format(R &&writer, const char *fmt, const A &...args) {
Size fmtn = 0;
return format(writer, fmtn, fmt, args...);
}
template<typename R, typename AL, typename ...A>
octa::Ptrdiff format(R &&writer, const octa::AnyString<AL> &fmt,
const A &...args) {
octa::Size fmtn = 0;
Ptrdiff format(R &&writer, const AnyString<AL> &fmt, const A &...args) {
Size fmtn = 0;
return format(writer, fmtn, fmt.data(), args...);
}

View File

@ -96,8 +96,8 @@ template<typename T> BinaryNegate<T> not2(const T &fn) {
/* endian swap */
template<typename T, octa::Size N = sizeof(T),
bool IsNum = octa::IsArithmetic<T>::value
template<typename T, Size N = sizeof(T),
bool IsNum = IsArithmetic<T>::value
> struct EndianSwap;
template<typename T>
@ -107,7 +107,7 @@ struct EndianSwap<T, 2, true> {
T operator()(T v) const {
union { T iv; uint16_t sv; } u;
u.iv = v;
u.sv = octa::endian_swap16(u.sv);
u.sv = endian_swap16(u.sv);
return u.iv;
}
};
@ -119,7 +119,7 @@ struct EndianSwap<T, 4, true> {
T operator()(T v) const {
union { T iv; uint32_t sv; } u;
u.iv = v;
u.sv = octa::endian_swap32(u.sv);
u.sv = endian_swap32(u.sv);
return u.iv;
}
};
@ -131,7 +131,7 @@ struct EndianSwap<T, 8, true> {
T operator()(T v) const {
union { T iv; uint64_t sv; } u;
u.iv = v;
u.sv = octa::endian_swap64(u.sv);
u.sv = endian_swap64(u.sv);
return u.iv;
}
};
@ -140,8 +140,8 @@ template<typename T>
T endian_swap(T x) { return EndianSwap<T>()(x); }
namespace detail {
template<typename T, octa::Size N = sizeof(T),
bool IsNum = octa::IsArithmetic<T>::value
template<typename T, Size N = sizeof(T),
bool IsNum = IsArithmetic<T>::value
> struct EndianSame;
template<typename T>
@ -165,11 +165,11 @@ namespace detail {
}
#if OCTA_BYTE_ORDER == OCTA_ENDIAN_LIL
template<typename T> struct FromLilEndian: octa::detail::EndianSame<T> {};
template<typename T> struct FromLilEndian: detail::EndianSame<T> {};
template<typename T> struct FromBigEndian: EndianSwap<T> {};
#else
template<typename T> struct FromLilEndian: EndianSwap<T> {};
template<typename T> struct FromBigEndian: octa::detail::EndianSame<T> {};
template<typename T> struct FromBigEndian: detail::EndianSame<T> {};
#endif
template<typename T> T from_lil_endian(T x) { return FromLilEndian<T>()(x); }
@ -179,9 +179,9 @@ template<typename T> T from_big_endian(T x) { return FromBigEndian<T>()(x); }
template<typename T> struct ToHash {
using Argument = T;
using Result = octa::Size;
using Result = Size;
octa::Size operator()(const T &v) const {
Size operator()(const T &v) const {
return v.to_hash();
}
};
@ -189,15 +189,15 @@ template<typename T> struct ToHash {
namespace detail {
template<typename T> struct ToHashBase {
using Argument = T;
using Result = octa::Size;
using Result = Size;
octa::Size operator()(T v) const {
return octa::Size(v);
Size operator()(T v) const {
return Size(v);
}
};
}
#define OCTA_HASH_BASIC(T) template<> struct ToHash<T>: octa::detail::ToHashBase<T> {};
#define OCTA_HASH_BASIC(T) template<> struct ToHash<T>: detail::ToHashBase<T> {};
OCTA_HASH_BASIC(bool)
OCTA_HASH_BASIC(char)
@ -205,35 +205,35 @@ OCTA_HASH_BASIC(short)
OCTA_HASH_BASIC(int)
OCTA_HASH_BASIC(long)
OCTA_HASH_BASIC(octa::sbyte)
OCTA_HASH_BASIC(octa::byte)
OCTA_HASH_BASIC(octa::ushort)
OCTA_HASH_BASIC(octa::uint)
OCTA_HASH_BASIC(octa::ulong)
OCTA_HASH_BASIC(sbyte)
OCTA_HASH_BASIC(byte)
OCTA_HASH_BASIC(ushort)
OCTA_HASH_BASIC(uint)
OCTA_HASH_BASIC(ulong)
OCTA_HASH_BASIC(octa::Char16)
OCTA_HASH_BASIC(octa::Char32)
OCTA_HASH_BASIC(octa::Wchar)
OCTA_HASH_BASIC(Char16)
OCTA_HASH_BASIC(Char32)
OCTA_HASH_BASIC(Wchar)
#undef OCTA_HASH_BASIC
namespace detail {
static inline Size mem_hash(const void *p, octa::Size l) {
const octa::byte *d = (const octa::byte *)p;
octa::Size h = 5381;
static inline Size mem_hash(const void *p, Size l) {
const byte *d = (const byte *)p;
Size h = 5381;
for (Size i = 0; i < l; ++i) h = ((h << 5) + h) ^ d[i];
return h;
}
template<typename T, octa::Size = sizeof(T) / sizeof(octa::Size)>
template<typename T, Size = sizeof(T) / sizeof(Size)>
struct ScalarHash;
template<typename T> struct ScalarHash<T, 0> {
using Argument = T;
using Result = octa::Size;
using Result = Size;
octa::Size operator()(T v) const {
union { T v; octa::Size h; } u;
Size operator()(T v) const {
union { T v; Size h; } u;
u.h = 0;
u.v = v;
return u.h;
@ -242,10 +242,10 @@ namespace detail {
template<typename T> struct ScalarHash<T, 1> {
using Argument = T;
using Result = octa::Size;
using Result = Size;
octa::Size operator()(T v) const {
union { T v; octa::Size h; } u;
Size operator()(T v) const {
union { T v; Size h; } u;
u.v = v;
return u.h;
}
@ -253,10 +253,10 @@ namespace detail {
template<typename T> struct ScalarHash<T, 2> {
using Argument = T;
using Result = octa::Size;
using Result = Size;
octa::Size operator()(T v) const {
union { T v; struct { octa::Size h1, h2; }; } u;
Size operator()(T v) const {
union { T v; struct { Size h1, h2; }; } u;
u.v = v;
return mem_hash((const void *)&u, sizeof(u));
}
@ -264,10 +264,10 @@ namespace detail {
template<typename T> struct ScalarHash<T, 3> {
using Argument = T;
using Result = octa::Size;
using Result = Size;
octa::Size operator()(T v) const {
union { T v; struct { octa::Size h1, h2, h3; }; } u;
Size operator()(T v) const {
union { T v; struct { Size h1, h2, h3; }; } u;
u.v = v;
return mem_hash((const void *)&u, sizeof(u));
}
@ -275,76 +275,76 @@ namespace detail {
template<typename T> struct ScalarHash<T, 4> {
using Argument = T;
using Result = octa::Size;
using Result = Size;
octa::Size operator()(T v) const {
union { T v; struct { octa::Size h1, h2, h3, h4; }; } u;
Size operator()(T v) const {
union { T v; struct { Size h1, h2, h3, h4; }; } u;
u.v = v;
return mem_hash((const void *)&u, sizeof(u));
}
};
} /* namespace detail */
template<> struct ToHash<octa::llong>: octa::detail::ScalarHash<octa::llong> {};
template<> struct ToHash<octa::ullong>: octa::detail::ScalarHash<octa::ullong> {};
template<> struct ToHash<llong>: detail::ScalarHash<llong> {};
template<> struct ToHash<ullong>: detail::ScalarHash<ullong> {};
template<> struct ToHash<float>: octa::detail::ScalarHash<float> {
octa::Size operator()(float v) const {
template<> struct ToHash<float>: detail::ScalarHash<float> {
Size operator()(float v) const {
if (v == 0) return 0;
return octa::detail::ScalarHash<float>::operator()(v);
return detail::ScalarHash<float>::operator()(v);
}
};
template<> struct ToHash<double>: octa::detail::ScalarHash<double> {
octa::Size operator()(double v) const {
template<> struct ToHash<double>: detail::ScalarHash<double> {
Size operator()(double v) const {
if (v == 0) return 0;
return octa::detail::ScalarHash<double>::operator()(v);
return detail::ScalarHash<double>::operator()(v);
}
};
template<> struct ToHash<octa::ldouble>: octa::detail::ScalarHash<octa::ldouble> {
octa::Size operator()(octa::ldouble v) const {
template<> struct ToHash<ldouble>: detail::ScalarHash<ldouble> {
Size operator()(ldouble v) const {
if (v == 0) return 0;
#ifdef __i386__
union { octa::ldouble v; struct { octa::Size h1, h2, h3, h4; }; } u;
union { ldouble v; struct { 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 { octa::ldouble v; struct { octa::Size h1, h2; }; } u;
union { ldouble v; struct { Size h1, h2; }; } u;
u.h1 = u.h2 = 0;
u.v = v;
return (u.h1 ^ u.h2);
#else
return octa::detail::ScalarHash<octa::ldouble>::operator()(v);
return detail::ScalarHash<ldouble>::operator()(v);
#endif
#endif
}
};
namespace detail {
template<typename T, bool = octa::IsSame<octa::RemoveConst<T>, char>::value>
template<typename T, bool = IsSame<RemoveConst<T>, char>::value>
struct ToHashPtr {
using Argument = T *;
using Result = octa::Size;
octa::Size operator()(T *v) const {
union { T *v; octa::Size h; } u;
using Result = Size;
Size operator()(T *v) const {
union { T *v; Size h; } u;
u.v = v;
return octa::detail::mem_hash((const void *)&u, sizeof(u));
return detail::mem_hash((const void *)&u, sizeof(u));
}
};
template<typename T> struct ToHashPtr<T, true> {
using Argument = T *;
using Result = octa::Size;
octa::Size operator()(T *v) const {
return octa::detail::mem_hash(v, strlen(v));
using Result = Size;
Size operator()(T *v) const {
return detail::mem_hash(v, strlen(v));
}
};
}
template<typename T> struct ToHash<T *>: octa::detail::ToHashPtr<T> {};
template<typename T> struct ToHash<T *>: detail::ToHashPtr<T> {};
template<typename T>
typename ToHash<T>::Result to_hash(const T &v) {
@ -446,8 +446,8 @@ namespace detail {
} /* namespace detail */
template<typename R, typename T>
octa::detail::MemFn<R, T> mem_fn(R T:: *ptr) {
return octa::detail::MemFn<R, T>(ptr);
detail::MemFn<R, T> mem_fn(R T:: *ptr) {
return detail::MemFn<R, T>(ptr);
}
/* function impl
@ -465,7 +465,7 @@ namespace detail {
struct FunctorInPlace {
static constexpr bool value = sizeof(T) <= sizeof(FunctorData)
&& (alignof(FunctorData) % alignof(T)) == 0
&& octa::IsMoveConstructible<T>::value;
&& IsMoveConstructible<T>::value;
};
struct FunctionManager;
@ -498,15 +498,15 @@ namespace detail {
struct FunctorDataManager {
template<typename R, typename ...Args>
static R call(const FunctorData &s, Args ...args) {
return ((T &)s)(octa::forward<Args>(args)...);
return ((T &)s)(forward<Args>(args)...);
}
static void store_f(FmStorage &s, T v) {
new (&get_ref(s)) T(octa::forward<T>(v));
new (&get_ref(s)) T(forward<T>(v));
}
static void move_f(FmStorage &lhs, FmStorage &&rhs) {
new (&get_ref(lhs)) T(octa::move(get_ref(rhs)));
new (&get_ref(lhs)) T(move(get_ref(rhs)));
}
static void destroy_f(A &, FmStorage &s) {
@ -529,20 +529,18 @@ namespace detail {
> {
template<typename R, typename ...Args>
static R call(const FunctorData &s, Args ...args) {
return (*(octa::AllocatorPointer<A> &)s)
(octa::forward<Args>(args)...);
return (*(AllocatorPointer<A> &)s)(forward<Args>(args)...);
}
static void store_f(FmStorage &s, T v) {
A &a = s.get_alloc<A>();
AllocatorPointer<A> *ptr = new (&get_ptr_ref(s))
AllocatorPointer<A>(allocator_allocate(a, 1));
allocator_construct(a, *ptr, octa::forward<T>(v));
allocator_construct(a, *ptr, forward<T>(v));
}
static void move_f(FmStorage &lhs, FmStorage &&rhs) {
new (&get_ptr_ref(lhs)) AllocatorPointer<A>(octa::move(
get_ptr_ref(rhs)));
new (&get_ptr_ref(lhs)) AllocatorPointer<A>(move(get_ptr_ref(rhs)));
get_ptr_ref(rhs) = nullptr;
}
@ -572,7 +570,7 @@ namespace detail {
template<typename T, typename A>
static void create_fm(FmStorage &s, A &&a) {
new (&s.get_alloc<A>()) A(octa::move(a));
new (&s.get_alloc<A>()) A(move(a));
s.manager = &get_default_fm<T, A>();
}
@ -599,9 +597,9 @@ namespace detail {
static void call_move_and_destroy(FmStorage &lhs,
FmStorage &&rhs) {
using Spec = FunctorDataManager<T, A>;
Spec::move_f(lhs, octa::move(rhs));
Spec::move_f(lhs, move(rhs));
Spec::destroy_f(rhs.get_alloc<A>(), rhs);
create_fm<T, A>(lhs, octa::move(rhs.get_alloc<A>()));
create_fm<T, A>(lhs, move(rhs.get_alloc<A>()));
rhs.get_alloc<A>().~A();
}
@ -665,7 +663,7 @@ namespace detail {
template<typename T>
T func_to_functor(T &&f) {
return octa::forward<T>(f);
return forward<T>(f);
}
template<typename RR, typename T, typename ...AA>
@ -685,24 +683,24 @@ namespace detail {
struct Nat {};
template<typename U>
static decltype(func_to_functor(octa::declval<U>())
(octa::declval<A>()...)) test(U *);
static decltype(func_to_functor(declval<U>()) (declval<A>()...))
test(U *);
template<typename>
static Nat test(...);
static constexpr bool value = octa::IsConvertible<
static constexpr bool value = IsConvertible<
decltype(test<T>(nullptr)), R
>::value;
};
template<typename T>
using FunctorType = decltype(func_to_functor(octa::declval<T>()));
using FunctorType = decltype(func_to_functor(declval<T>()));
} /* namespace detail */
template<typename R, typename ...Args>
struct Function<R(Args...)>: octa::detail::FunctionBase<R, Args...> {
Function( ) { init_empty(); }
Function(octa::Nullptr) { init_empty(); }
struct Function<R(Args...)>: detail::FunctionBase<R, Args...> {
Function( ) { init_empty(); }
Function(Nullptr) { init_empty(); }
Function(Function &&f) {
init_empty();
@ -713,45 +711,45 @@ struct Function<R(Args...)>: octa::detail::FunctionBase<R, Args...> {
f.p_stor.manager->call_copyf(p_stor, f.p_stor);
}
template<typename T, typename = octa::EnableIf<
octa::detail::IsValidFunctor<T, R(Args...)>::value
template<typename T, typename = EnableIf<
detail::IsValidFunctor<T, R(Args...)>::value
>> Function(T f) {
if (func_is_null(f)) {
init_empty();
return;
}
initialize(octa::detail::func_to_functor(octa::forward<T>(f)),
octa::Allocator<octa::detail::FunctorType<T>>());
initialize(detail::func_to_functor(forward<T>(f)),
Allocator<detail::FunctorType<T>>());
}
template<typename A>
Function(octa::AllocatorArg, const A &) { init_empty(); }
Function(AllocatorArg, const A &) { init_empty(); }
template<typename A>
Function(octa::AllocatorArg, const A &, octa::Nullptr) { init_empty(); }
Function(AllocatorArg, const A &, Nullptr) { init_empty(); }
template<typename A>
Function(octa::AllocatorArg, const A &, Function &&f) {
Function(AllocatorArg, const A &, Function &&f) {
init_empty();
swap(f);
}
template<typename A>
Function(octa::AllocatorArg, const A &a, const Function &f):
Function(AllocatorArg, const A &a, const Function &f):
p_call(f.p_call) {
const octa::detail::FunctionManager *mfa
= &octa::detail::get_default_fm<octa::AllocatorValue<A>, A>();
const detail::FunctionManager *mfa
= &detail::get_default_fm<AllocatorValue<A>, A>();
if (f.p_stor.manager == mfa) {
octa::detail::create_fm<octa::AllocatorValue<A>, A>(p_stor, A(a));
detail::create_fm<AllocatorValue<A>, A>(p_stor, A(a));
mfa->call_copyf_fo(p_stor, f.p_stor);
return;
}
using AA = AllocatorRebind<A, Function>;
const octa::detail::FunctionManager *mff
= &octa::detail::get_default_fm<Function, AA>();
const detail::FunctionManager *mff
= &detail::get_default_fm<Function, AA>();
if (f.p_stor.manager == mff) {
octa::detail::create_fm<Function, AA>(p_stor, AA(a));
detail::create_fm<Function, AA>(p_stor, AA(a));
mff->call_copyf_fo(p_stor, f.P_stor);
return;
}
@ -759,14 +757,14 @@ struct Function<R(Args...)>: octa::detail::FunctionBase<R, Args...> {
initialize(f, AA(a));
}
template<typename A, typename T, typename = octa::EnableIf<
octa::detail::IsValidFunctor<T, R(Args...)>::value
>> Function(octa::AllocatorArg, const A &a, T f) {
template<typename A, typename T, typename = EnableIf<
detail::IsValidFunctor<T, R(Args...)>::value
>> Function(AllocatorArg, const A &a, T f) {
if (func_is_null(f)) {
init_empty();
return;
}
initialize(octa::detail::func_to_functor(octa::forward<T>(f)), A(a));
initialize(detail::func_to_functor(forward<T>(f)), A(a));
}
~Function() {
@ -786,45 +784,41 @@ struct Function<R(Args...)>: octa::detail::FunctionBase<R, Args...> {
};
R operator()(Args ...args) const {
return p_call(p_stor.data, octa::forward<Args>(args)...);
return p_call(p_stor.data, forward<Args>(args)...);
}
template<typename F, typename A>
void assign(F &&f, const A &a) {
Function(octa::allocator_arg, a, octa::forward<F>(f)).swap(*this);
Function(allocator_arg, a, forward<F>(f)).swap(*this);
}
void swap(Function &f) {
octa::detail::FmStorage tmp;
f.p_stor.manager->call_move_and_destroyf(tmp,
octa::move(f.p_stor));
p_stor.manager->call_move_and_destroyf(f.p_stor,
octa::move(p_stor));
tmp.manager->call_move_and_destroyf(p_stor,
octa::move(tmp));
detail::FmStorage tmp;
f.p_stor.manager->call_move_and_destroyf(tmp, move(f.p_stor));
p_stor.manager->call_move_and_destroyf(f.p_stor, move(p_stor));
tmp.manager->call_move_and_destroyf(p_stor, move(tmp));
octa::swap(p_call, f.p_call);
}
operator bool() const { return p_call != nullptr; }
private:
octa::detail::FmStorage p_stor;
R (*p_call)(const octa::detail::FunctorData &, Args...);
detail::FmStorage p_stor;
R (*p_call)(const detail::FunctorData &, Args...);
template<typename T, typename A>
void initialize(T &&f, A &&a) {
p_call = &octa::detail::FunctorDataManager<T, A>::template call<R, Args...>;
octa::detail::create_fm<T, A>(p_stor, octa::forward<A>(a));
octa::detail::FunctorDataManager<T, A>::store_f(p_stor,
octa::forward<T>(f));
p_call = &detail::FunctorDataManager<T, A>::template call<R, Args...>;
detail::create_fm<T, A>(p_stor, forward<A>(a));
detail::FunctorDataManager<T, A>::store_f(p_stor, forward<T>(f));
}
void init_empty() {
using emptyf = R(*)(Args...);
using emptya = octa::Allocator<emptyf>;
using emptya = Allocator<emptyf>;
p_call = nullptr;
octa::detail::create_fm<emptyf, emptya>(p_stor, emptya());
octa::detail::FunctorDataManager<emptyf, emptya>::store_f(p_stor,
detail::create_fm<emptyf, emptya>(p_stor, emptya());
detail::FunctorDataManager<emptyf, emptya>::store_f(p_stor,
nullptr);
}
@ -847,16 +841,16 @@ private:
};
template<typename T>
bool operator==(octa::Nullptr, const Function<T> &rhs) { return !rhs; }
bool operator==(Nullptr, const Function<T> &rhs) { return !rhs; }
template<typename T>
bool operator==(const Function<T> &lhs, octa::Nullptr) { return !lhs; }
bool operator==(const Function<T> &lhs, Nullptr) { return !lhs; }
template<typename T>
bool operator!=(octa::Nullptr, const Function<T> &rhs) { return rhs; }
bool operator!=(Nullptr, const Function<T> &rhs) { return rhs; }
template<typename T>
bool operator!=(const Function<T> &lhs, octa::Nullptr) { return lhs; }
bool operator!=(const Function<T> &lhs, Nullptr) { return lhs; }
namespace detail {
template<typename F>
@ -865,7 +859,7 @@ namespace detail {
template<typename C, typename R, typename ...A>
struct DcLambdaTypes<R (C::*)(A...) const> {
using Ptr = R (*)(A...);
using Obj = octa::Function<R(A...)>;
using Obj = Function<R(A...)>;
};
template<typename F>
@ -874,7 +868,7 @@ namespace detail {
static char test(typename DcLambdaTypes<FF>::Ptr);
template<typename FF>
static int test(...);
static constexpr bool value = (sizeof(test<F>(octa::declval<F>())) == 1);
static constexpr bool value = (sizeof(test<F>(declval<F>())) == 1);
};
template<typename F, bool = DcFuncTest<F>::value>
@ -887,8 +881,8 @@ namespace detail {
using Type = typename DcLambdaTypes<F>::Ptr;
};
template<typename F, bool = octa::IsDefaultConstructible<F>::value &&
octa::IsMoveConstructible<F>::value
template<typename F, bool = IsDefaultConstructible<F>::value &&
IsMoveConstructible<F>::value
> struct DcFuncTypeObj {
using Type = typename DcFuncTypeObjBase<F>::Type;
};
@ -898,7 +892,7 @@ namespace detail {
using Type = F;
};
template<typename F, bool = octa::IsClass<F>::value>
template<typename F, bool = IsClass<F>::value>
struct DcFuncType {
using Type = F;
};
@ -910,7 +904,7 @@ namespace detail {
}
template<typename F> using FunctionMakeDefaultConstructible
= typename octa::detail::DcFuncType<F>::Type;
= typename detail::DcFuncType<F>::Type;
} /* namespace octa */

View File

@ -39,13 +39,13 @@ namespace octa {
template<typename T> using InitializerList = std::initializer_list<T>;
template<typename T>
octa::PointerRange<const T> iter(std::initializer_list<T> init) {
return octa::PointerRange<const T>(init.begin(), init.end());
PointerRange<const T> iter(std::initializer_list<T> init) {
return PointerRange<const T>(init.begin(), init.end());
}
template<typename T>
octa::PointerRange<const T> citer(std::initializer_list<T> init) {
return octa::PointerRange<const T>(init.begin(), init.end());
PointerRange<const T> citer(std::initializer_list<T> init) {
return PointerRange<const T>(init.begin(), init.end());
}
}

View File

@ -24,15 +24,15 @@ namespace detail {
};
template<typename R>
static inline octa::Size estimate_hrsize(const R &range,
octa::EnableIf<octa::IsFiniteRandomAccessRange<R>::value, bool> = true
static inline Size estimate_hrsize(const R &range,
EnableIf<IsFiniteRandomAccessRange<R>::value, bool> = true
) {
return range.size();
}
template<typename R>
static inline octa::Size estimate_hrsize(const R &,
octa::EnableIf<!octa::IsFiniteRandomAccessRange<R>::value, bool> = true
static inline Size estimate_hrsize(const R &,
EnableIf<!IsFiniteRandomAccessRange<R>::value, bool> = true
) {
/* we have no idea how big the range actually is */
return 16;
@ -40,12 +40,12 @@ namespace detail {
}
template<typename T>
struct HashRange: octa::InputRange<HashRange<T>, octa::ForwardRangeTag, T> {
struct HashRange: InputRange<HashRange<T>, ForwardRangeTag, T> {
private:
template<typename U>
friend struct HashRange;
using Chain = octa::detail::HashChain<T>;
using Chain = detail::HashChain<T>;
Chain **p_beg;
Chain **p_end;
@ -57,7 +57,7 @@ private:
if (p_beg != p_end) p_node = p_beg[0];
}
public:
HashRange() = delete;
HashRange(): p_beg(nullptr), p_end(nullptr), p_node(nullptr) {}
HashRange(const HashRange &v): p_beg(v.p_beg), p_end(v.p_end),
p_node(v.p_node) {}
HashRange(Chain **beg, Chain **end): p_beg(beg), p_end(end), p_node() {
@ -67,9 +67,9 @@ public:
p_node(node) {}
template<typename U>
HashRange(const HashRange<U> &v, octa::EnableIf<
octa::IsSame<RemoveCv<T>, RemoveCv<U>>::value &&
octa::IsConvertible<U *, T *>::value, bool
HashRange(const HashRange<U> &v, EnableIf<
IsSame<RemoveCv<T>, RemoveCv<U>>::value &&
IsConvertible<U *, T *>::value, bool
> = true): p_beg((Chain **)v.p_beg), p_end((Chain **)v.p_end),
p_node((Chain *)v.p_node) {}
@ -99,22 +99,22 @@ public:
};
template<typename T>
struct BucketRange: octa::InputRange<BucketRange<T>, octa::ForwardRangeTag, T> {
struct BucketRange: InputRange<BucketRange<T>, ForwardRangeTag, T> {
private:
template<typename U>
friend struct BucketRange;
using Chain = octa::detail::HashChain<T>;
using Chain = detail::HashChain<T>;
Chain *p_node;
public:
BucketRange() = delete;
BucketRange(): p_node(nullptr) {}
BucketRange(Chain *node): p_node(node) {}
BucketRange(const BucketRange &v): p_node(v.p_node) {}
template<typename U>
BucketRange(const BucketRange<U> &v, octa::EnableIf<
octa::IsSame<RemoveCv<T>, RemoveCv<U>>::value &&
octa::IsConvertible<U *, T *>::value, bool
BucketRange(const BucketRange<U> &v, EnableIf<
IsSame<RemoveCv<T>, RemoveCv<U>>::value &&
IsConvertible<U *, T *>::value, bool
> = true): p_node((Chain *)v.p_node) {}
BucketRange &operator=(const BucketRange &v) {
@ -149,51 +149,51 @@ namespace detail {
bool Multihash
> struct Hashtable {
private:
static constexpr octa::Size CHUNKSIZE = 64;
static constexpr Size CHUNKSIZE = 64;
using Chain = octa::detail::HashChain<E>;
using Chain = detail::HashChain<E>;
struct Chunk {
Chain chains[CHUNKSIZE];
Chunk *next;
};
octa::Size p_size;
octa::Size p_len;
Size p_size;
Size p_len;
Chunk *p_chunks;
Chain *p_unused;
using CPA = octa::AllocatorRebind<A, Chain *>;
using CHA = octa::AllocatorRebind<A, Chunk>;
using CPA = AllocatorRebind<A, Chain *>;
using CHA = AllocatorRebind<A, Chunk>;
using CoreAllocPair = octa::detail::CompressedPair<CPA, CHA>;
using AllocPair = octa::detail::CompressedPair<A, CoreAllocPair>;
using FuncPair = octa::detail::CompressedPair<H, C>;
using FAPair = octa::detail::CompressedPair<AllocPair, FuncPair>;
using DataPair = octa::detail::CompressedPair<Chain **, FAPair>;
using CoreAllocPair = detail::CompressedPair<CPA, CHA>;
using AllocPair = detail::CompressedPair<A, CoreAllocPair>;
using FuncPair = detail::CompressedPair<H, C>;
using FAPair = detail::CompressedPair<AllocPair, FuncPair>;
using DataPair = detail::CompressedPair<Chain **, FAPair>;
using Range = octa::HashRange<E>;
using ConstRange = octa::HashRange<const E>;
using LocalRange = octa::BucketRange<E>;
using ConstLocalRange = octa::BucketRange<const E>;
using Range = HashRange<E>;
using ConstRange = HashRange<const E>;
using LocalRange = BucketRange<E>;
using ConstLocalRange = BucketRange<const E>;
DataPair p_data;
float p_maxlf;
Range iter_from(Chain *c, octa::Size h) {
Range iter_from(Chain *c, Size h) {
return Range(p_data.first() + h + 1,
p_data.first() + bucket_count(), c);
}
ConstRange iter_from(Chain *c, octa::Size h) const {
using RChain = octa::detail::HashChain<const E>;
ConstRange iter_from(Chain *c, Size h) const {
using RChain = detail::HashChain<const E>;
return ConstRange((RChain **)(p_data.first() + h + 1),
(RChain **)(p_data.first() + bucket_count()),
(RChain *)c);
}
bool find(const K &key, octa::Size &h, Chain *&oc) const {
bool find(const K &key, Size &h, Chain *&oc) const {
if (!p_size) return false;
h = get_hash()(key) & (p_size - 1);
for (Chain *c = p_data.first()[h]; c; c = c->next) {
@ -205,10 +205,10 @@ private:
return false;
}
Chain *insert(octa::Size h) {
Chain *insert(Size h) {
if (!p_unused) {
Chunk *chunk = octa::allocator_allocate(get_challoc(), 1);
octa::allocator_construct(get_challoc(), chunk);
Chunk *chunk = allocator_allocate(get_challoc(), 1);
allocator_construct(get_challoc(), chunk);
chunk->next = p_chunks;
p_chunks = chunk;
for (Size i = 0; i < (CHUNKSIZE - 1); ++i)
@ -227,12 +227,12 @@ private:
void delete_chunks(Chunk *chunks) {
for (Chunk *nc; chunks; chunks = nc) {
nc = chunks->next;
octa::allocator_destroy(get_challoc(), chunks);
octa::allocator_deallocate(get_challoc(), chunks, 1);
allocator_destroy(get_challoc(), chunks);
allocator_deallocate(get_challoc(), chunks, 1);
}
}
T *access_base(const K &key, octa::Size &h) const {
T *access_base(const K &key, Size &h) const {
if (!p_size) return NULL;
h = get_hash()(key) & (p_size - 1);
for (Chain *c = p_data.first()[h]; c; c = c->next) {
@ -242,23 +242,23 @@ private:
return NULL;
}
void rehash_ahead(octa::Size n) {
void rehash_ahead(Size n) {
if (!bucket_count())
reserve(n);
else if ((float(size() + n) / bucket_count()) > max_load_factor())
rehash(octa::Size((size() + 1) / max_load_factor()) * 2);
rehash(Size((size() + 1) / max_load_factor()) * 2);
}
protected:
template<typename U>
T &insert(octa::Size h, U &&key) {
T &insert(Size h, U &&key) {
Chain *c = insert(h);
B::set_key(c->value, octa::forward<U>(key), get_alloc());
B::set_key(c->value, forward<U>(key), get_alloc());
return B::get_data(c->value);
}
T &access_or_insert(const K &key) {
octa::Size h = 0;
Size h = 0;
T *v = access_base(key, h);
if (v) return *v;
rehash_ahead(1);
@ -266,22 +266,22 @@ protected:
}
T &access_or_insert(K &&key) {
octa::Size h = 0;
Size h = 0;
T *v = access_base(key, h);
if (v) return *v;
rehash_ahead(1);
return insert(h, octa::move(key));
return insert(h, move(key));
}
T &access(const K &key) const {
octa::Size h;
Size h;
return *access_base(key, h);
}
template<typename R>
void assign_range(R range) {
clear();
reserve_at_least(octa::detail::estimate_hrsize(range));
reserve_at_least(detail::estimate_hrsize(range));
for (; !range.empty(); range.pop_front())
emplace(range.front());
rehash_up();
@ -311,13 +311,13 @@ protected:
return p_data.second().first().second().second();
}
Hashtable(octa::Size size, const H &hf, const C &eqf, const A &alloc):
Hashtable(Size size, const H &hf, const C &eqf, const A &alloc):
p_size(size), p_len(0), p_chunks(nullptr), p_unused(nullptr),
p_data(nullptr, FAPair(AllocPair(alloc, CoreAllocPair(alloc, alloc)),
FuncPair(hf, eqf))),
p_maxlf(1.0f) {
if (!size) return;
p_data.first() = octa::allocator_allocate(get_cpalloc(), size);
p_data.first() = allocator_allocate(get_cpalloc(), size);
memset(p_data.first(), 0, size * sizeof(Chain *));
}
@ -327,22 +327,22 @@ protected:
FuncPair(ht.get_hash(), ht.get_eq()))),
p_maxlf(ht.p_maxlf) {
if (!p_size) return;
p_data.first() = octa::allocator_allocate(get_cpalloc(), p_size);
p_data.first() = allocator_allocate(get_cpalloc(), p_size);
memset(p_data.first(), 0, p_size * sizeof(Chain *));
Chain **och = ht.p_data.first();
for (octa::Size h = 0; h < p_size; ++h) {
for (Size h = 0; h < p_size; ++h) {
Chain *oc = och[h];
for (; oc; oc = oc->next) {
Chain *nc = insert(h);
octa::allocator_destroy(get_alloc(), &nc->value);
octa::allocator_construct(get_alloc(), &nc->value, oc->value);
allocator_destroy(get_alloc(), &nc->value);
allocator_construct(get_alloc(), &nc->value, oc->value);
}
}
}
Hashtable(Hashtable &&ht): p_size(ht.p_size), p_len(ht.p_len),
p_chunks(ht.p_chunks), p_unused(ht.p_unused),
p_data(octa::move(ht.p_data)), p_maxlf(ht.p_maxlf) {
p_data(move(ht.p_data)), p_maxlf(ht.p_maxlf) {
ht.p_size = ht.p_len = 0;
ht.p_chunks = nullptr;
ht.p_unused = nullptr;
@ -368,10 +368,10 @@ protected:
p_len = 0;
p_chunks = nullptr;
p_unused = nullptr;
p_data.first() = octa::allocator_allocate(get_cpalloc(), p_size);
p_data.first() = allocator_allocate(get_cpalloc(), p_size);
memset(p_data.first(), 0, p_size * sizeof(Chain *));
Chain **och = ht.p_data.first();
for (octa::Size h = 0; h < p_size; ++h) {
for (Size h = 0; h < p_size; ++h) {
Chain *oc = och[h];
for (; oc; oc = oc->next) {
Chain *nc = insert(h);
@ -382,11 +382,11 @@ protected:
Hashtable &operator=(const Hashtable &ht) {
clear();
if (octa::AllocatorPropagateOnContainerCopyAssignment<A>::value) {
if (AllocatorPropagateOnContainerCopyAssignment<A>::value) {
if ((get_cpalloc() != ht.get_cpalloc()) && p_size) {
octa::allocator_deallocate(get_cpalloc(),
allocator_deallocate(get_cpalloc(),
p_data.first(), p_size);
p_data.first() = octa::allocator_allocate(get_cpalloc(),
p_data.first() = allocator_allocate(get_cpalloc(),
p_size);
memset(p_data.first(), 0, p_size * sizeof(Chain *));
}
@ -407,18 +407,18 @@ protected:
octa::swap(p_unused, ht.p_unused);
octa::swap(p_data.first(), ht.p_data.first());
octa::swap(p_data.second().second(), ht.p_data.second().second());
if (octa::AllocatorPropagateOnContainerMoveAssignment<A>::value)
if (AllocatorPropagateOnContainerMoveAssignment<A>::value)
octa::swap(p_data.second().first(), ht.p_data.second().first());
return *this;
}
void rehash_up() {
if (load_factor() <= max_load_factor()) return;
rehash(octa::Size(size() / max_load_factor()) * 2);
rehash(Size(size() / max_load_factor()) * 2);
}
void reserve_at_least(octa::Size count) {
octa::Size nc = octa::Size(ceil(count / max_load_factor()));
void reserve_at_least(Size count) {
Size nc = Size(ceil(count / max_load_factor()));
if (p_size > nc) return;
rehash(nc);
}
@ -430,13 +430,13 @@ protected:
octa::swap(p_unused, ht.p_unused);
octa::swap(p_data.first(), ht.p_data.first());
octa::swap(p_data.second().second(), ht.p_data.second().second());
if (octa::AllocatorPropagateOnContainerSwap<A>::value)
if (AllocatorPropagateOnContainerSwap<A>::value)
octa::swap(p_data.second().first(), ht.p_data.second().first());
}
public:
~Hashtable() {
if (p_size) octa::allocator_deallocate(get_cpalloc(),
if (p_size) allocator_deallocate(get_cpalloc(),
p_data.first(), p_size);
delete_chunks(p_chunks);
}
@ -454,18 +454,18 @@ public:
}
bool empty() const { return p_len == 0; }
octa::Size size() const { return p_len; }
Size size() const { return p_len; }
Size max_size() const { return Size(~0) / sizeof(E); }
octa::Size bucket_count() const { return p_size; }
octa::Size max_bucket_count() const { return Size(~0) / sizeof(Chain); }
Size bucket_count() const { return p_size; }
Size max_bucket_count() const { return Size(~0) / sizeof(Chain); }
octa::Size bucket(const K &key) const {
Size bucket(const K &key) const {
return get_hash()(key) & (p_size - 1);
}
octa::Size bucket_size(octa::Size n) const {
octa::Size ret = 0;
Size bucket_size(Size n) const {
Size ret = 0;
if (ret >= p_size) return ret;
Chain *c = p_data.first()[n];
if (!c) return ret;
@ -475,16 +475,16 @@ public:
}
template<typename ...Args>
octa::Pair<Range, bool> emplace(Args &&...args) {
Pair<Range, bool> emplace(Args &&...args) {
rehash_ahead(1);
E elem(octa::forward<Args>(args)...);
octa::Size h = get_hash()(B::get_key(elem)) & (p_size - 1);
E elem(forward<Args>(args)...);
Size h = get_hash()(B::get_key(elem)) & (p_size - 1);
if (Multihash) {
/* multihash: always insert */
Chain *ch = insert(h);
B::swap_elem(ch->value, elem);
Chain **hch = p_data.first();
return octa::make_pair(Range(hch + h + 1, hch + bucket_count(),
return make_pair(Range(hch + h + 1, hch + bucket_count(),
ch), true);
}
Chain *found = nullptr;
@ -501,14 +501,14 @@ public:
B::swap_elem(found->value, elem);
}
Chain **hch = p_data.first();
return octa::make_pair(Range(hch + h + 1, hch + bucket_count(),
return make_pair(Range(hch + h + 1, hch + bucket_count(),
found), ins);
}
octa::Size erase(const K &key) {
Size erase(const K &key) {
if (!p_len) return 0;
octa::Size olen = p_len;
octa::Size h = get_hash()(key) & (p_size - 1);
Size olen = p_len;
Size h = get_hash()(key) & (p_size - 1);
Chain **p = &p_data.first()[h], *c = *p;
while (c) {
if (get_eq()(key, B::get_key(c->value))) {
@ -516,8 +516,8 @@ public:
*p = c->next;
c->next = p_unused;
p_unused = c;
octa::allocator_destroy(get_alloc(), &c->value);
octa::allocator_construct(get_alloc(), &c->value);
allocator_destroy(get_alloc(), &c->value);
allocator_construct(get_alloc(), &c->value);
if (!Multihash) return 1;
} else {
p = &c->next;
@ -527,10 +527,10 @@ public:
return olen - p_len;
}
octa::Size count(const K &key) {
Size count(const K &key) {
if (!p_len) return 0;
octa::Size h = get_hash()(key) & (p_size - 1);
octa::Size ret = 0;
Size h = get_hash()(key) & (p_size - 1);
Size ret = 0;
for (Chain *c = p_data.first()[h]; c; c = c->next)
if (get_eq()(key, B::get_key(c->value))) {
++ret;
@ -540,14 +540,14 @@ public:
}
Range find(const K &key) {
octa::Size h = 0;
Size h = 0;
Chain *c;
if (find(key, h, c)) return iter_from(c, h);
return Range();
}
ConstRange find(const K &key) const {
octa::Size h = 0;
Size h = 0;
Chain *c;
if (find(key, h, c)) return iter_from(c, h);
return ConstRange();
@ -557,21 +557,21 @@ public:
float max_load_factor() const { return p_maxlf; }
void max_load_factor(float lf) { p_maxlf = lf; }
void rehash(octa::Size count) {
octa::Size fbcount = octa::Size(p_len / max_load_factor());
void rehash(Size count) {
Size fbcount = Size(p_len / max_load_factor());
if (fbcount > count) count = fbcount;
Chain **och = p_data.first();
Chain **nch = octa::allocator_allocate(get_cpalloc(), count);
Chain **nch = allocator_allocate(get_cpalloc(), count);
memset(nch, 0, count * sizeof(Chain *));
p_data.first() = nch;
octa::Size osize = p_size;
Size osize = p_size;
p_size = count;
for (octa::Size i = 0; i < osize; ++i) {
for (Size i = 0; i < osize; ++i) {
for (Chain *oc = och[i]; oc;) {
octa::Size h = get_hash()(B::get_key(oc->value)) & (p_size - 1);
Size h = get_hash()(B::get_key(oc->value)) & (p_size - 1);
Chain *nxc = oc->next;
oc->next = nch[h];
nch[h] = oc;
@ -579,39 +579,39 @@ public:
}
}
if (och && osize) octa::allocator_deallocate(get_cpalloc(),
if (och && osize) allocator_deallocate(get_cpalloc(),
och, osize);
}
void reserve(octa::Size count) {
rehash(octa::Size(ceil(count / max_load_factor())));
void reserve(Size count) {
rehash(Size(ceil(count / max_load_factor())));
}
Range iter() {
return Range(p_data.first(), p_data.first() + bucket_count());
}
ConstRange iter() const {
using Chain = octa::detail::HashChain<const E>;
using Chain = detail::HashChain<const E>;
return ConstRange((Chain **)p_data.first(),
(Chain **)(p_data.first() + bucket_count()));
}
ConstRange citer() const {
using Chain = octa::detail::HashChain<const E>;
using Chain = detail::HashChain<const E>;
return ConstRange((Chain **)p_data.first(),
(Chain **)(p_data.first() + bucket_count()));
}
LocalRange iter(octa::Size n) {
LocalRange iter(Size n) {
if (n >= p_size) return LocalRange();
return LocalRange(p_data.first()[n]);
}
ConstLocalRange iter(octa::Size n) const {
using Chain = octa::detail::HashChain<const E>;
ConstLocalRange iter(Size n) const {
using Chain = detail::HashChain<const E>;
if (n >= p_size) return ConstLocalRange();
return ConstLocalRange((Chain *)p_data.first()[n]);
}
ConstLocalRange citer(octa::Size n) const {
using Chain = octa::detail::HashChain<const E>;
ConstLocalRange citer(Size n) const {
using Chain = detail::HashChain<const E>;
if (n >= p_size) return ConstLocalRange();
return ConstLocalRange((Chain *)p_data.first()[n]);
}

View File

@ -39,7 +39,7 @@ struct FileStream: Stream {
}
template<typename A>
FileStream(const octa::AnyString<A> &path, StreamMode mode): p_f() {
FileStream(const AnyString<A> &path, StreamMode mode): p_f() {
open(path, mode);
}
@ -56,13 +56,13 @@ struct FileStream: Stream {
bool open(const char *path, StreamMode mode) {
if (p_f) return false;
p_f = fopen(path, octa::detail::filemodes[octa::Size(mode)]);
p_f = fopen(path, detail::filemodes[Size(mode)]);
p_owned = true;
return is_open();
}
template<typename A>
bool open(const octa::AnyString<A> &path, StreamMode mode) {
bool open(const AnyString<A> &path, StreamMode mode) {
return open(path.data(), mode);
}
@ -104,11 +104,11 @@ struct FileStream: Stream {
bool flush() { return !fflush(p_f); }
octa::Size read_bytes(void *buf, octa::Size count) {
Size read_bytes(void *buf, Size count) {
return fread(buf, 1, count, p_f);
}
octa::Size write_bytes(const void *buf, octa::Size count) {
Size write_bytes(const void *buf, Size count) {
return fwrite(buf, 1, count, p_f);
}
@ -147,46 +147,46 @@ static inline void write(const char *s) {
}
template<typename A>
static inline void write(const octa::AnyString<A> &s) {
static inline void write(const AnyString<A> &s) {
fwrite(s.data(), 1, s.size(), ::stdout);
}
template<typename T>
static inline void write(const T &v) {
octa::write(octa::to_string(v));
write(octa::to_string(v));
}
template<typename T, typename ...A>
static inline void write(const T &v, const A &...args) {
octa::write(v);
write(v);
write(args...);
}
static inline void writeln(const char *s) {
octa::write(s);
write(s);
putc('\n', ::stdout);
}
template<typename A>
static inline void writeln(const octa::AnyString<A> &s) {
octa::write(s);
static inline void writeln(const AnyString<A> &s) {
write(s);
putc('\n', ::stdout);
}
template<typename T>
static inline void writeln(const T &v) {
octa::writeln(octa::to_string(v));
writeln(octa::to_string(v));
}
template<typename T, typename ...A>
static inline void writeln(const T &v, const A &...args) {
octa::write(v);
write(v);
write(args...);
putc('\n', ::stdout);
}
namespace detail {
struct UnsafeWritefRange: octa::OutputRange<UnsafeWritefRange, char> {
struct UnsafeWritefRange: OutputRange<UnsafeWritefRange, char> {
UnsafeWritefRange(char *p): p_ptr(p) {}
bool put(char c) {
*p_ptr++ = c;
@ -199,21 +199,21 @@ namespace detail {
template<typename ...A>
static inline void writef(const char *fmt, const A &...args) {
char buf[512];
octa::Ptrdiff need = octa::format(octa::detail::FormatOutRange<
sizeof(buf)>(buf), fmt, args...);
Ptrdiff need = format(detail::FormatOutRange<sizeof(buf)>(buf),
fmt, args...);
if (need < 0) return;
else if (octa::Size(need) < sizeof(buf)) {
else if (Size(need) < sizeof(buf)) {
fwrite(buf, 1, need, ::stdout);
return;
}
octa::Vector<char> s;
Vector<char> s;
s.reserve(need);
octa::format(octa::detail::UnsafeWritefRange(s.data()), fmt, args...);
format(detail::UnsafeWritefRange(s.data()), fmt, args...);
fwrite(s.data(), 1, need, ::stdout);
}
template<typename AL, typename ...A>
static inline void writef(const octa::AnyString<AL> &fmt,
static inline void writef(const AnyString<AL> &fmt,
const A &...args) {
writef(fmt.data(), args...);
}
@ -225,7 +225,7 @@ static inline void writefln(const char *fmt, const A &...args) {
}
template<typename AL, typename ...A>
static inline void writefln(const octa::AnyString<AL> &fmt,
static inline void writefln(const AnyString<AL> &fmt,
const A &...args) {
writef(fmt, args...);
putc('\n', ::stdout);

View File

@ -18,7 +18,7 @@ namespace octa {
namespace detail {
template<typename K, typename T, typename A> struct MapBase {
using Element = octa::Pair<const K, T>;
using Element = Pair<const K, T>;
static inline const K &get_key(Element &e) {
return e.first;
@ -28,9 +28,8 @@ namespace detail {
}
template<typename U>
static inline void set_key(Element &e, U &&key, A &alloc) {
octa::allocator_destroy(alloc, &e);
octa::allocator_construct(alloc, &e, octa::forward<U>(key),
octa::move(T()));
allocator_destroy(alloc, &e);
allocator_construct(alloc, &e, forward<U>(key), move(T()));
}
static inline void swap_elem(Element &a, Element &b) {
octa::swap(*((K *)&a.first), *((K *)&b.first));
@ -41,59 +40,57 @@ namespace detail {
template<
typename K, typename T, typename H,
typename C, typename A, bool IsMultihash
> struct MapImpl: octa::detail::Hashtable<
octa::detail::MapBase<K, T, A>, octa::Pair<const K, T>,
K, T, H, C, A, IsMultihash
> struct MapImpl: detail::Hashtable<detail::MapBase<K, T, A>,
Pair<const K, T>, K, T, H, C, A, IsMultihash
> {
private:
using Base = octa::detail::Hashtable<
octa::detail::MapBase<K, T, A>, octa::Pair<const K, T>,
K, T, H, C, A, IsMultihash
using Base = detail::Hashtable<detail::MapBase<K, T, A>,
Pair<const K, T>, K, T, H, C, A, IsMultihash
>;
public:
using Key = K;
using Mapped = T;
using Size = octa::Size;
using Difference = octa::Ptrdiff;
using Size = Size;
using Difference = Ptrdiff;
using Hasher = H;
using KeyEqual = C;
using Value = octa::Pair<const K, T>;
using Value = Pair<const K, T>;
using Reference = Value &;
using Pointer = octa::AllocatorPointer<A>;
using ConstPointer = octa::AllocatorConstPointer<A>;
using Range = octa::HashRange<octa::Pair<const K, T>>;
using ConstRange = octa::HashRange<const octa::Pair<const K, T>>;
using LocalRange = octa::BucketRange<octa::Pair<const K, T>>;
using ConstLocalRange = octa::BucketRange<const octa::Pair<const K, T>>;
using Pointer = AllocatorPointer<A>;
using ConstPointer = AllocatorConstPointer<A>;
using Range = HashRange<Pair<const K, T>>;
using ConstRange = HashRange<const Pair<const K, T>>;
using LocalRange = BucketRange<Pair<const K, T>>;
using ConstLocalRange = BucketRange<const Pair<const K, T>>;
using Allocator = A;
explicit MapImpl(octa::Size size, const H &hf = H(),
explicit MapImpl(Size size, const H &hf = H(),
const C &eqf = C(), const A &alloc = A()
): Base(size, hf, eqf, alloc) {}
MapImpl(): MapImpl(0) {}
explicit MapImpl(const A &alloc): MapImpl(0, H(), C(), alloc) {}
MapImpl(octa::Size size, const A &alloc):
MapImpl(Size size, const A &alloc):
MapImpl(size, H(), C(), alloc) {}
MapImpl(octa::Size size, const H &hf, const A &alloc):
MapImpl(Size size, const H &hf, const A &alloc):
MapImpl(size, hf, C(), alloc) {}
MapImpl(const MapImpl &m): Base(m,
octa::allocator_container_copy(m.get_alloc())) {}
allocator_container_copy(m.get_alloc())) {}
MapImpl(const MapImpl &m, const A &alloc): Base(m, alloc) {}
MapImpl(MapImpl &&m): Base(octa::move(m)) {}
MapImpl(MapImpl &&m, const A &alloc): Base(octa::move(m), alloc) {}
MapImpl(MapImpl &&m): Base(move(m)) {}
MapImpl(MapImpl &&m, const A &alloc): Base(move(m), alloc) {}
template<typename R, typename = octa::EnableIf<
octa::IsInputRange<R>::value &&
octa::IsConvertible<RangeReference<R>, Value>::value
>> MapImpl(R range, octa::Size size = 0, const H &hf = H(),
template<typename R, typename = EnableIf<
IsInputRange<R>::value && IsConvertible<RangeReference<R>,
Value>::value
>> MapImpl(R range, Size size = 0, const H &hf = H(),
const C &eqf = C(), const A &alloc = A()
): Base(size ? size : octa::detail::estimate_hrsize(range),
): Base(size ? size : detail::estimate_hrsize(range),
hf, eqf, alloc) {
for (; !range.empty(); range.pop_front())
Base::emplace(range.front());
@ -101,23 +98,23 @@ namespace detail {
}
template<typename R>
MapImpl(R range, octa::Size size, const A &alloc)
MapImpl(R range, Size size, const A &alloc)
: MapImpl(range, size, H(), C(), alloc) {}
template<typename R>
MapImpl(R range, octa::Size size, const H &hf, const A &alloc)
MapImpl(R range, Size size, const H &hf, const A &alloc)
: MapImpl(range, size, hf, C(), alloc) {}
MapImpl(octa::InitializerList<Value> init, octa::Size size = 0,
MapImpl(InitializerList<Value> init, Size size = 0,
const H &hf = H(), const C &eqf = C(), const A &alloc = A()
): MapImpl(octa::iter(init), size, hf, eqf, alloc) {}
): MapImpl(iter(init), size, hf, eqf, alloc) {}
MapImpl(octa::InitializerList<Value> init, octa::Size size, const A &alloc)
: MapImpl(octa::iter(init), size, H(), C(), alloc) {}
MapImpl(InitializerList<Value> init, Size size, const A &alloc)
: MapImpl(iter(init), size, H(), C(), alloc) {}
MapImpl(octa::InitializerList<Value> init, octa::Size size, const H &hf,
MapImpl(InitializerList<Value> init, Size size, const H &hf,
const A &alloc
): MapImpl(octa::iter(init), size, hf, C(), alloc) {}
): MapImpl(iter(init), size, hf, C(), alloc) {}
MapImpl &operator=(const MapImpl &m) {
Base::operator=(m);
@ -125,13 +122,13 @@ namespace detail {
}
MapImpl &operator=(MapImpl &&m) {
Base::operator=(octa::move(m));
Base::operator=(move(m));
return *this;
}
template<typename R, typename = octa::EnableIf<
octa::IsInputRange<R>::value &&
octa::IsConvertible<RangeReference<R>, Value>::value
template<typename R, typename = EnableIf<
IsInputRange<R>::value &&
IsConvertible<RangeReference<R>, Value>::value
>> MapImpl &operator=(R range) {
Base::assign_range(range);
return *this;
@ -157,7 +154,7 @@ namespace detail {
}
T &operator[](K &&key) {
static_assert(!IsMultihash, "operator[] only allowed on regular maps");
return Base::access_or_insert(octa::move(key));
return Base::access_or_insert(move(key));
}
void swap(MapImpl &v) {
@ -168,17 +165,17 @@ namespace detail {
template<
typename K, typename T,
typename H = octa::ToHash<K>,
typename C = octa::Equal<K>,
typename A = octa::Allocator<octa::Pair<const K, T>>
> using Map = octa::detail::MapImpl<K, T, H, C, A, false>;
typename H = ToHash<K>,
typename C = Equal<K>,
typename A = Allocator<Pair<const K, T>>
> using Map = detail::MapImpl<K, T, H, C, A, false>;
template<
typename K, typename T,
typename H = octa::ToHash<K>,
typename C = octa::Equal<K>,
typename A = octa::Allocator<octa::Pair<const K, T>>
> using Multimap = octa::detail::MapImpl<K, T, H, C, A, true>;
typename H = ToHash<K>,
typename C = Equal<K>,
typename A = Allocator<Pair<const K, T>>
> using Multimap = detail::MapImpl<K, T, H, C, A, true>;
} /* namespace octa */

View File

@ -24,7 +24,7 @@ struct Nothing {
constexpr Nothing nothing = Nothing(0);
namespace detail {
template<typename T, bool = octa::IsTriviallyDestructible<T>::value>
template<typename T, bool = IsTriviallyDestructible<T>::value>
class MaybeStorage {
protected:
using Value = T;
@ -37,19 +37,19 @@ namespace detail {
constexpr MaybeStorage(): p_null_state('\0') {}
MaybeStorage(const MaybeStorage &v): p_engaged(v.p_engaged) {
if (p_engaged) ::new(octa::address_of(p_value)) Value(v.p_value);
if (p_engaged) ::new(address_of(p_value)) Value(v.p_value);
}
MaybeStorage(MaybeStorage &&v): p_engaged(v.p_engaged) {
if (p_engaged)
::new(octa::address_of(p_value)) Value(octa::move(v.p_value));
::new(address_of(p_value)) Value(move(v.p_value));
}
constexpr MaybeStorage(const Value &v): p_value(v), p_engaged(true) {}
constexpr MaybeStorage(Value &&v): p_value(octa::move(v)), p_engaged(true) {}
constexpr MaybeStorage(Value &&v): p_value(move(v)), p_engaged(true) {}
template<typename ...A> constexpr MaybeStorage(octa::InPlace, A &&...args):
p_value(octa::forward<A>(args)...), p_engaged(true) {}
template<typename ...A> constexpr MaybeStorage(InPlace, A &&...args):
p_value(forward<A>(args)...), p_engaged(true) {}
~MaybeStorage() {
if (p_engaged) p_value.~Value();
@ -69,58 +69,58 @@ namespace detail {
constexpr MaybeStorage(): p_null_state('\0') {}
MaybeStorage(const MaybeStorage &v): p_engaged(v.p_engaged) {
if (p_engaged) ::new(octa::address_of(p_value)) Value(v.p_value);
if (p_engaged) ::new(address_of(p_value)) Value(v.p_value);
}
MaybeStorage(MaybeStorage &&v): p_engaged(v.p_engaged) {
if (p_engaged)
::new(octa::address_of(p_value)) Value(octa::move(v.p_value));
::new(address_of(p_value)) Value(move(v.p_value));
}
constexpr MaybeStorage(const Value &v): p_value(v), p_engaged(true) {}
constexpr MaybeStorage(Value &&v):
p_value(octa::move(v)), p_engaged(true) {}
p_value(move(v)), p_engaged(true) {}
template<typename ...A>
constexpr MaybeStorage(octa::InPlace, A &&...args):
p_value(octa::forward<A>(args)...), p_engaged(true) {}
constexpr MaybeStorage(InPlace, A &&...args):
p_value(forward<A>(args)...), p_engaged(true) {}
};
}
template<typename T>
class Maybe: private octa::detail::MaybeStorage<T> {
using Base = octa::detail::MaybeStorage<T>;
class Maybe: private detail::MaybeStorage<T> {
using Base = detail::MaybeStorage<T>;
public:
using Value = T;
static_assert(!octa::IsReference<T>::value,
static_assert(!IsReference<T>::value,
"Initialization of Maybe with a reference type is not allowed.");
static_assert(!octa::IsSame<octa::RemoveCv<T>, octa::InPlace>::value,
static_assert(!IsSame<RemoveCv<T>, InPlace>::value,
"Initialization of Maybe with InPlace is not allowed.");
static_assert(!octa::IsSame<octa::RemoveCv<T>, octa::Nothing>::value,
static_assert(!IsSame<RemoveCv<T>, Nothing>::value,
"Initialization of Maybe with Nothing is not allowed.");
static_assert(octa::IsObject<T>::value,
static_assert(IsObject<T>::value,
"Initialization of Maybe with non-object type is not allowed.");
static_assert(octa::IsDestructible<T>::value,
static_assert(IsDestructible<T>::value,
"Initialization of Maybe with a non-destructible object is not allowed.");
constexpr Maybe() {}
Maybe(const Maybe &) = default;
Maybe(Maybe &&) = default;
constexpr Maybe(octa::Nothing) {}
constexpr Maybe(Nothing) {}
constexpr Maybe(const Value &v): Base(v) {}
constexpr Maybe(Value &&v): Base(octa::move(v)) {}
constexpr Maybe(Value &&v): Base(move(v)) {}
template<typename ...A, typename = octa::EnableIf<
octa::IsConstructible<T, A...>::value>>
constexpr explicit Maybe(octa::InPlace, A &&...args): Base(octa::in_place,
octa::forward<A>(args)...) {}
template<typename ...A, typename = EnableIf<
IsConstructible<T, A...>::value>>
constexpr explicit Maybe(InPlace, A &&...args): Base(in_place,
forward<A>(args)...) {}
template<typename U, typename ...A, typename = typename octa::EnableIf<
octa::IsConstructible<T, std::initializer_list<U> &, A...>::value>>
template<typename U, typename ...A, typename = typename EnableIf<
IsConstructible<T, std::initializer_list<U> &, A...>::value>>
constexpr explicit
Maybe(octa::InPlace, std::initializer_list<U> il, A &&...args):
Base(octa::in_place, il, octa::forward<A>(args)...) {}
Maybe(InPlace, std::initializer_list<U> il, A &&...args):
Base(in_place, il, forward<A>(args)...) {}
~Maybe() = default;
@ -139,7 +139,7 @@ public:
if (this->p_engaged)
this->p_value.~Value();
else
::new(octa::address_of(this->p_value)) Value(v.p_value);
::new(address_of(this->p_value)) Value(v.p_value);
this->p_engaged = v.p_engaged;
}
return *this;
@ -147,60 +147,58 @@ public:
Maybe &operator=(Maybe &&v) {
if (this->p_engaged == v.p_engaged) {
if (this->p_engaged) this->p_value = octa::move(v.p_value);
if (this->p_engaged) this->p_value = move(v.p_value);
} else {
if (this->p_engaged)
this->p_value.~Value();
else {
::new(octa::address_of(this->p_value))
Value(octa::move(v.p_value));
::new(address_of(this->p_value)) Value(move(v.p_value));
}
this->p_engaged = v.p_engaged;
}
return *this;
}
template<typename U, typename = octa::EnableIf<
octa::IsSame<octa::RemoveReference<U>, Value>::value &&
octa::IsConstructible<Value, U>::value &&
octa::IsAssignable<Value &, U>::value
template<typename U, typename = EnableIf<
IsSame<RemoveReference<U>, Value>::value &&
IsConstructible<Value, U>::value &&
IsAssignable<Value &, U>::value
>>
Maybe &operator=(U &&v) {
if (this->p_engaged) {
this->p_value = octa::forward<U>(v);
this->p_value = forward<U>(v);
} else {
::new(octa::address_of(this->p_value)) Value(octa::forward<U>(v));
::new(address_of(this->p_value)) Value(forward<U>(v));
this->p_engaged = true;
}
return *this;
}
template<typename ...A, typename = octa::EnableIf<
octa::IsConstructible<Value, A...>::value
template<typename ...A, typename = EnableIf<
IsConstructible<Value, A...>::value
>>
void emplace(A &&...args) {
*this = octa::nothing;
::new(octa::address_of(this->p_value))
Value(octa::forward<A>(args)...);
*this = nothing;
::new(address_of(this->p_value)) Value(forward<A>(args)...);
this->p_engaged = true;
}
template<typename U, typename ...A, typename = octa::EnableIf<
octa::IsConstructible<Value, std::initializer_list<U> &, A...>::value
template<typename U, typename ...A, typename = EnableIf<
IsConstructible<Value, std::initializer_list<U> &, A...>::value
>>
void emplace(std::initializer_list<U> il, A &&...args) {
*this = octa::nothing;
::new(octa::address_of(this->p_value))
Value(il, octa::forward<A>(args)...);
*this = nothing;
::new(address_of(this->p_value))
Value(il, forward<A>(args)...);
this->p_engaged = true;
}
constexpr const Value *operator->() const {
return octa::address_of(this->p_value);
return address_of(this->p_value);
}
Value *operator->() {
return octa::address_of(this->p_value);
return address_of(this->p_value);
}
constexpr const Value &operator*() const {
@ -223,21 +221,21 @@ public:
template<typename U>
constexpr Value value_or(U &&v) const & {
static_assert(octa::IsCopyConstructible<Value>::value,
static_assert(IsCopyConstructible<Value>::value,
"Maybe<T>::value_or: T must be copy constructible");
static_assert(octa::IsConvertible<U, Value>::value,
static_assert(IsConvertible<U, Value>::value,
"Maybe<T>::value_or: U must be convertible to T");
return this->p_engaged ? this->p_value : Value(octa::forward<U>(v));
return this->p_engaged ? this->p_value : Value(forward<U>(v));
}
template<typename U>
Value value_or(U &&v) && {
static_assert(octa::IsMoveConstructible<Value>::value,
static_assert(IsMoveConstructible<Value>::value,
"Maybe<T>::value_or: T must be copy constructible");
static_assert(octa::IsConvertible<U, Value>::value,
static_assert(IsConvertible<U, Value>::value,
"Maybe<T>::value_or: U must be convertible to T");
return this->p_engaged ? octa::move(this->p_value)
: Value(octa::forward<U>(v));
return this->p_engaged ? move(this->p_value)
: Value(forward<U>(v));
}
void swap(Maybe &v) {
@ -245,19 +243,17 @@ public:
if (this->p_engaged) octa::swap(this->p_value, v.p_value);
} else {
if (this->p_engaged) {
::new(octa::address_of(v.p_value))
Value(octa::move(this->p_value));
::new(address_of(v.p_value)) Value(move(this->p_value));
this->p_value.~Value();
} else {
::new(octa::address_of(this->p_value))
Value(octa::move(v.p_value));
::new(address_of(this->p_value)) Value(move(v.p_value));
v.p_value.~Value();
}
octa::swap(this->p_engaged, v.p_engaged);
}
}
octa::Size to_hash() const {
Size to_hash() const {
return this->p_engaged ? octa::ToHash<T>()(this->p_value) : 0;
}
};
@ -380,12 +376,12 @@ static inline constexpr bool operator!=(const T &b, const Maybe<T> &a) {
template<typename T>
static inline constexpr bool operator<(const Maybe<T> &a, const T &b) {
return bool(a) ? octa::Less<T>()(*a, b) : true;
return bool(a) ? Less<T>()(*a, b) : true;
}
template<typename T>
static inline constexpr bool operator<(const T &b, const Maybe<T> &a) {
return bool(a) ? octa::Less<T>()(b, *a) : false;
return bool(a) ? Less<T>()(b, *a) : false;
}
template<typename T>
@ -421,8 +417,8 @@ static inline constexpr bool operator>=(const T &b, const Maybe<T> &a) {
/* make maybe */
template<typename T>
constexpr Maybe<octa::Decay<T>> make_maybe(T &&v) {
return Maybe<octa::Decay<T>>(octa::forward<T>(v));
constexpr Maybe<Decay<T>> make_maybe(T &&v) {
return Maybe<Decay<T>>(forward<T>(v));
}
} /* namespace octa */

View File

@ -68,7 +68,7 @@ namespace detail {
template<typename T, bool = HasDifference<T>::value>
struct PointerDifferenceBase {
using Type = octa::Ptrdiff;
using Type = Ptrdiff;
};
template<typename T> struct PointerDifferenceBase<T, true> {
@ -82,7 +82,7 @@ namespace detail {
template<typename T>
struct PointerDifferenceType<T *> {
using Type = octa::Ptrdiff;
using Type = Ptrdiff;
};
template<typename T, typename U>
@ -135,16 +135,16 @@ namespace detail {
} /*namespace detail */
template<typename T>
using Pointer = typename octa::detail::PointerPointer<T>::Type;
using Pointer = typename detail::PointerPointer<T>::Type;
template<typename T>
using PointerElement = typename octa::detail::PointerElementType<T>::Type;
using PointerElement = typename detail::PointerElementType<T>::Type;
template<typename T>
using PointerDifference = typename octa::detail::PointerDifferenceType<T>::Type;
using PointerDifference = typename detail::PointerDifferenceType<T>::Type;
template<typename T, typename U>
using PointerRebind = typename octa::detail::PointerRebindType<T, U>::Type;
using PointerRebind = typename detail::PointerRebindType<T, U>::Type;
/* pointer to */
@ -153,8 +153,7 @@ namespace detail {
template<typename T>
struct PointerTo {
static T pointer_to(octa::Conditional<
octa::IsVoid<PointerElement<T>>::value,
static T pointer_to(Conditional<IsVoid<PointerElement<T>>::value,
PointerToNat, PointerElement<T>
> &r) {
return T::pointer_to(r);
@ -163,20 +162,19 @@ namespace detail {
template<typename T>
struct PointerTo<T *> {
static T pointer_to(octa::Conditional<
octa::IsVoid<T>::value, PointerToNat, T
static T pointer_to(Conditional<IsVoid<T>::value,
PointerToNat, T
> &r) {
return octa::address_of(r);
return address_of(r);
}
};
}
template<typename T>
static T pointer_to(octa::Conditional<
octa::IsVoid<PointerElement<T>>::value,
octa::detail::PointerToNat, PointerElement<T>
static T pointer_to(Conditional<IsVoid<PointerElement<T>>::value,
detail::PointerToNat, PointerElement<T>
> &r) {
return octa::detail::PointerTo<T>::pointer_to(r);
return detail::PointerTo<T>::pointer_to(r);
}
/* default deleter */
@ -212,7 +210,7 @@ namespace detail {
template<typename T>
static char ptr_test(typename T::Pointer * = 0);
template<typename T> struct HasPtr: octa::IntegralConstant<bool,
template<typename T> struct HasPtr: IntegralConstant<bool,
(sizeof(ptr_test<T>(0)) == 1)
> {};
@ -226,7 +224,7 @@ namespace detail {
};
template<typename T, typename D> struct PointerType {
using Type = typename PointerBase<T, octa::RemoveReference<D>>::Type;
using Type = typename PointerBase<T, RemoveReference<D>>::Type;
};
} /* namespace detail */
@ -234,7 +232,7 @@ template<typename T, typename D = DefaultDelete<T>>
struct Box {
using Element = T;
using Deleter = D;
using Pointer = typename octa::detail::PointerType<T, D>::Type;
using Pointer = typename detail::PointerType<T, D>::Type;
private:
struct Nat { int x; };
@ -244,63 +242,63 @@ private:
public:
constexpr Box(): p_stor(nullptr, D()) {
static_assert(!octa::IsPointer<D>::value,
static_assert(!IsPointer<D>::value,
"Box constructed with null fptr deleter");
}
constexpr Box(octa::Nullptr): p_stor(nullptr, D()) {
static_assert(!octa::IsPointer<D>::value,
constexpr Box(Nullptr): p_stor(nullptr, D()) {
static_assert(!IsPointer<D>::value,
"Box constructed with null fptr deleter");
}
explicit Box(Pointer p): p_stor(p, D()) {
static_assert(!octa::IsPointer<D>::value,
static_assert(!IsPointer<D>::value,
"Box constructed with null fptr deleter");
}
Box(Pointer p, octa::Conditional<octa::IsReference<D>::value,
D, octa::AddLvalueReference<const D>
Box(Pointer p, Conditional<IsReference<D>::value,
D, AddLvalueReference<const D>
> d): p_stor(p, d) {}
Box(Pointer p, octa::RemoveReference<D> &&d):
p_stor(p, octa::move(d)) {
static_assert(!octa::IsReference<D>::value,
Box(Pointer p, RemoveReference<D> &&d):
p_stor(p, move(d)) {
static_assert(!IsReference<D>::value,
"rvalue deleter cannot be a ref");
}
Box(Box &&u): p_stor(u.release(), octa::forward<D>(u.get_deleter())) {}
Box(Box &&u): p_stor(u.release(), forward<D>(u.get_deleter())) {}
template<typename TT, typename DD>
Box(Box<TT, DD> &&u, octa::EnableIf<!octa::IsArray<TT>::value
&& octa::IsConvertible<typename Box<TT, DD>::Pointer, Pointer>::value
&& octa::IsConvertible<DD, D>::value
&& (!octa::IsReference<D>::value || octa::IsSame<D, DD>::value)
> = Nat()): p_stor(u.release(), octa::forward<DD>(u.get_deleter())) {}
Box(Box<TT, DD> &&u, EnableIf<!IsArray<TT>::value
&& IsConvertible<typename Box<TT, DD>::Pointer, Pointer>::value
&& IsConvertible<DD, D>::value
&& (!IsReference<D>::value || IsSame<D, DD>::value)
> = Nat()): p_stor(u.release(), forward<DD>(u.get_deleter())) {}
Box &operator=(Box &&u) {
reset(u.release());
p_stor.second() = octa::forward<D>(u.get_deleter());
p_stor.second() = forward<D>(u.get_deleter());
return *this;
}
template<typename TT, typename DD>
EnableIf<!octa::IsArray<TT>::value
&& octa::IsConvertible<typename Box<TT, DD>::Pointer, Pointer>::value
&& octa::IsAssignable<D &, DD &&>::value,
EnableIf<!IsArray<TT>::value
&& IsConvertible<typename Box<TT, DD>::Pointer, Pointer>::value
&& IsAssignable<D &, DD &&>::value,
Box &
> operator=(Box<TT, DD> &&u) {
reset(u.release());
p_stor.second() = octa::forward<DD>(u.get_deleter());
p_stor.second() = forward<DD>(u.get_deleter());
return *this;
}
Box &operator=(octa::Nullptr) {
Box &operator=(Nullptr) {
reset();
return *this;
}
~Box() { reset(); }
octa::AddLvalueReference<T> operator*() const { return *p_stor.first(); }
AddLvalueReference<T> operator*() const { return *p_stor.first(); }
Pointer operator->() const { return p_stor.first(); }
explicit operator bool() const {
@ -329,31 +327,31 @@ public:
}
private:
octa::detail::CompressedPair<T *, D> p_stor;
detail::CompressedPair<T *, D> p_stor;
};
namespace detail {
template<typename T, typename U, bool = octa::IsSame<
octa::RemoveCv<PointerElement<T>>,
octa::RemoveCv<PointerElement<U>>
>::value> struct SameOrLessCvQualifiedBase: octa::IsConvertible<T, U> {};
template<typename T, typename U, bool = IsSame<
RemoveCv<PointerElement<T>>,
RemoveCv<PointerElement<U>>
>::value> struct SameOrLessCvQualifiedBase: IsConvertible<T, U> {};
template<typename T, typename U>
struct SameOrLessCvQualifiedBase<T, U, false>: octa::False {};
struct SameOrLessCvQualifiedBase<T, U, false>: False {};
template<typename T, typename U, bool = octa::IsPointer<T>::value
|| octa::IsSame<T, U>::value || octa::detail::HasElement<T>::value
template<typename T, typename U, bool = IsPointer<T>::value
|| IsSame<T, U>::value || detail::HasElement<T>::value
> struct SameOrLessCvQualified: SameOrLessCvQualifiedBase<T, U> {};
template<typename T, typename U>
struct SameOrLessCvQualified<T, U, false>: octa::False {};
struct SameOrLessCvQualified<T, U, false>: False {};
} /* namespace detail */
template<typename T, typename D>
struct Box<T[], D> {
using Element = T;
using Deleter = D;
using Pointer = typename octa::detail::PointerType<T, D>::Type;
using Pointer = typename detail::PointerType<T, D>::Type;
private:
struct Nat { int x; };
@ -363,82 +361,82 @@ private:
public:
constexpr Box(): p_stor(nullptr, D()) {
static_assert(!octa::IsPointer<D>::value,
static_assert(!IsPointer<D>::value,
"Box constructed with null fptr deleter");
}
constexpr Box(octa::Nullptr): p_stor(nullptr, D()) {
static_assert(!octa::IsPointer<D>::value,
constexpr Box(Nullptr): p_stor(nullptr, D()) {
static_assert(!IsPointer<D>::value,
"Box constructed with null fptr deleter");
}
template<typename U> explicit Box(U p, octa::EnableIf<
octa::detail::SameOrLessCvQualified<U, Pointer>::value, Nat
template<typename U> explicit Box(U p, EnableIf<
detail::SameOrLessCvQualified<U, Pointer>::value, Nat
> = Nat()): p_stor(p, D()) {
static_assert(!octa::IsPointer<D>::value,
static_assert(!IsPointer<D>::value,
"Box constructed with null fptr deleter");
}
template<typename U> Box(U p, octa::Conditional<
octa::IsReference<D>::value,
template<typename U> Box(U p, Conditional<
IsReference<D>::value,
D, AddLvalueReference<const D>
> d, octa::EnableIf<octa::detail::SameOrLessCvQualified<U, Pointer>::value,
> d, EnableIf<detail::SameOrLessCvQualified<U, Pointer>::value,
Nat> = Nat()): p_stor(p, d) {}
Box(octa::Nullptr, octa::Conditional<octa::IsReference<D>::value,
Box(Nullptr, Conditional<IsReference<D>::value,
D, AddLvalueReference<const D>
> d): p_stor(nullptr, d) {}
template<typename U> Box(U p, octa::RemoveReference<D> &&d,
octa::EnableIf<
octa::detail::SameOrLessCvQualified<U, Pointer>::value, Nat
> = Nat()): p_stor(p, octa::move(d)) {
static_assert(!octa::IsReference<D>::value,
template<typename U> Box(U p, RemoveReference<D> &&d,
EnableIf<
detail::SameOrLessCvQualified<U, Pointer>::value, Nat
> = Nat()): p_stor(p, move(d)) {
static_assert(!IsReference<D>::value,
"rvalue deleter cannot be a ref");
}
Box(octa::Nullptr, octa::RemoveReference<D> &&d):
p_stor(nullptr, octa::move(d)) {
static_assert(!octa::IsReference<D>::value,
Box(Nullptr, RemoveReference<D> &&d):
p_stor(nullptr, move(d)) {
static_assert(!IsReference<D>::value,
"rvalue deleter cannot be a ref");
}
Box(Box &&u): p_stor(u.release(), octa::forward<D>(u.get_deleter())) {}
Box(Box &&u): p_stor(u.release(), forward<D>(u.get_deleter())) {}
template<typename TT, typename DD>
Box(Box<TT, DD> &&u, EnableIf<IsArray<TT>::value
&& octa::detail::SameOrLessCvQualified<typename Box<TT, DD>::Pointer,
Pointer>::value
&& octa::IsConvertible<DD, D>::value
&& (!octa::IsReference<D>::value ||
octa::IsSame<D, DD>::value)> = Nat()
): p_stor(u.release(), octa::forward<DD>(u.get_deleter())) {}
&& detail::SameOrLessCvQualified<typename Box<TT, DD>::Pointer,
Pointer>::value
&& IsConvertible<DD, D>::value
&& (!IsReference<D>::value ||
IsSame<D, DD>::value)> = Nat()
): p_stor(u.release(), forward<DD>(u.get_deleter())) {}
Box &operator=(Box &&u) {
reset(u.release());
p_stor.second() = octa::forward<D>(u.get_deleter());
p_stor.second() = forward<D>(u.get_deleter());
return *this;
}
template<typename TT, typename DD>
EnableIf<octa::IsArray<TT>::value
&& octa::detail::SameOrLessCvQualified<typename Box<TT, DD>::Pointer,
Pointer>::value
EnableIf<IsArray<TT>::value
&& detail::SameOrLessCvQualified<typename Box<TT, DD>::Pointer,
Pointer>::value
&& IsAssignable<D &, DD &&>::value,
Box &
> operator=(Box<TT, DD> &&u) {
reset(u.release());
p_stor.second() = octa::forward<DD>(u.get_deleter());
p_stor.second() = forward<DD>(u.get_deleter());
return *this;
}
Box &operator=(octa::Nullptr) {
Box &operator=(Nullptr) {
reset();
return *this;
}
~Box() { reset(); }
octa::AddLvalueReference<T> operator[](octa::Size idx) const {
AddLvalueReference<T> operator[](Size idx) const {
return p_stor.first()[idx];
}
@ -458,14 +456,14 @@ public:
}
template<typename U> EnableIf<
octa::detail::SameOrLessCvQualified<U, Pointer>::value, void
detail::SameOrLessCvQualified<U, Pointer>::value, void
> reset(U p) {
Pointer tmp = p_stor.first();
p_stor.first() = p;
if (tmp) p_stor.second()(tmp);
}
void reset(octa::Nullptr) {
void reset(Nullptr) {
Pointer tmp = p_stor.first();
p_stor.first() = nullptr;
if (tmp) p_stor.second()(tmp);
@ -480,35 +478,35 @@ public:
}
private:
octa::detail::CompressedPair<T *, D> p_stor;
detail::CompressedPair<T *, D> p_stor;
};
namespace detail {
template<typename T> struct BoxIf {
using Box = octa::Box<T>;
using Box = Box<T>;
};
template<typename T> struct BoxIf<T[]> {
using BoxUnknownSize = octa::Box<T[]>;
using BoxUnknownSize = Box<T[]>;
};
template<typename T, octa::Size N> struct BoxIf<T[N]> {
template<typename T, Size N> struct BoxIf<T[N]> {
using BoxKnownSize = void;
};
}
template<typename T, typename ...A>
typename octa::detail::BoxIf<T>::Box make_box(A &&...args) {
return Box<T>(new T(octa::forward<A>(args)...));
typename detail::BoxIf<T>::Box make_box(A &&...args) {
return Box<T>(new T(forward<A>(args)...));
}
template<typename T>
typename octa::detail::BoxIf<T>::BoxUnknownSize make_box(octa::Size n) {
return Box<T>(new octa::RemoveExtent<T>[n]());
typename detail::BoxIf<T>::BoxUnknownSize make_box(Size n) {
return Box<T>(new RemoveExtent<T>[n]());
}
template<typename T, typename ...A>
typename octa::detail::BoxIf<T>::BoxKnownSize make_box(A &&...args) = delete;
typename detail::BoxIf<T>::BoxKnownSize make_box(A &&...args) = delete;
/* allocator */
@ -531,8 +529,8 @@ template<> struct Allocator<const void> {
};
template<typename T> struct Allocator {
using Size = octa::Size;
using Difference = octa::Ptrdiff;
using Size = Size;
using Difference = Ptrdiff;
using Value = T;
using Reference = T &;
using ConstReference = const T &;
@ -554,22 +552,22 @@ 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 octa::byte[n * sizeof(T)];
return (Pointer) ::new byte[n * sizeof(T)];
}
void deallocate(Pointer p, Size) { ::delete[] (octa::byte *) p; }
void deallocate(Pointer p, Size) { ::delete[] (byte *) p; }
template<typename U, typename ...A>
void construct(U *p, A &&...args) {
::new((void *)p) U(octa::forward<A>(args)...);
::new((void *)p) U(forward<A>(args)...);
}
void destroy(Pointer p) { p->~T(); }
};
template<typename T> struct Allocator<const T> {
using Size = octa::Size;
using Difference = octa::Ptrdiff;
using Size = Size;
using Difference = Ptrdiff;
using Value = const T;
using Reference = const T &;
using ConstReference = const T &;
@ -588,14 +586,14 @@ 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 octa::byte[n * sizeof(T)];
return (Pointer) ::new byte[n * sizeof(T)];
}
void deallocate(Pointer p, Size) { ::delete[] (octa::byte *) p; }
void deallocate(Pointer p, Size) { ::delete[] (byte *) p; }
template<typename U, typename ...A>
void construct(U *p, A &&...args) {
::new((void *)p) U(octa::forward<A>(args)...);
::new((void *)p) U(forward<A>(args)...);
}
void destroy(Pointer p) { p->~T(); }
@ -678,7 +676,7 @@ namespace detail {
template<typename A, typename D, bool = SizeTest<A>::value>
struct SizeBase {
using Type = octa::MakeUnsigned<D>;
using Type = MakeUnsigned<D>;
};
template<typename A, typename D>
@ -696,22 +694,22 @@ template<typename A>
using AllocatorValue = typename AllocatorType<A>::Value;
template<typename A>
using AllocatorPointer = typename octa::detail::PointerType<
using AllocatorPointer = typename detail::PointerType<
AllocatorValue<A>, AllocatorType<A>
>::Type;
template<typename A>
using AllocatorConstPointer = typename octa::detail::ConstPointer<
using AllocatorConstPointer = typename detail::ConstPointer<
AllocatorValue<A>, AllocatorPointer<A>, AllocatorType<A>
>::Type;
template<typename A>
using AllocatorVoidPointer = typename octa::detail::VoidPointer<
using AllocatorVoidPointer = typename detail::VoidPointer<
AllocatorPointer<A>, AllocatorType<A>
>::Type;
template<typename A>
using AllocatorConstVoidPointer = typename octa::detail::ConstVoidPointer<
using AllocatorConstVoidPointer = typename detail::ConstVoidPointer<
AllocatorPointer<A>, AllocatorType<A>
>::Type;
@ -737,21 +735,21 @@ namespace detail {
}
template<typename A>
using AllocatorDifference = typename octa::detail::AllocDifference<
using AllocatorDifference = typename detail::AllocDifference<
A, AllocatorPointer<A>
>::Type;
/* allocator size */
template<typename A>
using AllocatorSize = typename octa::detail::SizeBase<
using AllocatorSize = typename detail::SizeBase<
A, AllocatorDifference<A>
>::Type;
/* allocator rebind */
namespace detail {
template<typename T, typename U, bool = octa::detail::HasRebind<T, U>::value>
template<typename T, typename U, bool = detail::HasRebind<T, U>::value>
struct AllocTraitsRebindType {
using Type = typename T::template Rebind<U>;
};
@ -772,7 +770,7 @@ namespace detail {
} /* namespace detail */
template<typename A, typename T>
using AllocatorRebind = typename octa::detail::AllocTraitsRebindType<
using AllocatorRebind = typename detail::AllocTraitsRebindType<
AllocatorType<A>, T
>::Type;
@ -790,7 +788,7 @@ namespace detail {
template<typename A, bool = PropagateOnContainerCopyAssignmentTest<
A
>::value> struct PropagateOnContainerCopyAssignmentBase {
using Type = octa::False;
using Type = False;
};
template<typename A>
@ -801,7 +799,7 @@ namespace detail {
template<typename A>
using AllocatorPropagateOnContainerCopyAssignment
= typename octa::detail::PropagateOnContainerCopyAssignmentBase<A>::Type;
= typename detail::PropagateOnContainerCopyAssignmentBase<A>::Type;
/* allocator propagate on container move assignment */
@ -817,7 +815,7 @@ namespace detail {
template<typename A, bool = PropagateOnContainerMoveAssignmentTest<
A
>::value> struct PropagateOnContainerMoveAssignmentBase {
using Type = octa::False;
using Type = False;
};
template<typename A>
@ -828,7 +826,7 @@ namespace detail {
template<typename A>
using AllocatorPropagateOnContainerMoveAssignment
= typename octa::detail::PropagateOnContainerMoveAssignmentBase<A>::Type;
= typename detail::PropagateOnContainerMoveAssignmentBase<A>::Type;
/* allocator propagate on container swap */
@ -843,7 +841,7 @@ namespace detail {
template<typename A, bool = PropagateOnContainerSwapTest<A>::value>
struct PropagateOnContainerSwapBase {
using Type = octa::False;
using Type = False;
};
template<typename A>
@ -854,7 +852,7 @@ namespace detail {
template<typename A>
using AllocatorPropagateOnContainerSwap
= typename octa::detail::PropagateOnContainerSwapBase<A>::Type;
= typename detail::PropagateOnContainerSwapBase<A>::Type;
/* allocator is always equal */
@ -868,7 +866,7 @@ namespace detail {
template<typename A, bool = IsAlwaysEqualTest<A>::value>
struct IsAlwaysEqualBase {
using Type = typename octa::IsEmpty<A>::Type;
using Type = typename IsEmpty<A>::Type;
};
template<typename A>
@ -878,7 +876,7 @@ namespace detail {
} /* namespace detail */
template<typename A>
using AllocatorIsAlwaysEqual = typename octa::detail::IsAlwaysEqualBase<A>::Type;
using AllocatorIsAlwaysEqual = typename detail::IsAlwaysEqualBase<A>::Type;
/* allocator allocate */
@ -891,33 +889,31 @@ allocator_allocate(A &a, AllocatorSize<A> n) {
namespace detail {
template<typename A, typename S, typename CVP>
auto allocate_hint_test(A &&a, S &&sz, CVP &&p)
-> decltype(a.allocate(sz, p), octa::True());
-> decltype(a.allocate(sz, p), True());
template<typename A, typename S, typename CVP>
auto allocate_hint_test(const A &, S &&, CVP &&)
-> octa::False;
-> False;
template<typename A, typename S, typename CVP>
struct AllocateHintTest: octa::IntegralConstant<bool,
octa::IsSame<
decltype(allocate_hint_test(octa::declval<A>(),
octa::declval<S>(),
octa::declval<CVP>())),
octa::True
struct AllocateHintTest: IntegralConstant<bool,
IsSame<decltype(allocate_hint_test(declval<A>(),
declval<S>(),
declval<CVP>())), True
>::value
> {};
template<typename A>
inline AllocatorPointer<A> allocate(A &a, AllocatorSize<A> n,
AllocatorConstVoidPointer<A> h,
octa::True) {
True) {
return a.allocate(n, h);
}
template<typename A>
inline AllocatorPointer<A> allocate(A &a, AllocatorSize<A> n,
AllocatorConstVoidPointer<A>,
octa::False) {
False) {
return a.allocate(n);
}
} /* namespace detail */
@ -926,8 +922,8 @@ template<typename A>
inline AllocatorPointer<A>
allocator_allocate(A &a, AllocatorSize<A> n,
AllocatorConstVoidPointer<A> h) {
return octa::detail::allocate(a, n, h,
octa::detail::AllocateHintTest<
return detail::allocate(a, n, h,
detail::AllocateHintTest<
A, AllocatorSize<A>, AllocatorConstVoidPointer<A>
>());
}
@ -945,139 +941,129 @@ inline void allocator_deallocate(A &a, AllocatorPointer<A> p,
namespace detail {
template<typename A, typename T, typename ...Args>
auto construct_test(A &&a, T *p, Args &&...args)
-> decltype(a.construct(p, octa::forward<Args>(args)...),
octa::True());
-> decltype(a.construct(p, forward<Args>(args)...),
True());
template<typename A, typename T, typename ...Args>
auto construct_test(const A &, T *, Args &&...)
-> octa::False;
-> False;
template<typename A, typename T, typename ...Args>
struct ConstructTest: octa::IntegralConstant<bool,
octa::IsSame<
decltype(construct_test(octa::declval<A>(),
octa::declval<T>(),
octa::declval<Args>()...)),
octa::True
struct ConstructTest: IntegralConstant<bool,
IsSame< decltype(construct_test(declval<A>(),
declval<T>(),
declval<Args>()...)), True
>::value
> {};
template<typename A, typename T, typename ...Args>
inline void construct(octa::True, A &a, T *p, Args &&...args) {
a.construct(p, octa::forward<Args>(args)...);
inline void construct(True, A &a, T *p, Args &&...args) {
a.construct(p, forward<Args>(args)...);
}
template<typename A, typename T, typename ...Args>
inline void construct(octa::False, A &, T *p, Args &&...args) {
::new ((void *)p) T(octa::forward<Args>(args)...);
inline void construct(False, A &, T *p, Args &&...args) {
::new ((void *)p) T(forward<Args>(args)...);
}
} /* namespace detail */
template<typename A, typename T, typename ...Args>
inline void allocator_construct(A &a, T *p, Args &&...args) {
octa::detail::construct(octa::detail::ConstructTest<
A, T *, Args...
>(), a, p, octa::forward<Args>(args)...);
detail::construct(detail::ConstructTest<A, T *, Args...>(), a, p,
forward<Args>(args)...);
}
/* allocator destroy */
namespace detail {
template<typename A, typename P>
auto destroy_test(A &&a, P &&p) -> decltype(a.destroy(p), octa::True());
auto destroy_test(A &&a, P &&p) -> decltype(a.destroy(p), True());
template<typename A, typename P>
auto destroy_test(const A &, P &&) -> octa::False;
auto destroy_test(const A &, P &&) -> False;
template<typename A, typename P>
struct DestroyTest: octa::IntegralConstant<bool,
octa::IsSame<
decltype(destroy_test(octa::declval<A>(), octa::declval<P>())),
octa::True
struct DestroyTest: IntegralConstant<bool,
IsSame<decltype(destroy_test(declval<A>(), declval<P>())), True
>::value
> {};
template<typename A, typename T>
inline void destroy(octa::True, A &a, T *p) {
inline void destroy(True, A &a, T *p) {
a.destroy(p);
}
template<typename A, typename T>
inline void destroy(octa::False, A &, T *p) {
inline void destroy(False, A &, T *p) {
p->~T();
}
} /* namespace detail */
template<typename A, typename T>
inline void allocator_destroy(A &a, T *p) {
octa::detail::destroy(octa::detail::DestroyTest<A, T *>(), a, p);
detail::destroy(detail::DestroyTest<A, T *>(), a, p);
}
/* allocator max size */
namespace detail {
template<typename A>
auto alloc_max_size_test(A &&a) -> decltype(a.max_size(), octa::True());
auto alloc_max_size_test(A &&a) -> decltype(a.max_size(), True());
template<typename A>
auto alloc_max_size_test(const A &) -> octa::False;
auto alloc_max_size_test(const A &) -> False;
template<typename A>
struct AllocMaxSizeTest: octa::IntegralConstant<bool,
octa::IsSame<
decltype(alloc_max_size_test(octa::declval<A &>())),
octa::True
struct AllocMaxSizeTest: IntegralConstant<bool,
IsSame<decltype(alloc_max_size_test(declval<A &>())), True
>::value
> {};
template<typename A>
inline AllocatorSize<A> alloc_max_size(octa::True, const A &a) {
inline AllocatorSize<A> alloc_max_size(True, const A &a) {
return a.max_size();
}
template<typename A>
inline AllocatorSize<A> alloc_max_size(octa::False, const A &) {
inline AllocatorSize<A> alloc_max_size(False, const A &) {
return AllocatorSize<A>(~0);
}
} /* namespace detail */
template<typename A>
inline AllocatorSize<A> allocator_max_size(const A &a) {
return octa::detail::alloc_max_size(octa::detail::AllocMaxSizeTest<
const A
>(), a);
return detail::alloc_max_size(detail::AllocMaxSizeTest<const A>(), a);
}
/* allocator container copy */
namespace detail {
template<typename A>
auto alloc_copy_test(A &&a) -> decltype(a.container_copy(), octa::True());
auto alloc_copy_test(A &&a) -> decltype(a.container_copy(), True());
template<typename A>
auto alloc_copy_test(const A &) -> octa::False;
auto alloc_copy_test(const A &) -> False;
template<typename A>
struct AllocCopyTest: octa::IntegralConstant<bool,
octa::IsSame<
decltype(alloc_copy_test(octa::declval<A &>())), octa::True
struct AllocCopyTest: IntegralConstant<bool,
IsSame<decltype(alloc_copy_test(declval<A &>())), True
>::value
> {};
template<typename A>
inline AllocatorType<A> alloc_container_copy(octa::True, const A &a) {
inline AllocatorType<A> alloc_container_copy(True, const A &a) {
return a.container_copy();
}
template<typename A>
inline AllocatorType<A> alloc_container_copy(octa::False, const A &a) {
inline AllocatorType<A> alloc_container_copy(False, const A &a) {
return a;
}
} /* namespace detail */
template<typename A>
inline AllocatorType<A> allocator_container_copy(const A &a) {
return octa::detail::alloc_container_copy(octa::detail::AllocCopyTest<
return detail::alloc_container_copy(detail::AllocCopyTest<
const A
>(), a);
}

View File

@ -41,7 +41,7 @@ namespace detail { \
}; \
} \
template<typename T> \
using Range##Name = typename octa::detail::Range##Name##Base<T>::Type;
using Range##Name = typename detail::Range##Name##Base<T>::Type;
OCTA_RANGE_TRAIT(Category)
OCTA_RANGE_TRAIT(Size)
@ -70,7 +70,7 @@ namespace detail {
// is input range
namespace detail {
template<typename T, bool = octa::IsConvertible<
template<typename T, bool = IsConvertible<
RangeCategory<T>, InputRangeTag
>::value> struct IsInputRangeBase: False {};
@ -78,16 +78,16 @@ namespace detail {
struct IsInputRangeBase<T, true>: True {};
}
template<typename T, bool = octa::detail::IsRangeTest<T>::value>
template<typename T, bool = detail::IsRangeTest<T>::value>
struct IsInputRange: False {};
template<typename T>
struct IsInputRange<T, true>: octa::detail::IsInputRangeBase<T>::Type {};
struct IsInputRange<T, true>: detail::IsInputRangeBase<T>::Type {};
// is forward range
namespace detail {
template<typename T, bool = octa::IsConvertible<
template<typename T, bool = IsConvertible<
RangeCategory<T>, ForwardRangeTag
>::value> struct IsForwardRangeBase: False {};
@ -95,16 +95,16 @@ namespace detail {
struct IsForwardRangeBase<T, true>: True {};
}
template<typename T, bool = octa::detail::IsRangeTest<T>::value>
template<typename T, bool = detail::IsRangeTest<T>::value>
struct IsForwardRange: False {};
template<typename T>
struct IsForwardRange<T, true>: octa::detail::IsForwardRangeBase<T>::Type {};
struct IsForwardRange<T, true>: detail::IsForwardRangeBase<T>::Type {};
// is bidirectional range
namespace detail {
template<typename T, bool = octa::IsConvertible<
template<typename T, bool = IsConvertible<
RangeCategory<T>, BidirectionalRangeTag
>::value> struct IsBidirectionalRangeBase: False {};
@ -112,17 +112,17 @@ namespace detail {
struct IsBidirectionalRangeBase<T, true>: True {};
}
template<typename T, bool = octa::detail::IsRangeTest<T>::value>
template<typename T, bool = detail::IsRangeTest<T>::value>
struct IsBidirectionalRange: False {};
template<typename T>
struct IsBidirectionalRange<T, true>:
octa::detail::IsBidirectionalRangeBase<T>::Type {};
detail::IsBidirectionalRangeBase<T>::Type {};
// is random access range
namespace detail {
template<typename T, bool = octa::IsConvertible<
template<typename T, bool = IsConvertible<
RangeCategory<T>, RandomAccessRangeTag
>::value> struct IsRandomAccessRangeBase: False {};
@ -130,17 +130,17 @@ namespace detail {
struct IsRandomAccessRangeBase<T, true>: True {};
}
template<typename T, bool = octa::detail::IsRangeTest<T>::value>
template<typename T, bool = detail::IsRangeTest<T>::value>
struct IsRandomAccessRange: False {};
template<typename T>
struct IsRandomAccessRange<T, true>:
octa::detail::IsRandomAccessRangeBase<T>::Type {};
detail::IsRandomAccessRangeBase<T>::Type {};
// is finite random access range
namespace detail {
template<typename T, bool = octa::IsConvertible<
template<typename T, bool = IsConvertible<
RangeCategory<T>, FiniteRandomAccessRangeTag
>::value> struct IsFiniteRandomAccessRangeBase: False {};
@ -148,12 +148,12 @@ namespace detail {
struct IsFiniteRandomAccessRangeBase<T, true>: True {};
}
template<typename T, bool = octa::detail::IsRangeTest<T>::value>
template<typename T, bool = detail::IsRangeTest<T>::value>
struct IsFiniteRandomAccessRange: False {};
template<typename T>
struct IsFiniteRandomAccessRange<T, true>:
octa::detail::IsFiniteRandomAccessRangeBase<T>::Type {};
detail::IsFiniteRandomAccessRangeBase<T>::Type {};
// is infinite random access range
@ -174,12 +174,12 @@ namespace detail {
};
}
template<typename T, bool = (octa::IsConvertible<
template<typename T, bool = (IsConvertible<
RangeCategory<T>, OutputRangeTag
>::value || (IsInputRange<T>::value &&
(octa::detail::OutputRangeTest<T, const RangeValue<T> &>::value ||
octa::detail::OutputRangeTest<T, RangeValue<T> &&>::value ||
octa::detail::OutputRangeTest<T, RangeValue<T> >::value)
(detail::OutputRangeTest<T, const RangeValue<T> &>::value ||
detail::OutputRangeTest<T, RangeValue<T> &&>::value ||
detail::OutputRangeTest<T, RangeValue<T> >::value)
))> struct IsOutputRange: False {};
template<typename T>
@ -195,7 +195,7 @@ namespace detail {
::new(&get_ref()) T(range);
}
explicit RangeIterator(T &&range) {
::new(&get_ref()) T(octa::move(range));
::new(&get_ref()) T(move(range));
}
RangeIterator &operator++() {
get_ref().pop_front();
@ -208,7 +208,7 @@ namespace detail {
private:
T &get_ref() { return *((T *)&p_range); }
const T &get_ref() const { return *((T *)&p_range); }
octa::AlignedStorage<sizeof(T), alignof(T)> p_range;
AlignedStorage<sizeof(T), alignof(T)> p_range;
};
}
@ -259,12 +259,12 @@ public:
RangeHalf() = delete;
RangeHalf(const T &range): p_range(range) {}
template<typename U, typename = octa::EnableIf<
octa::IsConvertible<U, T>::value
template<typename U, typename = EnableIf<
IsConvertible<U, T>::value
>> RangeHalf(const RangeHalf<U> &half): p_range(half.p_range) {}
RangeHalf(const RangeHalf &half): p_range(half.p_range) {}
RangeHalf(RangeHalf &&half): p_range(octa::move(half.p_range)) {}
RangeHalf(RangeHalf &&half): p_range(move(half.p_range)) {}
RangeHalf &operator=(const RangeHalf &half) {
p_range = half.p_range;
@ -272,7 +272,7 @@ public:
}
RangeHalf &operator=(RangeHalf &&half) {
p_range = octa::move(half.p_range);
p_range = move(half.p_range);
return *this;
}
@ -287,10 +287,10 @@ public:
}
RangeDifference<T> add_n(RangeDifference<T> n) {
return octa::detail::RangeAdd<RangeHalf<T>>::add_n(*this, n);
return detail::RangeAdd<RangeHalf<T>>::add_n(*this, n);
}
RangeDifference<T> sub_n(RangeDifference<T> n) {
return octa::detail::RangeAdd<RangeHalf<T>>::sub_n(*this, n);
return detail::RangeAdd<RangeHalf<T>>::sub_n(*this, n);
}
RangeReference<T> get() const {
@ -408,7 +408,7 @@ template<typename> struct ReverseRange;
template<typename> struct MoveRange;
template<typename B, typename C, typename V, typename R = V &,
typename S = octa::Size, typename D = octa::Ptrdiff
typename S = Size, typename D = Ptrdiff
> struct InputRange {
using Category = C;
using Size = S;
@ -416,27 +416,27 @@ template<typename B, typename C, typename V, typename R = V &,
using Value = V;
using Reference = R;
octa::detail::RangeIterator<B> begin() const {
return octa::detail::RangeIterator<B>((const B &)*this);
detail::RangeIterator<B> begin() const {
return detail::RangeIterator<B>((const B &)*this);
}
octa::detail::RangeIterator<B> end() const {
return octa::detail::RangeIterator<B>();
detail::RangeIterator<B> end() const {
return detail::RangeIterator<B>();
}
Size pop_front_n(Size n) {
return octa::detail::pop_front_n<B>(*((B *)this), n);
return detail::pop_front_n<B>(*((B *)this), n);
}
Size pop_back_n(Size n) {
return octa::detail::pop_back_n<B>(*((B *)this), n);
return detail::pop_back_n<B>(*((B *)this), n);
}
Size push_front_n(Size n) {
return octa::detail::push_front_n<B>(*((B *)this), n);
return detail::push_front_n<B>(*((B *)this), n);
}
Size push_back_n(Size n) {
return octa::detail::push_back_n<B>(*((B *)this), n);
return detail::push_back_n<B>(*((B *)this), n);
}
B iter() const {
@ -463,8 +463,8 @@ template<typename B, typename C, typename V, typename R = V &,
}
template<typename OR,
typename = octa::EnableIf<octa::IsOutputRange<OR>::value
>> Size copy(OR &&orange, Size n = -1) {
typename = EnableIf<IsOutputRange<OR>::value>
> Size copy(OR &&orange, Size n = -1) {
B r(*((B *)this));
Size on = n;
for (; n && !r.empty(); --n) {
@ -474,7 +474,7 @@ template<typename B, typename C, typename V, typename R = V &,
return (on - n);
}
Size copy(octa::RemoveCv<Value> *p, Size n = -1) {
Size copy(RemoveCv<Value> *p, Size n = -1) {
B r(*((B *)this));
Size on = n;
for (; n && !r.empty(); --n) {
@ -501,7 +501,7 @@ auto citer(const T &r) -> decltype(r.iter()) {
}
template<typename B, typename V, typename R = V &,
typename S = octa::Size, typename D = octa::Ptrdiff
typename S = Size, typename D = Ptrdiff
> struct OutputRange {
using Category = OutputRangeTag;
using Size = S;
@ -533,12 +533,12 @@ public:
HalfRange() = delete;
HalfRange(const HalfRange &range): p_beg(range.p_beg),
p_end(range.p_end) {}
HalfRange(HalfRange &&range): p_beg(octa::move(range.p_beg)),
p_end(octa::move(range.p_end)) {}
HalfRange(HalfRange &&range): p_beg(move(range.p_beg)),
p_end(move(range.p_end)) {}
HalfRange(const T &beg, const T &end): p_beg(beg),
p_end(end) {}
HalfRange(T &&beg, T &&end): p_beg(octa::move(beg)),
p_end(octa::move(end)) {}
HalfRange(T &&beg, T &&end): p_beg(move(beg)),
p_end(move(end)) {}
HalfRange &operator=(const HalfRange &range) {
p_beg = range.p_beg;
@ -547,8 +547,8 @@ public:
}
HalfRange &operator=(HalfRange &&range) {
p_beg = octa::move(range.p_beg);
p_end = octa::move(range.p_end);
p_beg = move(range.p_beg);
p_end = move(range.p_end);
return *this;
}
@ -601,7 +601,7 @@ public:
return p_beg.range().put(v);
}
bool put(RangeValue<Rtype> &&v) {
return p_beg.range().put(octa::move(v));
return p_beg.range().put(move(v));
}
};
@ -620,14 +620,14 @@ public:
ReverseRange() = delete;
ReverseRange(const T &range): p_range(range) {}
ReverseRange(const ReverseRange &it): p_range(it.p_range) {}
ReverseRange(ReverseRange &&it): p_range(octa::move(it.p_range)) {}
ReverseRange(ReverseRange &&it): p_range(move(it.p_range)) {}
ReverseRange &operator=(const ReverseRange &v) {
p_range = v.p_range;
return *this;
}
ReverseRange &operator=(ReverseRange &&v) {
p_range = octa::move(v.p_range);
p_range = move(v.p_range);
return *this;
}
ReverseRange &operator=(const T &v) {
@ -635,7 +635,7 @@ public:
return *this;
}
ReverseRange &operator=(T &&v) {
p_range = octa::move(v);
p_range = move(v);
return *this;
}
@ -695,14 +695,14 @@ public:
MoveRange() = delete;
MoveRange(const T &range): p_range(range) {}
MoveRange(const MoveRange &it): p_range(it.p_range) {}
MoveRange(MoveRange &&it): p_range(octa::move(it.p_range)) {}
MoveRange(MoveRange &&it): p_range(move(it.p_range)) {}
MoveRange &operator=(const MoveRange &v) {
p_range = v.p_range;
return *this;
}
MoveRange &operator=(MoveRange &&v) {
p_range = octa::move(v.p_range);
p_range = move(v.p_range);
return *this;
}
MoveRange &operator=(const T &v) {
@ -710,7 +710,7 @@ public:
return *this;
}
MoveRange &operator=(T &&v) {
p_range = octa::move(v);
p_range = move(v);
return *this;
}
@ -743,17 +743,17 @@ public:
Rsize push_front_n(Rsize n) { return p_range.push_front_n(n); }
Rsize push_back_n(Rsize n) { return p_range.push_back_n(n); }
Rref front() const { return octa::move(p_range.front()); }
Rref back() const { return octa::move(p_range.back()); }
Rref front() const { return move(p_range.front()); }
Rref back() const { return move(p_range.back()); }
Rref operator[](Rsize i) const { return octa::move(p_range[i]); }
Rref operator[](Rsize i) const { return move(p_range[i]); }
MoveRange<T> slice(Rsize start, Rsize end) const {
return MoveRange<T>(p_range.slice(start, end));
}
bool put(const Rval &v) { return p_range.put(v); }
bool put(Rval &&v) { return p_range.put(octa::move(v)); }
bool put(Rval &&v) { return p_range.put(move(v)); }
};
template<typename T>
@ -792,10 +792,10 @@ template<typename T>
struct PointerRange: InputRange<PointerRange<T>, FiniteRandomAccessRangeTag, T> {
PointerRange() = delete;
PointerRange(T *beg, T *end): p_beg(beg), p_end(end) {}
PointerRange(T *beg, octa::Size n): p_beg(beg), p_end(beg + n) {}
PointerRange(T *beg, Size n): p_beg(beg), p_end(beg + n) {}
template<typename U, typename = octa::EnableIf<
octa::IsConvertible<U *, T *>::value
template<typename U, typename = EnableIf<
IsConvertible<U *, T *>::value
>> PointerRange(const PointerRange<U> &v):
p_beg(&v[0]), p_end(&v[v.size()]) {}
@ -817,8 +817,8 @@ struct PointerRange: InputRange<PointerRange<T>, FiniteRandomAccessRangeTag, T>
--p_beg; return true;
}
octa::Size pop_front_n(octa::Size n) {
octa::Size olen = p_end - p_beg;
Size pop_front_n(Size n) {
Size olen = p_end - p_beg;
p_beg += n;
if (p_beg > p_end) {
p_beg = p_end;
@ -827,7 +827,7 @@ struct PointerRange: InputRange<PointerRange<T>, FiniteRandomAccessRangeTag, T>
return n;
}
octa::Size push_front_n(octa::Size n) {
Size push_front_n(Size n) {
p_beg -= n; return true;
}
@ -837,7 +837,7 @@ struct PointerRange: InputRange<PointerRange<T>, FiniteRandomAccessRangeTag, T>
return p_beg == range.p_beg;
}
octa::Ptrdiff distance_front(const PointerRange &range) const {
Ptrdiff distance_front(const PointerRange &range) const {
return range.p_beg - p_beg;
}
@ -851,8 +851,8 @@ struct PointerRange: InputRange<PointerRange<T>, FiniteRandomAccessRangeTag, T>
++p_end; return true;
}
octa::Size pop_back_n(octa::Size n) {
octa::Size olen = p_end - p_beg;
Size pop_back_n(Size n) {
Size olen = p_end - p_beg;
p_end -= n;
if (p_end < p_beg) {
p_end = p_beg;
@ -861,7 +861,7 @@ struct PointerRange: InputRange<PointerRange<T>, FiniteRandomAccessRangeTag, T>
return n;
}
octa::Size push_back_n(octa::Size n) {
Size push_back_n(Size n) {
p_end += n; return true;
}
@ -871,18 +871,18 @@ struct PointerRange: InputRange<PointerRange<T>, FiniteRandomAccessRangeTag, T>
return p_end == range.p_end;
}
octa::Ptrdiff distance_back(const PointerRange &range) const {
Ptrdiff distance_back(const PointerRange &range) const {
return range.p_end - p_end;
}
/* satisfy FiniteRandomAccessRange */
octa::Size size() const { return p_end - p_beg; }
Size size() const { return p_end - p_beg; }
PointerRange slice(octa::Size start, octa::Size end) const {
PointerRange slice(Size start, Size end) const {
return PointerRange(p_beg + start, p_beg + end);
}
T &operator[](octa::Size i) const { return p_beg[i]; }
T &operator[](Size i) const { return p_beg[i]; }
/* satisfy OutputRange */
bool put(const T &v) {
@ -892,33 +892,33 @@ struct PointerRange: InputRange<PointerRange<T>, FiniteRandomAccessRangeTag, T>
}
bool put(T &&v) {
if (empty()) return false;
*(p_beg++) = octa::move(v);
*(p_beg++) = move(v);
return true;
}
octa::Size put_n(const T *p, octa::Size n) {
octa::Size ret = size();
Size put_n(const T *p, Size n) {
Size ret = size();
if (n < ret) ret = n;
if (octa::IsPod<T>()) {
if (IsPod<T>()) {
memcpy(p_beg, p, ret * sizeof(T));
p_beg += ret;
return ret;
}
for (octa::Size i = ret; i; --i)
for (Size i = ret; i; --i)
*p_beg++ = *p++;
return ret;
}
template<typename R,
typename = octa::EnableIf<octa::IsOutputRange<R>::value
>> octa::Size copy(R &&orange, octa::Size n = -1) {
octa::Size c = size();
typename = EnableIf<IsOutputRange<R>::value
>> Size copy(R &&orange, Size n = -1) {
Size c = size();
if (n < c) c = n;
return orange.put_n(p_beg, c);
}
octa::Size copy(octa::RemoveCv<T> *p, octa::Size n = -1) {
octa::Size c = size();
Size copy(RemoveCv<T> *p, Size n = -1) {
Size c = size();
if (n < c) c = n;
return copy(PointerRange(p, c), c);
}
@ -927,12 +927,12 @@ private:
T *p_beg, *p_end;
};
template<typename T, octa::Size N>
template<typename T, Size N>
PointerRange<T> iter(T (&array)[N]) {
return PointerRange<T>(array, N);
}
template<typename T, octa::Size N>
template<typename T, Size N>
PointerRange<const T> iter(const T (&array)[N]) {
return PointerRange<const T>(array, N);
}
@ -965,7 +965,7 @@ public:
p_range(it.p_range), p_index(it.p_index) {}
EnumeratedRange(EnumeratedRange &&it):
p_range(octa::move(it.p_range)), p_index(it.p_index) {}
p_range(move(it.p_range)), p_index(it.p_index) {}
EnumeratedRange &operator=(const EnumeratedRange &v) {
p_range = v.p_range;
@ -973,7 +973,7 @@ public:
return *this;
}
EnumeratedRange &operator=(EnumeratedRange &&v) {
p_range = octa::move(v.p_range);
p_range = move(v.p_range);
p_index = v.p_index;
return *this;
}
@ -983,7 +983,7 @@ public:
return *this;
}
EnumeratedRange &operator=(T &&v) {
p_range = octa::move(v);
p_range = move(v);
p_index = 0;
return *this;
}
@ -1032,14 +1032,14 @@ public:
p_remaining(rem) {}
TakeRange(const TakeRange &it): p_range(it.p_range),
p_remaining(it.p_remaining) {}
TakeRange(TakeRange &&it): p_range(octa::move(it.p_range)),
TakeRange(TakeRange &&it): p_range(move(it.p_range)),
p_remaining(it.p_remaining) {}
TakeRange &operator=(const TakeRange &v) {
p_range = v.p_range; p_remaining = v.p_remaining; return *this;
}
TakeRange &operator=(TakeRange &&v) {
p_range = octa::move(v.p_range);
p_range = move(v.p_range);
p_remaining = v.p_remaining;
return *this;
}
@ -1086,14 +1086,14 @@ public:
p_chunksize(chs) {}
ChunksRange(const ChunksRange &it): p_range(it.p_range),
p_chunksize(it.p_chunksize) {}
ChunksRange(ChunksRange &&it): p_range(octa::move(it.p_range)),
ChunksRange(ChunksRange &&it): p_range(move(it.p_range)),
p_chunksize(it.p_chunksize) {}
ChunksRange &operator=(const ChunksRange &v) {
p_range = v.p_range; p_chunksize = v.p_chunksize; return *this;
}
ChunksRange &operator=(ChunksRange &&v) {
p_range = octa::move(v.p_range);
p_range = move(v.p_range);
p_chunksize = v.p_chunksize;
return *this;
}
@ -1122,9 +1122,9 @@ struct AppenderRange: OutputRange<AppenderRange<T>, typename T::Value,
typename T::Reference, typename T::Size, typename T::Difference> {
AppenderRange(): p_data() {}
AppenderRange(const T &v): p_data(v) {}
AppenderRange(T &&v): p_data(octa::move(v)) {}
AppenderRange(T &&v): p_data(move(v)) {}
AppenderRange(const AppenderRange &v): p_data(v.p_data) {}
AppenderRange(AppenderRange &&v): p_data(octa::move(v.p_data)) {}
AppenderRange(AppenderRange &&v): p_data(move(v.p_data)) {}
AppenderRange &operator=(const AppenderRange &v) {
p_data = v.p_data;
@ -1132,7 +1132,7 @@ struct AppenderRange: OutputRange<AppenderRange<T>, typename T::Value,
}
AppenderRange &operator=(AppenderRange &&v) {
p_data = octa::move(v.p_data);
p_data = move(v.p_data);
return *this;
}
@ -1142,7 +1142,7 @@ struct AppenderRange: OutputRange<AppenderRange<T>, typename T::Value,
}
AppenderRange &operator=(T &&v) {
p_data = octa::move(v);
p_data = move(v);
return *this;
}
@ -1160,7 +1160,7 @@ struct AppenderRange: OutputRange<AppenderRange<T>, typename T::Value,
}
bool put(typename T::Value &&v) {
p_data.push(octa::move(v));
p_data.push(move(v));
return true;
}
@ -1176,11 +1176,11 @@ AppenderRange<T> appender() {
template<typename T>
AppenderRange<T> appender(T &&v) {
return AppenderRange<T>(octa::forward<T>(v));
return AppenderRange<T>(forward<T>(v));
}
// range of
template<typename T> using RangeOf = decltype(octa::iter(octa::declval<T>()));
template<typename T> using RangeOf = decltype(iter(declval<T>()));
} /* namespace octa */

View File

@ -30,56 +30,56 @@ namespace detail {
};
template<typename T, typename H, typename C, typename A, bool IsMultihash>
struct SetImpl: octa::detail::Hashtable<
octa::detail::SetBase<T, A>, T, T, T, H, C, A, IsMultihash
struct SetImpl: detail::Hashtable<
detail::SetBase<T, A>, T, T, T, H, C, A, IsMultihash
> {
private:
using Base = octa::detail::Hashtable<
octa::detail::SetBase<T, A>, T, T, T, H, C, A, IsMultihash
using Base = detail::Hashtable<
detail::SetBase<T, A>, T, T, T, H, C, A, IsMultihash
>;
public:
using Key = T;
using Size = octa::Size;
using Difference = octa::Ptrdiff;
using Size = Size;
using Difference = Ptrdiff;
using Hasher = H;
using KeyEqual = C;
using Value = T;
using Reference = Value &;
using Pointer = octa::AllocatorPointer<A>;
using ConstPointer = octa::AllocatorConstPointer<A>;
using Range = octa::HashRange<T>;
using ConstRange = octa::HashRange<const T>;
using LocalRange = octa::BucketRange<T>;
using ConstLocalRange = octa::BucketRange<const T>;
using Pointer = AllocatorPointer<A>;
using ConstPointer = AllocatorConstPointer<A>;
using Range = HashRange<T>;
using ConstRange = HashRange<const T>;
using LocalRange = BucketRange<T>;
using ConstLocalRange = BucketRange<const T>;
using Allocator = A;
explicit SetImpl(octa::Size size, const H &hf = H(),
explicit SetImpl(Size size, const H &hf = H(),
const C &eqf = C(), const A &alloc = A()
): Base(size, hf, eqf, alloc) {}
SetImpl(): SetImpl(0) {}
explicit SetImpl(const A &alloc): SetImpl(0, H(), C(), alloc) {}
SetImpl(octa::Size size, const A &alloc):
SetImpl(Size size, const A &alloc):
SetImpl(size, H(), C(), alloc) {}
SetImpl(octa::Size size, const H &hf, const A &alloc):
SetImpl(Size size, const H &hf, const A &alloc):
SetImpl(size, hf, C(), alloc) {}
SetImpl(const SetImpl &m): Base(m,
octa::allocator_container_copy(m.get_alloc())) {}
allocator_container_copy(m.get_alloc())) {}
SetImpl(const SetImpl &m, const A &alloc): Base(m, alloc) {}
SetImpl(SetImpl &&m): Base(octa::move(m)) {}
SetImpl(SetImpl &&m, const A &alloc): Base(octa::move(m), alloc) {}
SetImpl(SetImpl &&m): Base(move(m)) {}
SetImpl(SetImpl &&m, const A &alloc): Base(move(m), alloc) {}
template<typename R, typename = octa::EnableIf<
octa::IsInputRange<R>::value &&
octa::IsConvertible<RangeReference<R>, Value>::value
>> SetImpl(R range, octa::Size size = 0, const H &hf = H(),
template<typename R, typename = EnableIf<
IsInputRange<R>::value &&
IsConvertible<RangeReference<R>, Value>::value
>> SetImpl(R range, Size size = 0, const H &hf = H(),
const C &eqf = C(), const A &alloc = A()
): Base(size ? size : octa::detail::estimate_hrsize(range),
): Base(size ? size : detail::estimate_hrsize(range),
hf, eqf, alloc) {
for (; !range.empty(); range.pop_front())
Base::emplace(range.front());
@ -87,23 +87,23 @@ namespace detail {
}
template<typename R>
SetImpl(R range, octa::Size size, const A &alloc)
SetImpl(R range, Size size, const A &alloc)
: SetImpl(range, size, H(), C(), alloc) {}
template<typename R>
SetImpl(R range, octa::Size size, const H &hf, const A &alloc)
SetImpl(R range, Size size, const H &hf, const A &alloc)
: SetImpl(range, size, hf, C(), alloc) {}
SetImpl(octa::InitializerList<Value> init, octa::Size size = 0,
SetImpl(InitializerList<Value> init, Size size = 0,
const H &hf = H(), const C &eqf = C(), const A &alloc = A()
): SetImpl(octa::iter(init), size, hf, eqf, alloc) {}
): SetImpl(iter(init), size, hf, eqf, alloc) {}
SetImpl(octa::InitializerList<Value> init, octa::Size size, const A &alloc)
: SetImpl(octa::iter(init), size, H(), C(), alloc) {}
SetImpl(InitializerList<Value> init, Size size, const A &alloc)
: SetImpl(iter(init), size, H(), C(), alloc) {}
SetImpl(octa::InitializerList<Value> init, octa::Size size, const H &hf,
SetImpl(InitializerList<Value> init, Size size, const H &hf,
const A &alloc
): SetImpl(octa::iter(init), size, hf, C(), alloc) {}
): SetImpl(iter(init), size, hf, C(), alloc) {}
SetImpl &operator=(const SetImpl &m) {
Base::operator=(m);
@ -111,13 +111,13 @@ namespace detail {
}
SetImpl &operator=(SetImpl &&m) {
Base::operator=(octa::move(m));
Base::operator=(move(m));
return *this;
}
template<typename R, typename = octa::EnableIf<
octa::IsInputRange<R>::value &&
octa::IsConvertible<RangeReference<R>, Value>::value
template<typename R, typename = EnableIf<
IsInputRange<R>::value &&
IsConvertible<RangeReference<R>, Value>::value
>> SetImpl &operator=(R range) {
Base::assign_range(range);
return *this;
@ -136,17 +136,17 @@ namespace detail {
template<
typename T,
typename H = octa::ToHash<T>,
typename C = octa::Equal<T>,
typename A = octa::Allocator<T>
> using Set = octa::detail::SetImpl<T, H, C, A, false>;
typename H = ToHash<T>,
typename C = Equal<T>,
typename A = Allocator<T>
> using Set = detail::SetImpl<T, H, C, A, false>;
template<
typename T,
typename H = octa::ToHash<T>,
typename C = octa::Equal<T>,
typename A = octa::Allocator<T>
> using Multiset = octa::detail::SetImpl<T, H, C, A, true>;
typename H = ToHash<T>,
typename C = Equal<T>,
typename A = Allocator<T>
> using Multiset = detail::SetImpl<T, H, C, A, true>;
} /* namespace octa */

View File

@ -30,16 +30,16 @@ enum class StreamSeek {
set = SEEK_SET
};
template<typename T = char, bool = octa::IsPod<T>::value>
template<typename T = char, bool = IsPod<T>::value>
struct StreamRange;
namespace detail {
template<octa::Size N>
struct FormatOutRange: octa::OutputRange<FormatOutRange<N>, char> {
template<Size N>
struct FormatOutRange: OutputRange<FormatOutRange<N>, char> {
FormatOutRange(char *buf): buf(buf), idx(0) {}
FormatOutRange(const FormatOutRange &r): buf(r.buf), idx(r.idx) {}
char *buf;
octa::Size idx;
Size idx;
bool put(char v) {
if (idx < N) {
buf[idx++] = v;
@ -74,30 +74,30 @@ struct Stream {
virtual bool flush() { return true; }
virtual octa::Size read_bytes(void *, octa::Size) { return 0; }
virtual octa::Size write_bytes(const void *, octa::Size) { return 0; }
virtual Size read_bytes(void *, Size) { return 0; }
virtual Size write_bytes(const void *, Size) { return 0; }
virtual int getchar() {
octa::byte c;
byte c;
return (read_bytes(&c, 1) == 1) ? c : -1;
}
virtual bool putchar(int c) {
octa::byte wc = octa::byte(c);
byte wc = byte(c);
return write_bytes(&wc, 1) == 1;
}
virtual bool write(const char *s) {
octa::Size len = strlen(s);
Size len = strlen(s);
return write_bytes(s, len) == len;
}
virtual bool write(const octa::String &s) {
virtual bool write(const String &s) {
return write_bytes(s.data(), s.size()) == s.size();
}
template<typename T> bool write(const T &v) {
return write(octa::to_string(v));
return write(to_string(v));
}
template<typename T, typename ...A>
@ -105,7 +105,7 @@ struct Stream {
return write(v) && write(args...);
}
virtual bool writeln(const octa::String &s) {
virtual bool writeln(const String &s) {
return write(s) && putchar('\n');
}
@ -125,19 +125,19 @@ struct Stream {
template<typename ...A>
bool writef(const char *fmt, const A &...args) {
char buf[512];
octa::Size need = octa::format(octa::detail::FormatOutRange<
sizeof(buf)>(buf), fmt, args...);
Size need = format(detail::FormatOutRange<sizeof(buf)>(buf),
fmt, args...);
if (need < sizeof(buf))
return write_bytes(buf, need) == need;
octa::String s;
String s;
s.reserve(need);
s[need] = '\0';
octa::format(s.iter(), fmt, args...);
format(s.iter(), fmt, args...);
return write_bytes(s.data(), need) == need;
}
template<typename ...A>
bool writef(const octa::String &fmt, const A &...args) {
bool writef(const String &fmt, const A &...args) {
return writef(fmt.data(), args...);
}
@ -147,14 +147,14 @@ struct Stream {
}
template<typename ...A>
bool writefln(const octa::String &fmt, const A &...args) {
bool writefln(const String &fmt, const A &...args) {
return writefln(fmt.data(), args...);
}
template<typename T = char>
StreamRange<T> iter();
template<typename T> octa::Size put(const T *v, octa::Size count) {
template<typename T> Size put(const T *v, Size count) {
return write_bytes(v, count * sizeof(T)) / sizeof(T);
}
@ -162,7 +162,7 @@ struct Stream {
return write_bytes(&v, sizeof(T)) == sizeof(T);
}
template<typename T> octa::Size get(T *v, octa::Size count) {
template<typename T> Size get(T *v, Size count) {
return read_bytes(v, count * sizeof(T)) / sizeof(T);
}
@ -178,7 +178,7 @@ struct Stream {
template<typename T>
struct StreamRange<T, true>: InputRange<
StreamRange<T>, octa::InputRangeTag, T, T, octa::Size, StreamOffset
StreamRange<T>, InputRangeTag, T, T, Size, StreamOffset
> {
StreamRange() = delete;
StreamRange(Stream &s): p_stream(&s), p_size(s.size()) {}
@ -205,17 +205,17 @@ struct StreamRange<T, true>: InputRange<
}
bool put(T val) {
octa::Size v = p_stream->write_bytes(&val, sizeof(T));
Size v = p_stream->write_bytes(&val, sizeof(T));
p_size += v;
return (v == sizeof(T));
}
octa::Size put_n(const T *p, octa::Size n) {
Size put_n(const T *p, Size n) {
return p_stream->put(p, n);
}
octa::Size copy(octa::RemoveCv<T> *p, octa::Size n = -1) {
if (n == octa::Size(-1)) {
Size copy(RemoveCv<T> *p, Size n = -1) {
if (n == Size(-1)) {
n = p_stream->size() / sizeof(T);
}
return p_stream->get(p, n);

View File

@ -14,9 +14,9 @@
#include "octa/vector.hh"
namespace octa {
static constexpr octa::Size npos = -1;
static constexpr Size npos = -1;
template<typename T, typename A = octa::Allocator<T>> class StringBase;
template<typename T, typename A = Allocator<T>> class StringBase;
template<typename T>
struct StringRangeBase: InputRange<
@ -24,7 +24,7 @@ struct StringRangeBase: InputRange<
> {
StringRangeBase() = delete;
StringRangeBase(T *beg, T *end): p_beg(beg), p_end(end) {}
StringRangeBase(T *beg, octa::Size n): p_beg(beg), p_end(beg + n) {}
StringRangeBase(T *beg, Size n): p_beg(beg), p_end(beg + n) {}
/* TODO: traits for utf-16/utf-32 string lengths, for now assume char */
StringRangeBase(T *beg): p_beg(beg), p_end(beg + strlen(beg)) {}
@ -32,8 +32,8 @@ struct StringRangeBase: InputRange<
StringRangeBase(const StringBase<T, A> &s): p_beg(s.data()),
p_end(s.data() + s.size()) {}
template<typename U, typename = octa::EnableIf<
octa::IsConvertible<U *, T *>::value
template<typename U, typename = EnableIf<
IsConvertible<U *, T *>::value
>> StringRangeBase(const StringRangeBase<U> &v):
p_beg(&v[0]), p_end(&v[v.size()]) {}
@ -59,8 +59,8 @@ struct StringRangeBase: InputRange<
}
bool push_front() { --p_beg; return true; }
octa::Size pop_front_n(octa::Size n) {
octa::Size olen = p_end - p_beg;
Size pop_front_n(Size n) {
Size olen = p_end - p_beg;
p_beg += n;
if (p_beg > p_end) {
p_beg = p_end;
@ -69,7 +69,7 @@ struct StringRangeBase: InputRange<
return n;
}
octa::Size push_front_n(octa::Size n) { p_beg -= n; return true; }
Size push_front_n(Size n) { p_beg -= n; return true; }
T &front() const { return *p_beg; }
@ -77,7 +77,7 @@ struct StringRangeBase: InputRange<
return p_beg == range.p_beg;
}
octa::Ptrdiff distance_front(const StringRangeBase &range) const {
Ptrdiff distance_front(const StringRangeBase &range) const {
return range.p_beg - p_beg;
}
@ -88,8 +88,8 @@ struct StringRangeBase: InputRange<
}
bool push_back() { ++p_end; return true; }
octa::Size pop_back_n(octa::Size n) {
octa::Size olen = p_end - p_beg;
Size pop_back_n(Size n) {
Size olen = p_end - p_beg;
p_end -= n;
if (p_end < p_beg) {
p_end = p_beg;
@ -98,7 +98,7 @@ struct StringRangeBase: InputRange<
return n;
}
octa::Size push_back_n(octa::Size n) { p_end += n; return true; }
Size push_back_n(Size n) { p_end += n; return true; }
T &back() const { return *(p_end - 1); }
@ -106,17 +106,17 @@ struct StringRangeBase: InputRange<
return p_end == range.p_end;
}
octa::Ptrdiff distance_back(const StringRangeBase &range) const {
Ptrdiff distance_back(const StringRangeBase &range) const {
return range.p_end - p_end;
}
octa::Size size() const { return p_end - p_beg; }
Size size() const { return p_end - p_beg; }
StringRangeBase slice(octa::Size start, octa::Size end) const {
StringRangeBase slice(Size start, Size end) const {
return StringRangeBase(p_beg + start, p_beg + end);
}
T &operator[](octa::Size i) const { return p_beg[i]; }
T &operator[](Size i) const { return p_beg[i]; }
bool put(T v) {
if (empty()) return false;
@ -128,7 +128,7 @@ struct StringRangeBase: InputRange<
T *data() { return p_beg; }
const T *data() const { return p_beg; }
octa::Size to_hash() const {
Size to_hash() const {
const T *d = data();
Size h = 5381, len = size();
for (Size i = 0; i < len; ++i)
@ -142,22 +142,22 @@ private:
template<typename T, typename A>
class StringBase {
octa::Vector<T, A> p_buf;
Vector<T, A> p_buf;
void terminate() {
if (p_buf.empty() || (p_buf.back() != '\0')) p_buf.push('\0');
}
public:
using Size = octa::Size;
using Difference = octa::Ptrdiff;
using Size = Size;
using Difference = Ptrdiff;
using Value = T;
using Reference = T &;
using ConstReference = const T &;
using Pointer = octa::AllocatorPointer<A>;
using ConstPointer = octa::AllocatorConstPointer<A>;
using Range = octa::StringRangeBase<T>;
using ConstRange = octa::StringRangeBase<const T>;
using Pointer = AllocatorPointer<A>;
using ConstPointer = AllocatorConstPointer<A>;
using Range = StringRangeBase<T>;
using ConstRange = StringRangeBase<const T>;
using Allocator = A;
StringBase(const A &a = A()): p_buf(1, '\0', a) {}
@ -168,11 +168,11 @@ public:
StringBase(const StringBase &s): p_buf(s.p_buf) {}
StringBase(const StringBase &s, const A &a):
p_buf(s.p_buf, a) {}
StringBase(StringBase &&s): p_buf(octa::move(s.p_buf)) {}
StringBase(StringBase &&s): p_buf(move(s.p_buf)) {}
StringBase(StringBase &&s, const A &a):
p_buf(octa::move(s.p_buf), a) {}
p_buf(move(s.p_buf), a) {}
StringBase(const StringBase &s, octa::Size pos, octa::Size len = npos,
StringBase(const StringBase &s, Size pos, Size len = npos,
const A &a = A()):
p_buf(s.p_buf.iter().slice(pos,
(len == npos) ? s.p_buf.size() : (pos + len)), a) {
@ -186,9 +186,9 @@ public:
StringBase(const Value *v, Size n, const A &a = A()):
p_buf(ConstRange(v, n), a) {}
template<typename R, typename = octa::EnableIf<
octa::IsInputRange<R>::value &&
octa::IsConvertible<RangeReference<R>, Value>::value
template<typename R, typename = EnableIf<
IsInputRange<R>::value &&
IsConvertible<RangeReference<R>, Value>::value
>> StringBase(R range, const A &a = A()): p_buf(range, a) {
terminate();
}
@ -200,37 +200,37 @@ public:
return *this;
}
StringBase &operator=(StringBase &&v) {
p_buf.operator=(octa::move(v));
p_buf.operator=(move(v));
return *this;
}
StringBase &operator=(const Value *v) {
p_buf = ConstRange(v, strlen(v) + 1);
return *this;
}
template<typename R, typename = octa::EnableIf<
octa::IsInputRange<R>::value &&
octa::IsConvertible<RangeReference<R>, Value>::value
template<typename R, typename = EnableIf<
IsInputRange<R>::value &&
IsConvertible<RangeReference<R>, Value>::value
>> StringBase &operator=(const R &r) {
p_buf = r;
terminate();
return *this;
}
void resize(octa::Size n, T v = T()) {
void resize(Size n, T v = T()) {
p_buf.pop();
p_buf.resize(n, v);
terminate();
}
void reserve(octa::Size n) {
void reserve(Size n) {
p_buf.reserve(n + 1);
}
T &operator[](octa::Size i) { return p_buf[i]; }
const T &operator[](octa::Size 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(octa::Size i) { return p_buf[i]; }
const T &at(octa::Size 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]; };
@ -241,15 +241,15 @@ public:
Value *data() { return p_buf.data(); }
const Value *data() const { return p_buf.data(); }
octa::Size size() const {
Size size() const {
return p_buf.size() - 1;
}
octa::Size capacity() const {
Size capacity() const {
return p_buf.capacity() - 1;
}
octa::Size length() const {
Size length() const {
/* TODO: unicode */
return size();
}
@ -267,7 +267,7 @@ public:
return *this;
}
StringBase &append(const StringBase &s, octa::Size idx, octa::Size len) {
StringBase &append(const StringBase &s, Size idx, Size len) {
p_buf.pop();
p_buf.insert_range(p_buf.size(), Range(&s[idx],
(len == npos) ? (s.size() - idx) : len));
@ -282,9 +282,9 @@ public:
return *this;
}
StringBase &append(octa::Size n, T c) {
StringBase &append(Size n, T c) {
p_buf.pop();
for (octa::Size i = 0; i < n; ++i) p_buf.push(c);
for (Size i = 0; i < n; ++i) p_buf.push(c);
p_buf.push('\0');
return *this;
}
@ -441,23 +441,21 @@ template<typename T> struct ToString {
template<typename U>
static String to_str(const U &v,
octa::EnableIf<octa::detail::ToStringTest<U>::value, bool> = true
EnableIf<detail::ToStringTest<U>::value, bool> = true
) {
return v.to_string();
}
template<typename U>
static String to_str(const U &v,
octa::EnableIf<!octa::detail::ToStringTest<U>::value &&
!octa::IsScalar<U>::value, bool> = true
EnableIf<!detail::ToStringTest<U>::value &&
!IsScalar<U>::value, bool> = true
) {
String ret("{");
ret += concat(octa::iter(v), ", ", ToString<
octa::RemoveCv<
octa::RemoveReference<
octa::RangeReference<decltype(octa::iter(v))>
>
>
RemoveCv<RemoveReference<
RangeReference<decltype(octa::iter(v))>
>>
>());
ret += "}";
return ret;
@ -465,8 +463,8 @@ template<typename T> struct ToString {
template<typename U>
static String to_str(const U &v,
octa::EnableIf<!octa::detail::ToStringTest<U>::value &&
octa::IsScalar<U>::value, bool> = true
EnableIf<!detail::ToStringTest<U>::value &&
IsScalar<U>::value, bool> = true
) {
return ToString<U>()(v);
}
@ -478,7 +476,7 @@ template<typename T> struct ToString {
namespace detail {
template<typename T>
void str_printf(octa::Vector<char> *s, const char *fmt, T v) {
void str_printf(Vector<char> *s, const char *fmt, T v) {
char buf[256];
int n = snprintf(buf, sizeof(buf), fmt, v);
s->clear();
@ -491,7 +489,7 @@ namespace detail {
n = 0;
*(s->data()) = '\0';
}
*((octa::Size *)s) = n + 1;
*((Size *)s) = n + 1;
}
}
@ -519,24 +517,24 @@ template<> struct ToString<T> { \
using Result = String; \
String operator()(T v) { \
String ret; \
octa::detail::str_printf((octa::Vector<char> *)&ret, fmt, v); \
detail::str_printf((Vector<char> *)&ret, fmt, v); \
return ret; \
} \
};
OCTA_TOSTR_NUM(octa::sbyte, "%d")
OCTA_TOSTR_NUM(sbyte, "%d")
OCTA_TOSTR_NUM(int, "%d")
OCTA_TOSTR_NUM(int &, "%d")
OCTA_TOSTR_NUM(long, "%ld")
OCTA_TOSTR_NUM(float, "%f")
OCTA_TOSTR_NUM(double, "%f")
OCTA_TOSTR_NUM(octa::byte, "%u")
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")
OCTA_TOSTR_NUM(byte, "%u")
OCTA_TOSTR_NUM(uint, "%u")
OCTA_TOSTR_NUM(ulong, "%lu")
OCTA_TOSTR_NUM(llong, "%lld")
OCTA_TOSTR_NUM(ullong, "%llu")
OCTA_TOSTR_NUM(ldouble, "%Lf")
#undef OCTA_TOSTR_NUM
@ -545,7 +543,7 @@ template<typename T> struct ToString<T *> {
using Result = String;
String operator()(Argument v) {
String ret;
octa::detail::str_printf((octa::Vector<char> *)&ret, "%p", v);
detail::str_printf((Vector<char> *)&ret, "%p", v);
return ret;
}
};
@ -566,8 +564,8 @@ template<> struct ToString<StringRange> {
}
};
template<typename T, typename U> struct ToString<octa::Pair<T, U>> {
using Argument = octa::Pair<T, U>;
template<typename T, typename U> struct ToString<Pair<T, U>> {
using Argument = Pair<T, U>;
using Result = String;
String operator()(const Argument &v) {
String ret("{");
@ -579,7 +577,7 @@ template<typename T, typename U> struct ToString<octa::Pair<T, U>> {
}
};
template<typename T, typename = decltype(ToString<T>()(octa::declval<T>()))>
template<typename T, typename = decltype(ToString<T>()(declval<T>()))>
String to_string(const T &v) {
return ToString<T>()(v);
}

View File

@ -28,25 +28,25 @@ template<typename> struct IsReference;
template<typename> struct IsTriviallyDefaultConstructible;
template<typename T>
using RemoveCv = typename octa::detail::RemoveCvBase<T>::Type;
using RemoveCv = typename detail::RemoveCvBase<T>::Type;
template<typename T>
using AddLvalueReference = typename octa::detail::AddLr<T>::Type;
using AddLvalueReference = typename detail::AddLr<T>::Type;
template<typename T>
using AddRvalueReference = typename octa::detail::AddRr<T>::Type;
using AddRvalueReference = typename detail::AddRr<T>::Type;
template<typename T>
using AddConst = typename octa::detail::AddConstBase<T>::Type;
using AddConst = typename detail::AddConstBase<T>::Type;
template<typename T>
using RemoveReference = typename octa::detail::RemoveReferenceBase<T>::Type;
using RemoveReference = typename detail::RemoveReferenceBase<T>::Type;
template<typename T>
using RemoveAllExtents = typename octa::detail::RemoveAllExtentsBase<T>::Type;
using RemoveAllExtents = typename detail::RemoveAllExtentsBase<T>::Type;
namespace detail {
template<typename T> octa::AddRvalueReference<T> declval_in();
template<typename T> AddRvalueReference<T> declval_in();
}
/* integral constant */
@ -75,17 +75,17 @@ namespace detail {
}
template<typename T>
struct IsVoid: octa::detail::IsVoidBase<RemoveCv<T>> {};
struct IsVoid: detail::IsVoidBase<RemoveCv<T>> {};
/* is null pointer */
namespace detail {
template<typename> struct IsNullPointerBase : False {};
template< > struct IsNullPointerBase<octa::Nullptr>: True {};
template<typename> struct IsNullPointerBase : False {};
template< > struct IsNullPointerBase<Nullptr>: True {};
}
template<typename T> struct IsNullPointer:
octa::detail::IsNullPointerBase<RemoveCv<T>> {};
detail::IsNullPointerBase<RemoveCv<T>> {};
/* is integer */
@ -98,21 +98,21 @@ namespace detail {
template<> struct IsIntegralBase<int >: True {};
template<> struct IsIntegralBase<long >: True {};
template<> struct IsIntegralBase<octa::sbyte >: True {};
template<> struct IsIntegralBase<octa::byte >: 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<sbyte >: True {};
template<> struct IsIntegralBase<byte >: True {};
template<> struct IsIntegralBase<ushort>: True {};
template<> struct IsIntegralBase<uint >: True {};
template<> struct IsIntegralBase<ulong >: True {};
template<> struct IsIntegralBase<llong >: True {};
template<> struct IsIntegralBase<ullong>: True {};
template<> struct IsIntegralBase<octa::Char16>: True {};
template<> struct IsIntegralBase<octa::Char32>: True {};
template<> struct IsIntegralBase<octa::Wchar >: True {};
template<> struct IsIntegralBase<Char16>: True {};
template<> struct IsIntegralBase<Char32>: True {};
template<> struct IsIntegralBase<Wchar >: True {};
}
template<typename T>
struct IsIntegral: octa::detail::IsIntegralBase<RemoveCv<T>> {};
struct IsIntegral: detail::IsIntegralBase<RemoveCv<T>> {};
/* is floating point */
@ -122,17 +122,17 @@ namespace detail {
template<> struct IsFloatingPointBase<float >: True {};
template<> struct IsFloatingPointBase<double>: True {};
template<> struct IsFloatingPointBase<octa::ldouble>: True {};
template<> struct IsFloatingPointBase<ldouble>: True {};
}
template<typename T>
struct IsFloatingPoint: octa::detail::IsFloatingPointBase<RemoveCv<T>> {};
struct IsFloatingPoint: detail::IsFloatingPointBase<RemoveCv<T>> {};
/* is array */
template<typename > struct IsArray : False {};
template<typename T > struct IsArray<T[] >: True {};
template<typename T, octa::Size N> struct IsArray<T[N]>: True {};
template<typename > struct IsArray : False {};
template<typename T > struct IsArray<T[] >: True {};
template<typename T, Size N> struct IsArray<T[N]>: True {};
/* is pointer */
@ -142,7 +142,7 @@ namespace detail {
}
template<typename T>
struct IsPointer: octa::detail::IsPointerBase<RemoveCv<T>> {};
struct IsPointer: detail::IsPointerBase<RemoveCv<T>> {};
/* is lvalue reference */
@ -178,11 +178,11 @@ namespace detail {
template<typename T> T &function_source(int);
template<typename T> FunctionTestDummy function_source(...);
template<typename T, bool = octa::IsClass<T>::value ||
octa::IsUnion<T>::value ||
octa::IsVoid<T>::value ||
octa::IsReference<T>::value ||
octa::IsNullPointer<T>::value
template<typename T, bool = IsClass<T>::value ||
IsUnion<T>::value ||
IsVoid<T>::value ||
IsReference<T>::value ||
IsNullPointer<T>::value
> struct IsFunctionBase: IntegralConstant<bool,
sizeof(function_test<T>(function_source<T>(0))) == 1
> {};
@ -190,7 +190,7 @@ namespace detail {
template<typename T> struct IsFunctionBase<T, true>: False {};
} /* namespace detail */
template<typename T> struct IsFunction: octa::detail::IsFunctionBase<T> {};
template<typename T> struct IsFunction: detail::IsFunctionBase<T> {};
/* is arithmetic */
@ -221,7 +221,7 @@ namespace detail {
}
template<typename T>
struct IsMemberPointer: octa::detail::IsMemberPointerBase<RemoveCv<T>> {};
struct IsMemberPointer: detail::IsMemberPointerBase<RemoveCv<T>> {};
/* is pointer to member object */
@ -231,12 +231,12 @@ namespace detail {
template<typename T, typename U>
struct IsMemberObjectPointerBase<T U::*>: IntegralConstant<bool,
!octa::IsFunction<T>::value
!IsFunction<T>::value
> {};
}
template<typename T> struct IsMemberObjectPointer:
octa::detail::IsMemberObjectPointerBase<RemoveCv<T>> {};
detail::IsMemberObjectPointerBase<RemoveCv<T>> {};
/* is pointer to member function */
@ -246,12 +246,12 @@ namespace detail {
template<typename T, typename U>
struct IsMemberFunctionPointerBase<T U::*>: IntegralConstant<bool,
octa::IsFunction<T>::value
IsFunction<T>::value
> {};
}
template<typename T> struct IsMemberFunctionPointer:
octa::detail::IsMemberFunctionPointerBase<RemoveCv<T>> {};
detail::IsMemberFunctionPointerBase<RemoveCv<T>> {};
/* is reference */
@ -308,11 +308,11 @@ namespace detail {
struct IsSignedBase: IntegralConstant<bool, T(-1) < T(0)> {};
}
template<typename T, bool = octa::IsArithmetic<T>::value>
template<typename T, bool = IsArithmetic<T>::value>
struct IsSigned: False {};
template<typename T>
struct IsSigned<T, true>: octa::detail::IsSignedBase<T> {};
struct IsSigned<T, true>: detail::IsSignedBase<T> {};
/* is unsigned */
@ -321,11 +321,11 @@ namespace detail {
struct IsUnsignedBase: IntegralConstant<bool, T(0) < T(-1)> {};
}
template<typename T, bool = octa::IsArithmetic<T>::value>
template<typename T, bool = IsArithmetic<T>::value>
struct IsUnsigned: False {};
template<typename T>
struct IsUnsigned<T, true>: octa::detail::IsUnsignedBase<T> {};
struct IsUnsigned<T, true>: detail::IsUnsignedBase<T> {};
/* is standard layout */
@ -359,7 +359,7 @@ struct HasVirtualDestructor: IntegralConstant<bool,
/* is constructible */
namespace detail {
#define OCTA_MOVE(v) static_cast<octa::RemoveReference<decltype(v)> &&>(v)
#define OCTA_MOVE(v) static_cast<RemoveReference<decltype(v)> &&>(v)
template<typename, typename T> struct Select2nd { using Type = T; };
struct Any { Any(...); };
@ -383,7 +383,7 @@ namespace detail {
/* scalars are default constructible, refs are not */
template<typename T>
struct CtibleCore<true, T>: octa::IsScalar<T> {};
struct CtibleCore<true, T>: IsScalar<T> {};
/* scalars and references are constructible from one arg if
* implicitly convertible to scalar or reference */
@ -405,7 +405,7 @@ namespace detail {
/* treat scalars and refs separately */
template<bool, typename T, typename ...A>
struct CtibleVoidCheck: CtibleCore<
(octa::IsScalar<T>::value || octa::IsReference<T>::value), T, A...
(IsScalar<T>::value || IsReference<T>::value), T, A...
> {};
/* if any of T or A is void, IsConstructible should be false */
@ -418,23 +418,23 @@ namespace detail {
template<typename T, typename ...A>
struct CtibleContainsVoid<T, A...> {
static constexpr bool value = octa::IsVoid<T>::value
static constexpr bool value = IsVoid<T>::value
|| CtibleContainsVoid<A...>::value;
};
/* entry point */
template<typename T, typename ...A>
struct Ctible: CtibleVoidCheck<
CtibleContainsVoid<T, A...>::value || octa::IsAbstract<T>::value,
CtibleContainsVoid<T, A...>::value || IsAbstract<T>::value,
T, A...
> {};
/* array types are default constructible if their element type is */
template<typename T, octa::Size N>
struct CtibleCore<false, T[N]>: Ctible<octa::RemoveAllExtents<T>> {};
template<typename T, Size N>
struct CtibleCore<false, T[N]>: Ctible<RemoveAllExtents<T>> {};
/* otherwise array types are not constructible by this syntax */
template<typename T, octa::Size N, typename ...A>
template<typename T, Size N, typename ...A>
struct CtibleCore<false, T[N], A...>: False {};
/* incomplete array types are not constructible */
@ -443,7 +443,7 @@ namespace detail {
} /* namespace detail */
template<typename T, typename ...A>
struct IsConstructible: octa::detail::Ctible<T, A...> {};
struct IsConstructible: detail::Ctible<T, A...> {};
/* is default constructible */
@ -464,14 +464,14 @@ template<typename T> struct IsMoveConstructible: IsConstructible<T,
/* is assignable */
namespace detail {
template<typename T, typename U> typename octa::detail::Select2nd<
template<typename T, typename U> typename detail::Select2nd<
decltype((declval_in<T>() = declval_in<U>())), True
>::Type assign_test(T &&, U &&);
template<typename T> False assign_test(Any, T &&);
template<typename T, typename U, bool = octa::IsVoid<T>::value ||
octa::IsVoid<U>::value
template<typename T, typename U, bool = IsVoid<T>::value ||
IsVoid<U>::value
> struct IsAssignableBase: CommonTypeBase<
decltype(assign_test(declval_in<T>(), declval_in<U>()))
>::Type {};
@ -481,7 +481,7 @@ namespace detail {
} /* namespace detail */
template<typename T, typename U>
struct IsAssignable: octa::detail::IsAssignableBase<T, U> {};
struct IsAssignable: detail::IsAssignableBase<T, U> {};
/* is copy assignable */
@ -504,7 +504,7 @@ namespace detail {
template<typename T> struct IsDestructorWellformed {
template<typename TT> static char test(typename IsDtibleApply<
decltype(octa::detail::declval_in<TT &>().~TT())
decltype(detail::declval_in<TT &>().~TT())
>::Type);
template<typename TT> static int test(...);
@ -515,8 +515,8 @@ namespace detail {
template<typename, bool> struct DtibleImpl;
template<typename T>
struct DtibleImpl<T, false>: octa::IntegralConstant<bool,
IsDestructorWellformed<octa::RemoveAllExtents<T>>::value
struct DtibleImpl<T, false>: IntegralConstant<bool,
IsDestructorWellformed<RemoveAllExtents<T>>::value
> {};
template<typename T>
@ -525,13 +525,13 @@ namespace detail {
template<typename T, bool> struct DtibleFalse;
template<typename T> struct DtibleFalse<T, false>
: DtibleImpl<T, octa::IsReference<T>::value> {};
: DtibleImpl<T, IsReference<T>::value> {};
template<typename T> struct DtibleFalse<T, true>: False {};
} /* namespace detail */
template<typename T>
struct IsDestructible: octa::detail::DtibleFalse<T, IsFunction<T>::value> {};
struct IsDestructible: detail::DtibleFalse<T, IsFunction<T>::value> {};
template<typename T> struct IsDestructible<T[]>: False {};
template< > struct IsDestructible<void>: False {};
@ -634,10 +634,10 @@ struct IsBaseOf: IntegralConstant<bool, __is_base_of(B, D)> {};
/* is convertible */
namespace detail {
template<typename F, typename T, bool = octa::IsVoid<F>::value
|| octa::IsFunction<T>::value || octa::IsArray<T>::value
template<typename F, typename T, bool = IsVoid<F>::value
|| IsFunction<T>::value || IsArray<T>::value
> struct IsConvertibleBase {
using Type = typename octa::IsVoid<T>::Type;
using Type = typename IsVoid<T>::Type;
};
template<typename F, typename T>
@ -646,16 +646,16 @@ namespace detail {
template<typename FF, typename TT,
typename = decltype(test_f<TT>(declval_in<FF>()))
> static octa::True test(int);
> static True test(int);
template<typename, typename> static octa::False test(...);
template<typename, typename> static False test(...);
using Type = decltype(test<F, T>(0));
};
}
template<typename F, typename T>
struct IsConvertible: octa::detail::IsConvertibleBase<F, T>::Type {};
struct IsConvertible: detail::IsConvertibleBase<F, T>::Type {};
/* type equality */
@ -664,30 +664,30 @@ template<typename T > struct IsSame<T, T>: True {};
/* extent */
template<typename T, octa::uint I = 0>
struct Extent: IntegralConstant<octa::Size, 0> {};
template<typename T, uint I = 0>
struct Extent: IntegralConstant<Size, 0> {};
template<typename T>
struct Extent<T[], 0>: IntegralConstant<octa::Size, 0> {};
struct Extent<T[], 0>: IntegralConstant<Size, 0> {};
template<typename T, octa::uint I>
struct Extent<T[], I>: IntegralConstant<octa::Size, Extent<T, I - 1>::value> {};
template<typename T, uint I>
struct Extent<T[], I>: IntegralConstant<Size, Extent<T, I - 1>::value> {};
template<typename T, octa::Size N>
struct Extent<T[N], 0>: IntegralConstant<octa::Size, N> {};
template<typename T, Size N>
struct Extent<T[N], 0>: IntegralConstant<Size, N> {};
template<typename T, octa::Size N, octa::uint I>
struct Extent<T[N], I>: IntegralConstant<octa::Size, Extent<T, I - 1>::value> {};
template<typename T, Size N, uint I>
struct Extent<T[N], I>: IntegralConstant<Size, Extent<T, I - 1>::value> {};
/* rank */
template<typename T> struct Rank: IntegralConstant<octa::Size, 0> {};
template<typename T> struct Rank: IntegralConstant<Size, 0> {};
template<typename T>
struct Rank<T[]>: IntegralConstant<octa::Size, Rank<T>::value + 1> {};
struct Rank<T[]>: IntegralConstant<Size, Rank<T>::value + 1> {};
template<typename T, octa::Size N>
struct Rank<T[N]>: IntegralConstant<octa::Size, Rank<T>::value + 1> {};
template<typename T, Size N>
struct Rank<T[N]>: IntegralConstant<Size, Rank<T>::value + 1> {};
/* remove const, volatile, cv */
@ -704,22 +704,22 @@ namespace detail {
}
template<typename T>
using RemoveConst = typename octa::detail::RemoveConstBase<T>::Type;
using RemoveConst = typename detail::RemoveConstBase<T>::Type;
template<typename T>
using RemoveVolatile = typename octa::detail::RemoveVolatileBase<T>::Type;
using RemoveVolatile = typename detail::RemoveVolatileBase<T>::Type;
namespace detail {
template<typename T>
struct RemoveCvBase {
using Type = octa::RemoveVolatile<octa::RemoveConst<T>>;
using Type = RemoveVolatile<RemoveConst<T>>;
};
}
/* add const, volatile, cv */
namespace detail {
template<typename T, bool = octa::IsReference<T>::value
|| octa::IsFunction<T>::value || octa::IsConst<T>::value>
template<typename T, bool = IsReference<T>::value
|| IsFunction<T>::value || IsConst<T>::value>
struct AddConstCore { using Type = T; };
template<typename T> struct AddConstCore<T, false> {
@ -730,8 +730,8 @@ namespace detail {
using Type = typename AddConstCore<T>::Type;
};
template<typename T, bool = octa::IsReference<T>::value
|| octa::IsFunction<T>::value || octa::IsVolatile<T>::value>
template<typename T, bool = IsReference<T>::value
|| IsFunction<T>::value || IsVolatile<T>::value>
struct AddVolatileCore { using Type = T; };
template<typename T> struct AddVolatileCore<T, false> {
@ -744,17 +744,17 @@ namespace detail {
}
template<typename T>
using AddVolatile = typename octa::detail::AddVolatileBase<T>::Type;
using AddVolatile = typename detail::AddVolatileBase<T>::Type;
namespace detail {
template<typename T>
struct AddCvBase {
using Type = octa::AddConst<octa::AddVolatile<T>>;
using Type = AddConst<AddVolatile<T>>;
};
}
template<typename T>
using AddCv = typename octa::detail::AddCvBase<T>::Type;
using AddCv = typename detail::AddCvBase<T>::Type;
/* remove reference */
@ -783,18 +783,18 @@ namespace detail {
}
template<typename T>
using RemovePointer = typename octa::detail::RemovePointerBase<T>::Type;
using RemovePointer = typename detail::RemovePointerBase<T>::Type;
/* add pointer */
namespace detail {
template<typename T> struct AddPointerBase {
using Type = octa::RemoveReference<T> *;
using Type = RemoveReference<T> *;
};
}
template<typename T>
using AddPointer = typename octa::detail::AddPointerBase<T>::Type;
using AddPointer = typename detail::AddPointerBase<T>::Type;
/* add lvalue reference */
@ -843,12 +843,12 @@ namespace detail {
struct RemoveExtentBase { using Type = T; };
template<typename T>
struct RemoveExtentBase<T[ ]> { using Type = T; };
template<typename T, octa::Size N>
template<typename T, Size N>
struct RemoveExtentBase<T[N]> { using Type = T; };
}
template<typename T>
using RemoveExtent = typename octa::detail::RemoveExtentBase<T>::Type;
using RemoveExtent = typename detail::RemoveExtentBase<T>::Type;
/* remove all extents */
@ -859,7 +859,7 @@ namespace detail {
using Type = RemoveAllExtentsBase<T>;
};
template<typename T, octa::Size N> struct RemoveAllExtentsBase<T[N]> {
template<typename T, Size N> struct RemoveAllExtentsBase<T[N]> {
using Type = RemoveAllExtentsBase<T>;
};
}
@ -884,34 +884,34 @@ namespace detail {
~TlNat() = delete;
};
using Stypes = TypeList<octa::sbyte,
using Stypes = TypeList<sbyte,
TypeList<short,
TypeList<int,
TypeList<long,
TypeList<octa::llong, TlNat>>>>>;
TypeList<llong, TlNat>>>>>;
using Utypes = TypeList<octa::byte,
TypeList<octa::ushort,
TypeList<octa::uint,
TypeList<octa::ulong,
TypeList<octa::ullong, TlNat>>>>>;
using Utypes = TypeList<byte,
TypeList<ushort,
TypeList<uint,
TypeList<ulong,
TypeList<ullong, TlNat>>>>>;
template<typename T, octa::Size N, bool = (N <= sizeof(typename T::First))>
template<typename T, Size N, bool = (N <= sizeof(typename T::First))>
struct TypeFindFirst;
template<typename T, typename U, octa::Size N>
template<typename T, typename U, Size N>
struct TypeFindFirst<TypeList<T, U>, N, true> {
using Type = T;
};
template<typename T, typename U, octa::Size N>
template<typename T, typename U, Size N>
struct TypeFindFirst<TypeList<T, U>, N, false> {
using Type = typename TypeFindFirst<U, N>::Type;
};
template<typename T, typename U,
bool = octa::IsConst<octa::RemoveReference<T>>::value,
bool = octa::IsVolatile<octa::RemoveReference<T>>::value
bool = IsConst<RemoveReference<T>>::value,
bool = IsVolatile<RemoveReference<T>>::value
> struct ApplyCv {
using Type = U;
};
@ -946,67 +946,67 @@ namespace detail {
using Type = const volatile U &;
};
template<typename T, bool = octa::IsIntegral<T>::value ||
octa::IsEnum<T>::value>
struct MakeSigned {};
template<typename T, bool = IsIntegral<T>::value ||
IsEnum<T>::value>
struct MakeSignedCore {};
template<typename T, bool = octa::IsIntegral<T>::value ||
octa::IsEnum<T>::value>
struct MakeUnsigned {};
template<typename T, bool = IsIntegral<T>::value ||
IsEnum<T>::value>
struct MakeUnsignedCore {};
template<typename T>
struct MakeSigned<T, true> {
struct MakeSignedCore<T, true> {
using Type = typename TypeFindFirst<Stypes, sizeof(T)>::Type;
};
template<typename T>
struct MakeUnsigned<T, true> {
struct MakeUnsignedCore<T, true> {
using Type = typename TypeFindFirst<Utypes, sizeof(T)>::Type;
};
template<> struct MakeSigned<bool , true> {};
template<> struct MakeSigned<short , true> { using Type = short; };
template<> struct MakeSigned<int , true> { using Type = int; };
template<> struct MakeSigned<long , true> { using Type = long; };
template<> struct MakeSignedCore<bool , true> {};
template<> struct MakeSignedCore<short , true> { using Type = short; };
template<> struct MakeSignedCore<int , true> { using Type = int; };
template<> struct MakeSignedCore<long , true> { using Type = long; };
template<> struct MakeSigned<octa::sbyte , true> { using Type = octa::sbyte; };
template<> struct MakeSigned<octa::byte , true> { using Type = octa::sbyte; };
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 MakeSignedCore<sbyte , true> { using Type = sbyte; };
template<> struct MakeSignedCore<byte , true> { using Type = sbyte; };
template<> struct MakeSignedCore<ushort, true> { using Type = short; };
template<> struct MakeSignedCore<uint , true> { using Type = int; };
template<> struct MakeSignedCore<ulong , true> { using Type = long; };
template<> struct MakeSignedCore<llong , true> { using Type = llong; };
template<> struct MakeSignedCore<ullong, true> { using Type = llong; };
template<> struct MakeUnsigned<bool , true> {};
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 MakeUnsignedCore<bool , true> {};
template<> struct MakeUnsignedCore<short , true> { using Type = ushort; };
template<> struct MakeUnsignedCore<int , true> { using Type = uint; };
template<> struct MakeUnsignedCore<long , true> { using Type = ulong; };
template<> struct MakeUnsigned<octa::sbyte , true> { using Type = octa::byte; };
template<> struct MakeUnsigned<octa::byte , true> { using Type = octa::byte; };
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<> struct MakeUnsignedCore<sbyte , true> { using Type = byte; };
template<> struct MakeUnsignedCore<byte , true> { using Type = byte; };
template<> struct MakeUnsignedCore<ushort, true> { using Type = ushort; };
template<> struct MakeUnsignedCore<uint , true> { using Type = uint; };
template<> struct MakeUnsignedCore<ulong , true> { using Type = ulong; };
template<> struct MakeUnsignedCore<llong , true> { using Type = ullong; };
template<> struct MakeUnsignedCore<ullong, true> { using Type = ullong; };
template<typename T> struct MakeSignedBase {
using Type = typename ApplyCv<T,
typename MakeSigned<octa::RemoveCv<T>>::Type
typename MakeSignedCore<RemoveCv<T>>::Type
>::Type;
};
template<typename T> struct MakeUnsignedBase {
using Type = typename ApplyCv<T,
typename MakeUnsigned<octa::RemoveCv<T>>::Type
typename MakeUnsignedCore<RemoveCv<T>>::Type
>::Type;
};
} /* namespace detail */
template<typename T>
using MakeSigned = typename octa::detail::MakeSignedBase<T>::Type;
using MakeSigned = typename detail::MakeSignedBase<T>::Type;
template<typename T>
using MakeUnsigned = typename octa::detail::MakeUnsignedBase<T>::Type;
using MakeUnsigned = typename detail::MakeUnsignedBase<T>::Type;
/* conditional */
@ -1023,7 +1023,7 @@ namespace detail {
}
template<bool _cond, typename T, typename U>
using Conditional = typename octa::detail::ConditionalBase<_cond, T, U>::Type;
using Conditional = typename detail::ConditionalBase<_cond, T, U>::Type;
/* result of call at compile time */
@ -1062,16 +1062,16 @@ namespace detail {
struct ResultOfCore {};
template<typename F, typename ...A>
struct ResultOfCore<F(A...), decltype(void(rof_invoke(
octa::detail::declval_in<F>(), octa::detail::declval_in<A>()...)))> {
using type = decltype(rof_invoke(octa::detail::declval_in<F>(),
octa::detail::declval_in<A>()...));
detail::declval_in<F>(), detail::declval_in<A>()...)))> {
using type = decltype(rof_invoke(detail::declval_in<F>(),
detail::declval_in<A>()...));
};
template<typename T> struct ResultOfBase: ResultOfCore<T> {};
} /* namespace detail */
template<typename T>
using ResultOf = typename octa::detail::ResultOfBase<T>::Type;
using ResultOf = typename detail::ResultOfBase<T>::Type;
/* enable if */
@ -1082,7 +1082,7 @@ namespace detail {
}
template<bool B, typename T = void>
using EnableIf = typename octa::detail::EnableIfBase<B, T>::Type;
using EnableIf = typename detail::EnableIfBase<B, T>::Type;
/* decay */
@ -1090,18 +1090,18 @@ namespace detail {
template<typename T>
struct DecayBase {
private:
using U = octa::RemoveReference<T>;
using U = RemoveReference<T>;
public:
using Type = octa::Conditional<octa::IsArray<U>::value,
octa::RemoveExtent<U> *,
octa::Conditional<octa::IsFunction<U>::value,
octa::AddPointer<U>, octa::RemoveCv<U>>
using Type = Conditional<IsArray<U>::value,
RemoveExtent<U> *,
Conditional<IsFunction<U>::value,
AddPointer<U>, RemoveCv<U>>
>;
};
}
template<typename T>
using Decay = typename octa::detail::DecayBase<T>::Type;
using Decay = typename detail::DecayBase<T>::Type;
/* common type */
@ -1113,8 +1113,8 @@ namespace detail {
};
template<typename T, typename U> struct CommonTypeBase<T, U> {
using Type = Decay<decltype(true ? octa::detail::declval_in<T>()
: octa::detail::declval_in<U>())>;
using Type = Decay<decltype(true ? detail::declval_in<T>()
: detail::declval_in<U>())>;
};
template<typename T, typename U, typename ...V>
@ -1126,61 +1126,61 @@ namespace detail {
}
template<typename T, typename U, typename ...V>
using CommonType = typename octa::detail::CommonTypeBase<T, U, V...>::Type;
using CommonType = typename detail::CommonTypeBase<T, U, V...>::Type;
/* aligned storage */
namespace detail {
template<octa::Size N> struct AlignedTest {
template<Size N> struct AlignedTest {
union Type {
octa::byte data[N];
octa::MaxAlign align;
byte data[N];
MaxAlign align;
};
};
template<octa::Size N, octa::Size A> struct AlignedStorageBase {
template<Size N, Size A> struct AlignedStorageBase {
struct Type {
alignas(A) octa::byte data[N];
alignas(A) byte data[N];
};
};
}
template<octa::Size N, octa::Size A
= alignof(typename octa::detail::AlignedTest<N>::Type)
> using AlignedStorage = typename octa::detail::AlignedStorageBase<N, A>::Type;
template<Size N, Size A
= alignof(typename detail::AlignedTest<N>::Type)
> using AlignedStorage = typename detail::AlignedStorageBase<N, A>::Type;
/* aligned union */
namespace detail {
template<octa::Size ...N> struct AlignMax;
template<Size ...N> struct AlignMax;
template<octa::Size N> struct AlignMax<N> {
static constexpr octa::Size value = N;
template<Size N> struct AlignMax<N> {
static constexpr Size value = N;
};
template<octa::Size N1, octa::Size N2> struct AlignMax<N1, N2> {
static constexpr octa::Size value = (N1 > N2) ? N1 : N2;
template<Size N1, Size N2> struct AlignMax<N1, N2> {
static constexpr Size value = (N1 > N2) ? N1 : N2;
};
template<octa::Size N1, octa::Size N2, octa::Size ...N>
template<Size N1, Size N2, Size ...N>
struct AlignMax<N1, N2, N...> {
static constexpr octa::Size value
static constexpr Size value
= AlignMax<AlignMax<N1, N2>::value, N...>::value;
};
template<octa::Size N, typename ...T> struct AlignedUnionBase {
static constexpr octa::Size alignment_value
template<Size N, typename ...T> struct AlignedUnionBase {
static constexpr Size alignment_value
= AlignMax<alignof(T)...>::value;
struct type {
alignas(alignment_value) octa::byte data[AlignMax<N,
alignas(alignment_value) byte data[AlignMax<N,
sizeof(T)...>::value];
};
};
} /* namespace detail */
template<octa::Size N, typename ...T>
using AlignedUnion = typename octa::detail::AlignedUnionBase<N, T...>::Type;
template<Size N, typename ...T>
using AlignedUnion = typename detail::AlignedUnionBase<N, T...>::Type;
/* underlying type */
@ -1192,7 +1192,7 @@ namespace detail {
}
template<typename T>
using UnderlyingType = typename octa::detail::UnderlyingTypeBase<T>::Type;
using UnderlyingType = typename detail::UnderlyingTypeBase<T>::Type;
} /* namespace octa */
#endif

View File

@ -56,26 +56,26 @@ namespace detail {
};
template<typename T> inline void swap(T &a, T &b, EnableIf<
octa::detail::SwapTest<T>::value, bool
detail::SwapTest<T>::value, bool
> = true) {
a.swap(b);
}
template<typename T> inline void swap(T &a, T &b, EnableIf<
!octa::detail::SwapTest<T>::value, bool
!detail::SwapTest<T>::value, bool
> = true) {
T c(octa::move(a));
a = octa::move(b);
b = octa::move(c);
T c(move(a));
a = move(b);
b = move(c);
}
}
template<typename T> void swap(T &a, T &b) {
octa::detail::swap(a, b);
detail::swap(a, b);
}
template<typename T, octa::Size N> void swap(T (&a)[N], T (&b)[N]) {
for (octa::Size i = 0; i < N; ++i) {
template<typename T, Size N> void swap(T (&a)[N], T (&b)[N]) {
for (Size i = 0; i < N; ++i) {
octa::swap(a[i], b[i]);
}
}
@ -97,14 +97,14 @@ struct Pair {
template<typename TT, typename UU>
Pair(TT &&x, UU &&y):
first(octa::forward<TT>(x)), second(octa::forward<UU>(y)) {}
first(forward<TT>(x)), second(forward<UU>(y)) {}
template<typename TT, typename UU>
Pair(const Pair<TT, UU> &v): first(v.first), second(v.second) {}
template<typename TT, typename UU>
Pair(Pair<TT, UU> &&v):
first(octa::move(v.first)), second(octa::move(v.second)) {}
first(move(v.first)), second(move(v.second)) {}
Pair &operator=(const Pair &v) {
first = v.first;
@ -120,21 +120,21 @@ struct Pair {
}
Pair &operator=(Pair &&v) {
first = octa::move(v.first);
second = octa::move(v.second);
first = move(v.first);
second = move(v.second);
return *this;
}
template<typename TT, typename UU>
Pair &operator=(Pair<TT, UU> &&v) {
first = octa::forward<TT>(v.first);
second = octa::forward<UU>(v.second);
first = forward<TT>(v.first);
second = forward<UU>(v.second);
return *this;
}
void swap(Pair &v) {
octa::swap(first, v.first);
octa::swap(second, v.second);
swap(first, v.first);
swap(second, v.second);
}
};
@ -153,24 +153,24 @@ namespace detail {
template<typename T>
struct MakePairRet {
using Type = typename octa::detail::MakePairRetBase<octa::Decay<T>>::Type;
using Type = typename detail::MakePairRetBase<Decay<T>>::Type;
};
} /* namespace detail */
template<typename T, typename U>
Pair<typename octa::detail::MakePairRet<T>::Type,
typename octa::detail::MakePairRet<U>::Type
Pair<typename detail::MakePairRet<T>::Type,
typename detail::MakePairRet<U>::Type
> make_pair(T &&a, U &&b) {
return Pair<typename octa::detail::MakePairRet<T>::Type,
typename octa::detail::MakePairRet<U>::Type
return Pair<typename detail::MakePairRet<T>::Type,
typename detail::MakePairRet<U>::Type
>(forward<T>(a), forward<U>(b));;
}
namespace detail {
template<typename T, typename U,
bool = octa::IsSame<octa::RemoveCv<T>, octa::RemoveCv<U>>::value,
bool = octa::IsEmpty<T>::value,
bool = octa::IsEmpty<U>::value
bool = IsSame<RemoveCv<T>, RemoveCv<U>>::value,
bool = IsEmpty<T>::value,
bool = IsEmpty<U>::value
> struct CompressedPairSwitch;
/* neither empty */
@ -193,7 +193,7 @@ namespace detail {
template<typename T, typename U>
struct CompressedPairSwitch<T, U, true, true, true> { enum { value = 1 }; };
template<typename T, typename U, octa::Size = CompressedPairSwitch<T, U>::value>
template<typename T, typename U, Size = CompressedPairSwitch<T, U>::value>
struct CompressedPairBase;
template<typename T, typename U>
@ -202,8 +202,8 @@ namespace detail {
U p_second;
template<typename TT, typename UU>
CompressedPairBase(TT &&a, UU &&b): p_first(octa::forward<TT>(a)),
p_second(octa::forward<UU>(b)) {}
CompressedPairBase(TT &&a, UU &&b): p_first(forward<TT>(a)),
p_second(forward<UU>(b)) {}
T &first() { return p_first; }
const T &first() const { return p_first; }
@ -222,8 +222,8 @@ namespace detail {
U p_second;
template<typename TT, typename UU>
CompressedPairBase(TT &&a, UU &&b): T(octa::forward<TT>(a)),
p_second(octa::forward<UU>(b)) {}
CompressedPairBase(TT &&a, UU &&b): T(forward<TT>(a)),
p_second(forward<UU>(b)) {}
T &first() { return *this; }
const T &first() const { return *this; }
@ -241,8 +241,8 @@ namespace detail {
T p_first;
template<typename TT, typename UU>
CompressedPairBase(TT &&a, UU &&b): U(octa::forward<UU>(b)),
p_first(octa::forward<TT>(a)) {}
CompressedPairBase(TT &&a, UU &&b): U(forward<UU>(b)),
p_first(forward<TT>(a)) {}
T &first() { return p_first; }
const T &first() const { return p_first; }
@ -258,8 +258,8 @@ namespace detail {
template<typename T, typename U>
struct CompressedPairBase<T, U, 3>: T, U {
template<typename TT, typename UU>
CompressedPairBase(TT &&a, UU &&b): T(octa::forward<TT>(a)),
U(octa::forward<UU>(b)) {}
CompressedPairBase(TT &&a, UU &&b): T(forward<TT>(a)),
U(forward<UU>(b)) {}
T &first() { return *this; }
const T &first() const { return *this; }
@ -275,8 +275,8 @@ namespace detail {
using Base = CompressedPairBase<T, U>;
template<typename TT, typename UU>
CompressedPair(TT &&a, UU &&b): Base(octa::forward<TT>(a),
octa::forward<UU>(b)) {}
CompressedPair(TT &&a, UU &&b): Base(forward<TT>(a),
forward<UU>(b)) {}
T &first() { return Base::first(); }
const T &first() const { return Base::first(); }

View File

@ -21,28 +21,28 @@ namespace octa {
namespace detail {
} /* namespace detail */
template<typename T, typename A = octa::Allocator<T>>
template<typename T, typename A = Allocator<T>>
class Vector {
using VecPair = octa::detail::CompressedPair<octa::AllocatorPointer<A>, A>;
using VecPair = detail::CompressedPair<AllocatorPointer<A>, A>;
octa::Size p_len, p_cap;
Size p_len, p_cap;
VecPair p_buf;
void insert_base(octa::Size idx, octa::Size n) {
void insert_base(Size idx, Size n) {
if (p_len + n > p_cap) reserve(p_len + n);
p_len += n;
for (octa::Size i = p_len - 1; i > idx + n - 1; --i) {
p_buf.first()[i] = octa::move(p_buf.first()[i - n]);
for (Size i = p_len - 1; i > idx + n - 1; --i) {
p_buf.first()[i] = move(p_buf.first()[i - n]);
}
}
template<typename R>
void ctor_from_range(R &range, octa::EnableIf<
octa::IsFiniteRandomAccessRange<R>::value &&
octa::IsPod<T>::value &&
octa::IsSame<T, octa::RemoveCv<octa::RangeValue<R>>>::value, bool
void ctor_from_range(R &range, EnableIf<
IsFiniteRandomAccessRange<R>::value &&
IsPod<T>::value &&
IsSame<T, RemoveCv<RangeValue<R>>>::value, bool
> = true) {
octa::RangeSize<R> l = range.size();
RangeSize<R> l = range.size();
reserve(l);
p_len = l;
range.copy(p_buf.first(), l);
@ -50,58 +50,57 @@ class Vector {
template<typename R>
void ctor_from_range(R &range, EnableIf<
!octa::IsFiniteRandomAccessRange<R>::value ||
!octa::IsPod<T>::value ||
!octa::IsSame<T, octa::RemoveCv<octa::RangeValue<R>>>::value, bool
!IsFiniteRandomAccessRange<R>::value ||
!IsPod<T>::value ||
!IsSame<T, RemoveCv<RangeValue<R>>>::value, bool
> = true) {
octa::Size i = 0;
Size i = 0;
for (; !range.empty(); range.pop_front()) {
reserve(i + 1);
octa::allocator_construct(p_buf.second(),
&p_buf.first()[i], range.front());
allocator_construct(p_buf.second(), &p_buf.first()[i],
range.front());
++i;
p_len = i;
}
}
void copy_contents(const Vector &v) {
if (octa::IsPod<T>()) {
if (IsPod<T>()) {
memcpy(p_buf.first(), v.p_buf.first(), p_len * sizeof(T));
} else {
Pointer cur = p_buf.first(), last = p_buf.first() + p_len;
Pointer vbuf = v.p_buf.first();
while (cur != last) {
octa::allocator_construct(p_buf.second(),
cur++, *vbuf++);
allocator_construct(p_buf.second(), cur++, *vbuf++);
}
}
}
public:
using Size = octa::Size;
using Difference = octa::Ptrdiff;
using Size = Size;
using Difference = Ptrdiff;
using Value = T;
using Reference = T &;
using ConstReference = const T &;
using Pointer = octa::AllocatorPointer<A>;
using ConstPointer = octa::AllocatorConstPointer<A>;
using Range = octa::PointerRange<T>;
using ConstRange = octa::PointerRange<const T>;
using Pointer = AllocatorPointer<A>;
using ConstPointer = AllocatorConstPointer<A>;
using Range = PointerRange<T>;
using ConstRange = PointerRange<const T>;
using Allocator = A;
Vector(const A &a = A()): p_len(0), p_cap(0), p_buf(nullptr, a) {}
explicit Vector(Size n, const T &val = T(),
const A &al = A()): Vector(al) {
p_buf.first() = octa::allocator_allocate(p_buf.second(), n);
p_buf.first() = allocator_allocate(p_buf.second(), n);
p_len = p_cap = n;
Pointer cur = p_buf.first(), last = p_buf.first() + n;
while (cur != last)
octa::allocator_construct(p_buf.second(), cur++, val);
allocator_construct(p_buf.second(), cur++, val);
}
Vector(const Vector &v): p_len(0), p_cap(0), p_buf(nullptr,
octa::allocator_container_copy(v.p_buf.second())) {
allocator_container_copy(v.p_buf.second())) {
reserve(v.p_cap);
p_len = v.p_len;
copy_contents(v);
@ -114,7 +113,7 @@ public:
}
Vector(Vector &&v): p_len(v.p_len), p_cap(v.p_cap), p_buf(v.p_buf.first(),
octa::move(v.p_buf.second())) {
move(v.p_buf.second())) {
v.p_buf.first() = nullptr;
v.p_len = v.p_cap = 0;
}
@ -123,14 +122,13 @@ public:
if (a != v.p_buf.second()) {
reserve(v.p_cap);
p_len = v.p_len;
if (octa::IsPod<T>()) {
if (IsPod<T>()) {
memcpy(p_buf.first(), v.p_buf.first(), p_len * sizeof(T));
} else {
Pointer cur = p_buf.first(), last = p_buf.first() + p_len;
Pointer vbuf = v.p_buf.first();
while (cur != last) {
octa::allocator_construct(p_buf.second(), cur++,
octa::move(*vbuf++));
allocator_construct(p_buf.second(), cur++, move(*vbuf++));
}
}
return;
@ -144,12 +142,11 @@ public:
Vector(const Value *buf, Size n, const A &a = A()): Vector(a) {
reserve(n);
if (octa::IsPod<T>()) {
if (IsPod<T>()) {
memcpy(p_buf.first(), buf, n * sizeof(T));
} else {
for (Size i = 0; i < n; ++i)
octa::allocator_construct(p_buf.second(),
&p_buf.first()[i], buf[i]);
allocator_construct(p_buf.second(), &p_buf.first()[i], buf[i]);
}
p_len = n;
}
@ -157,23 +154,23 @@ public:
Vector(InitializerList<T> v, const A &a = A()):
Vector(v.begin(), v.size(), a) {}
template<typename R, typename = octa::EnableIf<
octa::IsInputRange<R>::value &&
octa::IsConvertible<RangeReference<R>, Value>::value
template<typename R, typename = EnableIf<
IsInputRange<R>::value &&
IsConvertible<RangeReference<R>, Value>::value
>> Vector(R range, const A &a = A()): Vector(a) {
ctor_from_range(range);
}
~Vector() {
clear();
octa::allocator_deallocate(p_buf.second(), p_buf.first(), p_cap);
allocator_deallocate(p_buf.second(), p_buf.first(), p_cap);
}
void clear() {
if (p_len > 0 && !octa::IsPod<T>()) {
if (p_len > 0 && !IsPod<T>()) {
Pointer cur = p_buf.first(), last = p_buf.first() + p_len;
while (cur != last)
octa::allocator_destroy(p_buf.second(), cur++);
allocator_destroy(p_buf.second(), cur++);
}
p_len = 0;
}
@ -181,9 +178,9 @@ public:
Vector &operator=(const Vector &v) {
if (this == &v) return *this;
clear();
if (octa::AllocatorPropagateOnContainerCopyAssignment<A>::value) {
if (AllocatorPropagateOnContainerCopyAssignment<A>::value) {
if (p_buf.second() != v.p_buf.second()) {
octa::allocator_deallocate(p_buf.second(), p_buf.first(), p_cap);
allocator_deallocate(p_buf.second(), p_buf.first(), p_cap);
p_cap = 0;
}
p_buf.second() = v.p_buf.second();
@ -196,13 +193,13 @@ public:
Vector &operator=(Vector &&v) {
clear();
octa::allocator_deallocate(p_buf.second(), p_buf.first(), p_cap);
if (octa::AllocatorPropagateOnContainerMoveAssignment<A>::value)
allocator_deallocate(p_buf.second(), p_buf.first(), p_cap);
if (AllocatorPropagateOnContainerMoveAssignment<A>::value)
p_buf.second() = v.p_buf.second();
p_len = v.p_len;
p_cap = v.p_cap;
p_buf.~VecPair();
new (&p_buf) VecPair(v.disown(), octa::move(v.p_buf.second()));
new (&p_buf) VecPair(v.disown(), move(v.p_buf.second()));
return *this;
}
@ -210,13 +207,13 @@ public:
clear();
Size ilen = il.end() - il.begin();
reserve(ilen);
if (octa::IsPod<T>()) {
if (IsPod<T>()) {
memcpy(p_buf.first(), il.begin(), ilen);
} else {
Pointer tbuf = p_buf.first(), ibuf = il.begin(),
last = il.end();
while (ibuf != last) {
octa::allocator_construct(p_buf.second(),
allocator_construct(p_buf.second(),
tbuf++, *ibuf++);
}
}
@ -224,9 +221,9 @@ public:
return *this;
}
template<typename R, typename = octa::EnableIf<
octa::IsInputRange<R>::value &&
octa::IsConvertible<RangeReference<R>, Value>::value
template<typename R, typename = EnableIf<
IsInputRange<R>::value &&
IsConvertible<RangeReference<R>, Value>::value
>> Vector &operator=(R range) {
clear();
ctor_from_range(range);
@ -237,7 +234,7 @@ public:
Size l = p_len;
reserve(n);
p_len = n;
if (octa::IsPod<T>()) {
if (IsPod<T>()) {
for (Size i = l; i < p_len; ++i) {
p_buf.first()[i] = T(v);
}
@ -245,7 +242,7 @@ public:
Pointer first = p_buf.first() + l;
Pointer last = p_buf.first() + p_len;
while (first != last)
octa::allocator_construct(p_buf.second(), first++, v);
allocator_construct(p_buf.second(), first++, v);
}
}
@ -253,25 +250,24 @@ public:
if (n <= p_cap) return;
Size oc = p_cap;
if (!oc) {
p_cap = octa::max(n, Size(8));
p_cap = max(n, Size(8));
} else {
while (p_cap < n) p_cap *= 2;
}
Pointer tmp = octa::allocator_allocate(p_buf.second(), p_cap);
Pointer tmp = allocator_allocate(p_buf.second(), p_cap);
if (oc > 0) {
if (octa::IsPod<T>()) {
if (IsPod<T>()) {
memcpy(tmp, p_buf.first(), p_len * sizeof(T));
} else {
Pointer cur = p_buf.first(), tcur = tmp,
last = tmp + p_len;
while (tcur != last) {
octa::allocator_construct(p_buf.second(), tcur++,
octa::move(*cur));
octa::allocator_destroy(p_buf.second(), cur);
allocator_construct(p_buf.second(), tcur++, move(*cur));
allocator_destroy(p_buf.second(), cur);
++cur;
}
}
octa::allocator_deallocate(p_buf.second(), p_buf.first(), oc);
allocator_deallocate(p_buf.second(), p_buf.first(), oc);
}
p_buf.first() = tmp;
}
@ -290,36 +286,33 @@ public:
T &push(const T &v) {
if (p_len == p_cap) reserve(p_len + 1);
octa::allocator_construct(p_buf.second(),
&p_buf.first()[p_len], v);
allocator_construct(p_buf.second(), &p_buf.first()[p_len], v);
return p_buf.first()[p_len++];
}
T &push(T &&v) {
if (p_len == p_cap) reserve(p_len + 1);
octa::allocator_construct(p_buf.second(),
&p_buf.first()[p_len], octa::move(v));
allocator_construct(p_buf.second(), &p_buf.first()[p_len], move(v));
return p_buf.first()[p_len++];
}
T &push() {
if (p_len == p_cap) reserve(p_len + 1);
octa::allocator_construct(p_buf.second(), &p_buf.first()[p_len]);
allocator_construct(p_buf.second(), &p_buf.first()[p_len]);
return p_buf.first()[p_len++];
}
template<typename ...U>
T &emplace_back(U &&...args) {
if (p_len == p_cap) reserve(p_len + 1);
octa::allocator_construct(p_buf.second(), &p_buf.first()[p_len],
octa::forward<U>(args)...);
allocator_construct(p_buf.second(), &p_buf.first()[p_len],
forward<U>(args)...);
return p_buf.first()[p_len++];
}
void pop() {
if (!octa::IsPod<T>()) {
octa::allocator_destroy(p_buf.second(),
&p_buf.first()[--p_len]);
if (!IsPod<T>()) {
allocator_destroy(p_buf.second(), &p_buf.first()[--p_len]);
} else {
--p_len;
}
@ -356,7 +349,7 @@ public:
Range insert(Size idx, T &&v) {
insert_base(idx, 1);
p_buf.first()[idx] = octa::move(v);
p_buf.first()[idx] = move(v);
return Range(&p_buf.first()[idx], &p_buf.first()[p_len]);
}
@ -407,7 +400,7 @@ public:
octa::swap(p_len, v.p_len);
octa::swap(p_cap, v.p_cap);
octa::swap(p_buf.first(), v.p_buf.first());
if (octa::AllocatorPropagateOnContainerSwap<A>::value)
if (AllocatorPropagateOnContainerSwap<A>::value)
octa::swap(p_buf.second(), v.p_buf.second());
}