diff options
Diffstat (limited to 'gdbsupport/traits.h')
-rw-r--r-- | gdbsupport/traits.h | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/gdbsupport/traits.h b/gdbsupport/traits.h index 2a6f00654c7..93b609ac109 100644 --- a/gdbsupport/traits.h +++ b/gdbsupport/traits.h @@ -52,6 +52,73 @@ struct make_void { typedef void type; }; template<typename... Ts> using void_t = typename make_void<Ts...>::type; +/* Implementation of the detection idiom: + + - http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4502.pdf + - http://en.cppreference.com/w/cpp/experimental/is_detected + +*/ + +struct nonesuch +{ + nonesuch () = delete; + ~nonesuch () = delete; + nonesuch (const nonesuch &) = delete; + void operator= (const nonesuch &) = delete; +}; + +namespace detection_detail { +/* Implementation of the detection idiom (negative case). */ +template<typename Default, typename AlwaysVoid, + template<typename...> class Op, typename... Args> +struct detector +{ + using value_t = std::false_type; + using type = Default; +}; + +/* Implementation of the detection idiom (positive case). */ +template<typename Default, template<typename...> class Op, typename... Args> +struct detector<Default, void_t<Op<Args...>>, Op, Args...> +{ + using value_t = std::true_type; + using type = Op<Args...>; +}; + +/* Detect whether Op<Args...> is a valid type, use Default if not. */ +template<typename Default, template<typename...> class Op, + typename... Args> +using detected_or = detector<Default, void, Op, Args...>; + +/* Op<Args...> if that is a valid type, otherwise Default. */ +template<typename Default, template<typename...> class Op, + typename... Args> +using detected_or_t + = typename detected_or<Default, Op, Args...>::type; + +} /* detection_detail */ + +template<template<typename...> class Op, typename... Args> +using is_detected + = typename detection_detail::detector<nonesuch, void, Op, Args...>::value_t; + +template<template<typename...> class Op, typename... Args> +using detected_t + = typename detection_detail::detector<nonesuch, void, Op, Args...>::type; + +template<typename Default, template<typename...> class Op, typename... Args> +using detected_or = detection_detail::detected_or<Default, Op, Args...>; + +template<typename Default, template<typename...> class Op, typename... Args> +using detected_or_t = typename detected_or<Default, Op, Args...>::type; + +template<typename Expected, template<typename...> class Op, typename... Args> +using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>; + +template<typename To, template<typename...> class Op, typename... Args> +using is_detected_convertible + = std::is_convertible<detected_t<Op, Args...>, To>; + /* A few trait helpers, mainly stolen from libstdc++. Uppercase because "and/or", etc. are reserved keywords. */ |