diff --git a/libcxx/include/compare b/libcxx/include/compare index 7d483a77c59c54..ff3469d7f1b856 100644 --- a/libcxx/include/compare +++ b/libcxx/include/compare @@ -15,15 +15,13 @@ namespace std { // [cmp.categories], comparison category types - class weak_equality; - class strong_equality; class partial_ordering; class weak_ordering; class strong_ordering; // named comparison functions - constexpr bool is_eq (weak_equality cmp) noexcept { return cmp == 0; } - constexpr bool is_neq (weak_equality cmp) noexcept { return cmp != 0; } + constexpr bool is_eq (partial_ordering cmp) noexcept { return cmp == 0; } + constexpr bool is_neq (partial_ordering cmp) noexcept { return cmp != 0; } constexpr bool is_lt (partial_ordering cmp) noexcept { return cmp < 0; } constexpr bool is_lteq(partial_ordering cmp) noexcept { return cmp <= 0; } constexpr bool is_gt (partial_ordering cmp) noexcept { return cmp > 0; } @@ -41,8 +39,6 @@ namespace std { template constexpr strong_ordering strong_order(const T& a, const T& b); template constexpr weak_ordering weak_order(const T& a, const T& b); template constexpr partial_ordering partial_order(const T& a, const T& b); - template constexpr strong_equality strong_equal(const T& a, const T& b); - template constexpr weak_equality weak_equal(const T& a, const T& b); // [cmp.partialord], Class partial_ordering class partial_ordering { @@ -161,130 +157,6 @@ struct _CmpUnspecifiedParam { _CmpUnspecifiedParam(_Tp) = delete; }; -class weak_equality { - _LIBCPP_INLINE_VISIBILITY - constexpr explicit weak_equality(_EqResult __val) noexcept : __value_(__val) {} - -public: - static const weak_equality equivalent; - static const weak_equality nonequivalent; - - _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept; - _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept; - _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept; - _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept; - -#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR - _LIBCPP_INLINE_VISIBILITY friend constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept; - _LIBCPP_INLINE_VISIBILITY friend constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept; -#endif - -private: - _EqResult __value_; -}; - -_LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::equivalent(_EqResult::__equiv); -_LIBCPP_INLINE_VAR constexpr weak_equality weak_equality::nonequivalent(_EqResult::__nonequiv); - -_LIBCPP_INLINE_VISIBILITY -inline constexpr bool operator==(weak_equality __v, _CmpUnspecifiedParam) noexcept { - return __v.__value_ == _EqResult::__zero; -} - -_LIBCPP_INLINE_VISIBILITY -inline constexpr bool operator==(_CmpUnspecifiedParam, weak_equality __v) noexcept { - return __v.__value_ == _EqResult::__zero; -} - -_LIBCPP_INLINE_VISIBILITY -inline constexpr bool operator!=(weak_equality __v, _CmpUnspecifiedParam) noexcept { - return __v.__value_ != _EqResult::__zero; -} - -_LIBCPP_INLINE_VISIBILITY -inline constexpr bool operator!=(_CmpUnspecifiedParam, weak_equality __v) noexcept { - return __v.__value_ != _EqResult::__zero; -} - -#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR -_LIBCPP_INLINE_VISIBILITY -inline constexpr weak_equality operator<=>(weak_equality __v, _CmpUnspecifiedParam) noexcept { - return __v; -} - -_LIBCPP_INLINE_VISIBILITY -inline constexpr weak_equality operator<=>(_CmpUnspecifiedParam, weak_equality __v) noexcept { - return __v; -} -#endif - -class strong_equality { - _LIBCPP_INLINE_VISIBILITY - explicit constexpr strong_equality(_EqResult __val) noexcept : __value_(__val) {} - -public: - static const strong_equality equal; - static const strong_equality nonequal; - static const strong_equality equivalent; - static const strong_equality nonequivalent; - - // conversion - _LIBCPP_INLINE_VISIBILITY constexpr operator weak_equality() const noexcept { - return __value_ == _EqResult::__zero ? weak_equality::equivalent - : weak_equality::nonequivalent; - } - - // comparisons - _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept; - _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept; - _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept; - _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept; - -#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR - _LIBCPP_INLINE_VISIBILITY friend constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept; - _LIBCPP_INLINE_VISIBILITY friend constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept; -#endif -private: - _EqResult __value_; -}; - -_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::equal(_EqResult::__equal); -_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::nonequal(_EqResult::__nonequal); -_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::equivalent(_EqResult::__equiv); -_LIBCPP_INLINE_VAR constexpr strong_equality strong_equality::nonequivalent(_EqResult::__nonequiv); - -_LIBCPP_INLINE_VISIBILITY -constexpr bool operator==(strong_equality __v, _CmpUnspecifiedParam) noexcept { - return __v.__value_ == _EqResult::__zero; -} - -_LIBCPP_INLINE_VISIBILITY -constexpr bool operator==(_CmpUnspecifiedParam, strong_equality __v) noexcept { - return __v.__value_ == _EqResult::__zero; -} - -_LIBCPP_INLINE_VISIBILITY -constexpr bool operator!=(strong_equality __v, _CmpUnspecifiedParam) noexcept { - return __v.__value_ != _EqResult::__zero; -} - -_LIBCPP_INLINE_VISIBILITY -constexpr bool operator!=(_CmpUnspecifiedParam, strong_equality __v) noexcept { - return __v.__value_ != _EqResult::__zero; -} - -#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR -_LIBCPP_INLINE_VISIBILITY -constexpr strong_equality operator<=>(strong_equality __v, _CmpUnspecifiedParam) noexcept { - return __v; -} - -_LIBCPP_INLINE_VISIBILITY -constexpr strong_equality operator<=>(_CmpUnspecifiedParam, strong_equality __v) noexcept { - return __v; -} -#endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR - class partial_ordering { using _ValueT = signed char; @@ -310,11 +182,6 @@ public: static const partial_ordering greater; static const partial_ordering unordered; - // conversion - constexpr operator weak_equality() const noexcept { - return __value_ == 0 ? weak_equality::equivalent : weak_equality::nonequivalent; - } - // comparisons _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept; _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator!=(partial_ordering __v, _CmpUnspecifiedParam) noexcept; @@ -420,13 +287,6 @@ public: static const weak_ordering equivalent; static const weak_ordering greater; - // conversions - _LIBCPP_INLINE_VISIBILITY - constexpr operator weak_equality() const noexcept { - return __value_ == 0 ? weak_equality::equivalent - : weak_equality::nonequivalent; - } - _LIBCPP_INLINE_VISIBILITY constexpr operator partial_ordering() const noexcept { return __value_ == 0 ? partial_ordering::equivalent @@ -537,18 +397,6 @@ public: static const strong_ordering greater; // conversions - _LIBCPP_INLINE_VISIBILITY - constexpr operator weak_equality() const noexcept { - return __value_ == 0 ? weak_equality::equivalent - : weak_equality::nonequivalent; - } - - _LIBCPP_INLINE_VISIBILITY - constexpr operator strong_equality() const noexcept { - return __value_ == 0 ? strong_equality::equal - : strong_equality::nonequal; - } - _LIBCPP_INLINE_VISIBILITY constexpr operator partial_ordering() const noexcept { return __value_ == 0 ? partial_ordering::equivalent @@ -652,12 +500,6 @@ constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) #endif // _LIBCPP_HAS_NO_SPACESHIP_OPERATOR // named comparison functions -_LIBCPP_INLINE_VISIBILITY -constexpr bool is_eq(weak_equality __cmp) noexcept { return __cmp == 0; } - -_LIBCPP_INLINE_VISIBILITY -constexpr bool is_neq(weak_equality __cmp) noexcept { return __cmp != 0; } - _LIBCPP_INLINE_VISIBILITY constexpr bool is_lt(partial_ordering __cmp) noexcept { return __cmp < 0; } @@ -674,8 +516,6 @@ namespace __comp_detail { enum _ClassifyCompCategory : unsigned{ _None, - _WeakEq, - _StrongEq, _PartialOrd, _WeakOrd, _StrongOrd, @@ -685,10 +525,6 @@ enum _ClassifyCompCategory : unsigned{ template _LIBCPP_INLINE_VISIBILITY constexpr _ClassifyCompCategory __type_to_enum() noexcept { - if (is_same_v<_Tp, weak_equality>) - return _WeakEq; - if (is_same_v<_Tp, strong_equality>) - return _StrongEq; if (is_same_v<_Tp, partial_ordering>) return _PartialOrd; if (is_same_v<_Tp, weak_ordering>) @@ -706,12 +542,6 @@ __compute_comp_type(const _ClassifyCompCategory (&__types)[_Size]) { ++__seen[__type]; if (__seen[_None]) return _None; - if (__seen[_WeakEq]) - return _WeakEq; - if (__seen[_StrongEq] && (__seen[_PartialOrd] || __seen[_WeakOrd])) - return _WeakEq; - if (__seen[_StrongEq]) - return _StrongEq; if (__seen[_PartialOrd]) return _PartialOrd; if (__seen[_WeakOrd]) @@ -726,10 +556,6 @@ constexpr auto __get_comp_type() { constexpr _CCC _Cat = __compute_comp_type(__type_kinds); if constexpr (_Cat == _None) return void(); - else if constexpr (_Cat == _WeakEq) - return weak_equality::equivalent; - else if constexpr (_Cat == _StrongEq) - return strong_equality::equivalent; else if constexpr (_Cat == _PartialOrd) return partial_ordering::equivalent; else if constexpr (_Cat == _WeakOrd) @@ -755,8 +581,6 @@ using common_comparison_category_t = typename common_comparison_category<_Ts...> template constexpr strong_ordering strong_order(const _Tp& __lhs, const _Tp& __rhs); template constexpr weak_ordering weak_order(const _Tp& __lhs, const _Tp& __rhs); template constexpr partial_ordering partial_order(const _Tp& __lhs, const _Tp& __rhs); -template constexpr strong_equality strong_equal(const _Tp& __lhs, const _Tp& __rhs); -template constexpr weak_equality weak_equal(const _Tp& __lhs, const _Tp& __rhs); #endif // _LIBCPP_STD_VER > 17 diff --git a/libcxx/test/std/language.support/cmp/cmp.common/common_comparison_category.pass.cpp b/libcxx/test/std/language.support/cmp/cmp.common/common_comparison_category.pass.cpp index 9a9a5da0a636b4..6c0efec93b604b 100644 --- a/libcxx/test/std/language.support/cmp/cmp.common/common_comparison_category.pass.cpp +++ b/libcxx/test/std/language.support/cmp/cmp.common/common_comparison_category.pass.cpp @@ -34,13 +34,13 @@ void test_cat() { // [class.spaceship]p4: The 'common comparison type' U of a possibly-empty list // of 'n' types T0, T1, ..., TN, is defined as follows: int main(int, char**) { - using WE = std::weak_equality; - using SE = std::strong_equality; using PO = std::partial_ordering; using WO = std::weak_ordering; using SO = std::strong_ordering; - // [class.spaceship]p4.1: If any Ti is not a comparison category tpe, U is void. + // [cmp.common]p2: The member typedef-name type denotes the common comparison + /// type ([class.spaceship]) of Ts..., the expanded parameter pack, or void if + // any element of Ts is not a comparison category type. { test_cat(); test_cat(); @@ -50,45 +50,32 @@ int main(int, char**) { test_cat(); } - // [class.spaceship]p4.2: Otherwise, if at least on Ti is - // std::weak_equality, or at least one Ti is std::strong_equality and at least - // one Tj is std::partial_ordering or std::weak_ordering, U is std::weak_equality - { - test_cat(); - test_cat(); - test_cat(); - test_cat(); - } - - // [class.spaceship]p4.3: Otherwise, if at least one Ti is std::strong_equality, - // U is std::strong_equality - { - test_cat(); - test_cat(); - } - - // [class.spaceship]p4.4: Otherwise, if at least one Ti is std::partial_ordering, - // U is std::partial_ordering + // [class.spaceship]p4.1: If at least one Ti is std::partial_ordering, U is + // std::partial_ordering ([cmp.partialord]). { test_cat(); test_cat(); test_cat(); } - // [class.spaceship]p4.5: Otherwise, if at least one Ti is std::weak_ordering, + // [class.spaceship]p4.2: Otherwise, if at least one Ti is std::weak_ordering, // U is std::weak_ordering { test_cat(); test_cat(); } - // [class.spaceship]p4.6: Otherwise, U is std::strong_ordering. [Note: in - // particular this is the result when n is 0. -- end note] + // [class.spaceship]p4.3: Otherwise, U is std::strong_ordering. { - test_cat(); // empty type list test_cat(); test_cat(); } + // [cmp.common]p2, note 2: This is std::strong_ordering if the expansion is empty. + // [class.spaceship]p4.3, note 2: In particular this is the result when n is 0. + { + test_cat(); // empty type list + } + return 0; } diff --git a/libcxx/test/std/language.support/cmp/cmp.partialord/partialord.pass.cpp b/libcxx/test/std/language.support/cmp/cmp.partialord/partialord.pass.cpp index 4ecfe21f06f88e..c47307396c8318 100644 --- a/libcxx/test/std/language.support/cmp/cmp.partialord/partialord.pass.cpp +++ b/libcxx/test/std/language.support/cmp/cmp.partialord/partialord.pass.cpp @@ -51,26 +51,6 @@ void test_signatures() { #endif } -constexpr bool test_conversion() { - static_assert(std::is_convertible::value, ""); - { // value == 0 - auto V = std::partial_ordering::equivalent; - std::weak_equality WV = V; - assert(WV == 0); - } - std::partial_ordering TestCases[] = { - std::partial_ordering::less, - std::partial_ordering::greater, - std::partial_ordering::unordered - }; - for (auto V : TestCases) - { // value != 0 - std::weak_equality WV = V; - assert(WV != 0); - } - return true; -} - constexpr bool test_constexpr() { auto& Eq = std::partial_ordering::equivalent; auto& Less = std::partial_ordering::less; @@ -194,7 +174,6 @@ constexpr bool test_constexpr() { int main(int, char**) { test_static_members(); test_signatures(); - static_assert(test_conversion(), "conversion test failed"); static_assert(test_constexpr(), "constexpr test failed"); return 0; diff --git a/libcxx/test/std/language.support/cmp/cmp.strongeq/cmp.strongeq.pass.cpp b/libcxx/test/std/language.support/cmp/cmp.strongeq/cmp.strongeq.pass.cpp deleted file mode 100644 index 368a1a43693664..00000000000000 --- a/libcxx/test/std/language.support/cmp/cmp.strongeq/cmp.strongeq.pass.cpp +++ /dev/null @@ -1,97 +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, c++17 - -// - -// class strong_equality - - -#include -#include -#include - -#include "test_macros.h" - -const volatile void* volatile sink; - -void test_static_members() { - DoNotOptimize(&std::strong_equality::equal); - DoNotOptimize(&std::strong_equality::nonequal); - DoNotOptimize(&std::strong_equality::equivalent); - DoNotOptimize(&std::strong_equality::nonequivalent); -} - -void test_signatures() { - auto& Eq = std::strong_equality::equivalent; - - ASSERT_NOEXCEPT(Eq == 0); - ASSERT_NOEXCEPT(0 == Eq); - ASSERT_NOEXCEPT(Eq != 0); - ASSERT_NOEXCEPT(0 != Eq); -#ifndef TEST_HAS_NO_SPACESHIP_OPERATOR - ASSERT_NOEXCEPT(0 <=> Eq); - ASSERT_NOEXCEPT(Eq <=> 0); - ASSERT_SAME_TYPE(decltype(Eq <=> 0), std::strong_equality); - ASSERT_SAME_TYPE(decltype(0 <=> Eq), std::strong_equality); -#endif -} - -void test_conversion() { - constexpr std::weak_equality res = std::strong_equality::equivalent; - static_assert(res == 0, ""); - static_assert(std::is_convertible::value, ""); - static_assert(res == 0, "expected equal"); - - constexpr std::weak_equality neq_res = std::strong_equality::nonequivalent; - static_assert(neq_res != 0, "expected not equal"); -} - -constexpr bool test_constexpr() { - auto& Eq = std::strong_equality::equal; - auto& NEq = std::strong_equality::nonequal; - auto& Equiv = std::strong_equality::equivalent; - auto& NEquiv = std::strong_equality::nonequivalent; - assert((Eq == 0) == true); - assert((0 == Eq) == true); - assert((Equiv == 0) == true); - assert((0 == Equiv) == true); - assert((NEq == 0) == false); - assert((0 == NEq) == false); - assert((NEquiv == 0) == false); - assert((0 == NEquiv) == false); - - assert((Eq != 0) == false); - assert((0 != Eq) == false); - assert((Equiv != 0) == false); - assert((0 != Equiv) == false); - assert((NEq != 0) == true); - assert((0 != NEq) == true); - assert((NEquiv != 0) == true); - assert((0 != NEquiv) == true); - -#ifndef TEST_HAS_NO_SPACESHIP_OPERATOR - std::strong_equality res = (Eq <=> 0); - ((void)res); - res = (0 <=> Eq); - ((void)res); -#endif - - return true; -} - -int main(int, char**) { - test_static_members(); - test_signatures(); - test_conversion(); - static_assert(test_constexpr(), "constexpr test failed"); - - return 0; -} diff --git a/libcxx/test/std/language.support/cmp/cmp.strongord/strongord.pass.cpp b/libcxx/test/std/language.support/cmp/cmp.strongord/strongord.pass.cpp index 2a8f9494004852..40ffb356f4804d 100644 --- a/libcxx/test/std/language.support/cmp/cmp.strongord/strongord.pass.cpp +++ b/libcxx/test/std/language.support/cmp/cmp.strongord/strongord.pass.cpp @@ -52,44 +52,6 @@ void test_signatures() { } constexpr bool test_conversion() { - static_assert(std::is_convertible::value, ""); - { // value == 0 - auto V = std::strong_ordering::equivalent; - std::weak_equality WV = V; - assert(WV == 0); - } - std::strong_ordering WeakTestCases[] = { - std::strong_ordering::less, - std::strong_ordering::greater, - }; - for (auto V : WeakTestCases) - { // value != 0 - std::weak_equality WV = V; - assert(WV != 0); - } - static_assert(std::is_convertible::value, ""); - { // value == 0 - auto V = std::strong_ordering::equivalent; - std::strong_equality WV = V; - assert(WV == 0); - } - { // value == 0 - auto V = std::strong_ordering::equal; - std::strong_equality WV = V; - assert(WV == 0); - } - std::strong_ordering StrongTestCases[] = { - std::strong_ordering::less, - std::strong_ordering::greater, - }; - for (auto V : StrongTestCases) - { // value != 0 - std::strong_equality WV = V; - assert(WV != 0); - } - static_assert(std::is_convertible::value, ""); { // value == 0 diff --git a/libcxx/test/std/language.support/cmp/cmp.weakeq/cmp.weakeq.pass.cpp b/libcxx/test/std/language.support/cmp/cmp.weakeq/cmp.weakeq.pass.cpp deleted file mode 100644 index 0d947ec5321205..00000000000000 --- a/libcxx/test/std/language.support/cmp/cmp.weakeq/cmp.weakeq.pass.cpp +++ /dev/null @@ -1,71 +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, c++17 - -// - -// class weak_equality - - -#include -#include -#include "test_macros.h" - -const volatile void* volatile sink; - -void test_static_members() { - DoNotOptimize(&std::weak_equality::equivalent); - DoNotOptimize(&std::weak_equality::nonequivalent); -} - -void test_signatures() { - auto& Eq = std::weak_equality::equivalent; - - ASSERT_NOEXCEPT(Eq == 0); - ASSERT_NOEXCEPT(0 == Eq); - ASSERT_NOEXCEPT(Eq != 0); - ASSERT_NOEXCEPT(0 != Eq); -#ifndef TEST_HAS_NO_SPACESHIP_OPERATOR - ASSERT_NOEXCEPT(0 <=> Eq); - ASSERT_NOEXCEPT(Eq <=> 0); - ASSERT_SAME_TYPE(decltype(Eq <=> 0), std::weak_equality); - ASSERT_SAME_TYPE(decltype(0 <=> Eq), std::weak_equality); -#endif -} - -constexpr bool test_constexpr() { - auto& Eq = std::weak_equality::equivalent; - auto& NEq = std::weak_equality::nonequivalent; - assert((Eq == 0) == true); - assert((0 == Eq) == true); - assert((NEq == 0) == false); - assert((0 == NEq) == false); - - assert((Eq != 0) == false); - assert((0 != Eq) == false); - assert((NEq != 0) == true); - assert((0 != NEq) == true); - -#ifndef TEST_HAS_NO_SPACESHIP_OPERATOR - std::weak_equality res = (Eq <=> 0); - ((void)res); - res = (0 <=> Eq); - ((void)res); -#endif - - return true; -} - -int main(int, char**) { - test_static_members(); - test_signatures(); - static_assert(test_constexpr(), "constexpr test failed"); - - return 0; -} diff --git a/libcxx/test/std/language.support/cmp/cmp.weakord/weakord.pass.cpp b/libcxx/test/std/language.support/cmp/cmp.weakord/weakord.pass.cpp index d4fade6bb984a3..b39513a0533034 100644 --- a/libcxx/test/std/language.support/cmp/cmp.weakord/weakord.pass.cpp +++ b/libcxx/test/std/language.support/cmp/cmp.weakord/weakord.pass.cpp @@ -51,22 +51,6 @@ void test_signatures() { } constexpr bool test_conversion() { - static_assert(std::is_convertible::value, ""); - { // value == 0 - auto V = std::weak_ordering::equivalent; - std::weak_equality WV = V; - assert(WV == 0); - } - std::weak_ordering WeakTestCases[] = { - std::weak_ordering::less, - std::weak_ordering::greater, - }; - for (auto V : WeakTestCases) - { // value != 0 - std::weak_equality WV = V; - assert(WV != 0); - } static_assert(std::is_convertible::value, ""); { // value == 0