[libcxx-commits] [libcxx] 44c8ef0 - [libc++] Disentangle _If, _Or and _And

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Thu Jun 30 05:01:16 PDT 2022


Author: Nikolas Klauser
Date: 2022-06-30T14:01:10+02:00
New Revision: 44c8ef01baf3da01d5b813a079835bfcfd60d57d

URL: https://github.com/llvm/llvm-project/commit/44c8ef01baf3da01d5b813a079835bfcfd60d57d
DIFF: https://github.com/llvm/llvm-project/commit/44c8ef01baf3da01d5b813a079835bfcfd60d57d.diff

LOG: [libc++] Disentangle _If, _Or and _And

Reviewed By: ldionne, #libc, EricWF

Spies: EricWF, libcxx-commits

Differential Revision: https://reviews.llvm.org/D127919

Added: 
    

Modified: 
    libcxx/include/__type_traits/conditional.h
    libcxx/include/__type_traits/conjunction.h
    libcxx/include/__type_traits/disjunction.h
    libcxx/include/type_traits

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__type_traits/conditional.h b/libcxx/include/__type_traits/conditional.h
index 9988cf7e89e6..4b1a560ddc7c 100644
--- a/libcxx/include/__type_traits/conditional.h
+++ b/libcxx/include/__type_traits/conditional.h
@@ -17,13 +17,32 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+template <bool>
+struct _IfImpl;
+
+template <>
+struct _IfImpl<true> {
+  template <class _IfRes, class _ElseRes>
+  using _Select _LIBCPP_NODEBUG = _IfRes;
+};
+
+template <>
+struct _IfImpl<false> {
+  template <class _IfRes, class _ElseRes>
+  using _Select _LIBCPP_NODEBUG = _ElseRes;
+};
+
+template <bool _Cond, class _IfRes, class _ElseRes>
+using _If _LIBCPP_NODEBUG = typename _IfImpl<_Cond>::template _Select<_IfRes, _ElseRes>;
+
 template <bool _Bp, class _If, class _Then>
     struct _LIBCPP_TEMPLATE_VIS conditional {typedef _If type;};
 template <class _If, class _Then>
     struct _LIBCPP_TEMPLATE_VIS conditional<false, _If, _Then> {typedef _Then type;};
 
 #if _LIBCPP_STD_VER > 11
-template <bool _Bp, class _If, class _Then> using conditional_t = typename conditional<_Bp, _If, _Then>::type;
+template <bool _Bp, class _IfRes, class _ElseRes>
+using conditional_t = typename conditional<_Bp, _IfRes, _ElseRes>::type;
 #endif
 
 // Helper so we can use "conditional_t" in all language versions.

diff  --git a/libcxx/include/__type_traits/conjunction.h b/libcxx/include/__type_traits/conjunction.h
index 187b73e6b198..45fe5cdca351 100644
--- a/libcxx/include/__type_traits/conjunction.h
+++ b/libcxx/include/__type_traits/conjunction.h
@@ -11,16 +11,17 @@
 
 #include <__config>
 #include <__type_traits/conditional.h>
+#include <__type_traits/enable_if.h>
 #include <__type_traits/integral_constant.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 14
-
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+#if _LIBCPP_STD_VER > 14
+
 template <class _Arg, class... _Args>
 struct __conjunction_impl {
   using type = conditional_t<!bool(_Arg::value), _Arg, typename __conjunction_impl<_Args...>::type>;
@@ -37,8 +38,20 @@ struct conjunction : __conjunction_impl<true_type, _Args...>::type {};
 template<class... _Args>
 inline constexpr bool conjunction_v = conjunction<_Args...>::value;
 
-_LIBCPP_END_NAMESPACE_STD
-
 #endif // _LIBCPP_STD_VER > 14
 
+template <class...>
+using __expand_to_true = true_type;
+
+template <class... _Pred>
+__expand_to_true<__enable_if_t<_Pred::value>...> __and_helper(int);
+
+template <class...>
+false_type __and_helper(...);
+
+template <class... _Pred>
+using _And _LIBCPP_NODEBUG = decltype(__and_helper<_Pred...>(0));
+
+_LIBCPP_END_NAMESPACE_STD
+
 #endif // _LIBCPP___TYPE_TRAITS_CONJUNCTION_H

diff  --git a/libcxx/include/__type_traits/disjunction.h b/libcxx/include/__type_traits/disjunction.h
index 1f7c5fe36fd5..6c6d1a8f21b6 100644
--- a/libcxx/include/__type_traits/disjunction.h
+++ b/libcxx/include/__type_traits/disjunction.h
@@ -17,27 +17,37 @@
 #  pragma GCC system_header
 #endif
 
-#if _LIBCPP_STD_VER > 14
-
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Arg, class... _Args>
-struct __disjunction_impl {
-  using type = conditional_t<bool(_Arg::value), _Arg, typename __disjunction_impl<_Args...>::type>;
+template <bool>
+struct _OrImpl;
+
+template <>
+struct _OrImpl<true> {
+  template <class _Res, class _First, class... _Rest>
+  using _Result _LIBCPP_NODEBUG =
+      typename _OrImpl<!bool(_First::value) && sizeof...(_Rest) != 0>::template _Result<_First, _Rest...>;
 };
 
-template <class _Arg>
-struct __disjunction_impl<_Arg> {
-  using type = _Arg;
+template <>
+struct _OrImpl<false> {
+  template <class _Res, class...>
+  using _Result = _Res;
 };
 
 template <class... _Args>
-struct disjunction : __disjunction_impl<false_type, _Args...>::type {};
-template<class... _Args>
-inline constexpr bool disjunction_v = disjunction<_Args...>::value;
+using _Or _LIBCPP_NODEBUG = typename _OrImpl<sizeof...(_Args) != 0>::template _Result<false_type, _Args...>;
 
-_LIBCPP_END_NAMESPACE_STD
+#if _LIBCPP_STD_VER > 14
+
+template <class... _Args>
+struct disjunction : _Or<_Args...> {};
+
+template <class... _Args>
+inline constexpr bool disjunction_v = _Or<_Args...>::value;
 
 #endif // _LIBCPP_STD_VER > 14
 
+_LIBCPP_END_NAMESPACE_STD
+
 #endif // _LIBCPP___TYPE_TRAITS_DISJUNCTION_H

diff  --git a/libcxx/include/type_traits b/libcxx/include/type_traits
index 7afbafd17397..f4d89235ad64 100644
--- a/libcxx/include/type_traits
+++ b/libcxx/include/type_traits
@@ -532,35 +532,24 @@ template <class _Tp> struct _LIBCPP_TEMPLATE_VIS hash;
 template <bool> struct _MetaBase;
 template <>
 struct _MetaBase<true> {
-  template <class _Tp, class _Up>
-  using _SelectImpl _LIBCPP_NODEBUG = _Tp;
   template <template <class...> class _FirstFn, template <class...> class, class ..._Args>
   using _SelectApplyImpl _LIBCPP_NODEBUG = _FirstFn<_Args...>;
-  template <class _Result, class _First, class ..._Rest>
-  using _OrImpl _LIBCPP_NODEBUG = typename _MetaBase<_First::value != true && sizeof...(_Rest) != 0>::template _OrImpl<_First, _Rest...>;
+  template <class _First, class...>
+  using _FirstImpl _LIBCPP_NODEBUG = _First;
+  template <class, class _Second, class...>
+  using _SecondImpl _LIBCPP_NODEBUG = _Second;
 };
 
 template <>
 struct _MetaBase<false> {
-  template <class _Tp, class _Up>
-  using _SelectImpl _LIBCPP_NODEBUG = _Up;
   template <template <class...> class, template <class...> class _SecondFn, class ..._Args>
   using _SelectApplyImpl _LIBCPP_NODEBUG = _SecondFn<_Args...>;
-  template <class _Result, class ...>
-  using _OrImpl _LIBCPP_NODEBUG = _Result;
-};
-template <bool _Cond, class _IfRes, class _ElseRes>
-using _If _LIBCPP_NODEBUG = typename _MetaBase<_Cond>::template _SelectImpl<_IfRes, _ElseRes>;
-template <class ..._Rest>
-using _Or _LIBCPP_NODEBUG = typename _MetaBase< sizeof...(_Rest) != 0 >::template _OrImpl<false_type, _Rest...>;
-
-template <class ...> using __expand_to_true = true_type;
-template <class ..._Pred>
-__expand_to_true<__enable_if_t<_Pred::value>...> __and_helper(int);
-template <class ...>
-false_type __and_helper(...);
-template <class ..._Pred>
-using _And _LIBCPP_NODEBUG = decltype(__and_helper<_Pred...>(0));
+};
+
+template <class ..._Args>
+using _FirstType _LIBCPP_NODEBUG = typename _MetaBase<(sizeof...(_Args) >= 1)>::template _FirstImpl<_Args...>;
+template <class ..._Args>
+using _SecondType _LIBCPP_NODEBUG = typename _MetaBase<(sizeof...(_Args) >= 2)>::template _SecondImpl<_Args...>;
 
 template <template <class...> class _Func, class ..._Args>
 struct _Lazy : _Func<_Args...> {};


        


More information about the libcxx-commits mailing list