convert a part of type traits to template variables (reduces verbosity in a lot of places)

master
Daniel Kolesa 2016-01-12 21:45:26 +00:00
parent 05bc21e255
commit d53556d336
15 changed files with 219 additions and 250 deletions

View File

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

View File

@ -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 &param, EnableIf< bool convert_arg_param(const T &val, int &param, 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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