Home | History | Annotate | Download | only in experimental
      1 // -*- C++ -*-
      2 //===-------------------------- type_traits -------------------------------===//
      3 //
      4 //                     The LLVM Compiler Infrastructure
      5 //
      6 // This file is dual licensed under the MIT and the University of Illinois Open
      7 // Source Licenses. See LICENSE.TXT for details.
      8 //
      9 //===----------------------------------------------------------------------===//
     10 
     11 #ifndef _LIBCPP_EXPERIMENTAL_TYPE_TRAITS
     12 #define _LIBCPP_EXPERIMENTAL_TYPE_TRAITS
     13 
     14 /**
     15     experimental/type_traits synopsis
     16 
     17 // C++1y
     18 #include <type_traits>
     19 
     20 namespace std {
     21 namespace experimental {
     22 inline namespace fundamentals_v1 {
     23 
     24   // 3.3.2, Other type transformations
     25   template <class> class invocation_type; // not defined
     26   template <class F, class... ArgTypes> class invocation_type<F(ArgTypes...)>;
     27   template <class> class raw_invocation_type; // not defined
     28   template <class F, class... ArgTypes> class raw_invocation_type<F(ArgTypes...)>;
     29 
     30   template <class T>
     31     using invocation_type_t = typename invocation_type<T>::type;
     32   template <class T>
     33     using raw_invocation_type_t = typename raw_invocation_type<T>::type;
     34 
     35   // 3.3.4, Detection idiom
     36   template <class...> using void_t = void;
     37 
     38   struct nonesuch {
     39     nonesuch() = delete;
     40     ~nonesuch() = delete;
     41     nonesuch(nonesuch const&) = delete;
     42     void operator=(nonesuch const&) = delete;
     43   };
     44 
     45   template <template<class...> class Op, class... Args>
     46     using is_detected = see below;
     47   template <template<class...> class Op, class... Args>
     48     constexpr bool is_detected_v = is_detected<Op, Args...>::value;
     49   template <template<class...> class Op, class... Args>
     50     using detected_t = see below;
     51   template <class Default, template<class...> class Op, class... Args>
     52     using detected_or = see below;
     53   template <class Default, template<class...> class Op, class... Args>
     54     using detected_or_t = typename detected_or<Default, Op, Args...>::type;
     55   template <class Expected, template<class...> class Op, class... Args>
     56     using is_detected_exact = is_same<Expected, detected_t<Op, Args...>>;
     57   template <class Expected, template<class...> class Op, class... Args>
     58     constexpr bool is_detected_exact_v
     59       = is_detected_exact<Expected, Op, Args...>::value;
     60   template <class To, template<class...> class Op, class... Args>
     61      using is_detected_convertible = is_convertible<detected_t<Op, Args...>, To>;
     62   template <class To, template<class...> class Op, class... Args>
     63      constexpr bool is_detected_convertible_v
     64        = is_detected_convertible<To, Op, Args...>::value;  
     65 
     66 } // namespace fundamentals_v1
     67 } // namespace experimental
     68 } // namespace std
     69 
     70  */
     71 
     72 #include <experimental/__config>
     73 
     74 #if _LIBCPP_STD_VER > 11
     75 
     76 #include <type_traits>
     77 
     78 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
     79 #pragma GCC system_header
     80 #endif
     81 
     82 _LIBCPP_BEGIN_NAMESPACE_LFTS
     83 
     84 // 3.3.2, Other type transformations
     85 /*
     86 template <class>
     87 class _LIBCPP_TEMPLATE_VIS raw_invocation_type;
     88 
     89 template <class _Fn, class ..._Args>
     90 class _LIBCPP_TEMPLATE_VIS raw_invocation_type<_Fn(_Args...)>;
     91 
     92 template <class>
     93 class _LIBCPP_TEMPLATE_VIS invokation_type;
     94 
     95 template <class _Fn, class ..._Args>
     96 class _LIBCPP_TEMPLATE_VIS invokation_type<_Fn(_Args...)>;
     97 
     98 template <class _Tp>
     99 using invokation_type_t = typename invokation_type<_Tp>::type;
    100 
    101 template <class _Tp>
    102 using raw_invocation_type_t = typename raw_invocation_type<_Tp>::type;
    103 */
    104 
    105 // 3.3.4, Detection idiom
    106 template <class...> using void_t = void;
    107 
    108 struct nonesuch {
    109     nonesuch()  = delete;
    110     ~nonesuch() = delete;
    111     nonesuch      (nonesuch const&) = delete;
    112     void operator=(nonesuch const&) = delete;
    113   };
    114 
    115 template <class _Default, class _AlwaysVoid, template <class...> class _Op, class... _Args>
    116 struct _DETECTOR {
    117    using value_t = false_type;
    118    using type = _Default;
    119    };
    120 
    121 template <class _Default, template <class...> class _Op, class... _Args>
    122 struct _DETECTOR<_Default, void_t<_Op<_Args...>>, _Op, _Args...> {
    123    using value_t = true_type;
    124    using type = _Op<_Args...>;
    125    };
    126      
    127 
    128 template <template<class...> class _Op, class... _Args>
    129   using is_detected = typename _DETECTOR<nonesuch, void, _Op, _Args...>::value_t;
    130 template <template<class...> class _Op, class... _Args>
    131   using detected_t = typename _DETECTOR<nonesuch, void, _Op, _Args...>::type;
    132 template <template<class...> class _Op, class... _Args>
    133   _LIBCPP_CONSTEXPR bool is_detected_v = is_detected<_Op, _Args...>::value;
    134 
    135 template <class Default, template<class...> class _Op, class... _Args>
    136   using detected_or = _DETECTOR<Default, void, _Op, _Args...>;
    137 template <class Default, template<class...> class _Op, class... _Args>
    138   using detected_or_t = typename detected_or<Default, _Op, _Args...>::type;
    139 
    140 template <class Expected, template<class...> class _Op, class... _Args>
    141   using is_detected_exact = is_same<Expected, detected_t<_Op, _Args...>>;
    142 template <class Expected, template<class...> class _Op, class... _Args>
    143   _LIBCPP_CONSTEXPR bool is_detected_exact_v = is_detected_exact<Expected, _Op, _Args...>::value;
    144 
    145 template <class To, template<class...> class _Op, class... _Args>
    146   using is_detected_convertible = is_convertible<detected_t<_Op, _Args...>, To>;
    147 template <class To, template<class...> class _Op, class... _Args>
    148   _LIBCPP_CONSTEXPR bool is_detected_convertible_v = is_detected_convertible<To, _Op, _Args...>::value;  
    149 
    150 
    151 _LIBCPP_END_NAMESPACE_LFTS
    152 
    153 #endif /* _LIBCPP_STD_VER > 11 */
    154 
    155 #endif /* _LIBCPP_EXPERIMENTAL_TYPE_TRAITS */
    156