use standard declval

This commit is contained in:
q66 2017-01-29 15:29:11 +01:00
parent a41299505c
commit a8f7122d45
8 changed files with 53 additions and 62 deletions

View file

@ -849,7 +849,9 @@ public:
namespace detail { namespace detail {
template<typename R, typename F> template<typename R, typename F>
using MapReturnType = decltype(declval<F>()(declval<RangeReference<R>>())); using MapReturnType = decltype(
std::declval<F>()(std::declval<RangeReference<R>>())
);
} }
template<typename R, typename F> template<typename R, typename F>
@ -928,9 +930,9 @@ public:
namespace detail { namespace detail {
template<typename R, typename P> template<typename R, typename P>
using FilterPred = EnableIf< using FilterPred = EnableIf<IsSame<
IsSame<decltype(declval<P>()(declval<RangeReference<R>>())), bool>, P decltype(std::declval<P>()(std::declval<RangeReference<R>>())), bool
>; >, P>;
} }
template<typename R, typename P> template<typename R, typename P>

View file

@ -438,9 +438,9 @@ protected:
template< template<
typename T, typename R, typename = EnableIf< typename T, typename R, typename = EnableIf<
IsSame<decltype(declval<T const &>() IsSame<decltype(std::declval<T const &>().to_format(
.to_format(declval<R &>(), declval<FormatSpec const &>())), bool std::declval<R &>(), std::declval<FormatSpec const &>()
> )), bool>
> >
> >
inline bool to_format(T const &v, R &writer, FormatSpec const &fs) { inline bool to_format(T const &v, R &writer, FormatSpec const &fs) {
@ -615,7 +615,7 @@ namespace detail {
} }
template<typename T> template<typename T>
static True test_fmt_tostr(decltype(ostd::to_string(declval<T>())) *); static True test_fmt_tostr(decltype(ostd::to_string(std::declval<T>())) *);
template<typename> template<typename>
static False test_fmt_tostr(...); static False test_fmt_tostr(...);
@ -662,7 +662,8 @@ namespace detail {
template<typename T, typename R> template<typename T, typename R>
static True test_tofmt(decltype(to_format( static True test_tofmt(decltype(to_format(
declval<T const &>(), declval<R &>(), declval<FormatSpec const &>() std::declval<T const &>(), std::declval<R &>(),
std::declval<FormatSpec const &>()
)) *); )) *);
template<typename, typename> template<typename, typename>

View file

@ -19,7 +19,7 @@ namespace ostd {
namespace detail { namespace detail {
template<typename T> template<typename T>
using KeysetKeyRet = decltype(declval<T const &>().get_key()); using KeysetKeyRet = decltype(std::declval<T const &>().get_key());
template<typename T> template<typename T>
using KeysetKey = Decay<KeysetKeyRet<T>> const; using KeysetKey = Decay<KeysetKeyRet<T>> const;

View file

@ -533,7 +533,7 @@ namespace detail {
constexpr bool AllocateHintTest = constexpr bool AllocateHintTest =
IsSame< IsSame<
decltype(allocate_hint_test( decltype(allocate_hint_test(
declval<A>(), declval<S>(), declval<CVP>() std::declval<A>(), std::declval<S>(), std::declval<CVP>()
)), True )), True
>; >;
@ -586,7 +586,7 @@ namespace detail {
constexpr bool ConstructTest = constexpr bool ConstructTest =
IsSame< IsSame<
decltype(construct_test( decltype(construct_test(
declval<A>(), declval<T>(), declval<Args>()... std::declval<A>(), std::declval<T>(), std::declval<Args>()...
)), True )), True
>; >;
@ -619,8 +619,9 @@ namespace detail {
auto destroy_test(A const &, P &&) -> False; auto destroy_test(A const &, P &&) -> False;
template<typename A, typename P> template<typename A, typename P>
constexpr bool DestroyTest = constexpr bool DestroyTest = IsSame<
IsSame<decltype(destroy_test(declval<A>(), declval<P>())), True>; decltype(destroy_test(std::declval<A>(), std::declval<P>())), True
>;
template<typename A, typename T> template<typename A, typename T>
inline void destroy(True, A &a, T *p) { inline void destroy(True, A &a, T *p) {
@ -649,7 +650,7 @@ namespace detail {
template<typename A> template<typename A>
constexpr bool AllocMaxSizeTest = constexpr bool AllocMaxSizeTest =
IsSame<decltype(alloc_max_size_test(declval<A &>())), True>; IsSame<decltype(alloc_max_size_test(std::declval<A &>())), True>;
template<typename A> template<typename A>
inline AllocatorSize<A> alloc_max_size(True, A const &a) { inline AllocatorSize<A> alloc_max_size(True, A const &a) {
@ -680,7 +681,7 @@ namespace detail {
template<typename A> template<typename A>
constexpr bool AllocCopyTest = constexpr bool AllocCopyTest =
IsSame<decltype(alloc_copy_test(declval<A &>())), True>; IsSame<decltype(alloc_copy_test(std::declval<A &>())), True>;
template<typename A> template<typename A>
inline AllocatorType<A> alloc_container_copy(True, A const &a) { inline AllocatorType<A> alloc_container_copy(True, A const &a) {

View file

@ -756,7 +756,7 @@ struct ranged_traits;
namespace detail { namespace detail {
template<typename C> template<typename C>
static True test_direct_iter(decltype(declval<C>().iter()) *); static True test_direct_iter(decltype(std::declval<C>().iter()) *);
template<typename> template<typename>
static False test_direct_iter(...); static False test_direct_iter(...);

View file

@ -779,11 +779,11 @@ namespace detail {
template<typename T, typename R> template<typename T, typename R>
static auto test_stringify(int) -> static auto test_stringify(int) ->
BoolConstant<IsSame<decltype(declval<T>().stringify()), String>>; BoolConstant<IsSame<decltype(std::declval<T>().stringify()), String>>;
template<typename T, typename R> template<typename T, typename R>
static True test_stringify(decltype(declval<T const &>().to_string static True test_stringify(decltype(std::declval<T const &>().to_string
(declval<R &>())) *); (std::declval<R &>())) *);
template<typename, typename> template<typename, typename>
static False test_stringify(...); static False test_stringify(...);
@ -792,7 +792,7 @@ namespace detail {
constexpr bool StringifyTest = decltype(test_stringify<T, R>(0))::value; constexpr bool StringifyTest = decltype(test_stringify<T, R>(0))::value;
template<typename T> template<typename T>
static True test_iterable(decltype(ostd::iter(declval<T>())) *); static True test_iterable(decltype(ostd::iter(std::declval<T>())) *);
template<typename> template<typename>
static False test_iterable(...); static False test_iterable(...);

View file

@ -10,6 +10,8 @@
#include <limits.h> #include <limits.h>
#include <stddef.h> #include <stddef.h>
#include <utility>
#include "ostd/types.hh" #include "ostd/types.hh"
namespace ostd { namespace ostd {
@ -51,11 +53,6 @@ using RemoveReference = typename detail::RemoveReferenceBase<T>::Type;
template<typename T> template<typename T>
using RemoveAllExtents = typename detail::RemoveAllExtentsBase<T>::Type; using RemoveAllExtents = typename detail::RemoveAllExtentsBase<T>::Type;
namespace detail {
template<typename T>
AddRvalueReference<T> declval_in() noexcept;
}
/* size in bits */ /* size in bits */
template<typename T> template<typename T>
@ -613,8 +610,6 @@ constexpr bool HasVirtualDestructor = __has_virtual_destructor(T);
/* is constructible */ /* is constructible */
namespace detail { namespace detail {
#define OSTD_MOVE(v) static_cast<RemoveReference<decltype(v)> &&>(v)
template<typename, typename T> template<typename, typename T>
struct Select2nd { using Type = T; }; struct Select2nd { using Type = T; };
@ -622,18 +617,16 @@ namespace detail {
template<typename T, typename ...A> template<typename T, typename ...A>
typename Select2nd< typename Select2nd<
decltype(OSTD_MOVE(T(declval_in<A>()...))), True decltype(std::move(T(std::declval<A>()...))), True
>::Type is_ctible_test(T &&, A &&...); >::Type is_ctible_test(T &&, A &&...);
#undef OSTD_MOVE
template<typename ...A> template<typename ...A>
False is_ctible_test(Any, A &&...); False is_ctible_test(Any, A &&...);
template<bool, typename T, typename ...A> template<bool, typename T, typename ...A>
constexpr bool CtibleCore = constexpr bool CtibleCore =
CommonTypeBase< CommonTypeBase<
decltype(is_ctible_test(declval_in<T>(), declval_in<A>()...)) decltype(is_ctible_test(std::declval<T>(), std::declval<A>()...))
>::Type::value; >::Type::value;
/* function types are not constructible */ /* function types are not constructible */
@ -654,7 +647,7 @@ namespace detail {
template<typename T, typename U> template<typename T, typename U>
constexpr bool CtibleCore<true, T, U> = CommonTypeBase< constexpr bool CtibleCore<true, T, U> = CommonTypeBase<
decltype(CtibleRef<T>::test(declval_in<U>())) decltype(CtibleRef<T>::test(std::declval<U>()))
>::Type::value; >::Type::value;
/* scalars and references are not constructible from multiple args */ /* scalars and references are not constructible from multiple args */
@ -726,14 +719,14 @@ namespace detail {
template<typename T, typename ...A> template<typename T, typename ...A>
constexpr bool NothrowCtibleCore<true, false, T, A...> = constexpr bool NothrowCtibleCore<true, false, T, A...> =
noexcept(T(declval_in<A>()...)); noexcept(T(std::declval<A>()...));
template<typename T> template<typename T>
void implicit_conv_to(T) noexcept {} void implicit_conv_to(T) noexcept {}
template<typename T, typename A> template<typename T, typename A>
constexpr bool NothrowCtibleCore<true, true, T, A> = constexpr bool NothrowCtibleCore<true, true, T, A> =
noexcept(ostd::detail::implicit_conv_to<T>(declval_in<A>())); noexcept(ostd::detail::implicit_conv_to<T>(std::declval<A>()));
template<typename T, bool R, typename ...A> template<typename T, bool R, typename ...A>
constexpr bool NothrowCtibleCore<false, R, T, A...> = false; constexpr bool NothrowCtibleCore<false, R, T, A...> = false;
@ -767,7 +760,7 @@ constexpr bool IsNothrowMoveConstructible =
namespace detail { namespace detail {
template<typename T, typename U> template<typename T, typename U>
typename detail::Select2nd< typename detail::Select2nd<
decltype((declval_in<T>() = declval_in<U>())), True decltype((std::declval<T>() = std::declval<U>())), True
>::Type assign_test(T &&, U &&); >::Type assign_test(T &&, U &&);
template<typename T> template<typename T>
@ -775,7 +768,7 @@ namespace detail {
template<typename T, typename U, bool = IsVoid<T> || IsVoid<U>> template<typename T, typename U, bool = IsVoid<T> || IsVoid<U>>
constexpr bool IsAssignableBase = CommonTypeBase< constexpr bool IsAssignableBase = CommonTypeBase<
decltype(assign_test(declval_in<T>(), declval_in<U>())) decltype(assign_test(std::declval<T>(), std::declval<U>()))
>::Type::value; >::Type::value;
template<typename T, typename U> template<typename T, typename U>
@ -808,7 +801,7 @@ namespace detail {
template<typename T, typename A> template<typename T, typename A>
constexpr bool NothrowAssignableCore<true, T, A> = constexpr bool NothrowAssignableCore<true, T, A> =
noexcept(declval_in<T>() = declval_in<A>()); noexcept(std::declval<T>() = std::declval<A>());
} }
template<typename T, typename A> constexpr bool IsNothrowAssignable = template<typename T, typename A> constexpr bool IsNothrowAssignable =
@ -835,7 +828,7 @@ namespace detail {
template<typename T> struct IsDestructorWellformed { template<typename T> struct IsDestructorWellformed {
template<typename TT> template<typename TT>
static char test(typename IsDtibleApply< static char test(typename IsDtibleApply<
decltype(detail::declval_in<TT &>().~TT()) decltype(std::declval<TT &>().~TT())
>::Type); >::Type);
template<typename TT> template<typename TT>
@ -885,7 +878,7 @@ namespace detail {
constexpr bool NothrowDtibleCore<false, T> = false; constexpr bool NothrowDtibleCore<false, T> = false;
template<typename T> template<typename T>
constexpr bool NothrowDtibleCore<true, T> = noexcept(declval_in<T>().~T()); constexpr bool NothrowDtibleCore<true, T> = noexcept(std::declval<T>().~T());
} }
template<typename T> template<typename T>
@ -995,7 +988,7 @@ namespace detail {
static void test_f(TT); static void test_f(TT);
template<typename FF, typename TT, template<typename FF, typename TT,
typename = decltype(test_f<TT>(declval_in<FF>())) typename = decltype(test_f<TT>(std::declval<FF>()))
> >
static True test(int); static True test(int);
@ -1456,7 +1449,6 @@ namespace detail {
struct InvokeAny { InvokeAny(...); }; struct InvokeAny { InvokeAny(...); };
#define OSTD_FWD(T, _v) static_cast<T &&>(_v)
template<typename ...A> template<typename ...A>
inline auto func_invoke(InvokeAny, A &&...) -> InvokeNat; inline auto func_invoke(InvokeAny, A &&...) -> InvokeNat;
@ -1472,9 +1464,9 @@ namespace detail {
> >
> >
inline auto func_invoke(F &&f, T &&v, A &&...args) -> inline auto func_invoke(F &&f, T &&v, A &&...args) ->
decltype((OSTD_FWD(T, v).*f)(OSTD_FWD(A, args)...)) decltype((std::forward<T>(v).*f)(std::forward<A>(args)...))
{ {
return (OSTD_FWD(T, v).*f)(OSTD_FWD(A, args)...); return (std::forward<T>(v).*f)(std::forward<A>(args)...);
} }
template< template<
@ -1488,9 +1480,9 @@ namespace detail {
> >
> >
inline auto func_invoke(F &&f, T &&v, A &&...args) -> inline auto func_invoke(F &&f, T &&v, A &&...args) ->
decltype(((*OSTD_FWD(T, v)).*f)(OSTD_FWD(A, args)...)) decltype(((*std::forward<T>(v)).*f)(std::forward<A>(args)...))
{ {
return ((*OSTD_FWD(T, v)).*f)(OSTD_FWD(A, args)...); return ((*std::forward<T>(v)).*f)(std::forward<A>(args)...);
} }
template< template<
@ -1503,8 +1495,8 @@ namespace detail {
> >
> >
> >
inline auto func_invoke(F &&f, T &&v) -> decltype(OSTD_FWD(T, v).*f) { inline auto func_invoke(F &&f, T &&v) -> decltype(std::forward<T>(v).*f) {
return OSTD_FWD(T, v).*f; return std::forward<T>(v).*f;
} }
template< template<
@ -1517,22 +1509,21 @@ namespace detail {
> >
> >
> >
inline auto func_invoke(F &&f, T &&v) -> decltype((*OSTD_FWD(T, v)).*f) { inline auto func_invoke(F &&f, T &&v) -> decltype((*std::forward<T>(v)).*f) {
return (*OSTD_FWD(T, v)).*f; return (*std::forward<T>(v)).*f;
} }
template<typename F, typename ...A> template<typename F, typename ...A>
inline auto func_invoke(F &&f, A &&...args) -> inline auto func_invoke(F &&f, A &&...args) ->
decltype(OSTD_FWD(F, f)(OSTD_FWD(A, args)...)) decltype(std::forward<F>(f)(std::forward<A>(args)...))
{ {
return OSTD_FWD(F, f)(OSTD_FWD(A, args)...); return std::forward<F>(f)(std::forward<A>(args)...);
} }
#undef OSTD_FWD
template<typename F, typename ...A> template<typename F, typename ...A>
struct FuncInvokableBase { struct FuncInvokableBase {
using Type = decltype( using Type = decltype(
func_invoke(declval_in<F>(), declval_in<A>()...) func_invoke(std::declval<F>(), std::declval<A>()...)
); );
static constexpr bool value = !IsSame<Type, InvokeNat>; static constexpr bool value = !IsSame<Type, InvokeNat>;
}; };
@ -1596,7 +1587,7 @@ namespace detail {
template<typename T, typename U> template<typename T, typename U>
struct CommonTypeBase<T, U> { struct CommonTypeBase<T, U> {
using Type = Decay<decltype( using Type = Decay<decltype(
true ? detail::declval_in<T>(): detail::declval_in<U>() true ? std::declval<T>(): std::declval<U>()
)>; )>;
}; };

View file

@ -15,17 +15,13 @@
namespace ostd { namespace ostd {
/* declval */
template<typename T>
AddRvalueReference<T> declval() noexcept;
/* swap */ /* swap */
namespace detail { namespace detail {
template<typename T> template<typename T>
auto test_swap(int) -> auto test_swap(int) -> BoolConstant<IsVoid<
BoolConstant<IsVoid<decltype(declval<T>().swap(declval<T &>()))>>; decltype(std::declval<T>().swap(std::declval<T &>()))
>>;
template<typename> template<typename>
False test_swap(...); False test_swap(...);