forked from OctaForge/libostd
remove traits dependency on utility.h and thus the need to put some of the traits in utility.h
This commit is contained in:
parent
0c217e2128
commit
e92f5bba4b
|
@ -9,20 +9,24 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "octa/types.h"
|
#include "octa/types.h"
|
||||||
#include "octa/utility.h"
|
|
||||||
|
|
||||||
namespace octa {
|
namespace octa {
|
||||||
/* forward declarations */
|
/* forward declarations */
|
||||||
|
|
||||||
template<typename> struct RemoveCV;
|
template<typename> struct RemoveCV;
|
||||||
template<typename> struct AddLvalueReference;
|
template<typename> struct AddLvalueReference;
|
||||||
|
template<typename> struct AddRvalueReference;
|
||||||
template<typename> struct AddConst;
|
template<typename> struct AddConst;
|
||||||
template<typename> struct IsReference;
|
template<typename> struct IsReference;
|
||||||
|
template<typename> struct RemoveReference;
|
||||||
template<typename> struct RemoveAllExtents;
|
template<typename> struct RemoveAllExtents;
|
||||||
template<typename> struct IsTriviallyDefaultConstructible;
|
template<typename> struct IsTriviallyDefaultConstructible;
|
||||||
|
|
||||||
template<typename...> struct CommonType;
|
template<typename...> struct CommonType;
|
||||||
|
|
||||||
|
/* declval also defined here to avoid including utility.h */
|
||||||
|
template<typename T> typename AddRvalueReference<T>::type __octa_declval();
|
||||||
|
|
||||||
/* integral constant */
|
/* integral constant */
|
||||||
|
|
||||||
template<typename T, T val>
|
template<typename T, T val>
|
||||||
|
@ -300,19 +304,23 @@ namespace octa {
|
||||||
|
|
||||||
/* is constructible */
|
/* is constructible */
|
||||||
|
|
||||||
|
#define __OCTA_MOVE(v) static_cast<typename RemoveReference<decltype(v)>::type &&>(v)
|
||||||
|
|
||||||
template<typename, typename T> struct __OctaSelect2nd { typedef T type; };
|
template<typename, typename T> struct __OctaSelect2nd { typedef T type; };
|
||||||
struct __OctaAny { __OctaAny(...); };
|
struct __OctaAny { __OctaAny(...); };
|
||||||
|
|
||||||
template<typename T, typename ...A> typename __OctaSelect2nd<
|
template<typename T, typename ...A> typename __OctaSelect2nd<
|
||||||
decltype(octa::move(T(octa::declval<A>()...))), true_t
|
decltype(__OCTA_MOVE(T(__octa_declval<A>()...))), true_t
|
||||||
>::type __octa_is_ctible_test(T &&, A &&...);
|
>::type __octa_is_ctible_test(T &&, A &&...);
|
||||||
|
|
||||||
|
#undef __OCTA_MOVE
|
||||||
|
|
||||||
template<typename ...A> false_t __octa_is_ctible_test(__OctaAny, A &&...);
|
template<typename ...A> false_t __octa_is_ctible_test(__OctaAny, A &&...);
|
||||||
|
|
||||||
template<bool, typename T, typename ...A>
|
template<bool, typename T, typename ...A>
|
||||||
struct __OctaCtibleCore: CommonType<
|
struct __OctaCtibleCore: CommonType<
|
||||||
decltype(__octa_is_ctible_test(octa::declval<T>(),
|
decltype(__octa_is_ctible_test(__octa_declval<T>(),
|
||||||
octa::declval<A>()...))
|
__octa_declval<A>()...))
|
||||||
>::type {};
|
>::type {};
|
||||||
|
|
||||||
/* function types are not constructible */
|
/* function types are not constructible */
|
||||||
|
@ -333,7 +341,7 @@ namespace octa {
|
||||||
|
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
struct __OctaCtibleCore<true, T, U>: CommonType<
|
struct __OctaCtibleCore<true, T, U>: CommonType<
|
||||||
decltype(__OctaCtibleRef<T>::test(octa::declval<U>()))
|
decltype(__OctaCtibleRef<T>::test(__octa_declval<U>()))
|
||||||
>::type {};
|
>::type {};
|
||||||
|
|
||||||
/* scalars and references are not constructible from multiple args */
|
/* scalars and references are not constructible from multiple args */
|
||||||
|
@ -397,20 +405,20 @@ namespace octa {
|
||||||
/* is move constructible */
|
/* is move constructible */
|
||||||
|
|
||||||
template<typename T> struct IsMoveConstructible: IsConstructible<T,
|
template<typename T> struct IsMoveConstructible: IsConstructible<T,
|
||||||
typename internal::AddRvalueReference<T>::type
|
typename AddRvalueReference<T>::type
|
||||||
> {};
|
> {};
|
||||||
|
|
||||||
/* is assignable */
|
/* is assignable */
|
||||||
|
|
||||||
template<typename T, typename U> typename __OctaSelect2nd<
|
template<typename T, typename U> typename __OctaSelect2nd<
|
||||||
decltype((octa::declval<T>() = octa::declval<U>())), true_t
|
decltype((__octa_declval<T>() = __octa_declval<U>())), true_t
|
||||||
>::type __octa_assign_test(T &&, U &&);
|
>::type __octa_assign_test(T &&, U &&);
|
||||||
|
|
||||||
template<typename T> false_t __octa_assign_test(__OctaAny, T &&);
|
template<typename T> false_t __octa_assign_test(__OctaAny, T &&);
|
||||||
|
|
||||||
template<typename T, typename U, bool = IsVoid<T>::value || IsVoid<U>::value>
|
template<typename T, typename U, bool = IsVoid<T>::value || IsVoid<U>::value>
|
||||||
struct __OctaIsAssignable: CommonType<
|
struct __OctaIsAssignable: CommonType<
|
||||||
decltype(__octa_assign_test(octa::declval<T>(), octa::declval<U>()))
|
decltype(__octa_assign_test(__octa_declval<T>(), __octa_declval<U>()))
|
||||||
>::type {};
|
>::type {};
|
||||||
|
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
|
@ -430,7 +438,7 @@ namespace octa {
|
||||||
|
|
||||||
template<typename T> struct IsMoveAssignable: IsAssignable<
|
template<typename T> struct IsMoveAssignable: IsAssignable<
|
||||||
typename AddLvalueReference<T>::type,
|
typename AddLvalueReference<T>::type,
|
||||||
const typename internal::AddRvalueReference<T>::type
|
const typename AddRvalueReference<T>::type
|
||||||
> {};
|
> {};
|
||||||
|
|
||||||
/* is destructible */
|
/* is destructible */
|
||||||
|
@ -439,7 +447,7 @@ namespace octa {
|
||||||
|
|
||||||
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 __OctaIsDtibleApply<
|
||||||
decltype(octa::declval<TT &>().~TT())
|
decltype(__octa_declval<TT &>().~TT())
|
||||||
>::type);
|
>::type);
|
||||||
|
|
||||||
template<typename TT> static int test(...);
|
template<typename TT> static int test(...);
|
||||||
|
@ -511,7 +519,7 @@ namespace octa {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsTriviallyMoveConstructible: IsTriviallyConstructible<T,
|
struct IsTriviallyMoveConstructible: IsTriviallyConstructible<T,
|
||||||
typename internal::AddRvalueReference<T>::type
|
typename AddRvalueReference<T>::type
|
||||||
> {};
|
> {};
|
||||||
|
|
||||||
/* is trivially assignable */
|
/* is trivially assignable */
|
||||||
|
@ -550,7 +558,7 @@ namespace octa {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsTriviallyMoveAssignable: IsTriviallyAssignable<T,
|
struct IsTriviallyMoveAssignable: IsTriviallyAssignable<T,
|
||||||
typename internal::AddRvalueReference<T>::type
|
typename AddRvalueReference<T>::type
|
||||||
> {};
|
> {};
|
||||||
|
|
||||||
/* is trivially destructible */
|
/* is trivially destructible */
|
||||||
|
@ -601,7 +609,7 @@ namespace octa {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsNothrowMoveConstructible: IsNothrowConstructible<T,
|
struct IsNothrowMoveConstructible: IsNothrowConstructible<T,
|
||||||
typename internal::AddRvalueReference<T>::type
|
typename AddRvalueReference<T>::type
|
||||||
> {};
|
> {};
|
||||||
|
|
||||||
/* is nothrow assignable */
|
/* is nothrow assignable */
|
||||||
|
@ -640,7 +648,7 @@ namespace octa {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsNothrowMoveAssignable: IsNothrowAssignable<T,
|
struct IsNothrowMoveAssignable: IsNothrowAssignable<T,
|
||||||
typename internal::AddRvalueReference<T>::type
|
typename AddRvalueReference<T>::type
|
||||||
> {};
|
> {};
|
||||||
|
|
||||||
/* is nothrow destructible */
|
/* is nothrow destructible */
|
||||||
|
@ -649,7 +657,7 @@ namespace octa {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct __OctaIsNothrowDtible<T, false>: IntegralConstant<bool,
|
struct __OctaIsNothrowDtible<T, false>: IntegralConstant<bool,
|
||||||
noexcept(octa::declval<T>().~T())
|
noexcept(__octa_declval<T>().~T())
|
||||||
> {};
|
> {};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -683,7 +691,7 @@ namespace octa {
|
||||||
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::declval<FF>()))
|
typename = decltype(test_f<TT>(__octa_declval<FF>()))
|
||||||
> static true_t test(int);
|
> static true_t test(int);
|
||||||
|
|
||||||
template<typename, typename> static false_t test(...);
|
template<typename, typename> static false_t test(...);
|
||||||
|
@ -772,7 +780,9 @@ namespace octa {
|
||||||
|
|
||||||
/* remove reference */
|
/* remove reference */
|
||||||
|
|
||||||
template<typename T> using RemoveReference = internal::RemoveReference<T>;
|
template<typename T> struct RemoveReference { typedef T type; };
|
||||||
|
template<typename T> struct RemoveReference<T &> { typedef T type; };
|
||||||
|
template<typename T> struct RemoveReference<T &&> { typedef T type; };
|
||||||
|
|
||||||
/* remove pointer */
|
/* remove pointer */
|
||||||
|
|
||||||
|
@ -808,7 +818,21 @@ namespace octa {
|
||||||
|
|
||||||
/* add rvalue reference */
|
/* add rvalue reference */
|
||||||
|
|
||||||
template<typename T> using AddRvalueReference = internal::AddRvalueReference<T>;
|
template<typename T> struct AddRvalueReference { typedef T &&type; };
|
||||||
|
template<typename T> struct AddRvalueReference<T &> { typedef T &&type; };
|
||||||
|
template<typename T> struct AddRvalueReference<T &&> { typedef T &&type; };
|
||||||
|
template<> struct AddRvalueReference<void> {
|
||||||
|
typedef void type;
|
||||||
|
};
|
||||||
|
template<> struct AddRvalueReference<const void> {
|
||||||
|
typedef const void type;
|
||||||
|
};
|
||||||
|
template<> struct AddRvalueReference<volatile void> {
|
||||||
|
typedef volatile void type;
|
||||||
|
};
|
||||||
|
template<> struct AddRvalueReference<const volatile void> {
|
||||||
|
typedef const volatile void type;
|
||||||
|
};
|
||||||
|
|
||||||
/* remove extent */
|
/* remove extent */
|
||||||
|
|
||||||
|
@ -979,39 +1003,41 @@ namespace octa {
|
||||||
|
|
||||||
/* result of call at compile time */
|
/* result of call at compile time */
|
||||||
|
|
||||||
|
#define __OCTA_FWD(T, v) static_cast<T &&>(v)
|
||||||
template<typename F, typename ...A>
|
template<typename F, typename ...A>
|
||||||
inline auto __octa_rof_invoke(F &&f, A &&...args) ->
|
inline auto __octa_rof_invoke(F &&f, A &&...args) ->
|
||||||
decltype(forward<F>(f)(forward<A>(args)...)) {
|
decltype(__OCTA_FWD(F, f)(__OCTA_FWD(A, args)...)) {
|
||||||
return forward<F>(f)(forward<A>(args)...);
|
return __OCTA_FWD(F, f)(__OCTA_FWD(A, args)...);
|
||||||
}
|
}
|
||||||
template<typename B, typename T, typename D>
|
template<typename B, typename T, typename D>
|
||||||
inline auto __octa_rof_invoke(T B::*pmd, D &&ref) ->
|
inline auto __octa_rof_invoke(T B::*pmd, D &&ref) ->
|
||||||
decltype(forward<D>(ref).*pmd) {
|
decltype(__OCTA_FWD(D, ref).*pmd) {
|
||||||
return forward<D>(ref).*pmd;
|
return __OCTA_FWD(D, ref).*pmd;
|
||||||
}
|
}
|
||||||
template<typename PMD, typename P>
|
template<typename PMD, typename P>
|
||||||
inline auto __octa_rof_invoke(PMD &&pmd, P &&ptr) ->
|
inline auto __octa_rof_invoke(PMD &&pmd, P &&ptr) ->
|
||||||
decltype((*forward<P>(ptr)).*forward<PMD>(pmd)) {
|
decltype((*__OCTA_FWD(P, ptr)).*__OCTA_FWD(PMD, pmd)) {
|
||||||
return (*forward<P>(ptr)).*forward<PMD>(pmd);
|
return (*__OCTA_FWD(P, ptr)).*__OCTA_FWD(PMD, pmd);
|
||||||
}
|
}
|
||||||
template<typename B, typename T, typename D, typename ...A>
|
template<typename B, typename T, typename D, typename ...A>
|
||||||
inline auto __octa_rof_invoke(T B::*pmf, D &&ref, A &&...args) ->
|
inline auto __octa_rof_invoke(T B::*pmf, D &&ref, A &&...args) ->
|
||||||
decltype((forward<D>(ref).*pmf)(forward<A>(args)...)) {
|
decltype((__OCTA_FWD(D, ref).*pmf)(__OCTA_FWD(A, args)...)) {
|
||||||
return (forward<D>(ref).*pmf)(forward<A>(args)...);
|
return (__OCTA_FWD(D, ref).*pmf)(__OCTA_FWD(A, args)...);
|
||||||
}
|
}
|
||||||
template<typename PMF, typename P, typename ...A>
|
template<typename PMF, typename P, typename ...A>
|
||||||
inline auto __octa_rof_invoke(PMF &&pmf, P &&ptr, A &&...args) ->
|
inline auto __octa_rof_invoke(PMF &&pmf, P &&ptr, A &&...args) ->
|
||||||
decltype(((*forward<P>(ptr)).*forward<PMF>(pmf))(forward<A>(args)...)) {
|
decltype(((*__OCTA_FWD(P, ptr)).*__OCTA_FWD(PMF, pmf))(__OCTA_FWD(A, args)...)) {
|
||||||
return ((*forward<P>(ptr)).*forward<PMF>(pmf))(forward<A>(args)...);
|
return ((*__OCTA_FWD(P, ptr)).*__OCTA_FWD(PMF, pmf))(__OCTA_FWD(A, args)...);
|
||||||
}
|
}
|
||||||
|
#undef __OCTA_FWD
|
||||||
|
|
||||||
template<typename, typename = void>
|
template<typename, typename = void>
|
||||||
struct __OctaResultOf {};
|
struct __OctaResultOf {};
|
||||||
template<typename F, typename ...A>
|
template<typename F, typename ...A>
|
||||||
struct __OctaResultOf<F(A...), decltype(void(__octa_rof_invoke(
|
struct __OctaResultOf<F(A...), decltype(void(__octa_rof_invoke(
|
||||||
octa::declval<F>(), octa::declval<A>()...)))> {
|
__octa_declval<F>(), __octa_declval<A>()...)))> {
|
||||||
using type = decltype(__octa_rof_invoke(octa::declval<F>(),
|
using type = decltype(__octa_rof_invoke(__octa_declval<F>(),
|
||||||
octa::declval<A>()...));
|
__octa_declval<A>()...));
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T> struct ResultOf: __OctaResultOf<T> {};
|
template<typename T> struct ResultOf: __OctaResultOf<T> {};
|
||||||
|
@ -1047,7 +1073,7 @@ namespace octa {
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename U> struct CommonType<T, U> {
|
template<typename T, typename U> struct CommonType<T, U> {
|
||||||
typedef Decay<decltype(true ? octa::declval<T>() : octa::declval<U>())> type;
|
typedef Decay<decltype(true ? __octa_declval<T>() : __octa_declval<U>())> type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename U, typename ...V>
|
template<typename T, typename U, typename ...V>
|
||||||
|
|
|
@ -8,49 +8,28 @@
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "octa/traits.h"
|
||||||
|
|
||||||
namespace octa {
|
namespace octa {
|
||||||
/* aliased in traits.h later */
|
|
||||||
namespace internal {
|
|
||||||
template<typename T> struct RemoveReference { typedef T type; };
|
|
||||||
template<typename T> struct RemoveReference<T &> { typedef T type; };
|
|
||||||
template<typename T> struct RemoveReference<T &&> { typedef T type; };
|
|
||||||
|
|
||||||
template<typename T> struct AddRvalueReference { typedef T &&type; };
|
|
||||||
template<typename T> struct AddRvalueReference<T &> { typedef T &&type; };
|
|
||||||
template<typename T> struct AddRvalueReference<T &&> { typedef T &&type; };
|
|
||||||
template<> struct AddRvalueReference<void> {
|
|
||||||
typedef void type;
|
|
||||||
};
|
|
||||||
template<> struct AddRvalueReference<const void> {
|
|
||||||
typedef const void type;
|
|
||||||
};
|
|
||||||
template<> struct AddRvalueReference<volatile void> {
|
|
||||||
typedef volatile void type;
|
|
||||||
};
|
|
||||||
template<> struct AddRvalueReference<const volatile void> {
|
|
||||||
typedef const volatile void type;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static inline constexpr typename internal::RemoveReference<T>::type &&
|
static inline constexpr typename RemoveReference<T>::type &&
|
||||||
move(T &&v) noexcept {
|
move(T &&v) noexcept {
|
||||||
return static_cast<typename internal::RemoveReference<T>::type &&>(v);
|
return static_cast<typename RemoveReference<T>::type &&>(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static inline constexpr T &&
|
static inline constexpr T &&
|
||||||
forward(typename internal::RemoveReference<T>::type &v) noexcept {
|
forward(typename RemoveReference<T>::type &v) noexcept {
|
||||||
return static_cast<T &&>(v);
|
return static_cast<T &&>(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static inline constexpr T &&
|
static inline constexpr T &&
|
||||||
forward(typename internal::RemoveReference<T>::type &&v) noexcept {
|
forward(typename RemoveReference<T>::type &&v) noexcept {
|
||||||
return static_cast<T &&>(v);
|
return static_cast<T &&>(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> typename internal::AddRvalueReference<T>::type declval();
|
template<typename T> typename AddRvalueReference<T>::type declval();
|
||||||
|
|
||||||
template<typename T> void swap(T &a, T &b) {
|
template<typename T> void swap(T &a, T &b) {
|
||||||
T c(move(a));
|
T c(move(a));
|
||||||
|
|
Loading…
Reference in a new issue