forked from OctaForge/libostd
more trait cleanups
parent
37059e505b
commit
31a46ef07d
|
@ -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 */
|
||||||
|
|
Loading…
Reference in New Issue