diff --git a/libcxx/docs/Status/Cxx17Issues.csv b/libcxx/docs/Status/Cxx17Issues.csv --- a/libcxx/docs/Status/Cxx17Issues.csv +++ b/libcxx/docs/Status/Cxx17Issues.csv @@ -199,7 +199,7 @@ "`2521 `__","[fund.ts.v2] weak_ptr's converting move constructor should be modified as well for array support","Issaquah","","" "`2525 `__","[fund.ts.v2] get_memory_resource should be const and noexcept","Issaquah","","" "`2527 `__","[fund.ts.v2] ALLOCATOR_OF for function::operator= has incorrect default","Issaquah","","" -"`2531 `__","future::get should explicitly state that the shared state is released","Issaquah","","" +"`2531 `__","future::get should explicitly state that the shared state is released","Issaquah","|Nothing To Do|","" "`2534 `__","Constrain rvalue stream operators","Issaquah","|Complete|","" "`2536 `__","What should do?","Issaquah","|Complete|","" "`2540 `__","unordered_multimap::insert hint iterator","Issaquah","|Complete|","" @@ -208,13 +208,13 @@ "`2556 `__","Wide contract for future::share()","Issaquah","|Complete|","" "`2562 `__","Consistent total ordering of pointers by comparison functors","Issaquah","","" "`2567 `__","Specification of logical operator traits uses BaseCharacteristic, which is defined only for UnaryTypeTraits and BinaryTypeTraits","Issaquah","|Complete|","" -"`2568 `__","[fund.ts.v2] Specification of logical operator traits uses BaseCharacteristic, which is defined only for UnaryTypeTraits and BinaryTypeTraits","Issaquah","","" -"`2569 `__","conjunction and disjunction requirements are too strict","Issaquah","|Complete|","" +"`2568 `__","[fund.ts.v2] Specification of logical operator traits uses BaseCharacteristic, which is defined only for UnaryTypeTraits and BinaryTypeTraits","Issaquah","|Complete|","15.0" +"`2569 `__","conjunction and disjunction requirements are too strict","Issaquah","|Complete|","15.0" "`2570 `__","[fund.ts.v2] conjunction and disjunction requirements are too strict","Issaquah","","" "`2578 `__","Iterator requirements should reference iterator traits","Issaquah","|Complete|","" "`2584 `__"," ECMAScript IdentityEscape is ambiguous","Issaquah","","" "`2587 `__","""Convertible to bool"" requirement in conjunction and disjunction","Issaquah","Resolved by 2567","" -"`2588 `__","[fund.ts.v2] ""Convertible to bool"" requirement in conjunction and disjunction","Issaquah","","" +"`2588 `__","[fund.ts.v2] ""Convertible to bool"" requirement in conjunction and disjunction","Issaquah","Resolved by 2568","" "`2589 `__","match_results can't satisfy the requirements of a container","Issaquah","|Complete|","" "`2591 `__","std::function's member template target() should not lead to undefined behaviour","Issaquah","|Complete|","" "`2598 `__","addressof works on temporaries","Issaquah","|Complete|","" @@ -247,7 +247,7 @@ "`2748 `__","swappable traits for optionals","Issaquah","|Complete|","" "`2749 `__","swappable traits for variants","Issaquah","|Complete|","" "`2750 `__","[fund.ts.v2] LWG 2451 conversion constructor constraint","Issaquah","|Nothing To Do|","" -"`2752 `__","""Throws:"" clauses of async and packaged_task are unimplementable","Issaquah","","" +"`2752 `__","""Throws:"" clauses of async and packaged_task are unimplementable","Issaquah","|Nothing To Do|","" "`2755 `__","[string.view.io] uses non-existent basic_string_view::to_string function","Issaquah","|Complete|","" "`2756 `__","C++ WP optional should 'forward' T's implicit conversions","Issaquah","|Complete|","" "`2758 `__","std::string{}.assign(""ABCDE"", 0, 1) is ambiguous","Issaquah","|Complete|","" @@ -301,7 +301,7 @@ "`2873 `__","Add noexcept to several shared_ptr related functions","Kona","|Complete|","" "`2874 `__","Constructor ``shared_ptr::shared_ptr(Y*)``\ should be constrained","Kona","|Complete|","13.0" "`2875 `__","shared_ptr::shared_ptr(Y\*, D, [|hellip|\ ]) constructors should be constrained","Kona","|Complete|","" -"`2876 `__","``shared_ptr::shared_ptr(const weak_ptr&)``\ constructor should be constrained","Kona","","" +"`2876 `__","``shared_ptr::shared_ptr(const weak_ptr&)``\ constructor should be constrained","Kona","|Complete|","14.0" "`2878 `__","Missing DefaultConstructible requirement for istream_iterator default constructor","Kona","|Complete|","" "`2890 `__","The definition of 'object state' applies only to class types","Kona","|Complete|","" "`2900 `__","The copy and move constructors of optional are not constexpr","Kona","|Complete|","" diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -424,6 +424,9 @@ __threading_support __tree __tuple + __type_traits/conditional.h + __type_traits/conjunction.h + __type_traits/disjunction.h __type_traits/integral_constant.h __type_traits/is_callable.h __undef_macros diff --git a/libcxx/include/__type_traits/conditional.h b/libcxx/include/__type_traits/conditional.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__type_traits/conditional.h @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// 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_CONDITIONAL_H +#define _LIBCPP___TYPE_TRAITS_CONDITIONAL_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template + struct _LIBCPP_TEMPLATE_VIS conditional {typedef _If type;}; +template + struct _LIBCPP_TEMPLATE_VIS conditional {typedef _Then type;}; + +#if _LIBCPP_STD_VER > 11 +template using conditional_t = typename conditional<_Bp, _If, _Then>::type; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_CONDITIONAL_H diff --git a/libcxx/include/__type_traits/conjunction.h b/libcxx/include/__type_traits/conjunction.h new file mode 100644 --- /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 +struct __conjunction_impl { + using __derive_from = conditional_t::__derive_from>; +}; + +template +struct __conjunction_impl<_Arg> { + using __derive_from = _Arg; +}; + +template +struct conjunction : __conjunction_impl::__derive_from {}; + +template +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 --- /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 +struct __disjunction_impl { + using __derive_from = conditional_t::__derive_from>; +}; + +template +struct __disjunction_impl<_Arg> { + using __derive_from = _Arg; +}; + +template +struct disjunction : __disjunction_impl::__derive_from {}; +template +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 --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -970,6 +970,9 @@ export functional.__functional.unwrap_ref export * + module conditional { private header "__type_traits/conditional.h" } + module conjunction { private header "__type_traits/conjunction.h" } + module disjunction { private header "__type_traits/disjunction.h" } module integral_constant { private header "__type_traits/integral_constant.h" } module is_callable { private header "__type_traits/is_callable.h" } } diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -418,6 +418,9 @@ */ #include <__assert> // all public C++ headers provide the assertion handler #include <__config> +#include <__type_traits/conditional.h> +#include <__type_traits/conjunction.h> +#include <__type_traits/disjunction.h> #include <__type_traits/integral_constant.h> #include <__type_traits/is_callable.h> #include <__utility/declval.h> @@ -505,16 +508,6 @@ template struct _LIBCPP_TEMPLATE_VIS __dependent_type : public _Tp {}; - -template - struct _LIBCPP_TEMPLATE_VIS conditional {typedef _If type;}; -template - struct _LIBCPP_TEMPLATE_VIS conditional {typedef _Then type;}; - -#if _LIBCPP_STD_VER > 11 -template using conditional_t = typename conditional<_Bp, _If, _Then>::type; -#endif - // is_same template @@ -3935,17 +3928,6 @@ #endif #if _LIBCPP_STD_VER > 14 - -template -struct conjunction : _And<_Args...> {}; -template -inline constexpr bool conjunction_v = conjunction<_Args...>::value; - -template -struct disjunction : _Or<_Args...> {}; -template -inline constexpr bool disjunction_v = disjunction<_Args...>::value; - template struct negation : _Not<_Tp> {}; template diff --git a/libcxx/test/libcxx/private_headers.verify.cpp b/libcxx/test/libcxx/private_headers.verify.cpp --- a/libcxx/test/libcxx/private_headers.verify.cpp +++ b/libcxx/test/libcxx/private_headers.verify.cpp @@ -434,6 +434,9 @@ #include <__thread/poll_with_backoff.h> // expected-error@*:* {{use of private header from outside its module: '__thread/poll_with_backoff.h'}} #include <__thread/timed_backoff_policy.h> // expected-error@*:* {{use of private header from outside its module: '__thread/timed_backoff_policy.h'}} #include <__tuple> // expected-error@*:* {{use of private header from outside its module: '__tuple'}} +#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/disjunction.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/disjunction.h'}} #include <__type_traits/integral_constant.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/integral_constant.h'}} #include <__type_traits/is_callable.h> // expected-error@*:* {{use of private header from outside its module: '__type_traits/is_callable.h'}} #include <__utility/as_const.h> // expected-error@*:* {{use of private header from outside its module: '__utility/as_const.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 --- /dev/null +++ b/libcxx/test/std/utilities/meta/meta.logical/conjunction.compile.pass.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// 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 struct conjunction; // C++17 +// template +// constexpr bool conjunction_v = conjunction::value; // C++17 + +#include +#include + +#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 = true; static constexpr auto MySpecial = 46; }; +struct MySpecialFalseType { static constexpr auto value = false; static constexpr auto MySpecial = 37; }; +struct HasNoValue {}; + +static_assert( std::conjunction<>::value); +static_assert( std::conjunction::value); +static_assert(!std::conjunction::value); + +static_assert( std::conjunction_v<>); +static_assert( std::conjunction_v); +static_assert(!std::conjunction_v); + +static_assert( std::conjunction::value); +static_assert(!std::conjunction::value); +static_assert(!std::conjunction::value); +static_assert(!std::conjunction::value); + +static_assert( std::conjunction_v); +static_assert(!std::conjunction_v); +static_assert(!std::conjunction_v); +static_assert(!std::conjunction_v); + +static_assert( std::conjunction::value); +static_assert(!std::conjunction::value); +static_assert(!std::conjunction::value); +static_assert(!std::conjunction::value); +static_assert(!std::conjunction::value); +static_assert(!std::conjunction::value); +static_assert(!std::conjunction::value); +static_assert(!std::conjunction::value); + +static_assert( std::conjunction_v); +static_assert(!std::conjunction_v); +static_assert(!std::conjunction_v); +static_assert(!std::conjunction_v); +static_assert(!std::conjunction_v); +static_assert(!std::conjunction_v); +static_assert(!std::conjunction_v); +static_assert(!std::conjunction_v); + +static_assert( std::conjunction::value); +static_assert(!std::conjunction::value); + +static_assert( std::conjunction_v); +static_assert(!std::conjunction_v); + +static_assert(std::is_base_of_v>); +static_assert(std::is_base_of_v>); +static_assert(std::is_base_of_v>); +static_assert(std::is_base_of_v>); + +static_assert(std::is_base_of_v>); 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 --- 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 struct conjunction; // C++17 -// template -// constexpr bool conjunction_v = conjunction::value; // C++17 - -#include -#include - -#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::value, "" ); - static_assert (!std::conjunction::value, "" ); - - static_assert ( std::conjunction_v<>, "" ); - static_assert ( std::conjunction_v, "" ); - static_assert (!std::conjunction_v, "" ); - - static_assert ( std::conjunction::value, "" ); - static_assert (!std::conjunction::value, "" ); - static_assert (!std::conjunction::value, "" ); - static_assert (!std::conjunction::value, "" ); - - static_assert ( std::conjunction_v, "" ); - static_assert (!std::conjunction_v, "" ); - static_assert (!std::conjunction_v, "" ); - static_assert (!std::conjunction_v, "" ); - - static_assert ( std::conjunction::value, "" ); - static_assert (!std::conjunction::value, "" ); - static_assert (!std::conjunction::value, "" ); - static_assert (!std::conjunction::value, "" ); - static_assert (!std::conjunction::value, "" ); - static_assert (!std::conjunction::value, "" ); - static_assert (!std::conjunction::value, "" ); - static_assert (!std::conjunction::value, "" ); - - static_assert ( std::conjunction_v, "" ); - static_assert (!std::conjunction_v, "" ); - static_assert (!std::conjunction_v, "" ); - static_assert (!std::conjunction_v, "" ); - static_assert (!std::conjunction_v, "" ); - static_assert (!std::conjunction_v, "" ); - static_assert (!std::conjunction_v, "" ); - static_assert (!std::conjunction_v, "" ); - - static_assert ( std::conjunction::value, "" ); - static_assert (!std::conjunction::value, "" ); - - static_assert ( std::conjunction_v, "" ); - static_assert (!std::conjunction_v, "" ); - - 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 --- /dev/null +++ b/libcxx/test/std/utilities/meta/meta.logical/disjunction.compile.pass.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// 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 struct disjunction; // C++17 +// template +// constexpr bool disjunction_v = disjunction::value; // C++17 + +#include +#include + +#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 = 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 {}; + +static_assert(!std::disjunction<>::value); +static_assert( std::disjunction::value); +static_assert(!std::disjunction::value); + +static_assert(!std::disjunction_v<>); +static_assert( std::disjunction_v); +static_assert(!std::disjunction_v); + +static_assert( std::disjunction::value); +static_assert( std::disjunction::value); +static_assert( std::disjunction::value); +static_assert(!std::disjunction::value); + +static_assert( std::disjunction_v); +static_assert( std::disjunction_v); +static_assert( std::disjunction_v); +static_assert(!std::disjunction_v); + +static_assert( std::disjunction::value); +static_assert( std::disjunction::value); +static_assert( std::disjunction::value); +static_assert( std::disjunction::value); +static_assert( std::disjunction::value); +static_assert( std::disjunction::value); +static_assert( std::disjunction::value); +static_assert(!std::disjunction::value); + +static_assert( std::disjunction_v); +static_assert( std::disjunction_v); +static_assert( std::disjunction_v); +static_assert( std::disjunction_v); +static_assert( std::disjunction_v); +static_assert( std::disjunction_v); +static_assert( std::disjunction_v); +static_assert(!std::disjunction_v); + +static_assert ( std::disjunction::value, "" ); +static_assert (!std::disjunction::value, "" ); + +static_assert ( std::disjunction_v, "" ); +static_assert (!std::disjunction_v, "" ); + +static_assert(std::is_base_of_v>); +static_assert(std::is_base_of_v>); +static_assert(std::is_base_of_v>); +static_assert(std::is_base_of_v>); + +static_assert(std::is_base_of_v>); 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 --- 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 struct disjunction; // C++17 -// template -// constexpr bool disjunction_v = disjunction::value; // C++17 - -#include -#include - -#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::value, "" ); - static_assert (!std::disjunction::value, "" ); - - static_assert (!std::disjunction_v<>, "" ); - static_assert ( std::disjunction_v, "" ); - static_assert (!std::disjunction_v, "" ); - - static_assert ( std::disjunction::value, "" ); - static_assert ( std::disjunction::value, "" ); - static_assert ( std::disjunction::value, "" ); - static_assert (!std::disjunction::value, "" ); - - static_assert ( std::disjunction_v, "" ); - static_assert ( std::disjunction_v, "" ); - static_assert ( std::disjunction_v, "" ); - static_assert (!std::disjunction_v, "" ); - - static_assert ( std::disjunction::value, "" ); - static_assert ( std::disjunction::value, "" ); - static_assert ( std::disjunction::value, "" ); - static_assert ( std::disjunction::value, "" ); - static_assert ( std::disjunction::value, "" ); - static_assert ( std::disjunction::value, "" ); - static_assert ( std::disjunction::value, "" ); - static_assert (!std::disjunction::value, "" ); - - static_assert ( std::disjunction_v, "" ); - static_assert ( std::disjunction_v, "" ); - static_assert ( std::disjunction_v, "" ); - static_assert ( std::disjunction_v, "" ); - static_assert ( std::disjunction_v, "" ); - static_assert ( std::disjunction_v, "" ); - static_assert ( std::disjunction_v, "" ); - static_assert (!std::disjunction_v, "" ); - - static_assert ( std::disjunction::value, "" ); - static_assert (!std::disjunction::value, "" ); - - static_assert ( std::disjunction_v, "" ); - static_assert (!std::disjunction_v, "" ); - - return 0; -}