clean up the rest of type traits

This commit is contained in:
q66 2015-06-04 21:47:30 +01:00
parent 49188f78ea
commit 47016ec6ad

View file

@ -14,24 +14,21 @@ namespace octa {
/* forward declarations */ /* forward declarations */
namespace detail { namespace detail {
template<typename> struct RemoveCv; template<typename> struct RemoveCvBase;
template<typename> struct AddLr; template<typename> struct AddLr;
template<typename> struct AddRr; template<typename> struct AddRr;
template<typename> struct AddConst; template<typename> struct AddConstBase;
template<typename> struct RemoveReference; template<typename> struct RemoveReferenceBase;
template<typename> struct RemoveAllExtents; template<typename> struct RemoveAllExtentsBase;
template<typename ...> struct CommonTypeBase; template<typename ...> struct CommonTypeBase;
} }
template<typename> struct __OctaAddConst;
template<typename> struct IsReference; template<typename> struct IsReference;
template<typename> struct __OctaRemoveReference;
template<typename> struct __OctaRemoveAllExtents;
template<typename> struct IsTriviallyDefaultConstructible; template<typename> struct IsTriviallyDefaultConstructible;
template<typename _T> template<typename _T>
using RemoveCv = typename octa::detail::RemoveCv<_T>::Type; using RemoveCv = typename octa::detail::RemoveCvBase<_T>::Type;
template<typename _T> template<typename _T>
using AddLvalueReference = typename octa::detail::AddLr<_T>::Type; using AddLvalueReference = typename octa::detail::AddLr<_T>::Type;
@ -40,13 +37,13 @@ template<typename _T>
using AddRvalueReference = typename octa::detail::AddRr<_T>::Type; using AddRvalueReference = typename octa::detail::AddRr<_T>::Type;
template<typename _T> template<typename _T>
using AddConst = typename __OctaAddConst<_T>::Type; using AddConst = typename octa::detail::AddConstBase<_T>::Type;
template<typename _T> template<typename _T>
using RemoveReference = typename __OctaRemoveReference<_T>::Type; using RemoveReference = typename octa::detail::RemoveReferenceBase<_T>::Type;
template<typename _T> template<typename _T>
using RemoveAllExtents = typename __OctaRemoveAllExtents<_T>::Type; using RemoveAllExtents = typename octa::detail::RemoveAllExtentsBase<_T>::Type;
namespace detail { namespace detail {
template<typename _T> octa::AddRvalueReference<_T> declval_in(); template<typename _T> octa::AddRvalueReference<_T> declval_in();
@ -484,37 +481,39 @@ template<typename _T> struct IsMoveAssignable: IsAssignable<
/* is destructible */ /* is destructible */
template<typename> struct __OctaIsDtibleApply { typedef int Type; }; namespace detail {
template<typename> struct IsDtibleApply { typedef int Type; };
template<typename _T> struct IsDestructorWellformed { template<typename _T> struct IsDestructorWellformed {
template<typename _TT> static char __test(typename __OctaIsDtibleApply< template<typename _TT> static char test(typename IsDtibleApply<
decltype(octa::detail::declval_in<_TT &>().~_TT()) decltype(octa::detail::declval_in<_TT &>().~_TT())
>::Type); >::Type);
template<typename _TT> static int __test(...); template<typename _TT> static int test(...);
static constexpr bool value = (sizeof(__test<_T>(12)) == sizeof(char)); static constexpr bool value = (sizeof(test<_T>(12)) == sizeof(char));
}; };
template<typename, bool> struct __OctaDtibleImpl; template<typename, bool> struct DtibleImpl;
template<typename _T> template<typename _T>
struct __OctaDtibleImpl<_T, false>: IntegralConstant<bool, struct DtibleImpl<_T, false>: octa::IntegralConstant<bool,
IsDestructorWellformed<RemoveAllExtents<_T>>::value IsDestructorWellformed<octa::RemoveAllExtents<_T>>::value
> {}; > {};
template<typename _T> template<typename _T>
struct __OctaDtibleImpl<_T, true>: True {}; struct DtibleImpl<_T, true>: True {};
template<typename _T, bool> struct __OctaDtibleFalse; template<typename _T, bool> struct DtibleFalse;
template<typename _T> struct __OctaDtibleFalse<_T, false> template<typename _T> struct DtibleFalse<_T, false>
: __OctaDtibleImpl<_T, IsReference<_T>::value> {}; : DtibleImpl<_T, octa::IsReference<_T>::value> {};
template<typename _T> struct __OctaDtibleFalse<_T, true>: False {}; template<typename _T> struct DtibleFalse<_T, true>: False {};
} /* namespace detail */
template<typename _T> template<typename _T>
struct IsDestructible: __OctaDtibleFalse<_T, IsFunction<_T>::value> {}; struct IsDestructible: octa::detail::DtibleFalse<_T, IsFunction<_T>::value> {};
template<typename _T> struct IsDestructible<_T[]>: False {}; template<typename _T> struct IsDestructible<_T[]>: False {};
template< > struct IsDestructible<void>: False {}; template< > struct IsDestructible<void>: False {};
@ -616,27 +615,29 @@ template<typename _T> struct IsMoveAssignable: IsAssignable<
/* is convertible */ /* is convertible */
template<typename _F, typename _T, bool = IsVoid<_F>::value namespace detail {
|| IsFunction<_T>::value || IsArray<_T>::value template<typename _F, typename _T, bool = octa::IsVoid<_F>::value
> struct __OctaIsConvertible { || octa::IsFunction<_T>::value || octa::IsArray<_T>::value
typedef typename IsVoid<_T>::Type Type; > struct IsConvertibleBase {
typedef typename octa::IsVoid<_T>::Type Type;
}; };
template<typename _F, typename _T> template<typename _F, typename _T>
struct __OctaIsConvertible<_F, _T, false> { struct IsConvertibleBase<_F, _T, false> {
template<typename _TT> static void __test_f(_TT); template<typename _TT> static void test_f(_TT);
template<typename _FF, typename _TT, template<typename _FF, typename _TT,
typename = decltype(__test_f<_TT>(octa::detail::declval_in<_FF>())) typename = decltype(test_f<_TT>(declval_in<_FF>()))
> static True __test(int); > static octa::True test(int);
template<typename, typename> static False __test(...); template<typename, typename> static octa::False test(...);
typedef decltype(__test<_F, _T>(0)) Type; typedef decltype(test<_F, _T>(0)) Type;
}; };
}
template<typename _F, typename _T> template<typename _F, typename _T>
struct IsConvertible: __OctaIsConvertible<_F, _T>::Type {}; struct IsConvertible: octa::detail::IsConvertibleBase<_F, _T>::Type {};
/* type equality */ /* type equality */
@ -672,98 +673,110 @@ template<typename _T> struct IsMoveAssignable: IsAssignable<
/* remove const, volatile, cv */ /* remove const, volatile, cv */
namespace detail {
template<typename _T> template<typename _T>
struct __OctaRemoveConst { typedef _T Type; }; struct RemoveConstBase { typedef _T Type; };
template<typename _T> template<typename _T>
struct __OctaRemoveConst<const _T> { typedef _T Type; }; struct RemoveConstBase<const _T> { typedef _T Type; };
template<typename _T> template<typename _T>
struct __OctaRemoveVolatile { typedef _T Type; }; struct RemoveVolatileBase { typedef _T Type; };
template<typename _T> template<typename _T>
struct __OctaRemoveVolatile<volatile _T> { typedef _T Type; }; struct RemoveVolatileBase<volatile _T> { typedef _T Type; };
}
template<typename _T> template<typename _T>
using RemoveConst = typename __OctaRemoveConst<_T>::Type; using RemoveConst = typename octa::detail::RemoveConstBase<_T>::Type;
template<typename _T> template<typename _T>
using RemoveVolatile = typename __OctaRemoveVolatile<_T>::Type; using RemoveVolatile = typename octa::detail::RemoveVolatileBase<_T>::Type;
namespace detail { namespace detail {
template<typename _T> template<typename _T>
struct RemoveCv { struct RemoveCvBase {
typedef octa::RemoveVolatile<octa::RemoveConst<_T>> Type; typedef octa::RemoveVolatile<octa::RemoveConst<_T>> Type;
}; };
} }
/* add const, volatile, cv */ /* add const, volatile, cv */
template<typename _T, bool = IsReference<_T>::value namespace detail {
|| IsFunction<_T>::value || IsConst<_T>::value> template<typename _T, bool = octa::IsReference<_T>::value
struct __OctaAddConstBase { typedef _T Type; }; || octa::IsFunction<_T>::value || octa::IsConst<_T>::value>
struct AddConstCore { typedef _T Type; };
template<typename _T> struct __OctaAddConstBase<_T, false> { template<typename _T> struct AddConstCore<_T, false> {
typedef const _T Type; typedef const _T Type;
}; };
template<typename _T> struct __OctaAddConst { template<typename _T> struct AddConstBase {
typedef typename __OctaAddConstBase<_T>::Type Type; typedef typename AddConstCore<_T>::Type Type;
}; };
template<typename _T, bool = IsReference<_T>::value template<typename _T, bool = octa::IsReference<_T>::value
|| IsFunction<_T>::value || IsVolatile<_T>::value> || octa::IsFunction<_T>::value || octa::IsVolatile<_T>::value>
struct __OctaAddVolatileBase { typedef _T Type; }; struct AddVolatileCore { typedef _T Type; };
template<typename _T> struct __OctaAddVolatileBase<_T, false> { template<typename _T> struct AddVolatileCore<_T, false> {
typedef volatile _T Type; typedef volatile _T Type;
}; };
template<typename _T> struct __OctaAddVolatile { template<typename _T> struct AddVolatileBase {
typedef typename __OctaAddVolatileBase<_T>::Type Type; typedef typename AddVolatileCore<_T>::Type Type;
}; };
}
template<typename _T> template<typename _T>
using AddVolatile = typename __OctaAddVolatile<_T>::Type; using AddVolatile = typename octa::detail::AddVolatileBase<_T>::Type;
namespace detail {
template<typename _T> template<typename _T>
struct __OctaAddCv { struct AddCvBase {
typedef AddConst<AddVolatile<_T>> Type; typedef octa::AddConst<octa::AddVolatile<_T>> Type;
}; };
}
template<typename _T> template<typename _T>
using AddCv = typename __OctaAddCv<_T>::Type; using AddCv = typename octa::detail::AddCvBase<_T>::Type;
/* remove reference */ /* remove reference */
namespace detail {
template<typename _T> template<typename _T>
struct __OctaRemoveReference { typedef _T Type; }; struct RemoveReferenceBase { typedef _T Type; };
template<typename _T> template<typename _T>
struct __OctaRemoveReference<_T &> { typedef _T Type; }; struct RemoveReferenceBase<_T &> { typedef _T Type; };
template<typename _T> template<typename _T>
struct __OctaRemoveReference<_T &&> { typedef _T Type; }; struct RemoveReferenceBase<_T &&> { typedef _T Type; };
}
/* remove pointer */ /* remove pointer */
namespace detail {
template<typename _T> template<typename _T>
struct __OctaRemovePointer { typedef _T Type; }; struct RemovePointerBase { typedef _T Type; };
template<typename _T> template<typename _T>
struct __OctaRemovePointer<_T * > { typedef _T Type; }; struct RemovePointerBase<_T * > { typedef _T Type; };
template<typename _T> template<typename _T>
struct __OctaRemovePointer<_T * const > { typedef _T Type; }; struct RemovePointerBase<_T * const > { typedef _T Type; };
template<typename _T> template<typename _T>
struct __OctaRemovePointer<_T * volatile > { typedef _T Type; }; struct RemovePointerBase<_T * volatile > { typedef _T Type; };
template<typename _T> template<typename _T>
struct __OctaRemovePointer<_T * const volatile> { typedef _T Type; }; struct RemovePointerBase<_T * const volatile> { typedef _T Type; };
}
template<typename _T> template<typename _T>
using RemovePointer = typename __OctaRemovePointer<_T>::Type; using RemovePointer = typename octa::detail::RemovePointerBase<_T>::Type;
/* add pointer */ /* add pointer */
template<typename _T> struct __OctaAddPointer { namespace detail {
typedef RemoveReference<_T> *Type; template<typename _T> struct AddPointerBase {
typedef octa::RemoveReference<_T> *Type;
}; };
}
template<typename _T> template<typename _T>
using AddPointer = typename __OctaAddPointer<_T>::Type; using AddPointer = typename octa::detail::AddPointerBase<_T>::Type;
/* add lvalue reference */ /* add lvalue reference */
@ -807,27 +820,31 @@ namespace detail {
/* remove extent */ /* remove extent */
namespace detail {
template<typename _T> template<typename _T>
struct __OctaRemoveExtent { typedef _T Type; }; struct RemoveExtentBase { typedef _T Type; };
template<typename _T> template<typename _T>
struct __OctaRemoveExtent<_T[ ] > { typedef _T Type; }; struct RemoveExtentBase<_T[ ] > { typedef _T Type; };
template<typename _T, size_t _N> template<typename _T, size_t _N>
struct __OctaRemoveExtent<_T[_N]> { typedef _T Type; }; struct RemoveExtentBase<_T[_N]> { typedef _T Type; };
}
template<typename _T> template<typename _T>
using RemoveExtent = typename __OctaRemoveExtent<_T>::Type; using RemoveExtent = typename octa::detail::RemoveExtentBase<_T>::Type;
/* remove all extents */ /* remove all extents */
template<typename _T> struct __OctaRemoveAllExtents { typedef _T Type; }; namespace detail {
template<typename _T> struct RemoveAllExtentsBase { typedef _T Type; };
template<typename _T> struct __OctaRemoveAllExtents<_T[]> { template<typename _T> struct RemoveAllExtentsBase<_T[]> {
typedef RemoveAllExtents<_T> Type; typedef RemoveAllExtentsBase<_T> Type;
}; };
template<typename _T, size_t _N> struct __OctaRemoveAllExtents<_T[_N]> { template<typename _T, size_t _N> struct RemoveAllExtentsBase<_T[_N]> {
typedef RemoveAllExtents<_T> Type; typedef RemoveAllExtentsBase<_T> Type;
}; };
}
/* make (un)signed /* make (un)signed
* *
@ -1092,63 +1109,69 @@ using CommonType = typename octa::detail::CommonTypeBase<_T, _U, _V...>::Type;
/* aligned storage */ /* aligned storage */
template<size_t _N> struct __OctaAlignedTest { namespace detail {
template<size_t _N> struct AlignedTest {
union type { union type {
uchar __data[_N]; uchar data[_N];
octa::max_align_t __align; octa::max_align_t align;
}; };
}; };
template<size_t _N, size_t _A> struct __OctaAlignedStorage { template<size_t _N, size_t _A> struct AlignedStorageBase {
struct type { struct type {
alignas(_A) uchar __data[_N]; alignas(_A) uchar data[_N];
}; };
}; };
}
template<size_t _N, size_t _A template<size_t _N, size_t _A
= alignof(typename __OctaAlignedTest<_N>::Type) = alignof(typename octa::detail::AlignedTest<_N>::Type)
> using AlignedStorage = typename __OctaAlignedStorage<_N, _A>::Type; > using AlignedStorage = typename octa::detail::AlignedStorageBase<_N, _A>::Type;
/* aligned union */ /* aligned union */
template<size_t ..._N> struct __OctaAlignMax; namespace detail {
template<size_t ..._N> struct AlignMax;
template<size_t _N> struct __OctaAlignMax<_N> { template<size_t _N> struct AlignMax<_N> {
static constexpr size_t value = _N; static constexpr size_t value = _N;
}; };
template<size_t _N1, size_t _N2> struct __OctaAlignMax<_N1, _N2> { template<size_t _N1, size_t _N2> struct AlignMax<_N1, _N2> {
static constexpr size_t value = (_N1 > _N2) ? _N1 : _N2; static constexpr size_t value = (_N1 > _N2) ? _N1 : _N2;
}; };
template<size_t _N1, size_t _N2, size_t ..._N> template<size_t _N1, size_t _N2, size_t ..._N>
struct __OctaAlignMax<_N1, _N2, _N...> { struct AlignMax<_N1, _N2, _N...> {
static constexpr size_t value static constexpr size_t value
= __OctaAlignMax<__OctaAlignMax<_N1, _N2>::value, _N...>::value; = AlignMax<AlignMax<_N1, _N2>::value, _N...>::value;
}; };
template<size_t _N, typename ..._T> struct __OctaAlignedUnion { template<size_t _N, typename ..._T> struct AlignedUnionBase {
static constexpr size_t __alignment_value static constexpr size_t alignment_value
= __OctaAlignMax<alignof(_T)...>::value; = AlignMax<alignof(_T)...>::value;
struct type { struct type {
alignas(__alignment_value) uchar __data[__OctaAlignMax<_N, alignas(alignment_value) uchar data[AlignMax<_N,
sizeof(_T)...>::value]; sizeof(_T)...>::value];
}; };
}; };
} /* namespace detail */
template<size_t _N, typename ..._T> template<size_t _N, typename ..._T>
using AlignedUnion = typename __OctaAlignedUnion<_N, _T...>::Type; using AlignedUnion = typename octa::detail::AlignedUnionBase<_N, _T...>::Type;
/* underlying type */ /* underlying type */
namespace detail {
/* gotta wrap, in a struct otherwise clang ICEs... */ /* gotta wrap, in a struct otherwise clang ICEs... */
template<typename _T> struct __OctaUnderlyingType { template<typename _T> struct UnderlyingTypeBase {
typedef __underlying_type(_T) Type; typedef __underlying_type(_T) Type;
}; };
}
template<typename _T> template<typename _T>
using UnderlyingType = typename __OctaUnderlyingType<_T>::Type; using UnderlyingType = typename octa::detail::UnderlyingTypeBase<_T>::Type;
} }
#endif #endif