convert a part of type traits to template variables (reduces verbosity in a lot of places)
This commit is contained in:
parent
05bc21e255
commit
d53556d336
|
@ -288,7 +288,7 @@ template <typename T> inline T kill_dependency(T v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T, bool = IsIntegral<T>::value && !IsSame<T, bool>::value>
|
template<typename T, bool = IsIntegral<T> && !IsSame<T, bool>::value>
|
||||||
struct Atomic {
|
struct Atomic {
|
||||||
mutable AtomicBase<T> p_a;
|
mutable AtomicBase<T> p_a;
|
||||||
|
|
||||||
|
@ -656,13 +656,13 @@ inline bool atomic_compare_exchange_strong_explicit(Atomic<T> *a, T *e,
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T> && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_add(volatile Atomic<T> *a, T op) {
|
atomic_fetch_add(volatile Atomic<T> *a, T op) {
|
||||||
return a->fetch_add(op);
|
return a->fetch_add(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T> && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_add(Atomic<T> *a, T op) {
|
atomic_fetch_add(Atomic<T> *a, T op) {
|
||||||
return a->fetch_add(op);
|
return a->fetch_add(op);
|
||||||
}
|
}
|
||||||
|
@ -678,14 +678,14 @@ inline T *atomic_fetch_add(Atomic<T *> *a, Ptrdiff op) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T> && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_add_explicit(volatile Atomic<T> *a, T op,
|
atomic_fetch_add_explicit(volatile Atomic<T> *a, T op,
|
||||||
MemoryOrder ord) {
|
MemoryOrder ord) {
|
||||||
return a->fetch_add(op, ord);
|
return a->fetch_add(op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T> && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_add_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
atomic_fetch_add_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
||||||
return a->fetch_add(op, ord);
|
return a->fetch_add(op, ord);
|
||||||
}
|
}
|
||||||
|
@ -703,13 +703,13 @@ inline T *atomic_fetch_add_explicit(Atomic<T *> *a, Ptrdiff op,
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T> && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_sub(volatile Atomic<T> *a, T op) {
|
atomic_fetch_sub(volatile Atomic<T> *a, T op) {
|
||||||
return a->fetch_sub(op);
|
return a->fetch_sub(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T> && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_sub(Atomic<T> *a, T op) {
|
atomic_fetch_sub(Atomic<T> *a, T op) {
|
||||||
return a->fetch_sub(op);
|
return a->fetch_sub(op);
|
||||||
}
|
}
|
||||||
|
@ -725,14 +725,14 @@ inline T *atomic_fetch_sub(Atomic<T *> *a, Ptrdiff op) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T> && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_sub_explicit(volatile Atomic<T> *a, T op,
|
atomic_fetch_sub_explicit(volatile Atomic<T> *a, T op,
|
||||||
MemoryOrder ord) {
|
MemoryOrder ord) {
|
||||||
return a->fetch_sub(op, ord);
|
return a->fetch_sub(op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T> && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_sub_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
atomic_fetch_sub_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
||||||
return a->fetch_sub(op, ord);
|
return a->fetch_sub(op, ord);
|
||||||
}
|
}
|
||||||
|
@ -750,76 +750,76 @@ inline T *atomic_fetch_sub_explicit(Atomic<T *> *a, Ptrdiff op,
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T> && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_and(volatile Atomic<T> *a, T op) {
|
atomic_fetch_and(volatile Atomic<T> *a, T op) {
|
||||||
return a->fetch_and(op);
|
return a->fetch_and(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T> && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_and(Atomic<T> *a, T op) {
|
atomic_fetch_and(Atomic<T> *a, T op) {
|
||||||
return a->fetch_and(op);
|
return a->fetch_and(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T> && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_and_explicit(volatile Atomic<T> *a, T op,
|
atomic_fetch_and_explicit(volatile Atomic<T> *a, T op,
|
||||||
MemoryOrder ord) {
|
MemoryOrder ord) {
|
||||||
return a->fetch_and(op, ord);
|
return a->fetch_and(op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T> && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_and_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
atomic_fetch_and_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
||||||
return a->fetch_and(op, ord);
|
return a->fetch_and(op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T> && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_or(volatile Atomic<T> *a, T op) {
|
atomic_fetch_or(volatile Atomic<T> *a, T op) {
|
||||||
return a->fetch_or(op);
|
return a->fetch_or(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T> && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_or(Atomic<T> *a, T op) {
|
atomic_fetch_or(Atomic<T> *a, T op) {
|
||||||
return a->fetch_or(op);
|
return a->fetch_or(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T> && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_or_explicit(volatile Atomic<T> *a, T op,
|
atomic_fetch_or_explicit(volatile Atomic<T> *a, T op,
|
||||||
MemoryOrder ord) {
|
MemoryOrder ord) {
|
||||||
return a->fetch_or(op, ord);
|
return a->fetch_or(op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T> && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_or_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
atomic_fetch_or_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
||||||
return a->fetch_or(op, ord);
|
return a->fetch_or(op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T> && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_xor(volatile Atomic<T> *a, T op) {
|
atomic_fetch_xor(volatile Atomic<T> *a, T op) {
|
||||||
return a->fetch_xor(op);
|
return a->fetch_xor(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T> && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_xor(Atomic<T> *a, T op) {
|
atomic_fetch_xor(Atomic<T> *a, T op) {
|
||||||
return a->fetch_xor(op);
|
return a->fetch_xor(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T> && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_xor_explicit(volatile Atomic<T> *a, T op,
|
atomic_fetch_xor_explicit(volatile Atomic<T> *a, T op,
|
||||||
MemoryOrder ord) {
|
MemoryOrder ord) {
|
||||||
return a->fetch_xor(op, ord);
|
return a->fetch_xor(op, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline EnableIf<IsIntegral<T>::value && !IsSame<T, bool>::value, T>
|
inline EnableIf<IsIntegral<T> && !IsSame<T, bool>::value, T>
|
||||||
atomic_fetch_xor_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
atomic_fetch_xor_explicit(Atomic<T> *a, T op, MemoryOrder ord) {
|
||||||
return a->fetch_xor(op, ord);
|
return a->fetch_xor(op, ord);
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ namespace detail {
|
||||||
/* retrieve width/precision */
|
/* retrieve width/precision */
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool convert_arg_param(const T &val, int ¶m, EnableIf<
|
bool convert_arg_param(const T &val, int ¶m, EnableIf<
|
||||||
IsIntegral<T>::value, bool
|
IsIntegral<T>, bool
|
||||||
> = true) {
|
> = true) {
|
||||||
param = int(val);
|
param = int(val);
|
||||||
return true;
|
return true;
|
||||||
|
@ -119,7 +119,7 @@ namespace detail {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool convert_arg_param(const T &, int &, EnableIf<
|
bool convert_arg_param(const T &, int &, EnableIf<
|
||||||
!IsIntegral<T>::value, bool
|
!IsIntegral<T>, bool
|
||||||
> = true) {
|
> = true) {
|
||||||
assert(false && "invalid argument for width/precision");
|
assert(false && "invalid argument for width/precision");
|
||||||
return false;
|
return false;
|
||||||
|
@ -677,7 +677,7 @@ namespace detail {
|
||||||
/* signed integers */
|
/* signed integers */
|
||||||
template<typename R, typename T>
|
template<typename R, typename T>
|
||||||
Ptrdiff write(R &writer, bool, T val, EnableIf<
|
Ptrdiff write(R &writer, bool, T val, EnableIf<
|
||||||
IsIntegral<T>::value && IsSigned<T>::value, bool
|
IsIntegral<T> && IsSigned<T>, bool
|
||||||
> = true) {
|
> = true) {
|
||||||
using UT = MakeUnsigned<T>;
|
using UT = MakeUnsigned<T>;
|
||||||
return detail::write_u(writer, this, val < 0,
|
return detail::write_u(writer, this, val < 0,
|
||||||
|
@ -687,7 +687,7 @@ namespace detail {
|
||||||
/* unsigned integers */
|
/* unsigned integers */
|
||||||
template<typename R, typename T>
|
template<typename R, typename T>
|
||||||
Ptrdiff write(R &writer, bool, T val, EnableIf<
|
Ptrdiff write(R &writer, bool, T val, EnableIf<
|
||||||
IsIntegral<T>::value && IsUnsigned<T>::value, bool
|
IsIntegral<T> && IsUnsigned<T>, bool
|
||||||
> = true) {
|
> = true) {
|
||||||
return detail::write_u(writer, this, false, val);
|
return detail::write_u(writer, this, false, val);
|
||||||
}
|
}
|
||||||
|
@ -695,7 +695,7 @@ namespace detail {
|
||||||
template<typename R, typename T,
|
template<typename R, typename T,
|
||||||
bool Long = IsSame<T, ldouble>::value
|
bool Long = IsSame<T, ldouble>::value
|
||||||
> Ptrdiff write(R &writer, bool, T val, EnableIf<
|
> Ptrdiff write(R &writer, bool, T val, EnableIf<
|
||||||
IsFloatingPoint<T>::value, bool
|
IsFloatingPoint<T>, bool
|
||||||
> = true) {
|
> = true) {
|
||||||
char buf[16], rbuf[128];
|
char buf[16], rbuf[128];
|
||||||
char fmtspec[Long + 1];
|
char fmtspec[Long + 1];
|
||||||
|
@ -741,7 +741,7 @@ namespace detail {
|
||||||
/* generic value */
|
/* generic value */
|
||||||
template<typename R, typename T>
|
template<typename R, typename T>
|
||||||
Ptrdiff write(R &writer, bool, const T &val, EnableIf<
|
Ptrdiff write(R &writer, bool, const T &val, EnableIf<
|
||||||
!IsArithmetic<T>::value &&
|
!IsArithmetic<T> &&
|
||||||
!IsConstructible<ConstCharRange, const T &>::value &&
|
!IsConstructible<ConstCharRange, const T &>::value &&
|
||||||
FmtTostrTest<T>::value &&
|
FmtTostrTest<T>::value &&
|
||||||
!FmtTofmtTest<T, TostrRange<R>>::value, bool
|
!FmtTofmtTest<T, TostrRange<R>>::value, bool
|
||||||
|
@ -766,7 +766,7 @@ namespace detail {
|
||||||
/* generic failure case */
|
/* generic failure case */
|
||||||
template<typename R, typename T>
|
template<typename R, typename T>
|
||||||
Ptrdiff write(R &, bool, const T &, EnableIf<
|
Ptrdiff write(R &, bool, const T &, EnableIf<
|
||||||
!IsArithmetic<T>::value &&
|
!IsArithmetic<T> &&
|
||||||
!IsConstructible<ConstCharRange, const T &>::value &&
|
!IsConstructible<ConstCharRange, const T &>::value &&
|
||||||
!FmtTostrTest<T>::value &&
|
!FmtTostrTest<T>::value &&
|
||||||
!FmtTofmtTest<T, TostrRange<R>>::value, bool
|
!FmtTofmtTest<T, TostrRange<R>>::value, bool
|
||||||
|
|
|
@ -127,9 +127,8 @@ template<typename T> BinaryNegate<T> not2(const T &fn) {
|
||||||
|
|
||||||
/* endian swap */
|
/* endian swap */
|
||||||
|
|
||||||
template<typename T, Size N = sizeof(T),
|
template<typename T, Size N = sizeof(T), bool IsNum = IsArithmetic<T>>
|
||||||
bool IsNum = IsArithmetic<T>::value
|
struct EndianSwap;
|
||||||
> struct EndianSwap;
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct EndianSwap<T, 2, true> {
|
struct EndianSwap<T, 2, true> {
|
||||||
|
@ -171,9 +170,8 @@ template<typename T>
|
||||||
T endian_swap(T x) { return EndianSwap<T>()(x); }
|
T endian_swap(T x) { return EndianSwap<T>()(x); }
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T, Size N = sizeof(T),
|
template<typename T, Size N = sizeof(T), bool IsNum = IsArithmetic<T>>
|
||||||
bool IsNum = IsArithmetic<T>::value
|
struct EndianSame;
|
||||||
> struct EndianSame;
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct EndianSame<T, 2, true> {
|
struct EndianSame<T, 2, true> {
|
||||||
|
@ -942,7 +940,7 @@ namespace detail {
|
||||||
using Type = F;
|
using Type = F;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename F, bool = IsClass<F>::value>
|
template<typename F, bool = IsClass<F>>
|
||||||
struct DcFuncType {
|
struct DcFuncType {
|
||||||
using Type = F;
|
using Type = F;
|
||||||
};
|
};
|
||||||
|
|
|
@ -157,7 +157,7 @@ namespace detail {
|
||||||
struct MakeTupleTypesBase<TupleTypes<TS...>, T, S, E> {
|
struct MakeTupleTypesBase<TupleTypes<TS...>, T, S, E> {
|
||||||
using TR = RemoveReference<T>;
|
using TR = RemoveReference<T>;
|
||||||
using Type = typename MakeTupleTypesBase<TupleTypes<TS...,
|
using Type = typename MakeTupleTypesBase<TupleTypes<TS...,
|
||||||
Conditional<IsLvalueReference<T>::value,
|
Conditional<IsLvalueReference<T>,
|
||||||
TupleElement<S, TR> &,
|
TupleElement<S, TR> &,
|
||||||
TupleElement<S, TR>>>, T, S + 1, E>::Type;
|
TupleElement<S, TR>>>, T, S + 1, E>::Type;
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,9 +26,7 @@ namespace detail {
|
||||||
template<typename T, typename A> struct KeysetBase {
|
template<typename T, typename A> struct KeysetBase {
|
||||||
using Key = KeysetKey<T>;
|
using Key = KeysetKey<T>;
|
||||||
|
|
||||||
using RetKey = Conditional<
|
using RetKey = Conditional<IsReference<KeysetKeyRet<T>>, Key &, Key>;
|
||||||
IsReference<KeysetKeyRet<T>>::value, Key &, Key
|
|
||||||
>;
|
|
||||||
static inline RetKey get_key(const T &e) {
|
static inline RetKey get_key(const T &e) {
|
||||||
return e.get_key();
|
return e.get_key();
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,13 +93,13 @@ class Maybe: private detail::MaybeStorage<T> {
|
||||||
public:
|
public:
|
||||||
using Value = T;
|
using Value = T;
|
||||||
|
|
||||||
static_assert(!IsReference<T>::value,
|
static_assert(!IsReference<T>,
|
||||||
"Initialization of Maybe with a reference type is not allowed.");
|
"Initialization of Maybe with a reference type is not allowed.");
|
||||||
static_assert(!IsSame<RemoveCv<T>, InPlace>::value,
|
static_assert(!IsSame<RemoveCv<T>, InPlace>::value,
|
||||||
"Initialization of Maybe with InPlace is not allowed.");
|
"Initialization of Maybe with InPlace is not allowed.");
|
||||||
static_assert(!IsSame<RemoveCv<T>, Nothing>::value,
|
static_assert(!IsSame<RemoveCv<T>, Nothing>::value,
|
||||||
"Initialization of Maybe with Nothing is not allowed.");
|
"Initialization of Maybe with Nothing is not allowed.");
|
||||||
static_assert(IsObject<T>::value,
|
static_assert(IsObject<T>,
|
||||||
"Initialization of Maybe with non-object type is not allowed.");
|
"Initialization of Maybe with non-object type is not allowed.");
|
||||||
static_assert(IsDestructible<T>::value,
|
static_assert(IsDestructible<T>::value,
|
||||||
"Initialization of Maybe with a non-destructible object is not allowed.");
|
"Initialization of Maybe with a non-destructible object is not allowed.");
|
||||||
|
|
|
@ -153,7 +153,7 @@ namespace detail {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct PointerTo {
|
struct PointerTo {
|
||||||
static T pointer_to(Conditional<IsVoid<PointerElement<T>>::value,
|
static T pointer_to(Conditional<IsVoid<PointerElement<T>>,
|
||||||
PointerToNat, PointerElement<T>
|
PointerToNat, PointerElement<T>
|
||||||
> &r) {
|
> &r) {
|
||||||
return T::pointer_to(r);
|
return T::pointer_to(r);
|
||||||
|
@ -162,16 +162,14 @@ namespace detail {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct PointerTo<T *> {
|
struct PointerTo<T *> {
|
||||||
static T pointer_to(Conditional<IsVoid<T>::value,
|
static T pointer_to(Conditional<IsVoid<T>, PointerToNat, T> &r) {
|
||||||
PointerToNat, T
|
|
||||||
> &r) {
|
|
||||||
return address_of(r);
|
return address_of(r);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static T pointer_to(Conditional<IsVoid<PointerElement<T>>::value,
|
static T pointer_to(Conditional<IsVoid<PointerElement<T>>,
|
||||||
detail::PointerToNat, PointerElement<T>
|
detail::PointerToNat, PointerElement<T>
|
||||||
> &r) {
|
> &r) {
|
||||||
return detail::PointerTo<T>::pointer_to(r);
|
return detail::PointerTo<T>::pointer_to(r);
|
||||||
|
@ -242,36 +240,31 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr Box(): p_stor(nullptr, D()) {
|
constexpr Box(): p_stor(nullptr, D()) {
|
||||||
static_assert(!IsPointer<D>::value,
|
static_assert(!IsPointer<D>, "Box constructed with null fptr deleter");
|
||||||
"Box constructed with null fptr deleter");
|
|
||||||
}
|
}
|
||||||
constexpr Box(Nullptr): p_stor(nullptr, D()) {
|
constexpr Box(Nullptr): p_stor(nullptr, D()) {
|
||||||
static_assert(!IsPointer<D>::value,
|
static_assert(!IsPointer<D>, "Box constructed with null fptr deleter");
|
||||||
"Box constructed with null fptr deleter");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit Box(Pointer p): p_stor(p, D()) {
|
explicit Box(Pointer p): p_stor(p, D()) {
|
||||||
static_assert(!IsPointer<D>::value,
|
static_assert(!IsPointer<D>, "Box constructed with null fptr deleter");
|
||||||
"Box constructed with null fptr deleter");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(Pointer p, Conditional<IsReference<D>::value,
|
Box(Pointer p, Conditional<IsReference<D>, D, AddLvalueReference<const D>> d):
|
||||||
D, AddLvalueReference<const D>
|
p_stor(p, d) {}
|
||||||
> d): p_stor(p, d) {}
|
|
||||||
|
|
||||||
Box(Pointer p, RemoveReference<D> &&d):
|
Box(Pointer p, RemoveReference<D> &&d):
|
||||||
p_stor(p, move(d)) {
|
p_stor(p, move(d)) {
|
||||||
static_assert(!IsReference<D>::value,
|
static_assert(!IsReference<D>, "rvalue deleter cannot be a ref");
|
||||||
"rvalue deleter cannot be a ref");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(Box &&u): p_stor(u.release(), forward<D>(u.get_deleter())) {}
|
Box(Box &&u): p_stor(u.release(), forward<D>(u.get_deleter())) {}
|
||||||
|
|
||||||
template<typename TT, typename DD>
|
template<typename TT, typename DD>
|
||||||
Box(Box<TT, DD> &&u, EnableIf<!IsArray<TT>::value
|
Box(Box<TT, DD> &&u, EnableIf<!IsArray<TT>
|
||||||
&& IsConvertible<typename Box<TT, DD>::Pointer, Pointer>::value
|
&& IsConvertible<typename Box<TT, DD>::Pointer, Pointer>::value
|
||||||
&& IsConvertible<DD, D>::value
|
&& IsConvertible<DD, D>::value
|
||||||
&& (!IsReference<D>::value || IsSame<D, DD>::value)
|
&& (!IsReference<D> || IsSame<D, DD>::value)
|
||||||
> = Nat()): p_stor(u.release(), forward<DD>(u.get_deleter())) {}
|
> = Nat()): p_stor(u.release(), forward<DD>(u.get_deleter())) {}
|
||||||
|
|
||||||
Box &operator=(Box &&u) {
|
Box &operator=(Box &&u) {
|
||||||
|
@ -281,7 +274,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TT, typename DD>
|
template<typename TT, typename DD>
|
||||||
EnableIf<!IsArray<TT>::value
|
EnableIf<!IsArray<TT>
|
||||||
&& IsConvertible<typename Box<TT, DD>::Pointer, Pointer>::value
|
&& IsConvertible<typename Box<TT, DD>::Pointer, Pointer>::value
|
||||||
&& IsAssignable<D &, DD &&>::value,
|
&& IsAssignable<D &, DD &&>::value,
|
||||||
Box &
|
Box &
|
||||||
|
@ -339,7 +332,7 @@ namespace detail {
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
struct SameOrLessCvQualifiedBase<T, U, false>: False {};
|
struct SameOrLessCvQualifiedBase<T, U, false>: False {};
|
||||||
|
|
||||||
template<typename T, typename U, bool = IsPointer<T>::value
|
template<typename T, typename U, bool = IsPointer<T>
|
||||||
|| IsSame<T, U>::value || detail::HasElement<T>::value
|
|| IsSame<T, U>::value || detail::HasElement<T>::value
|
||||||
> struct SameOrLessCvQualified: SameOrLessCvQualifiedBase<T, U> {};
|
> struct SameOrLessCvQualified: SameOrLessCvQualifiedBase<T, U> {};
|
||||||
|
|
||||||
|
@ -361,54 +354,46 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr Box(): p_stor(nullptr, D()) {
|
constexpr Box(): p_stor(nullptr, D()) {
|
||||||
static_assert(!IsPointer<D>::value,
|
static_assert(!IsPointer<D>, "Box constructed with null fptr deleter");
|
||||||
"Box constructed with null fptr deleter");
|
|
||||||
}
|
}
|
||||||
constexpr Box(Nullptr): p_stor(nullptr, D()) {
|
constexpr Box(Nullptr): p_stor(nullptr, D()) {
|
||||||
static_assert(!IsPointer<D>::value,
|
static_assert(!IsPointer<D>, "Box constructed with null fptr deleter");
|
||||||
"Box constructed with null fptr deleter");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U> explicit Box(U p, EnableIf<
|
template<typename U> explicit Box(U p, EnableIf<
|
||||||
detail::SameOrLessCvQualified<U, Pointer>::value, Nat
|
detail::SameOrLessCvQualified<U, Pointer>::value, Nat
|
||||||
> = Nat()): p_stor(p, D()) {
|
> = Nat()): p_stor(p, D()) {
|
||||||
static_assert(!IsPointer<D>::value,
|
static_assert(!IsPointer<D>, "Box constructed with null fptr deleter");
|
||||||
"Box constructed with null fptr deleter");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U> Box(U p, Conditional<
|
template<typename U> Box(U p, Conditional<
|
||||||
IsReference<D>::value,
|
IsReference<D>, D, AddLvalueReference<const D>
|
||||||
D, AddLvalueReference<const D>
|
|
||||||
> d, EnableIf<detail::SameOrLessCvQualified<U, Pointer>::value,
|
> d, EnableIf<detail::SameOrLessCvQualified<U, Pointer>::value,
|
||||||
Nat> = Nat()): p_stor(p, d) {}
|
Nat> = Nat()): p_stor(p, d) {}
|
||||||
|
|
||||||
Box(Nullptr, Conditional<IsReference<D>::value,
|
Box(Nullptr, Conditional<IsReference<D>, D, AddLvalueReference<const D>> d):
|
||||||
D, AddLvalueReference<const D>
|
p_stor(nullptr, d) {}
|
||||||
> d): p_stor(nullptr, d) {}
|
|
||||||
|
|
||||||
template<typename U> Box(U p, RemoveReference<D> &&d,
|
template<typename U> Box(U p, RemoveReference<D> &&d,
|
||||||
EnableIf<
|
EnableIf<
|
||||||
detail::SameOrLessCvQualified<U, Pointer>::value, Nat
|
detail::SameOrLessCvQualified<U, Pointer>::value, Nat
|
||||||
> = Nat()): p_stor(p, move(d)) {
|
> = Nat()): p_stor(p, move(d)) {
|
||||||
static_assert(!IsReference<D>::value,
|
static_assert(!IsReference<D>, "rvalue deleter cannot be a ref");
|
||||||
"rvalue deleter cannot be a ref");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(Nullptr, RemoveReference<D> &&d):
|
Box(Nullptr, RemoveReference<D> &&d):
|
||||||
p_stor(nullptr, move(d)) {
|
p_stor(nullptr, move(d)) {
|
||||||
static_assert(!IsReference<D>::value,
|
static_assert(!IsReference<D>, "rvalue deleter cannot be a ref");
|
||||||
"rvalue deleter cannot be a ref");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(Box &&u): p_stor(u.release(), forward<D>(u.get_deleter())) {}
|
Box(Box &&u): p_stor(u.release(), forward<D>(u.get_deleter())) {}
|
||||||
|
|
||||||
template<typename TT, typename DD>
|
template<typename TT, typename DD>
|
||||||
Box(Box<TT, DD> &&u, EnableIf<IsArray<TT>::value
|
Box(Box<TT, DD> &&u, EnableIf<IsArray<TT>
|
||||||
&& detail::SameOrLessCvQualified<typename Box<TT, DD>::Pointer,
|
&& detail::SameOrLessCvQualified<typename Box<TT, DD>::Pointer,
|
||||||
Pointer>::value
|
Pointer>::value
|
||||||
&& IsConvertible<DD, D>::value
|
&& IsConvertible<DD, D>::value
|
||||||
&& (!IsReference<D>::value ||
|
&& (!IsReference<D> || IsSame<D, DD>::value)> = Nat()
|
||||||
IsSame<D, DD>::value)> = Nat()
|
|
||||||
): p_stor(u.release(), forward<DD>(u.get_deleter())) {}
|
): p_stor(u.release(), forward<DD>(u.get_deleter())) {}
|
||||||
|
|
||||||
Box &operator=(Box &&u) {
|
Box &operator=(Box &&u) {
|
||||||
|
@ -418,7 +403,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TT, typename DD>
|
template<typename TT, typename DD>
|
||||||
EnableIf<IsArray<TT>::value
|
EnableIf<IsArray<TT>
|
||||||
&& detail::SameOrLessCvQualified<typename Box<TT, DD>::Pointer,
|
&& detail::SameOrLessCvQualified<typename Box<TT, DD>::Pointer,
|
||||||
Pointer>::value
|
Pointer>::value
|
||||||
&& IsAssignable<D &, DD &&>::value,
|
&& IsAssignable<D &, DD &&>::value,
|
||||||
|
@ -866,7 +851,7 @@ namespace detail {
|
||||||
|
|
||||||
template<typename A, bool = IsAlwaysEqualTest<A>::value>
|
template<typename A, bool = IsAlwaysEqualTest<A>::value>
|
||||||
struct IsAlwaysEqualBase {
|
struct IsAlwaysEqualBase {
|
||||||
using Type = typename IsEmpty<A>::Type;
|
using Type = IntegralConstant<bool, IsEmpty<A>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename A>
|
template<typename A>
|
||||||
|
|
|
@ -874,7 +874,7 @@ public:
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
PointerRange(T *beg, U end, EnableIf<
|
PointerRange(T *beg, U end, EnableIf<
|
||||||
(IsPointer<U>::value || IsNullPointer<U>::value) &&
|
(IsPointer<U> || IsNullPointer<U>) &&
|
||||||
IsConvertible<U, T *>::value, Nat
|
IsConvertible<U, T *>::value, Nat
|
||||||
> = Nat()): p_beg(beg), p_end(end) {}
|
> = Nat()): p_beg(beg), p_end(end) {}
|
||||||
|
|
||||||
|
@ -985,7 +985,7 @@ public:
|
||||||
Size put_n(const T *p, Size n) {
|
Size put_n(const T *p, Size n) {
|
||||||
Size ret = size();
|
Size ret = size();
|
||||||
if (n < ret) ret = n;
|
if (n < ret) ret = n;
|
||||||
if (IsPod<T>()) {
|
if (IsPod<T>) {
|
||||||
memcpy(p_beg, p, ret * sizeof(T));
|
memcpy(p_beg, p, ret * sizeof(T));
|
||||||
p_beg += ret;
|
p_beg += ret;
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1027,7 +1027,7 @@ namespace detail {
|
||||||
|
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
PointerRange<T> iter(T *a, U b, EnableIf<
|
PointerRange<T> iter(T *a, U b, EnableIf<
|
||||||
(IsPointer<U>::vvalue || IsNullPointer<U>::value) &&
|
(IsPointer<U> || IsNullPointer<U>) &&
|
||||||
IsConvertible<U, T *>::value, detail::PtrNat
|
IsConvertible<U, T *>::value, detail::PtrNat
|
||||||
> = detail::PtrNat()) {
|
> = detail::PtrNat()) {
|
||||||
return PointerRange<T>(a, b);
|
return PointerRange<T>(a, b);
|
||||||
|
|
|
@ -30,7 +30,7 @@ enum class StreamSeek {
|
||||||
set = SEEK_SET
|
set = SEEK_SET
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T = char, bool = IsPod<T>::value>
|
template<typename T = char, bool = IsPod<T>>
|
||||||
struct StreamRange;
|
struct StreamRange;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
|
@ -32,7 +32,7 @@ public:
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
CharRangeBase(T *beg, U end, EnableIf<
|
CharRangeBase(T *beg, U end, EnableIf<
|
||||||
(IsPointer<U>::value || IsNullPointer<U>::value) &&
|
(IsPointer<U> || IsNullPointer<U>) &&
|
||||||
IsConvertible<U, T *>::value, Nat
|
IsConvertible<U, T *>::value, Nat
|
||||||
> = Nat()): p_beg(beg), p_end(end) {}
|
> = Nat()): p_beg(beg), p_end(end) {}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ public:
|
||||||
/* TODO: traits for utf-16/utf-32 string lengths, for now assume char */
|
/* TODO: traits for utf-16/utf-32 string lengths, for now assume char */
|
||||||
template<typename U>
|
template<typename U>
|
||||||
CharRangeBase(U beg, EnableIf<
|
CharRangeBase(U beg, EnableIf<
|
||||||
IsConvertible<U, T *>::value && !IsArray<U>::value, Nat
|
IsConvertible<U, T *>::value && !IsArray<U>, Nat
|
||||||
> = Nat()): p_beg(beg), p_end((T *)beg + (beg ? strlen(beg) : 0)) {}
|
> = Nat()): p_beg(beg), p_end((T *)beg + (beg ? strlen(beg) : 0)) {}
|
||||||
|
|
||||||
CharRangeBase(Nullptr): p_beg(nullptr), p_end(nullptr) {}
|
CharRangeBase(Nullptr): p_beg(nullptr), p_end(nullptr) {}
|
||||||
|
@ -318,7 +318,7 @@ public:
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
StringBase(U v, const EnableIf<
|
StringBase(U v, const EnableIf<
|
||||||
IsConvertible<U, const Value *>::value && !IsArray<U>::value, A
|
IsConvertible<U, const Value *>::value && !IsArray<U>, A
|
||||||
> &a = A()): StringBase(ConstRange(v), a) {}
|
> &a = A()): StringBase(ConstRange(v), a) {}
|
||||||
|
|
||||||
template<typename U, Size N>
|
template<typename U, Size N>
|
||||||
|
@ -387,8 +387,7 @@ public:
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
EnableIf<
|
EnableIf<
|
||||||
IsConvertible<U, const Value *>::value && !IsArray<U>::value,
|
IsConvertible<U, const Value *>::value && !IsArray<U>, StringBase &
|
||||||
StringBase &
|
|
||||||
> operator=(U v) {
|
> operator=(U v) {
|
||||||
return operator=(ConstRange(v));
|
return operator=(ConstRange(v));
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,26 +30,26 @@ struct TupleElementBase<I, Tuple<T...>> {
|
||||||
/* tuple leaf */
|
/* tuple leaf */
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<Size I, typename H, bool = IsEmpty<H>::value>
|
template<Size I, typename H, bool = IsEmpty<H>>
|
||||||
struct TupleLeaf {
|
struct TupleLeaf {
|
||||||
constexpr TupleLeaf(): p_value() {
|
constexpr TupleLeaf(): p_value() {
|
||||||
static_assert(!IsReference<H>::value,
|
static_assert(!IsReference<H>,
|
||||||
"attempt to default construct a reference element in a tuple");
|
"attempt to default construct a reference element in a tuple");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A>
|
template<typename A>
|
||||||
TupleLeaf(IntegralConstant<int, 0>, const A &): p_value() {
|
TupleLeaf(IntegralConstant<int, 0>, const A &): p_value() {
|
||||||
static_assert(!IsReference<H>::value,
|
static_assert(!IsReference<H>,
|
||||||
"attempt to default construct a reference element in a tuple");
|
"attempt to default construct a reference element in a tuple");
|
||||||
}
|
}
|
||||||
template<typename A>
|
template<typename A>
|
||||||
TupleLeaf(IntegralConstant<int, 1>, const A &a): p_value(allocator_arg, a) {
|
TupleLeaf(IntegralConstant<int, 1>, const A &a): p_value(allocator_arg, a) {
|
||||||
static_assert(!IsReference<H>::value,
|
static_assert(!IsReference<H>,
|
||||||
"attempt to default construct a reference element in a tuple");
|
"attempt to default construct a reference element in a tuple");
|
||||||
}
|
}
|
||||||
template<typename A>
|
template<typename A>
|
||||||
TupleLeaf(IntegralConstant<int, 2>, const A &a): p_value(a) {
|
TupleLeaf(IntegralConstant<int, 2>, const A &a): p_value(a) {
|
||||||
static_assert(!IsReference<H>::value,
|
static_assert(!IsReference<H>,
|
||||||
"attempt to default construct a reference element in a tuple");
|
"attempt to default construct a reference element in a tuple");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,23 +57,23 @@ namespace detail {
|
||||||
typename = EnableIf<And<Not<IsSame<Decay<T>, TupleLeaf>>,
|
typename = EnableIf<And<Not<IsSame<Decay<T>, TupleLeaf>>,
|
||||||
IsConstructible<H, T>>::value>>
|
IsConstructible<H, T>>::value>>
|
||||||
explicit TupleLeaf(T &&t): p_value(forward<T>(t)) {
|
explicit TupleLeaf(T &&t): p_value(forward<T>(t)) {
|
||||||
static_assert(!IsReference<H>::value ||
|
static_assert(!IsReference<H> ||
|
||||||
(IsLvalueReference<H>::value &&
|
(IsLvalueReference<H> &&
|
||||||
(IsLvalueReference<T>::value ||
|
(IsLvalueReference<T> ||
|
||||||
IsSame<RemoveReference<T>,
|
IsSame<RemoveReference<T>,
|
||||||
ReferenceWrapper<RemoveReference<H>>
|
ReferenceWrapper<RemoveReference<H>>
|
||||||
>::value)) ||
|
>::value)) ||
|
||||||
(IsRvalueReference<H>::value &&
|
(IsRvalueReference<H> &&
|
||||||
!IsLvalueReference<T>::value),
|
!IsLvalueReference<T>),
|
||||||
"attempt to construct a reference element in a tuple with an rvalue");
|
"attempt to construct a reference element in a tuple with an rvalue");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename A>
|
template<typename T, typename A>
|
||||||
explicit TupleLeaf(IntegralConstant<int, 0>, const A &, T &&t):
|
explicit TupleLeaf(IntegralConstant<int, 0>, const A &, T &&t):
|
||||||
p_value(forward<T>(t)) {
|
p_value(forward<T>(t)) {
|
||||||
static_assert(!IsLvalueReference<H>::value ||
|
static_assert(!IsLvalueReference<H> ||
|
||||||
(IsLvalueReference<H>::value &&
|
(IsLvalueReference<H> &&
|
||||||
(IsLvalueReference<T>::value ||
|
(IsLvalueReference<T> ||
|
||||||
IsSame<RemoveReference<T>,
|
IsSame<RemoveReference<T>,
|
||||||
ReferenceWrapper<RemoveReference<H>>
|
ReferenceWrapper<RemoveReference<H>>
|
||||||
>::value)),
|
>::value)),
|
||||||
|
@ -83,9 +83,9 @@ namespace detail {
|
||||||
template<typename T, typename A>
|
template<typename T, typename A>
|
||||||
explicit TupleLeaf(IntegralConstant<int, 1>, const A &a, T &&t):
|
explicit TupleLeaf(IntegralConstant<int, 1>, const A &a, T &&t):
|
||||||
p_value(allocator_arg, a, forward<T>(t)) {
|
p_value(allocator_arg, a, forward<T>(t)) {
|
||||||
static_assert(!IsLvalueReference<H>::value ||
|
static_assert(!IsLvalueReference<H> ||
|
||||||
(IsLvalueReference<H>::value &&
|
(IsLvalueReference<H> &&
|
||||||
(IsLvalueReference<T>::value ||
|
(IsLvalueReference<T> ||
|
||||||
IsSame<RemoveReference<T>,
|
IsSame<RemoveReference<T>,
|
||||||
ReferenceWrapper<RemoveReference<H>>
|
ReferenceWrapper<RemoveReference<H>>
|
||||||
>::value)),
|
>::value)),
|
||||||
|
@ -95,9 +95,9 @@ namespace detail {
|
||||||
template<typename T, typename A>
|
template<typename T, typename A>
|
||||||
explicit TupleLeaf(IntegralConstant<int, 2>, const A &a, T &&t):
|
explicit TupleLeaf(IntegralConstant<int, 2>, const A &a, T &&t):
|
||||||
p_value(forward<T>(t), a) {
|
p_value(forward<T>(t), a) {
|
||||||
static_assert(!IsLvalueReference<H>::value ||
|
static_assert(!IsLvalueReference<H> ||
|
||||||
(IsLvalueReference<H>::value &&
|
(IsLvalueReference<H> &&
|
||||||
(IsLvalueReference<T>::value ||
|
(IsLvalueReference<T> ||
|
||||||
IsSame<RemoveReference<T>,
|
IsSame<RemoveReference<T>,
|
||||||
ReferenceWrapper<RemoveReference<H>>
|
ReferenceWrapper<RemoveReference<H>>
|
||||||
>::value)),
|
>::value)),
|
||||||
|
|
|
@ -24,7 +24,6 @@ namespace detail {
|
||||||
template<typename ...> struct CommonTypeBase;
|
template<typename ...> struct CommonTypeBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename> struct IsReference;
|
|
||||||
template<typename> struct IsTriviallyDefaultConstructible;
|
template<typename> struct IsTriviallyDefaultConstructible;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -111,25 +110,20 @@ struct Or: detail::OrBase<T::Type::value, A...> {};
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Not: IntegralConstant<bool, !T::Type::value> {};
|
struct Not: IntegralConstant<bool, !T::Type::value> {};
|
||||||
|
|
||||||
|
/* type equality */
|
||||||
|
|
||||||
|
template<typename, typename> struct IsSame : False {};
|
||||||
|
template<typename T > struct IsSame<T, T>: True {};
|
||||||
|
|
||||||
/* is void */
|
/* is void */
|
||||||
|
|
||||||
namespace detail {
|
template<typename T>
|
||||||
template<typename T> struct IsVoidBase : False {};
|
static constexpr bool IsVoid = IsSame<RemoveCv<T>, void>::value;
|
||||||
template< > struct IsVoidBase<void>: True {};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct IsVoid: detail::IsVoidBase<RemoveCv<T>> {};
|
|
||||||
|
|
||||||
/* is null pointer */
|
/* is null pointer */
|
||||||
|
|
||||||
namespace detail {
|
template<typename T>
|
||||||
template<typename> struct IsNullPointerBase : False {};
|
static constexpr bool IsNullPointer = IsSame<RemoveCv<T>, Nullptr>::value;
|
||||||
template< > struct IsNullPointerBase<Nullptr>: True {};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T> struct IsNullPointer:
|
|
||||||
detail::IsNullPointerBase<RemoveCv<T>> {};
|
|
||||||
|
|
||||||
/* is integer */
|
/* is integer */
|
||||||
|
|
||||||
|
@ -156,7 +150,7 @@ namespace detail {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsIntegral: detail::IsIntegralBase<RemoveCv<T>> {};
|
static constexpr bool IsIntegral = detail::IsIntegralBase<RemoveCv<T>>::value;
|
||||||
|
|
||||||
/* is floating point */
|
/* is floating point */
|
||||||
|
|
||||||
|
@ -170,13 +164,18 @@ namespace detail {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsFloatingPoint: detail::IsFloatingPointBase<RemoveCv<T>> {};
|
static constexpr bool IsFloatingPoint = detail::IsFloatingPointBase<RemoveCv<T>>::value;
|
||||||
|
|
||||||
/* is array */
|
/* is array */
|
||||||
|
|
||||||
template<typename > struct IsArray : False {};
|
namespace detail {
|
||||||
template<typename T > struct IsArray<T[] >: True {};
|
template<typename > struct IsArrayBase : False {};
|
||||||
template<typename T, Size N> struct IsArray<T[N]>: True {};
|
template<typename T > struct IsArrayBase<T[] >: True {};
|
||||||
|
template<typename T, Size N> struct IsArrayBase<T[N]>: True {};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static constexpr bool IsArray = detail::IsArrayBase<T>::value;
|
||||||
|
|
||||||
/* is pointer */
|
/* is pointer */
|
||||||
|
|
||||||
|
@ -186,29 +185,44 @@ namespace detail {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsPointer: detail::IsPointerBase<RemoveCv<T>> {};
|
static constexpr bool IsPointer = detail::IsPointerBase<RemoveCv<T>>::value;
|
||||||
|
|
||||||
/* is lvalue reference */
|
/* is lvalue reference */
|
||||||
|
|
||||||
template<typename > struct IsLvalueReference : False {};
|
namespace detail {
|
||||||
template<typename T> struct IsLvalueReference<T &>: True {};
|
template<typename > struct IsLvalueReferenceBase : False {};
|
||||||
|
template<typename T> struct IsLvalueReferenceBase<T &>: True {};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static constexpr bool IsLvalueReference = detail::IsLvalueReferenceBase<T>::value;
|
||||||
|
|
||||||
/* is rvalue reference */
|
/* is rvalue reference */
|
||||||
|
|
||||||
template<typename > struct IsRvalueReference : False {};
|
namespace detail {
|
||||||
template<typename T> struct IsRvalueReference<T &&>: True {};
|
template<typename > struct IsRvalueReferenceBase : False {};
|
||||||
|
template<typename T> struct IsRvalueReferenceBase<T &&>: True {};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static constexpr bool IsRvalueReference = detail::IsRvalueReferenceBase<T>::value;
|
||||||
|
|
||||||
|
/* is reference */
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static constexpr bool IsReference = IsLvalueReference<T> || IsRvalueReference<T>;
|
||||||
|
|
||||||
/* is enum */
|
/* is enum */
|
||||||
|
|
||||||
template<typename T> struct IsEnum: IntegralConstant<bool, __is_enum(T)> {};
|
template<typename T> static constexpr bool IsEnum = __is_enum(T);
|
||||||
|
|
||||||
/* is union */
|
/* is union */
|
||||||
|
|
||||||
template<typename T> struct IsUnion: IntegralConstant<bool, __is_union(T)> {};
|
template<typename T> static constexpr bool IsUnion = __is_union(T);
|
||||||
|
|
||||||
/* is class */
|
/* is class */
|
||||||
|
|
||||||
template<typename T> struct IsClass: IntegralConstant<bool, __is_class(T)> {};
|
template<typename T> static constexpr bool IsClass = __is_class(T);
|
||||||
|
|
||||||
/* is function */
|
/* is function */
|
||||||
|
|
||||||
|
@ -222,11 +236,11 @@ namespace detail {
|
||||||
template<typename T> T &function_source(int);
|
template<typename T> T &function_source(int);
|
||||||
template<typename T> FunctionTestDummy function_source(...);
|
template<typename T> FunctionTestDummy function_source(...);
|
||||||
|
|
||||||
template<typename T, bool = IsClass<T>::value ||
|
template<typename T, bool = IsClass<T> ||
|
||||||
IsUnion<T>::value ||
|
IsUnion<T> ||
|
||||||
IsVoid<T>::value ||
|
IsVoid<T> ||
|
||||||
IsReference<T>::value ||
|
IsReference<T> ||
|
||||||
IsNullPointer<T>::value
|
IsNullPointer<T>
|
||||||
> struct IsFunctionBase: IntegralConstant<bool,
|
> struct IsFunctionBase: IntegralConstant<bool,
|
||||||
sizeof(function_test<T>(function_source<T>(0))) == 1
|
sizeof(function_test<T>(function_source<T>(0))) == 1
|
||||||
> {};
|
> {};
|
||||||
|
@ -234,25 +248,24 @@ namespace detail {
|
||||||
template<typename T> struct IsFunctionBase<T, true>: False {};
|
template<typename T> struct IsFunctionBase<T, true>: False {};
|
||||||
} /* namespace detail */
|
} /* namespace detail */
|
||||||
|
|
||||||
template<typename T> struct IsFunction: detail::IsFunctionBase<T> {};
|
template<typename T>
|
||||||
|
static constexpr bool IsFunction = detail::IsFunctionBase<T>::value;
|
||||||
|
|
||||||
/* is arithmetic */
|
/* is arithmetic */
|
||||||
|
|
||||||
template<typename T> struct IsArithmetic: IntegralConstant<bool,
|
template<typename T>
|
||||||
(IsIntegral<T>::value || IsFloatingPoint<T>::value)
|
static constexpr bool IsArithmetic = IsIntegral<T> || IsFloatingPoint<T>;
|
||||||
> {};
|
|
||||||
|
|
||||||
/* is fundamental */
|
/* is fundamental */
|
||||||
|
|
||||||
template<typename T> struct IsFundamental: IntegralConstant<bool,
|
template<typename T>
|
||||||
(IsArithmetic<T>::value || IsVoid<T>::value || IsNullPointer<T>::value)
|
static constexpr bool IsFundamental = IsArithmetic<T> || IsVoid<T> ||
|
||||||
> {};
|
IsNullPointer<T>;
|
||||||
|
|
||||||
/* is compound */
|
/* is compound */
|
||||||
|
|
||||||
template<typename T> struct IsCompound: IntegralConstant<bool,
|
template<typename T>
|
||||||
!IsFundamental<T>::value
|
static constexpr bool IsCompound = !IsFundamental<T>;
|
||||||
> {};
|
|
||||||
|
|
||||||
/* is pointer to member */
|
/* is pointer to member */
|
||||||
|
|
||||||
|
@ -265,7 +278,7 @@ namespace detail {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsMemberPointer: detail::IsMemberPointerBase<RemoveCv<T>> {};
|
static constexpr bool IsMemberPointer = detail::IsMemberPointerBase<RemoveCv<T>>::value;
|
||||||
|
|
||||||
/* is pointer to member object */
|
/* is pointer to member object */
|
||||||
|
|
||||||
|
@ -275,12 +288,12 @@ namespace detail {
|
||||||
|
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
struct IsMemberObjectPointerBase<T U::*>: IntegralConstant<bool,
|
struct IsMemberObjectPointerBase<T U::*>: IntegralConstant<bool,
|
||||||
!IsFunction<T>::value
|
!IsFunction<T>
|
||||||
> {};
|
> {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> struct IsMemberObjectPointer:
|
template<typename T>
|
||||||
detail::IsMemberObjectPointerBase<RemoveCv<T>> {};
|
static constexpr bool IsMemberObjectPointer = detail::IsMemberObjectPointerBase<RemoveCv<T>>::value;
|
||||||
|
|
||||||
/* is pointer to member function */
|
/* is pointer to member function */
|
||||||
|
|
||||||
|
@ -290,115 +303,105 @@ namespace detail {
|
||||||
|
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
struct IsMemberFunctionPointerBase<T U::*>: IntegralConstant<bool,
|
struct IsMemberFunctionPointerBase<T U::*>: IntegralConstant<bool,
|
||||||
IsFunction<T>::value
|
IsFunction<T>
|
||||||
> {};
|
> {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> struct IsMemberFunctionPointer:
|
template<typename T>
|
||||||
detail::IsMemberFunctionPointerBase<RemoveCv<T>> {};
|
static constexpr bool IsMemberFunctionPointer = detail::IsMemberFunctionPointerBase<RemoveCv<T>>::value;
|
||||||
|
|
||||||
/* is reference */
|
|
||||||
|
|
||||||
template<typename T> struct IsReference: IntegralConstant<bool,
|
|
||||||
(IsLvalueReference<T>::value || IsRvalueReference<T>::value)
|
|
||||||
> {};
|
|
||||||
|
|
||||||
/* is object */
|
/* is object */
|
||||||
|
|
||||||
template<typename T> struct IsObject: IntegralConstant<bool,
|
template<typename T>
|
||||||
(!IsFunction<T>::value && !IsVoid<T>::value && !IsReference<T>::value)
|
static constexpr bool IsObject = !IsFunction<T> && !IsVoid<T> && !IsReference<T>;
|
||||||
> {};
|
|
||||||
|
|
||||||
/* is scalar */
|
/* is scalar */
|
||||||
|
|
||||||
template<typename T> struct IsScalar: IntegralConstant<bool,
|
template<typename T> static constexpr bool IsScalar
|
||||||
(IsMemberPointer<T>::value || IsPointer<T>::value || IsEnum<T>::value
|
= IsMemberPointer<T> || IsPointer<T> || IsEnum<T> ||
|
||||||
|| IsNullPointer <T>::value || IsArithmetic<T>::value)
|
IsNullPointer <T> || IsArithmetic<T>;
|
||||||
> {};
|
|
||||||
|
|
||||||
/* is abstract */
|
/* is abstract */
|
||||||
|
|
||||||
template<typename T>
|
template<typename T> static constexpr bool IsAbstract = __is_abstract(T);
|
||||||
struct IsAbstract: IntegralConstant<bool, __is_abstract(T)> {};
|
|
||||||
|
|
||||||
/* is const */
|
/* is const */
|
||||||
|
|
||||||
template<typename > struct IsConst : False {};
|
template<typename T>
|
||||||
template<typename T> struct IsConst<const T>: True {};
|
static constexpr bool IsConst = IsSame<T, const T>::value;
|
||||||
|
|
||||||
/* is volatile */
|
/* is volatile */
|
||||||
|
|
||||||
template<typename > struct IsVolatile : False {};
|
template<typename T>
|
||||||
template<typename T> struct IsVolatile<volatile T>: True {};
|
static constexpr bool IsVolatile = IsSame<T, volatile T>::value;
|
||||||
|
|
||||||
/* is empty */
|
/* is empty */
|
||||||
|
|
||||||
template<typename T>
|
template<typename T> static constexpr bool IsEmpty = __is_empty(T);
|
||||||
struct IsEmpty: IntegralConstant<bool, __is_empty(T)> {};
|
|
||||||
|
|
||||||
/* is POD */
|
/* is POD */
|
||||||
|
|
||||||
template<typename T> struct IsPod: IntegralConstant<bool, __is_pod(T)> {};
|
template<typename T> static constexpr bool IsPod = __is_pod(T);
|
||||||
|
|
||||||
/* is polymorphic */
|
/* is polymorphic */
|
||||||
|
|
||||||
template<typename T>
|
template<typename T> static constexpr bool IsPolymorphic = __is_polymorphic(T);
|
||||||
struct IsPolymorphic: IntegralConstant<bool, __is_polymorphic(T)> {};
|
|
||||||
|
|
||||||
/* is signed */
|
/* is signed */
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsSignedBase: IntegralConstant<bool, T(-1) < T(0)> {};
|
struct IsSignedCore: IntegralConstant<bool, T(-1) < T(0)> {};
|
||||||
|
|
||||||
|
template<typename T, bool = IsArithmetic<T>>
|
||||||
|
struct IsSignedBase: False {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct IsSignedBase<T, true>: detail::IsSignedCore<T> {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, bool = IsArithmetic<T>::value>
|
|
||||||
struct IsSigned: False {};
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsSigned<T, true>: detail::IsSignedBase<T> {};
|
static constexpr bool IsSigned = detail::IsSignedBase<T>::value;
|
||||||
|
|
||||||
/* is unsigned */
|
/* is unsigned */
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsUnsignedBase: IntegralConstant<bool, T(0) < T(-1)> {};
|
struct IsUnsignedCore: IntegralConstant<bool, T(0) < T(-1)> {};
|
||||||
|
|
||||||
|
template<typename T, bool = IsArithmetic<T>>
|
||||||
|
struct IsUnsignedBase: False {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct IsUnsignedBase<T, true>: detail::IsUnsignedCore<T> {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, bool = IsArithmetic<T>::value>
|
|
||||||
struct IsUnsigned: False {};
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsUnsigned<T, true>: detail::IsUnsignedBase<T> {};
|
static constexpr bool IsUnsigned = detail::IsUnsignedBase<T>::value;
|
||||||
|
|
||||||
/* is standard layout */
|
/* is standard layout */
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsStandardLayout: IntegralConstant<bool, __is_standard_layout(T)> {};
|
static constexpr bool IsStandardLayout = __is_standard_layout(T);
|
||||||
|
|
||||||
/* is literal type */
|
/* is literal type */
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsLiteralType: IntegralConstant<bool, __is_literal_type(T)> {};
|
static constexpr bool IsLiteralType = __is_literal_type(T);
|
||||||
|
|
||||||
/* is trivially copyable */
|
/* is trivially copyable */
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsTriviallyCopyable: IntegralConstant<bool,
|
static constexpr bool IsTriviallyCopyable = IsScalar<RemoveAllExtents<T>>;
|
||||||
IsScalar<RemoveAllExtents<T>>::value
|
|
||||||
> {};
|
|
||||||
|
|
||||||
/* is trivial */
|
/* is trivial */
|
||||||
|
|
||||||
template<typename T>
|
template<typename T> static constexpr bool IsTrivial = __is_trivial(T);
|
||||||
struct IsTrivial: IntegralConstant<bool, __is_trivial(T)> {};
|
|
||||||
|
|
||||||
/* has virtual destructor */
|
/* has virtual destructor */
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct HasVirtualDestructor: IntegralConstant<bool,
|
static constexpr bool HasVirtualDestructor = __has_virtual_destructor(T);
|
||||||
__has_virtual_destructor(T)
|
|
||||||
> {};
|
|
||||||
|
|
||||||
/* is constructible */
|
/* is constructible */
|
||||||
|
|
||||||
|
@ -427,7 +430,7 @@ namespace detail {
|
||||||
|
|
||||||
/* scalars are default constructible, refs are not */
|
/* scalars are default constructible, refs are not */
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct CtibleCore<true, T>: IsScalar<T> {};
|
struct CtibleCore<true, T>: IntegralConstant<bool, IsScalar<T>> {};
|
||||||
|
|
||||||
/* scalars and references are constructible from one arg if
|
/* scalars and references are constructible from one arg if
|
||||||
* implicitly convertible to scalar or reference */
|
* implicitly convertible to scalar or reference */
|
||||||
|
@ -449,7 +452,7 @@ namespace detail {
|
||||||
/* treat scalars and refs separately */
|
/* treat scalars and refs separately */
|
||||||
template<bool, typename T, typename ...A>
|
template<bool, typename T, typename ...A>
|
||||||
struct CtibleVoidCheck: CtibleCore<
|
struct CtibleVoidCheck: CtibleCore<
|
||||||
(IsScalar<T>::value || IsReference<T>::value), T, A...
|
(IsScalar<T> || IsReference<T>), T, A...
|
||||||
> {};
|
> {};
|
||||||
|
|
||||||
/* if any of T or A is void, IsConstructible should be false */
|
/* if any of T or A is void, IsConstructible should be false */
|
||||||
|
@ -462,14 +465,14 @@ namespace detail {
|
||||||
|
|
||||||
template<typename T, typename ...A>
|
template<typename T, typename ...A>
|
||||||
struct CtibleContainsVoid<T, A...> {
|
struct CtibleContainsVoid<T, A...> {
|
||||||
static constexpr bool value = IsVoid<T>::value
|
static constexpr bool value = IsVoid<T>
|
||||||
|| CtibleContainsVoid<A...>::value;
|
|| CtibleContainsVoid<A...>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* entry point */
|
/* entry point */
|
||||||
template<typename T, typename ...A>
|
template<typename T, typename ...A>
|
||||||
struct Ctible: CtibleVoidCheck<
|
struct Ctible: CtibleVoidCheck<
|
||||||
CtibleContainsVoid<T, A...>::value || IsAbstract<T>::value,
|
CtibleContainsVoid<T, A...>::value || IsAbstract<T>,
|
||||||
T, A...
|
T, A...
|
||||||
> {};
|
> {};
|
||||||
|
|
||||||
|
@ -514,9 +517,8 @@ namespace detail {
|
||||||
|
|
||||||
template<typename T> False assign_test(Any, T &&);
|
template<typename T> False assign_test(Any, T &&);
|
||||||
|
|
||||||
template<typename T, typename U, bool = IsVoid<T>::value ||
|
template<typename T, typename U, bool = IsVoid<T> || IsVoid<U>>
|
||||||
IsVoid<U>::value
|
struct IsAssignableBase: CommonTypeBase<
|
||||||
> struct IsAssignableBase: CommonTypeBase<
|
|
||||||
decltype(assign_test(declval_in<T>(), declval_in<U>()))
|
decltype(assign_test(declval_in<T>(), declval_in<U>()))
|
||||||
>::Type {};
|
>::Type {};
|
||||||
|
|
||||||
|
@ -569,13 +571,13 @@ namespace detail {
|
||||||
template<typename T, bool> struct DtibleFalse;
|
template<typename T, bool> struct DtibleFalse;
|
||||||
|
|
||||||
template<typename T> struct DtibleFalse<T, false>
|
template<typename T> struct DtibleFalse<T, false>
|
||||||
: DtibleImpl<T, IsReference<T>::value> {};
|
: DtibleImpl<T, IsReference<T>> {};
|
||||||
|
|
||||||
template<typename T> struct DtibleFalse<T, true>: False {};
|
template<typename T> struct DtibleFalse<T, true>: False {};
|
||||||
} /* namespace detail */
|
} /* namespace detail */
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsDestructible: detail::DtibleFalse<T, IsFunction<T>::value> {};
|
struct IsDestructible: detail::DtibleFalse<T, IsFunction<T>> {};
|
||||||
|
|
||||||
template<typename T> struct IsDestructible<T[]>: False {};
|
template<typename T> struct IsDestructible<T[]>: False {};
|
||||||
template< > struct IsDestructible<void>: False {};
|
template< > struct IsDestructible<void>: False {};
|
||||||
|
@ -678,10 +680,10 @@ struct IsBaseOf: IntegralConstant<bool, __is_base_of(B, D)> {};
|
||||||
/* is convertible */
|
/* is convertible */
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename F, typename T, bool = IsVoid<F>::value
|
template<typename F, typename T, bool = IsVoid<F>
|
||||||
|| IsFunction<T>::value || IsArray<T>::value
|
|| IsFunction<T> || IsArray<T>
|
||||||
> struct IsConvertibleBase {
|
> struct IsConvertibleBase {
|
||||||
using Type = typename IsVoid<T>::Type;
|
using Type = IntegralConstant<bool, IsVoid<T>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename F, typename T>
|
template<typename F, typename T>
|
||||||
|
@ -701,11 +703,6 @@ namespace detail {
|
||||||
template<typename F, typename T>
|
template<typename F, typename T>
|
||||||
struct IsConvertible: detail::IsConvertibleBase<F, T>::Type {};
|
struct IsConvertible: detail::IsConvertibleBase<F, T>::Type {};
|
||||||
|
|
||||||
/* type equality */
|
|
||||||
|
|
||||||
template<typename, typename> struct IsSame : False {};
|
|
||||||
template<typename T > struct IsSame<T, T>: True {};
|
|
||||||
|
|
||||||
/* extent */
|
/* extent */
|
||||||
|
|
||||||
template<typename T, uint I = 0>
|
template<typename T, uint I = 0>
|
||||||
|
@ -762,8 +759,7 @@ namespace detail {
|
||||||
/* add const, volatile, cv */
|
/* add const, volatile, cv */
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T, bool = IsReference<T>::value
|
template<typename T, bool = IsReference<T> || IsFunction<T> || IsConst<T>>
|
||||||
|| IsFunction<T>::value || IsConst<T>::value>
|
|
||||||
struct AddConstCore { using Type = T; };
|
struct AddConstCore { using Type = T; };
|
||||||
|
|
||||||
template<typename T> struct AddConstCore<T, false> {
|
template<typename T> struct AddConstCore<T, false> {
|
||||||
|
@ -774,8 +770,7 @@ namespace detail {
|
||||||
using Type = typename AddConstCore<T>::Type;
|
using Type = typename AddConstCore<T>::Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, bool = IsReference<T>::value
|
template<typename T, bool = IsReference<T> || IsFunction<T> || IsVolatile<T>>
|
||||||
|| IsFunction<T>::value || IsVolatile<T>::value>
|
|
||||||
struct AddVolatileCore { using Type = T; };
|
struct AddVolatileCore { using Type = T; };
|
||||||
|
|
||||||
template<typename T> struct AddVolatileCore<T, false> {
|
template<typename T> struct AddVolatileCore<T, false> {
|
||||||
|
@ -951,8 +946,8 @@ namespace detail {
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename U,
|
template<typename T, typename U,
|
||||||
bool = IsConst<RemoveReference<T>>::value,
|
bool = IsConst<RemoveReference<T>>,
|
||||||
bool = IsVolatile<RemoveReference<T>>::value
|
bool = IsVolatile<RemoveReference<T>>
|
||||||
> struct ApplyCv {
|
> struct ApplyCv {
|
||||||
using Type = U;
|
using Type = U;
|
||||||
};
|
};
|
||||||
|
@ -987,12 +982,10 @@ namespace detail {
|
||||||
using Type = const volatile U &;
|
using Type = const volatile U &;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, bool = IsIntegral<T>::value ||
|
template<typename T, bool = IsIntegral<T> || IsEnum<T>>
|
||||||
IsEnum<T>::value>
|
|
||||||
struct MakeSignedCore {};
|
struct MakeSignedCore {};
|
||||||
|
|
||||||
template<typename T, bool = IsIntegral<T>::value ||
|
template<typename T, bool = IsIntegral<T> || IsEnum<T>>
|
||||||
IsEnum<T>::value>
|
|
||||||
struct MakeUnsignedCore {};
|
struct MakeUnsignedCore {};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -1133,10 +1126,9 @@ namespace detail {
|
||||||
private:
|
private:
|
||||||
using U = RemoveReference<T>;
|
using U = RemoveReference<T>;
|
||||||
public:
|
public:
|
||||||
using Type = Conditional<IsArray<U>::value,
|
using Type = Conditional<IsArray<U>,
|
||||||
RemoveExtent<U> *,
|
RemoveExtent<U> *,
|
||||||
Conditional<IsFunction<U>::value,
|
Conditional<IsFunction<U>, AddPointer<U>, RemoveCv<U>>
|
||||||
AddPointer<U>, RemoveCv<U>>
|
|
||||||
>;
|
>;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ template<typename T> AddRvalueReference<T> declval();
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto test_swap(int) ->
|
auto test_swap(int) ->
|
||||||
decltype(IsVoid<decltype(declval<T>().swap(declval<T &>()))>());
|
IntegralConstant<bool, IsVoid<decltype(declval<T>().swap(declval<T &>()))>>;
|
||||||
template<typename>
|
template<typename>
|
||||||
False test_swap(...);
|
False test_swap(...);
|
||||||
|
|
||||||
|
@ -261,8 +261,7 @@ TupleElement<I, Pair<T, U>> &&get(Pair<T, U> &&p) {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T, typename U,
|
template<typename T, typename U,
|
||||||
bool = IsSame<RemoveCv<T>, RemoveCv<U>>::value,
|
bool = IsSame<RemoveCv<T>, RemoveCv<U>>::value,
|
||||||
bool = IsEmpty<T>::value,
|
bool = IsEmpty<T>, bool = IsEmpty<U>
|
||||||
bool = IsEmpty<U>::value
|
|
||||||
> struct CompressedPairSwitch;
|
> struct CompressedPairSwitch;
|
||||||
|
|
||||||
/* neither empty */
|
/* neither empty */
|
||||||
|
|
|
@ -35,8 +35,7 @@ class Vector {
|
||||||
|
|
||||||
template<typename R>
|
template<typename R>
|
||||||
void ctor_from_range(R &range, EnableIf<
|
void ctor_from_range(R &range, EnableIf<
|
||||||
IsFiniteRandomAccessRange<R>::value &&
|
IsFiniteRandomAccessRange<R>::value && IsPod<T> &&
|
||||||
IsPod<T>::value &&
|
|
||||||
IsSame<T, RemoveCv<RangeValue<R>>>::value, bool
|
IsSame<T, RemoveCv<RangeValue<R>>>::value, bool
|
||||||
> = true) {
|
> = true) {
|
||||||
RangeSize<R> l = range.size();
|
RangeSize<R> l = range.size();
|
||||||
|
@ -47,8 +46,7 @@ class Vector {
|
||||||
|
|
||||||
template<typename R>
|
template<typename R>
|
||||||
void ctor_from_range(R &range, EnableIf<
|
void ctor_from_range(R &range, EnableIf<
|
||||||
!IsFiniteRandomAccessRange<R>::value ||
|
!IsFiniteRandomAccessRange<R>::value || !IsPod<T> ||
|
||||||
!IsPod<T>::value ||
|
|
||||||
!IsSame<T, RemoveCv<RangeValue<R>>>::value, bool
|
!IsSame<T, RemoveCv<RangeValue<R>>>::value, bool
|
||||||
> = true) {
|
> = true) {
|
||||||
Size i = 0;
|
Size i = 0;
|
||||||
|
@ -62,7 +60,7 @@ class Vector {
|
||||||
}
|
}
|
||||||
|
|
||||||
void copy_contents(const Vector &v) {
|
void copy_contents(const Vector &v) {
|
||||||
if (IsPod<T>()) {
|
if (IsPod<T>) {
|
||||||
memcpy(p_buf.first(), v.p_buf.first(), p_len * sizeof(T));
|
memcpy(p_buf.first(), v.p_buf.first(), p_len * sizeof(T));
|
||||||
} else {
|
} else {
|
||||||
Pointer cur = p_buf.first(), last = p_buf.first() + p_len;
|
Pointer cur = p_buf.first(), last = p_buf.first() + p_len;
|
||||||
|
@ -120,7 +118,7 @@ public:
|
||||||
if (a != v.p_buf.second()) {
|
if (a != v.p_buf.second()) {
|
||||||
reserve(v.p_cap);
|
reserve(v.p_cap);
|
||||||
p_len = v.p_len;
|
p_len = v.p_len;
|
||||||
if (IsPod<T>()) {
|
if (IsPod<T>) {
|
||||||
memcpy(p_buf.first(), v.p_buf.first(), p_len * sizeof(T));
|
memcpy(p_buf.first(), v.p_buf.first(), p_len * sizeof(T));
|
||||||
} else {
|
} else {
|
||||||
Pointer cur = p_buf.first(), last = p_buf.first() + p_len;
|
Pointer cur = p_buf.first(), last = p_buf.first() + p_len;
|
||||||
|
@ -140,7 +138,7 @@ public:
|
||||||
|
|
||||||
Vector(ConstRange r, const A &a = A()): Vector(a) {
|
Vector(ConstRange r, const A &a = A()): Vector(a) {
|
||||||
reserve(r.size());
|
reserve(r.size());
|
||||||
if (IsPod<T>()) {
|
if (IsPod<T>) {
|
||||||
memcpy(p_buf.first(), &r[0], r.size() * sizeof(T));
|
memcpy(p_buf.first(), &r[0], r.size() * sizeof(T));
|
||||||
} else {
|
} else {
|
||||||
for (Size i = 0; i < r.size(); ++i)
|
for (Size i = 0; i < r.size(); ++i)
|
||||||
|
@ -165,7 +163,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
if (p_len > 0 && !IsPod<T>()) {
|
if (p_len > 0 && !IsPod<T>) {
|
||||||
Pointer cur = p_buf.first(), last = p_buf.first() + p_len;
|
Pointer cur = p_buf.first(), last = p_buf.first() + p_len;
|
||||||
while (cur != last)
|
while (cur != last)
|
||||||
allocator_destroy(p_buf.second(), cur++);
|
allocator_destroy(p_buf.second(), cur++);
|
||||||
|
@ -206,7 +204,7 @@ public:
|
||||||
clear();
|
clear();
|
||||||
Size ilen = il.end() - il.begin();
|
Size ilen = il.end() - il.begin();
|
||||||
reserve(ilen);
|
reserve(ilen);
|
||||||
if (IsPod<T>()) {
|
if (IsPod<T>) {
|
||||||
memcpy(p_buf.first(), il.begin(), ilen);
|
memcpy(p_buf.first(), il.begin(), ilen);
|
||||||
} else {
|
} else {
|
||||||
Pointer tbuf = p_buf.first(), ibuf = il.begin(),
|
Pointer tbuf = p_buf.first(), ibuf = il.begin(),
|
||||||
|
@ -237,7 +235,7 @@ public:
|
||||||
Size l = p_len;
|
Size l = p_len;
|
||||||
reserve(n);
|
reserve(n);
|
||||||
p_len = n;
|
p_len = n;
|
||||||
if (IsPod<T>()) {
|
if (IsPod<T>) {
|
||||||
for (Size i = l; i < p_len; ++i) {
|
for (Size i = l; i < p_len; ++i) {
|
||||||
p_buf.first()[i] = T(v);
|
p_buf.first()[i] = T(v);
|
||||||
}
|
}
|
||||||
|
@ -259,7 +257,7 @@ public:
|
||||||
}
|
}
|
||||||
Pointer tmp = allocator_allocate(p_buf.second(), p_cap);
|
Pointer tmp = allocator_allocate(p_buf.second(), p_cap);
|
||||||
if (oc > 0) {
|
if (oc > 0) {
|
||||||
if (IsPod<T>()) {
|
if (IsPod<T>) {
|
||||||
memcpy(tmp, p_buf.first(), p_len * sizeof(T));
|
memcpy(tmp, p_buf.first(), p_len * sizeof(T));
|
||||||
} else {
|
} else {
|
||||||
Pointer cur = p_buf.first(), tcur = tmp,
|
Pointer cur = p_buf.first(), tcur = tmp,
|
||||||
|
@ -307,7 +305,7 @@ public:
|
||||||
|
|
||||||
Range push_n(const T *v, Size n) {
|
Range push_n(const T *v, Size n) {
|
||||||
reserve(p_len + n);
|
reserve(p_len + n);
|
||||||
if (IsPod<T>()) {
|
if (IsPod<T>) {
|
||||||
memcpy(p_buf.first() + p_len, v, n * sizeof(T));
|
memcpy(p_buf.first() + p_len, v, n * sizeof(T));
|
||||||
} else {
|
} else {
|
||||||
for (Size i = 0; i < n; ++i)
|
for (Size i = 0; i < n; ++i)
|
||||||
|
@ -327,7 +325,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop() {
|
void pop() {
|
||||||
if (!IsPod<T>()) {
|
if (!IsPod<T>) {
|
||||||
allocator_destroy(p_buf.second(), &p_buf.first()[--p_len]);
|
allocator_destroy(p_buf.second(), &p_buf.first()[--p_len]);
|
||||||
} else {
|
} else {
|
||||||
--p_len;
|
--p_len;
|
||||||
|
|
|
@ -7,7 +7,7 @@ import subprocess as sp
|
||||||
|
|
||||||
COMPILER = "c++"
|
COMPILER = "c++"
|
||||||
CXXFLAGS = [
|
CXXFLAGS = [
|
||||||
"-std=c++11",
|
"-std=c++14",
|
||||||
"-Wall", "-Wextra",
|
"-Wall", "-Wextra",
|
||||||
"-Wno-missing-braces", # clang false positive
|
"-Wno-missing-braces", # clang false positive
|
||||||
"-I."
|
"-I."
|
||||||
|
|
Loading…
Reference in a new issue