diff --git a/octa/traits.h b/octa/traits.h index cf2b7f5..a5241e8 100644 --- a/octa/traits.h +++ b/octa/traits.h @@ -9,20 +9,24 @@ #include #include "octa/types.h" -#include "octa/utility.h" namespace octa { /* forward declarations */ template struct RemoveCV; template struct AddLvalueReference; + template struct AddRvalueReference; template struct AddConst; template struct IsReference; + template struct RemoveReference; template struct RemoveAllExtents; template struct IsTriviallyDefaultConstructible; template struct CommonType; + /* declval also defined here to avoid including utility.h */ + template typename AddRvalueReference::type __octa_declval(); + /* integral constant */ template @@ -300,19 +304,23 @@ namespace octa { /* is constructible */ +#define __OCTA_MOVE(v) static_cast::type &&>(v) + template struct __OctaSelect2nd { typedef T type; }; struct __OctaAny { __OctaAny(...); }; template typename __OctaSelect2nd< - decltype(octa::move(T(octa::declval()...))), true_t + decltype(__OCTA_MOVE(T(__octa_declval()...))), true_t >::type __octa_is_ctible_test(T &&, A &&...); +#undef __OCTA_MOVE + template false_t __octa_is_ctible_test(__OctaAny, A &&...); template struct __OctaCtibleCore: CommonType< - decltype(__octa_is_ctible_test(octa::declval(), - octa::declval()...)) + decltype(__octa_is_ctible_test(__octa_declval(), + __octa_declval()...)) >::type {}; /* function types are not constructible */ @@ -333,7 +341,7 @@ namespace octa { template struct __OctaCtibleCore: CommonType< - decltype(__OctaCtibleRef::test(octa::declval())) + decltype(__OctaCtibleRef::test(__octa_declval())) >::type {}; /* scalars and references are not constructible from multiple args */ @@ -397,20 +405,20 @@ namespace octa { /* is move constructible */ template struct IsMoveConstructible: IsConstructible::type + typename AddRvalueReference::type > {}; /* is assignable */ template typename __OctaSelect2nd< - decltype((octa::declval() = octa::declval())), true_t + decltype((__octa_declval() = __octa_declval())), true_t >::type __octa_assign_test(T &&, U &&); template false_t __octa_assign_test(__OctaAny, T &&); template::value || IsVoid::value> struct __OctaIsAssignable: CommonType< - decltype(__octa_assign_test(octa::declval(), octa::declval())) + decltype(__octa_assign_test(__octa_declval(), __octa_declval())) >::type {}; template @@ -430,7 +438,7 @@ namespace octa { template struct IsMoveAssignable: IsAssignable< typename AddLvalueReference::type, - const typename internal::AddRvalueReference::type + const typename AddRvalueReference::type > {}; /* is destructible */ @@ -439,7 +447,7 @@ namespace octa { template struct IsDestructorWellformed { template static char test(typename __OctaIsDtibleApply< - decltype(octa::declval().~TT()) + decltype(__octa_declval().~TT()) >::type); template static int test(...); @@ -511,7 +519,7 @@ namespace octa { template struct IsTriviallyMoveConstructible: IsTriviallyConstructible::type + typename AddRvalueReference::type > {}; /* is trivially assignable */ @@ -550,7 +558,7 @@ namespace octa { template struct IsTriviallyMoveAssignable: IsTriviallyAssignable::type + typename AddRvalueReference::type > {}; /* is trivially destructible */ @@ -601,7 +609,7 @@ namespace octa { template struct IsNothrowMoveConstructible: IsNothrowConstructible::type + typename AddRvalueReference::type > {}; /* is nothrow assignable */ @@ -640,7 +648,7 @@ namespace octa { template struct IsNothrowMoveAssignable: IsNothrowAssignable::type + typename AddRvalueReference::type > {}; /* is nothrow destructible */ @@ -649,7 +657,7 @@ namespace octa { template struct __OctaIsNothrowDtible: IntegralConstant().~T()) + noexcept(__octa_declval().~T()) > {}; template @@ -683,7 +691,7 @@ namespace octa { template static void test_f(TT); template(octa::declval())) + typename = decltype(test_f(__octa_declval())) > static true_t test(int); template static false_t test(...); @@ -772,7 +780,9 @@ namespace octa { /* remove reference */ - template using RemoveReference = internal::RemoveReference; + template struct RemoveReference { typedef T type; }; + template struct RemoveReference { typedef T type; }; + template struct RemoveReference { typedef T type; }; /* remove pointer */ @@ -808,7 +818,21 @@ namespace octa { /* add rvalue reference */ - template using AddRvalueReference = internal::AddRvalueReference; + template struct AddRvalueReference { typedef T &&type; }; + template struct AddRvalueReference { typedef T &&type; }; + template struct AddRvalueReference { typedef T &&type; }; + template<> struct AddRvalueReference { + typedef void type; + }; + template<> struct AddRvalueReference { + typedef const void type; + }; + template<> struct AddRvalueReference { + typedef volatile void type; + }; + template<> struct AddRvalueReference { + typedef const volatile void type; + }; /* remove extent */ @@ -979,39 +1003,41 @@ namespace octa { /* result of call at compile time */ +#define __OCTA_FWD(T, v) static_cast(v) template inline auto __octa_rof_invoke(F &&f, A &&...args) -> - decltype(forward(f)(forward(args)...)) { - return forward(f)(forward(args)...); + decltype(__OCTA_FWD(F, f)(__OCTA_FWD(A, args)...)) { + return __OCTA_FWD(F, f)(__OCTA_FWD(A, args)...); } template inline auto __octa_rof_invoke(T B::*pmd, D &&ref) -> - decltype(forward(ref).*pmd) { - return forward(ref).*pmd; + decltype(__OCTA_FWD(D, ref).*pmd) { + return __OCTA_FWD(D, ref).*pmd; } template inline auto __octa_rof_invoke(PMD &&pmd, P &&ptr) -> - decltype((*forward

(ptr)).*forward(pmd)) { - return (*forward

(ptr)).*forward(pmd); + decltype((*__OCTA_FWD(P, ptr)).*__OCTA_FWD(PMD, pmd)) { + return (*__OCTA_FWD(P, ptr)).*__OCTA_FWD(PMD, pmd); } template inline auto __octa_rof_invoke(T B::*pmf, D &&ref, A &&...args) -> - decltype((forward(ref).*pmf)(forward(args)...)) { - return (forward(ref).*pmf)(forward(args)...); + decltype((__OCTA_FWD(D, ref).*pmf)(__OCTA_FWD(A, args)...)) { + return (__OCTA_FWD(D, ref).*pmf)(__OCTA_FWD(A, args)...); } template inline auto __octa_rof_invoke(PMF &&pmf, P &&ptr, A &&...args) -> - decltype(((*forward

(ptr)).*forward(pmf))(forward(args)...)) { - return ((*forward

(ptr)).*forward(pmf))(forward(args)...); + decltype(((*__OCTA_FWD(P, ptr)).*__OCTA_FWD(PMF, pmf))(__OCTA_FWD(A, args)...)) { + return ((*__OCTA_FWD(P, ptr)).*__OCTA_FWD(PMF, pmf))(__OCTA_FWD(A, args)...); } +#undef __OCTA_FWD template struct __OctaResultOf {}; template struct __OctaResultOf(), octa::declval()...)))> { - using type = decltype(__octa_rof_invoke(octa::declval(), - octa::declval()...)); + __octa_declval(), __octa_declval()...)))> { + using type = decltype(__octa_rof_invoke(__octa_declval(), + __octa_declval()...)); }; template struct ResultOf: __OctaResultOf {}; @@ -1047,7 +1073,7 @@ namespace octa { }; template struct CommonType { - typedef Decay() : octa::declval())> type; + typedef Decay() : __octa_declval())> type; }; template diff --git a/octa/utility.h b/octa/utility.h index a6517b7..d998bb9 100644 --- a/octa/utility.h +++ b/octa/utility.h @@ -8,49 +8,28 @@ #include +#include "octa/traits.h" + namespace octa { - /* aliased in traits.h later */ - namespace internal { - template struct RemoveReference { typedef T type; }; - template struct RemoveReference { typedef T type; }; - template struct RemoveReference { typedef T type; }; - - template struct AddRvalueReference { typedef T &&type; }; - template struct AddRvalueReference { typedef T &&type; }; - template struct AddRvalueReference { typedef T &&type; }; - template<> struct AddRvalueReference { - typedef void type; - }; - template<> struct AddRvalueReference { - typedef const void type; - }; - template<> struct AddRvalueReference { - typedef volatile void type; - }; - template<> struct AddRvalueReference { - typedef const volatile void type; - }; - } - template - static inline constexpr typename internal::RemoveReference::type && + static inline constexpr typename RemoveReference::type && move(T &&v) noexcept { - return static_cast::type &&>(v); + return static_cast::type &&>(v); } template static inline constexpr T && - forward(typename internal::RemoveReference::type &v) noexcept { + forward(typename RemoveReference::type &v) noexcept { return static_cast(v); } template static inline constexpr T && - forward(typename internal::RemoveReference::type &&v) noexcept { + forward(typename RemoveReference::type &&v) noexcept { return static_cast(v); } - template typename internal::AddRvalueReference::type declval(); + template typename AddRvalueReference::type declval(); template void swap(T &a, T &b) { T c(move(a));