[libcxx-commits] [libcxx] a29a1a3 - [libc++] Fix conjunction/disjunction and mark a few LWG issues as complete
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Jun 3 01:31:49 PDT 2022
Author: Nikolas Klauser
Date: 2022-06-03T10:31:42+02:00
New Revision: a29a1a33ac7b567031e5995cc0f17784a1c4be7a
URL: https://github.com/llvm/llvm-project/commit/a29a1a33ac7b567031e5995cc0f17784a1c4be7a
DIFF: https://github.com/llvm/llvm-project/commit/a29a1a33ac7b567031e5995cc0f17784a1c4be7a.diff
LOG: [libc++] Fix conjunction/disjunction and mark a few LWG issues as complete
Fixes #54803
Fixes #53133
Reviewed By: ldionne, #libc
Spies: libcxx-commits, mgorny
Differential Revision: https://reviews.llvm.org/D125221
Added:
libcxx/include/__type_traits/conjunction.h
libcxx/include/__type_traits/disjunction.h
libcxx/test/std/utilities/meta/meta.logical/conjunction.compile.pass.cpp
libcxx/test/std/utilities/meta/meta.logical/disjunction.compile.pass.cpp
Modified:
libcxx/docs/Status/Cxx17Issues.csv
libcxx/include/CMakeLists.txt
libcxx/include/module.modulemap
libcxx/include/type_traits
libcxx/test/libcxx/private_headers.verify.cpp
Removed:
libcxx/test/std/utilities/meta/meta.logical/conjunction.pass.cpp
libcxx/test/std/utilities/meta/meta.logical/disjunction.pass.cpp
################################################################################
diff --git a/libcxx/docs/Status/Cxx17Issues.csv b/libcxx/docs/Status/Cxx17Issues.csv
index 27f0e660d4ad..0e6f5c505966 100644
--- a/libcxx/docs/Status/Cxx17Issues.csv
+++ b/libcxx/docs/Status/Cxx17Issues.csv
@@ -199,7 +199,7 @@
"`2521 <https://wg21.link/LWG2521>`__","[fund.ts.v2] weak_ptr's converting move constructor should be modified as well for array support","Issaquah","",""
"`2525 <https://wg21.link/LWG2525>`__","[fund.ts.v2] get_memory_resource should be const and noexcept","Issaquah","",""
"`2527 <https://wg21.link/LWG2527>`__","[fund.ts.v2] ALLOCATOR_OF for function::operator= has incorrect default","Issaquah","",""
-"`2531 <https://wg21.link/LWG2531>`__","future::get should explicitly state that the shared state is released","Issaquah","",""
+"`2531 <https://wg21.link/LWG2531>`__","future::get should explicitly state that the shared state is released","Issaquah","|Nothing To Do|",""
"`2534 <https://wg21.link/LWG2534>`__","Constrain rvalue stream operators","Issaquah","|Complete|",""
"`2536 <https://wg21.link/LWG2536>`__","What should <complex.h> do?","Issaquah","|Complete|",""
"`2540 <https://wg21.link/LWG2540>`__","unordered_multimap::insert hint iterator","Issaquah","|Complete|",""
@@ -208,13 +208,13 @@
"`2556 <https://wg21.link/LWG2556>`__","Wide contract for future::share()","Issaquah","|Complete|",""
"`2562 <https://wg21.link/LWG2562>`__","Consistent total ordering of pointers by comparison functors","Issaquah","",""
"`2567 <https://wg21.link/LWG2567>`__","Specification of logical operator traits uses BaseCharacteristic, which is defined only for UnaryTypeTraits and BinaryTypeTraits","Issaquah","|Complete|",""
-"`2568 <https://wg21.link/LWG2568>`__","[fund.ts.v2] Specification of logical operator traits uses BaseCharacteristic, which is defined only for UnaryTypeTraits and BinaryTypeTraits","Issaquah","",""
-"`2569 <https://wg21.link/LWG2569>`__","conjunction and disjunction requirements are too strict","Issaquah","|Complete|",""
+"`2568 <https://wg21.link/LWG2568>`__","[fund.ts.v2] Specification of logical operator traits uses BaseCharacteristic, which is defined only for UnaryTypeTraits and BinaryTypeTraits","Issaquah","|Complete|","15.0"
+"`2569 <https://wg21.link/LWG2569>`__","conjunction and disjunction requirements are too strict","Issaquah","|Complete|","15.0"
"`2570 <https://wg21.link/LWG2570>`__","[fund.ts.v2] conjunction and disjunction requirements are too strict","Issaquah","",""
"`2578 <https://wg21.link/LWG2578>`__","Iterator requirements should reference iterator traits","Issaquah","|Complete|",""
"`2584 <https://wg21.link/LWG2584>`__","<regex> ECMAScript IdentityEscape is ambiguous","Issaquah","",""
"`2587 <https://wg21.link/LWG2587>`__","""Convertible to bool"" requirement in conjunction and disjunction","Issaquah","Resolved by 2567",""
-"`2588 <https://wg21.link/LWG2588>`__","[fund.ts.v2] ""Convertible to bool"" requirement in conjunction and disjunction","Issaquah","",""
+"`2588 <https://wg21.link/LWG2588>`__","[fund.ts.v2] ""Convertible to bool"" requirement in conjunction and disjunction","Issaquah","Resolved by 2568",""
"`2589 <https://wg21.link/LWG2589>`__","match_results can't satisfy the requirements of a container","Issaquah","|Complete|",""
"`2591 <https://wg21.link/LWG2591>`__","std::function's member template target() should not lead to undefined behaviour","Issaquah","|Complete|",""
"`2598 <https://wg21.link/LWG2598>`__","addressof works on temporaries","Issaquah","|Complete|",""
@@ -247,7 +247,7 @@
"`2748 <https://wg21.link/LWG2748>`__","swappable traits for optionals","Issaquah","|Complete|",""
"`2749 <https://wg21.link/LWG2749>`__","swappable traits for variants","Issaquah","|Complete|",""
"`2750 <https://wg21.link/LWG2750>`__","[fund.ts.v2] LWG 2451 conversion constructor constraint","Issaquah","|Nothing To Do|",""
-"`2752 <https://wg21.link/LWG2752>`__","""Throws:"" clauses of async and packaged_task are unimplementable","Issaquah","",""
+"`2752 <https://wg21.link/LWG2752>`__","""Throws:"" clauses of async and packaged_task are unimplementable","Issaquah","|Nothing To Do|",""
"`2755 <https://wg21.link/LWG2755>`__","[string.view.io] uses non-existent basic_string_view::to_string function","Issaquah","|Complete|",""
"`2756 <https://wg21.link/LWG2756>`__","C++ WP optional<T> should 'forward' T's implicit conversions","Issaquah","|Complete|",""
"`2758 <https://wg21.link/LWG2758>`__","std::string{}.assign(""ABCDE"", 0, 1) is ambiguous","Issaquah","|Complete|",""
@@ -301,7 +301,7 @@
"`2873 <https://wg21.link/LWG2873>`__","Add noexcept to several shared_ptr related functions","Kona","|Complete|",""
"`2874 <https://wg21.link/LWG2874>`__","Constructor ``shared_ptr::shared_ptr(Y*)``\ should be constrained","Kona","|Complete|","13.0"
"`2875 <https://wg21.link/LWG2875>`__","shared_ptr::shared_ptr(Y\*, D, [|hellip|\ ]) constructors should be constrained","Kona","|Complete|",""
-"`2876 <https://wg21.link/LWG2876>`__","``shared_ptr::shared_ptr(const weak_ptr<Y>&)``\ constructor should be constrained","Kona","",""
+"`2876 <https://wg21.link/LWG2876>`__","``shared_ptr::shared_ptr(const weak_ptr<Y>&)``\ constructor should be constrained","Kona","|Complete|","14.0"
"`2878 <https://wg21.link/LWG2878>`__","Missing DefaultConstructible requirement for istream_iterator default constructor","Kona","|Complete|",""
"`2890 <https://wg21.link/LWG2890>`__","The definition of 'object state' applies only to class types","Kona","|Complete|",""
"`2900 <https://wg21.link/LWG2900>`__","The copy and move constructors of optional are not constexpr","Kona","|Complete|",""
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 4931ec8faae9..4cb717e6517d 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -449,7 +449,9 @@ set(files
__type_traits/add_rvalue_reference.h
__type_traits/add_volatile.h
__type_traits/conditional.h
+ __type_traits/conjunction.h
__type_traits/decay.h
+ __type_traits/disjunction.h
__type_traits/enable_if.h
__type_traits/extent.h
__type_traits/integral_constant.h
diff --git a/libcxx/include/__type_traits/conjunction.h b/libcxx/include/__type_traits/conjunction.h
new file mode 100644
index 000000000000..187b73e6b198
--- /dev/null
+++ b/libcxx/include/__type_traits/conjunction.h
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_CONJUNCTION_H
+#define _LIBCPP___TYPE_TRAITS_CONJUNCTION_H
+
+#include <__config>
+#include <__type_traits/conditional.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
+
+template <class _Arg, class... _Args>
+struct __conjunction_impl {
+ using type = conditional_t<!bool(_Arg::value), _Arg, typename __conjunction_impl<_Args...>::type>;
+};
+
+template <class _Arg>
+struct __conjunction_impl<_Arg> {
+ using type = _Arg;
+};
+
+template <class... _Args>
+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
+
+#endif // _LIBCPP___TYPE_TRAITS_CONJUNCTION_H
diff --git a/libcxx/include/__type_traits/disjunction.h b/libcxx/include/__type_traits/disjunction.h
new file mode 100644
index 000000000000..1f7c5fe36fd5
--- /dev/null
+++ b/libcxx/include/__type_traits/disjunction.h
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_DISJUNCTION_H
+#define _LIBCPP___TYPE_TRAITS_DISJUNCTION_H
+
+#include <__config>
+#include <__type_traits/conditional.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
+
+template <class _Arg, class... _Args>
+struct __disjunction_impl {
+ using type = conditional_t<bool(_Arg::value), _Arg, typename __disjunction_impl<_Args...>::type>;
+};
+
+template <class _Arg>
+struct __disjunction_impl<_Arg> {
+ using type = _Arg;
+};
+
+template <class... _Args>
+struct disjunction : __disjunction_impl<false_type, _Args...>::type {};
+template<class... _Args>
+inline constexpr bool disjunction_v = disjunction<_Args...>::value;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER > 14
+
+#endif // _LIBCPP___TYPE_TRAITS_DISJUNCTION_H
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index e24c38704a56..c501137564d1 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -996,7 +996,9 @@ module std [system] {
module add_rvalue_reference { private header "__type_traits/add_rvalue_reference.h" }
module add_volatile { private header "__type_traits/add_volatile.h" }
module conditional { private header "__type_traits/conditional.h" }
+ module conjunction { private header "__type_traits/conjunction.h" }
module decay { private header "__type_traits/decay.h" }
+ module disjunction { private header "__type_traits/disjunction.h" }
module enable_if { private header "__type_traits/enable_if.h" }
module extent { private header "__type_traits/extent.h" }
module integral_constant { private header "__type_traits/integral_constant.h" }
diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits
index 852aed161f08..9e16987f6f07 100644
--- a/libcxx/include/type_traits
+++ b/libcxx/include/type_traits
@@ -425,7 +425,9 @@ namespace std
#include <__type_traits/add_rvalue_reference.h>
#include <__type_traits/add_volatile.h>
#include <__type_traits/conditional.h>
+#include <__type_traits/conjunction.h>
#include <__type_traits/decay.h>
+#include <__type_traits/disjunction.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/extent.h>
#include <__type_traits/integral_constant.h>
@@ -2872,17 +2874,6 @@ inline constexpr bool is_scoped_enum_v = is_scoped_enum<_Tp>::value;
#endif
#if _LIBCPP_STD_VER > 14
-
-template <class... _Args>
-struct conjunction : _And<_Args...> {};
-template<class... _Args>
-inline constexpr bool conjunction_v = conjunction<_Args...>::value;
-
-template <class... _Args>
-struct disjunction : _Or<_Args...> {};
-template<class... _Args>
-inline constexpr bool disjunction_v = disjunction<_Args...>::value;
-
template <class _Tp>
struct negation : _Not<_Tp> {};
template<class _Tp>
diff --git a/libcxx/test/libcxx/private_headers.verify.cpp b/libcxx/test/libcxx/private_headers.verify.cpp
index 78e4b61a1938..79c548b0d8e0 100644
--- a/libcxx/test/libcxx/private_headers.verify.cpp
+++ b/libcxx/test/libcxx/private_headers.verify.cpp
@@ -459,7 +459,9 @@ END-SCRIPT
#include <__type_traits/add_rvalue_reference.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/add_rvalue_reference.h'}}
#include <__type_traits/add_volatile.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/add_volatile.h'}}
#include <__type_traits/conditional.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/conditional.h'}}
+#include <__type_traits/conjunction.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/conjunction.h'}}
#include <__type_traits/decay.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/decay.h'}}
+#include <__type_traits/disjunction.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/disjunction.h'}}
#include <__type_traits/enable_if.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/enable_if.h'}}
#include <__type_traits/extent.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/extent.h'}}
#include <__type_traits/integral_constant.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/integral_constant.h'}}
diff --git a/libcxx/test/std/utilities/meta/meta.logical/conjunction.compile.pass.cpp b/libcxx/test/std/utilities/meta/meta.logical/conjunction.compile.pass.cpp
new file mode 100644
index 000000000000..d5d3aa268cd7
--- /dev/null
+++ b/libcxx/test/std/utilities/meta/meta.logical/conjunction.compile.pass.cpp
@@ -0,0 +1,87 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// type_traits
+
+// template<class... B> struct conjunction; // C++17
+// template<class... B>
+// constexpr bool conjunction_v = conjunction<B...>::value; // C++17
+
+#include <cassert>
+#include <type_traits>
+
+#include "test_macros.h"
+
+struct True { static constexpr bool value = true; };
+struct False { static constexpr bool value = false; };
+
+struct MySpecialTrueType { static constexpr auto value = true; static constexpr auto MySpecial = 23; };
+struct MyOtherSpecialTrueType { static constexpr auto value = -1; static constexpr auto MySpecial = 46; };
+struct MySpecialFalseType { static constexpr auto value = false; static constexpr auto MySpecial = 37; };
+struct HasNoValue {};
+struct ExplicitlyConvertibleToBool { explicit constexpr operator bool() const { return true; } };
+struct ValueExplicitlyConvertible { static constexpr ExplicitlyConvertibleToBool value {}; };
+
+static_assert( std::conjunction<>::value);
+static_assert( std::conjunction<std::true_type >::value);
+static_assert(!std::conjunction<std::false_type>::value);
+
+static_assert( std::conjunction_v<>);
+static_assert( std::conjunction_v<std::true_type >);
+static_assert(!std::conjunction_v<std::false_type>);
+
+static_assert( std::conjunction<std::true_type, std::true_type >::value);
+static_assert(!std::conjunction<std::true_type, std::false_type>::value);
+static_assert(!std::conjunction<std::false_type, std::true_type >::value);
+static_assert(!std::conjunction<std::false_type, std::false_type>::value);
+
+static_assert( std::conjunction_v<std::true_type, std::true_type >);
+static_assert(!std::conjunction_v<std::true_type, std::false_type>);
+static_assert(!std::conjunction_v<std::false_type, std::true_type >);
+static_assert(!std::conjunction_v<std::false_type, std::false_type>);
+
+static_assert( std::conjunction<std::true_type, std::true_type, std::true_type >::value);
+static_assert(!std::conjunction<std::true_type, std::false_type, std::true_type >::value);
+static_assert(!std::conjunction<std::false_type, std::true_type, std::true_type >::value);
+static_assert(!std::conjunction<std::false_type, std::false_type, std::true_type >::value);
+static_assert(!std::conjunction<std::true_type, std::true_type, std::false_type>::value);
+static_assert(!std::conjunction<std::true_type, std::false_type, std::false_type>::value);
+static_assert(!std::conjunction<std::false_type, std::true_type, std::false_type>::value);
+static_assert(!std::conjunction<std::false_type, std::false_type, std::false_type>::value);
+
+static_assert( std::conjunction_v<std::true_type, std::true_type, std::true_type >);
+static_assert(!std::conjunction_v<std::true_type, std::false_type, std::true_type >);
+static_assert(!std::conjunction_v<std::false_type, std::true_type, std::true_type >);
+static_assert(!std::conjunction_v<std::false_type, std::false_type, std::true_type >);
+static_assert(!std::conjunction_v<std::true_type, std::true_type, std::false_type>);
+static_assert(!std::conjunction_v<std::true_type, std::false_type, std::false_type>);
+static_assert(!std::conjunction_v<std::false_type, std::true_type, std::false_type>);
+static_assert(!std::conjunction_v<std::false_type, std::false_type, std::false_type>);
+
+static_assert( std::conjunction<True >::value);
+static_assert(!std::conjunction<False>::value);
+
+static_assert( std::conjunction_v<True >);
+static_assert(!std::conjunction_v<False>);
+
+static_assert(std::is_base_of_v<MySpecialTrueType, std::conjunction<MyOtherSpecialTrueType, MySpecialTrueType>>);
+static_assert(std::is_base_of_v<MyOtherSpecialTrueType, std::conjunction<MySpecialTrueType, MyOtherSpecialTrueType>>);
+static_assert(std::is_base_of_v<MySpecialFalseType, std::conjunction<MySpecialFalseType, MyOtherSpecialTrueType>>);
+static_assert(std::is_base_of_v<MySpecialFalseType, std::conjunction<MyOtherSpecialTrueType, MySpecialFalseType>>);
+
+static_assert(std::is_base_of_v<std::false_type, std::conjunction<std::false_type, HasNoValue>>);
+
+static_assert(!std::conjunction<std::false_type, HasNoValue>::value);
+static_assert(!std::conjunction_v<std::false_type, HasNoValue>);
+
+static_assert(std::conjunction<MyOtherSpecialTrueType>::value == -1);
+static_assert(std::conjunction_v<MyOtherSpecialTrueType>);
+
+static_assert(std::is_base_of_v<ValueExplicitlyConvertible, std::conjunction<ValueExplicitlyConvertible>>);
+static_assert(std::conjunction_v<ValueExplicitlyConvertible, std::true_type>);
diff --git a/libcxx/test/std/utilities/meta/meta.logical/conjunction.pass.cpp b/libcxx/test/std/utilities/meta/meta.logical/conjunction.pass.cpp
deleted file mode 100644
index 3132a7c04bce..000000000000
--- a/libcxx/test/std/utilities/meta/meta.logical/conjunction.pass.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14
-// type_traits
-
-// template<class... B> struct conjunction; // C++17
-// template<class... B>
-// constexpr bool conjunction_v = conjunction<B...>::value; // C++17
-
-#include <type_traits>
-#include <cassert>
-
-#include "test_macros.h"
-
-struct True { static constexpr bool value = true; };
-struct False { static constexpr bool value = false; };
-
-int main(int, char**)
-{
- static_assert ( std::conjunction<>::value, "" );
- static_assert ( std::conjunction<std::true_type >::value, "" );
- static_assert (!std::conjunction<std::false_type>::value, "" );
-
- static_assert ( std::conjunction_v<>, "" );
- static_assert ( std::conjunction_v<std::true_type >, "" );
- static_assert (!std::conjunction_v<std::false_type>, "" );
-
- static_assert ( std::conjunction<std::true_type, std::true_type >::value, "" );
- static_assert (!std::conjunction<std::true_type, std::false_type>::value, "" );
- static_assert (!std::conjunction<std::false_type, std::true_type >::value, "" );
- static_assert (!std::conjunction<std::false_type, std::false_type>::value, "" );
-
- static_assert ( std::conjunction_v<std::true_type, std::true_type >, "" );
- static_assert (!std::conjunction_v<std::true_type, std::false_type>, "" );
- static_assert (!std::conjunction_v<std::false_type, std::true_type >, "" );
- static_assert (!std::conjunction_v<std::false_type, std::false_type>, "" );
-
- static_assert ( std::conjunction<std::true_type, std::true_type, std::true_type >::value, "" );
- static_assert (!std::conjunction<std::true_type, std::false_type, std::true_type >::value, "" );
- static_assert (!std::conjunction<std::false_type, std::true_type, std::true_type >::value, "" );
- static_assert (!std::conjunction<std::false_type, std::false_type, std::true_type >::value, "" );
- static_assert (!std::conjunction<std::true_type, std::true_type, std::false_type>::value, "" );
- static_assert (!std::conjunction<std::true_type, std::false_type, std::false_type>::value, "" );
- static_assert (!std::conjunction<std::false_type, std::true_type, std::false_type>::value, "" );
- static_assert (!std::conjunction<std::false_type, std::false_type, std::false_type>::value, "" );
-
- static_assert ( std::conjunction_v<std::true_type, std::true_type, std::true_type >, "" );
- static_assert (!std::conjunction_v<std::true_type, std::false_type, std::true_type >, "" );
- static_assert (!std::conjunction_v<std::false_type, std::true_type, std::true_type >, "" );
- static_assert (!std::conjunction_v<std::false_type, std::false_type, std::true_type >, "" );
- static_assert (!std::conjunction_v<std::true_type, std::true_type, std::false_type>, "" );
- static_assert (!std::conjunction_v<std::true_type, std::false_type, std::false_type>, "" );
- static_assert (!std::conjunction_v<std::false_type, std::true_type, std::false_type>, "" );
- static_assert (!std::conjunction_v<std::false_type, std::false_type, std::false_type>, "" );
-
- static_assert ( std::conjunction<True >::value, "" );
- static_assert (!std::conjunction<False>::value, "" );
-
- static_assert ( std::conjunction_v<True >, "" );
- static_assert (!std::conjunction_v<False>, "" );
-
- return 0;
-}
diff --git a/libcxx/test/std/utilities/meta/meta.logical/disjunction.compile.pass.cpp b/libcxx/test/std/utilities/meta/meta.logical/disjunction.compile.pass.cpp
new file mode 100644
index 000000000000..2a6c920710f7
--- /dev/null
+++ b/libcxx/test/std/utilities/meta/meta.logical/disjunction.compile.pass.cpp
@@ -0,0 +1,87 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// type_traits
+
+// template<class... B> struct disjunction; // C++17
+// template<class... B>
+// constexpr bool disjunction_v = disjunction<B...>::value; // C++17
+
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+struct True { static constexpr bool value = true; };
+struct False { static constexpr bool value = false; };
+
+struct MySpecialTrueType { static constexpr auto value = -1; static constexpr auto MySpecial = 37; };
+struct MySpecialFalseType { static constexpr auto value = false; static constexpr auto MySpecial = 23; };
+struct MyOtherSpecialFalseType { static constexpr auto value = false; static constexpr auto MySpecial = 46; };
+struct HasNoValue {};
+struct ExplicitlyConvertibleToBool { explicit constexpr operator bool() const { return false; } };
+struct ValueExplicitlyConvertible { static constexpr ExplicitlyConvertibleToBool value {}; };
+
+static_assert(!std::disjunction<>::value);
+static_assert( std::disjunction<std::true_type >::value);
+static_assert(!std::disjunction<std::false_type>::value);
+
+static_assert(!std::disjunction_v<>);
+static_assert( std::disjunction_v<std::true_type >);
+static_assert(!std::disjunction_v<std::false_type>);
+
+static_assert( std::disjunction<std::true_type, std::true_type >::value);
+static_assert( std::disjunction<std::true_type, std::false_type>::value);
+static_assert( std::disjunction<std::false_type, std::true_type >::value);
+static_assert(!std::disjunction<std::false_type, std::false_type>::value);
+
+static_assert( std::disjunction_v<std::true_type, std::true_type >);
+static_assert( std::disjunction_v<std::true_type, std::false_type>);
+static_assert( std::disjunction_v<std::false_type, std::true_type >);
+static_assert(!std::disjunction_v<std::false_type, std::false_type>);
+
+static_assert( std::disjunction<std::true_type, std::true_type, std::true_type >::value);
+static_assert( std::disjunction<std::true_type, std::false_type, std::true_type >::value);
+static_assert( std::disjunction<std::false_type, std::true_type, std::true_type >::value);
+static_assert( std::disjunction<std::false_type, std::false_type, std::true_type >::value);
+static_assert( std::disjunction<std::true_type, std::true_type, std::false_type>::value);
+static_assert( std::disjunction<std::true_type, std::false_type, std::false_type>::value);
+static_assert( std::disjunction<std::false_type, std::true_type, std::false_type>::value);
+static_assert(!std::disjunction<std::false_type, std::false_type, std::false_type>::value);
+
+static_assert( std::disjunction_v<std::true_type, std::true_type, std::true_type >);
+static_assert( std::disjunction_v<std::true_type, std::false_type, std::true_type >);
+static_assert( std::disjunction_v<std::false_type, std::true_type, std::true_type >);
+static_assert( std::disjunction_v<std::false_type, std::false_type, std::true_type >);
+static_assert( std::disjunction_v<std::true_type, std::true_type, std::false_type>);
+static_assert( std::disjunction_v<std::true_type, std::false_type, std::false_type>);
+static_assert( std::disjunction_v<std::false_type, std::true_type, std::false_type>);
+static_assert(!std::disjunction_v<std::false_type, std::false_type, std::false_type>);
+
+static_assert ( std::disjunction<True >::value, "" );
+static_assert (!std::disjunction<False>::value, "" );
+
+static_assert ( std::disjunction_v<True >, "" );
+static_assert (!std::disjunction_v<False>, "" );
+
+static_assert(std::is_base_of_v<MySpecialFalseType, std::disjunction<MyOtherSpecialFalseType, MySpecialFalseType>>);
+static_assert(std::is_base_of_v<MyOtherSpecialFalseType, std::disjunction<MySpecialFalseType, MyOtherSpecialFalseType>>);
+static_assert(std::is_base_of_v<MySpecialTrueType, std::disjunction<MySpecialTrueType, MyOtherSpecialFalseType>>);
+static_assert(std::is_base_of_v<MySpecialTrueType, std::disjunction<MyOtherSpecialFalseType, MySpecialTrueType>>);
+
+static_assert(std::is_base_of_v<std::true_type, std::disjunction<std::true_type, HasNoValue>>);
+
+static_assert(std::disjunction<std::true_type, HasNoValue>::value);
+static_assert(std::disjunction_v<std::true_type, HasNoValue>);
+
+static_assert(std::disjunction<MySpecialTrueType>::value == -1);
+static_assert(std::disjunction_v<MySpecialTrueType>);
+
+static_assert(std::is_base_of_v<ValueExplicitlyConvertible, std::disjunction<ValueExplicitlyConvertible>>);
+static_assert(std::disjunction_v<ValueExplicitlyConvertible, std::true_type>);
diff --git a/libcxx/test/std/utilities/meta/meta.logical/disjunction.pass.cpp b/libcxx/test/std/utilities/meta/meta.logical/disjunction.pass.cpp
deleted file mode 100644
index ac5d851062cc..000000000000
--- a/libcxx/test/std/utilities/meta/meta.logical/disjunction.pass.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14
-// type_traits
-
-// template<class... B> struct disjunction; // C++17
-// template<class... B>
-// constexpr bool disjunction_v = disjunction<B...>::value; // C++17
-
-#include <type_traits>
-#include <cassert>
-
-#include "test_macros.h"
-
-struct True { static constexpr bool value = true; };
-struct False { static constexpr bool value = false; };
-
-int main(int, char**)
-{
- static_assert (!std::disjunction<>::value, "" );
- static_assert ( std::disjunction<std::true_type >::value, "" );
- static_assert (!std::disjunction<std::false_type>::value, "" );
-
- static_assert (!std::disjunction_v<>, "" );
- static_assert ( std::disjunction_v<std::true_type >, "" );
- static_assert (!std::disjunction_v<std::false_type>, "" );
-
- static_assert ( std::disjunction<std::true_type, std::true_type >::value, "" );
- static_assert ( std::disjunction<std::true_type, std::false_type>::value, "" );
- static_assert ( std::disjunction<std::false_type, std::true_type >::value, "" );
- static_assert (!std::disjunction<std::false_type, std::false_type>::value, "" );
-
- static_assert ( std::disjunction_v<std::true_type, std::true_type >, "" );
- static_assert ( std::disjunction_v<std::true_type, std::false_type>, "" );
- static_assert ( std::disjunction_v<std::false_type, std::true_type >, "" );
- static_assert (!std::disjunction_v<std::false_type, std::false_type>, "" );
-
- static_assert ( std::disjunction<std::true_type, std::true_type, std::true_type >::value, "" );
- static_assert ( std::disjunction<std::true_type, std::false_type, std::true_type >::value, "" );
- static_assert ( std::disjunction<std::false_type, std::true_type, std::true_type >::value, "" );
- static_assert ( std::disjunction<std::false_type, std::false_type, std::true_type >::value, "" );
- static_assert ( std::disjunction<std::true_type, std::true_type, std::false_type>::value, "" );
- static_assert ( std::disjunction<std::true_type, std::false_type, std::false_type>::value, "" );
- static_assert ( std::disjunction<std::false_type, std::true_type, std::false_type>::value, "" );
- static_assert (!std::disjunction<std::false_type, std::false_type, std::false_type>::value, "" );
-
- static_assert ( std::disjunction_v<std::true_type, std::true_type, std::true_type >, "" );
- static_assert ( std::disjunction_v<std::true_type, std::false_type, std::true_type >, "" );
- static_assert ( std::disjunction_v<std::false_type, std::true_type, std::true_type >, "" );
- static_assert ( std::disjunction_v<std::false_type, std::false_type, std::true_type >, "" );
- static_assert ( std::disjunction_v<std::true_type, std::true_type, std::false_type>, "" );
- static_assert ( std::disjunction_v<std::true_type, std::false_type, std::false_type>, "" );
- static_assert ( std::disjunction_v<std::false_type, std::true_type, std::false_type>, "" );
- static_assert (!std::disjunction_v<std::false_type, std::false_type, std::false_type>, "" );
-
- static_assert ( std::disjunction<True >::value, "" );
- static_assert (!std::disjunction<False>::value, "" );
-
- static_assert ( std::disjunction_v<True >, "" );
- static_assert (!std::disjunction_v<False>, "" );
-
- return 0;
-}
More information about the libcxx-commits
mailing list