more trait cleanups

master
Daniel Kolesa 2016-01-14 21:16:42 +00:00
parent 37059e505b
commit 31a46ef07d
1 changed files with 64 additions and 84 deletions

View File

@ -348,17 +348,17 @@ namespace detail {
template<typename ...A> False is_ctible_test(Any, A &&...); template<typename ...A> False is_ctible_test(Any, A &&...);
template<bool, typename T, typename ...A> template<bool, typename T, typename ...A>
struct CtibleCore: CommonTypeBase< constexpr bool CtibleCore = CommonTypeBase<
decltype(is_ctible_test(declval_in<T>(), declval_in<A>()...)) decltype(is_ctible_test(declval_in<T>(), declval_in<A>()...))
>::Type {}; >::Type::value;
/* function types are not constructible */ /* function types are not constructible */
template<typename R, typename ...A1, typename ...A2> template<typename R, typename ...A1, typename ...A2>
struct CtibleCore<false, R(A1...), A2...>: False {}; constexpr bool CtibleCore<false, R(A1...), A2...> = false;
/* scalars are default constructible, refs are not */ /* scalars are default constructible, refs are not */
template<typename T> template<typename T>
struct CtibleCore<true, T>: IntegralConstant<bool, IsScalar<T>> {}; constexpr bool CtibleCore<true, T> = 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 */
@ -369,56 +369,53 @@ namespace detail {
}; };
template<typename T, typename U> template<typename T, typename U>
struct CtibleCore<true, T, U>: CommonTypeBase< constexpr bool CtibleCore<true, T, U> = CommonTypeBase<
decltype(CtibleRef<T>::test(declval_in<U>())) decltype(CtibleRef<T>::test(declval_in<U>()))
>::Type {}; >::Type::value;
/* scalars and references are not constructible from multiple args */ /* scalars and references are not constructible from multiple args */
template<typename T, typename U, typename ...A> template<typename T, typename U, typename ...A>
struct CtibleCore<true, T, U, A...>: False {}; constexpr bool CtibleCore<true, T, U, A...> = false;
/* 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< constexpr bool CtibleVoidCheck = CtibleCore<
(IsScalar<T> || IsReference<T>), 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 */
template<typename T, typename ...A> template<typename T, typename ...A>
struct CtibleVoidCheck<true, T, A...>: False {}; constexpr bool CtibleVoidCheck<true, T, A...> = false;
template<typename ...A> struct CtibleContainsVoid; template<typename ...A> constexpr bool CtibleContainsVoid = false;
template<> struct CtibleContainsVoid<>: False {}; template<> constexpr bool CtibleContainsVoid<> = false;
template<typename T, typename ...A> template<typename T, typename ...A>
struct CtibleContainsVoid<T, A...> { constexpr bool CtibleContainsVoid<T, A...>
static constexpr bool value = IsVoid<T> = IsVoid<T> || CtibleContainsVoid<A...>;
|| CtibleContainsVoid<A...>::value;
};
/* entry point */ /* entry point */
template<typename T, typename ...A> template<typename T, typename ...A>
struct Ctible: CtibleVoidCheck< constexpr bool Ctible = CtibleVoidCheck<
CtibleContainsVoid<T, A...>::value || IsAbstract<T>, CtibleContainsVoid<T, A...> || IsAbstract<T>, T, A...
T, A... >;
> {};
/* array types are default constructible if their element type is */ /* array types are default constructible if their element type is */
template<typename T, Size N> template<typename T, Size N>
struct CtibleCore<false, T[N]>: Ctible<RemoveAllExtents<T>> {}; constexpr bool CtibleCore<false, T[N]> = Ctible<RemoveAllExtents<T>>;
/* otherwise array types are not constructible by this syntax */ /* otherwise array types are not constructible by this syntax */
template<typename T, Size N, typename ...A> template<typename T, Size N, typename ...A>
struct CtibleCore<false, T[N], A...>: False {}; constexpr bool CtibleCore<false, T[N], A...> = false;
/* incomplete array types are not constructible */ /* incomplete array types are not constructible */
template<typename T, typename ...A> template<typename T, typename ...A>
struct CtibleCore<false, T[], A...>: False {}; constexpr bool CtibleCore<false, T[], A...> = false;
} /* namespace detail */ } /* namespace detail */
template<typename T, typename ...A> template<typename T, typename ...A>
constexpr bool IsConstructible = detail::Ctible<T, A...>::value; constexpr bool IsConstructible = detail::Ctible<T, A...>;
/* is default constructible */ /* is default constructible */
@ -449,16 +446,16 @@ 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> || IsVoid<U>> template<typename T, typename U, bool = IsVoid<T> || IsVoid<U>>
struct IsAssignableBase: CommonTypeBase< constexpr bool IsAssignableBase = CommonTypeBase<
decltype(assign_test(declval_in<T>(), declval_in<U>())) decltype(assign_test(declval_in<T>(), declval_in<U>()))
>::Type {}; >::Type::value;
template<typename T, typename U> template<typename T, typename U>
struct IsAssignableBase<T, U, true>: False {}; constexpr bool IsAssignableBase<T, U, true> = false;
} /* namespace detail */ } /* namespace detail */
template<typename T, typename U> template<typename T, typename U>
constexpr bool IsAssignable = detail::IsAssignableBase<T, U>::value; constexpr bool IsAssignable = detail::IsAssignableBase<T, U>;
/* is copy assignable */ /* is copy assignable */
@ -491,63 +488,58 @@ namespace detail {
static constexpr bool value = (sizeof(test<T>(12)) == sizeof(char)); static constexpr bool value = (sizeof(test<T>(12)) == sizeof(char));
}; };
template<typename, bool> struct DtibleImpl; template<typename, bool> constexpr bool DtibleImpl = false;
template<typename T> template<typename T>
struct DtibleImpl<T, false>: IntegralConstant<bool, constexpr bool DtibleImpl<T, false>
IsDestructorWellformed<RemoveAllExtents<T>>::value = IsDestructorWellformed<RemoveAllExtents<T>>::value;
> {};
template<typename T> template<typename T>
struct DtibleImpl<T, true>: True {}; constexpr bool DtibleImpl<T, true> = true;
template<typename T, bool> struct DtibleFalse; template<typename T, bool> constexpr bool DtibleFalse = false;
template<typename T> struct DtibleFalse<T, false> template<typename T> constexpr bool DtibleFalse<T, false>
: DtibleImpl<T, IsReference<T>> {}; = DtibleImpl<T, IsReference<T>>;
template<typename T> struct DtibleFalse<T, true>: False {}; template<typename T> constexpr bool DtibleFalse<T, true> = false;
template<typename T> template<typename T>
struct IsDestructibleBase: detail::DtibleFalse<T, IsFunction<T>> {}; constexpr bool IsDestructibleBase = detail::DtibleFalse<T, IsFunction<T>>;
template<typename T> struct IsDestructibleBase<T[]>: False {}; template<typename T> constexpr bool IsDestructibleBase<T[] > = false;
template< > struct IsDestructibleBase<void>: False {}; template< > constexpr bool IsDestructibleBase<void> = false;
} /* namespace detail */ } /* namespace detail */
template<typename T> template<typename T>
constexpr bool IsDestructible = detail::IsDestructibleBase<T>::value; constexpr bool IsDestructible = detail::IsDestructibleBase<T>;
/* is trivially constructible */ /* is trivially constructible */
namespace detail { namespace detail {
template<typename T, typename ...A> template<typename T, typename ...A>
struct IsTriviallyConstructibleBase: False {}; constexpr bool IsTriviallyConstructibleBase = false;
template<typename T> template<typename T>
struct IsTriviallyConstructibleBase<T>: IntegralConstant<bool, constexpr bool IsTriviallyConstructibleBase<T>
__has_trivial_constructor(T) = __has_trivial_constructor(T);
> {};
template<typename T> template<typename T>
struct IsTriviallyConstructibleBase<T, T &>: IntegralConstant<bool, constexpr bool IsTriviallyConstructibleBase<T, T &>
__has_trivial_copy(T) = __has_trivial_copy(T);
> {};
template<typename T> template<typename T>
struct IsTriviallyConstructibleBase<T, const T &>: IntegralConstant<bool, constexpr bool IsTriviallyConstructibleBase<T, const T &>
__has_trivial_copy(T) = __has_trivial_copy(T);
> {};
template<typename T> template<typename T>
struct IsTriviallyConstructibleBase<T, T &&>: IntegralConstant<bool, constexpr bool IsTriviallyConstructibleBase<T, T &&>
__has_trivial_copy(T) = __has_trivial_copy(T);
> {};
} /* namespace detail */ } /* namespace detail */
template<typename T, typename ...A> template<typename T, typename ...A>
constexpr bool IsTriviallyConstructible constexpr bool IsTriviallyConstructible
= detail::IsTriviallyConstructibleBase<T, A...>::value; = detail::IsTriviallyConstructibleBase<T, A...>;
/* is trivially default constructible */ /* is trivially default constructible */
@ -568,32 +560,28 @@ template<typename T> constexpr bool IsTriviallyMoveConstructible
namespace detail { namespace detail {
template<typename T, typename ...A> template<typename T, typename ...A>
struct IsTriviallyAssignableBase: False {}; constexpr bool IsTriviallyAssignableBase = false;
template<typename T> template<typename T>
struct IsTriviallyAssignableBase<T>: IntegralConstant<bool, constexpr bool IsTriviallyAssignableBase<T>
__has_trivial_assign(T) = __has_trivial_assign(T);
> {};
template<typename T> template<typename T>
struct IsTriviallyAssignableBase<T, T &>: IntegralConstant<bool, constexpr bool IsTriviallyAssignableBase<T, T &>
__has_trivial_copy(T) = __has_trivial_copy(T);
> {};
template<typename T> template<typename T>
struct IsTriviallyAssignableBase<T, const T &>: IntegralConstant<bool, constexpr bool IsTriviallyAssignableBase<T, const T &>
__has_trivial_copy(T) = __has_trivial_copy(T);
> {};
template<typename T> template<typename T>
struct IsTriviallyAssignableBase<T, T &&>: IntegralConstant<bool, constexpr bool IsTriviallyAssignableBase<T, T &&>
__has_trivial_copy(T) = __has_trivial_copy(T);
> {};
} /* namespace detail */ } /* namespace detail */
template<typename T, typename ...A> template<typename T, typename ...A>
constexpr bool IsTriviallyAssignable constexpr bool IsTriviallyAssignable
= detail::IsTriviallyAssignableBase<T>::value; = detail::IsTriviallyAssignableBase<T>;
/* is trivially copy assignable */ /* is trivially copy assignable */
@ -1131,29 +1119,21 @@ template<Size N, Size A
/* aligned union */ /* aligned union */
namespace detail { namespace detail {
template<Size ...N> struct AlignMax; template<Size ...N> constexpr Size AlignMax = 0;
template<Size N> constexpr Size AlignMax<N> = N;
template<Size N> struct AlignMax<N> { template<Size N1, Size N2> constexpr Size AlignMax<N1, N2>
static constexpr Size value = N; = (N1 > N2) ? N1 : N2;
};
template<Size N1, Size N2> struct AlignMax<N1, N2> {
static constexpr Size value = (N1 > N2) ? N1 : N2;
};
template<Size N1, Size N2, Size ...N> template<Size N1, Size N2, Size ...N>
struct AlignMax<N1, N2, N...> { constexpr Size AlignMax<N1, N2, N...> = AlignMax<AlignMax<N1, N2>, N...>;
static constexpr Size value
= AlignMax<AlignMax<N1, N2>::value, N...>::value;
};
template<Size N, typename ...T> struct AlignedUnionBase { template<Size N, typename ...T> struct AlignedUnionBase {
static constexpr Size alignment_value static constexpr Size alignment_value
= AlignMax<alignof(T)...>::value; = AlignMax<alignof(T)...>;
struct type { struct type {
alignas(alignment_value) byte data[AlignMax<N, alignas(alignment_value) byte data[AlignMax<N, sizeof(T)...>];
sizeof(T)...>::value];
}; };
}; };
} /* namespace detail */ } /* namespace detail */