diff --git a/libcxx/include/__config b/libcxx/include/__config --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -874,13 +874,6 @@ # define _LIBCPP_NOALIAS #endif -#if __has_feature(cxx_explicit_conversions) || defined(__IBMCPP__) || \ - (!defined(_LIBCPP_CXX03_LANG) && defined(__GNUC__)) // All supported GCC versions -# define _LIBCPP_EXPLICIT explicit -#else -# define _LIBCPP_EXPLICIT -#endif - #if __has_attribute(using_if_exists) # define _LIBCPP_USING_IF_EXISTS __attribute__((using_if_exists)) #else diff --git a/libcxx/include/__functional_03 b/libcxx/include/__functional_03 --- a/libcxx/include/__functional_03 +++ b/libcxx/include/__functional_03 @@ -493,7 +493,7 @@ {function(allocator_arg, __a, __f).swap(*this);} // 20.7.16.2.3, function capacity: - _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;} + _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;} private: // deleted overloads close possible hole in the type system @@ -773,7 +773,7 @@ {function(allocator_arg, __a, __f).swap(*this);} // 20.7.16.2.3, function capacity: - _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;} + _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;} private: // deleted overloads close possible hole in the type system @@ -1053,7 +1053,7 @@ {function(allocator_arg, __a, __f).swap(*this);} // 20.7.16.2.3, function capacity: - operator bool() const {return __f_;} + _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;} private: // deleted overloads close possible hole in the type system @@ -1332,7 +1332,7 @@ {function(allocator_arg, __a, __f).swap(*this);} // 20.7.16.2.3, function capacity: - _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;} + _LIBCPP_INLINE_VISIBILITY explicit operator bool() const {return __f_;} private: // deleted overloads close possible hole in the type system diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h --- a/libcxx/include/__memory/shared_ptr.h +++ b/libcxx/include/__memory/shared_ptr.h @@ -588,7 +588,7 @@ _LIBCPP_INLINE_VISIBILITY bool unique() const _NOEXCEPT {return use_count() == 1;} _LIBCPP_INLINE_VISIBILITY - _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {return get() != nullptr;} + explicit operator bool() const _NOEXCEPT {return get() != nullptr;} template _LIBCPP_INLINE_VISIBILITY bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h --- a/libcxx/include/__memory/unique_ptr.h +++ b/libcxx/include/__memory/unique_ptr.h @@ -296,7 +296,7 @@ return __ptr_.second(); } _LIBCPP_INLINE_VISIBILITY - _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT { + explicit operator bool() const _NOEXCEPT { return __ptr_.first() != nullptr; } @@ -517,7 +517,7 @@ return __ptr_.second(); } _LIBCPP_INLINE_VISIBILITY - _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT { + explicit operator bool() const _NOEXCEPT { return __ptr_.first() != nullptr; } diff --git a/libcxx/include/__mutex_base b/libcxx/include/__mutex_base --- a/libcxx/include/__mutex_base +++ b/libcxx/include/__mutex_base @@ -189,8 +189,7 @@ _LIBCPP_INLINE_VISIBILITY bool owns_lock() const _NOEXCEPT {return __owns_;} _LIBCPP_INLINE_VISIBILITY - _LIBCPP_EXPLICIT - operator bool () const _NOEXCEPT {return __owns_;} + explicit operator bool() const _NOEXCEPT {return __owns_;} _LIBCPP_INLINE_VISIBILITY mutex_type* mutex() const _NOEXCEPT {return __m_;} }; diff --git a/libcxx/include/exception b/libcxx/include/exception --- a/libcxx/include/exception +++ b/libcxx/include/exception @@ -151,7 +151,7 @@ exception_ptr& operator=(const exception_ptr&) _NOEXCEPT; ~exception_ptr() _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT + _LIBCPP_INLINE_VISIBILITY explicit operator bool() const _NOEXCEPT {return __ptr_ != nullptr;} friend _LIBCPP_INLINE_VISIBILITY @@ -205,7 +205,7 @@ exception_ptr& operator=(const exception_ptr& __other) _NOEXCEPT; exception_ptr& operator=(nullptr_t) _NOEXCEPT; ~exception_ptr() _NOEXCEPT; - _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT; + explicit operator bool() const _NOEXCEPT; }; _LIBCPP_FUNC_VIS diff --git a/libcxx/include/functional b/libcxx/include/functional --- a/libcxx/include/functional +++ b/libcxx/include/functional @@ -2111,7 +2111,7 @@ } _LIBCPP_INLINE_VISIBILITY - _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT { return __f_ != nullptr; } + explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; } #ifndef _LIBCPP_NO_RTTI _LIBCPP_INLINE_VISIBILITY @@ -2597,7 +2597,7 @@ // function capacity: _LIBCPP_INLINE_VISIBILITY - _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT { + explicit operator bool() const _NOEXCEPT { return static_cast(__f_); } diff --git a/libcxx/include/ios b/libcxx/include/ios --- a/libcxx/include/ios +++ b/libcxx/include/ios @@ -591,13 +591,6 @@ clear(__rdstate_); } -#if defined(_LIBCPP_CXX03_LANG) -struct _LIBCPP_TYPE_VIS __cxx03_bool { - typedef void (__cxx03_bool::*__bool_type)(); - void __true_value() {} -}; -#endif - template class _LIBCPP_TEMPLATE_VIS basic_ios : public ios_base @@ -614,18 +607,8 @@ static_assert((is_same<_CharT, typename traits_type::char_type>::value), "traits_type::char_type must be the same type as CharT"); - // __true_value will generate undefined references when linking unless - // we give it internal linkage. - -#if defined(_LIBCPP_CXX03_LANG) _LIBCPP_INLINE_VISIBILITY - operator __cxx03_bool::__bool_type() const { - return !fail() ? &__cxx03_bool::__true_value : nullptr; - } -#else - _LIBCPP_INLINE_VISIBILITY - _LIBCPP_EXPLICIT operator bool() const {return !fail();} -#endif + explicit operator bool() const {return !fail();} _LIBCPP_INLINE_VISIBILITY bool operator!() const {return fail();} _LIBCPP_INLINE_VISIBILITY iostate rdstate() const {return ios_base::rdstate();} diff --git a/libcxx/include/istream b/libcxx/include/istream --- a/libcxx/include/istream +++ b/libcxx/include/istream @@ -302,8 +302,7 @@ // ~sentry() = default; _LIBCPP_INLINE_VISIBILITY - _LIBCPP_EXPLICIT - operator bool() const {return __ok_;} + explicit operator bool() const {return __ok_;} }; template diff --git a/libcxx/include/ostream b/libcxx/include/ostream --- a/libcxx/include/ostream +++ b/libcxx/include/ostream @@ -254,8 +254,7 @@ ~sentry(); _LIBCPP_INLINE_VISIBILITY - _LIBCPP_EXPLICIT - operator bool() const {return __ok_;} + explicit operator bool() const {return __ok_;} }; template diff --git a/libcxx/include/system_error b/libcxx/include/system_error --- a/libcxx/include/system_error +++ b/libcxx/include/system_error @@ -291,8 +291,7 @@ string message() const; _LIBCPP_INLINE_VISIBILITY - _LIBCPP_EXPLICIT - operator bool() const _NOEXCEPT {return __val_ != 0;} + explicit operator bool() const _NOEXCEPT {return __val_ != 0;} }; inline _LIBCPP_INLINE_VISIBILITY @@ -368,8 +367,7 @@ string message() const; _LIBCPP_INLINE_VISIBILITY - _LIBCPP_EXPLICIT - operator bool() const _NOEXCEPT {return __val_ != 0;} + explicit operator bool() const _NOEXCEPT {return __val_ != 0;} }; inline _LIBCPP_INLINE_VISIBILITY diff --git a/libcxx/test/std/diagnostics/syserr/syserr.errcode/syserr.errcode.observers/bool.compile.fail.cpp b/libcxx/test/std/diagnostics/syserr/syserr.errcode/syserr.errcode.observers/bool.compile.fail.cpp deleted file mode 100644 --- a/libcxx/test/std/diagnostics/syserr/syserr.errcode/syserr.errcode.observers/bool.compile.fail.cpp +++ /dev/null @@ -1,28 +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 -// -//===----------------------------------------------------------------------===// - -// XFAIL: c++03 - -// - -// class error_code - -// explicit operator bool() const; - -#include - -bool test_func(void) -{ - const std::error_code ec(0, std::generic_category()); - return ec; // conversion to bool is explicit; should fail. -} - -int main(int, char**) -{ - return 0; -} diff --git a/libcxx/test/std/diagnostics/syserr/syserr.errcode/syserr.errcode.observers/bool.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.errcode/syserr.errcode.observers/bool.pass.cpp --- a/libcxx/test/std/diagnostics/syserr/syserr.errcode/syserr.errcode.observers/bool.pass.cpp +++ b/libcxx/test/std/diagnostics/syserr/syserr.errcode/syserr.errcode.observers/bool.pass.cpp @@ -13,13 +13,17 @@ // explicit operator bool() const; #include -#include #include +#include +#include #include "test_macros.h" int main(int, char**) { + static_assert(std::is_constructible::value, ""); + static_assert(!std::is_convertible::value, ""); + { const std::error_code ec(6, std::generic_category()); assert(static_cast(ec)); diff --git a/libcxx/test/std/input.output/iostreams.base/ios/iostate.flags/bool.pass.cpp b/libcxx/test/std/input.output/iostreams.base/ios/iostate.flags/bool.pass.cpp --- a/libcxx/test/std/input.output/iostreams.base/ios/iostate.flags/bool.pass.cpp +++ b/libcxx/test/std/input.output/iostreams.base/ios/iostate.flags/bool.pass.cpp @@ -27,9 +27,7 @@ static_assert((!std::is_convertible::value), ""); static_assert((!std::is_convertible::value), ""); static_assert((!std::is_convertible::value), ""); -#if TEST_STD_VER >= 11 static_assert((!std::is_convertible::value), ""); -#endif return 0; } diff --git a/libcxx/test/std/language.support/support.exception/propagation/exception_ptr.pass.cpp b/libcxx/test/std/language.support/support.exception/propagation/exception_ptr.pass.cpp --- a/libcxx/test/std/language.support/support.exception/propagation/exception_ptr.pass.cpp +++ b/libcxx/test/std/language.support/support.exception/propagation/exception_ptr.pass.cpp @@ -14,6 +14,7 @@ #include #include +#include #include "test_macros.h" @@ -33,5 +34,5 @@ p3 = nullptr; assert(p3 == nullptr); - return 0; + return 0; } diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp @@ -9,11 +9,6 @@ // UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: c++03, c++11 -// dylib support for shared_mutex was added in macosx10.12 -// XFAIL: use_system_cxx_lib && x86_64-apple-macosx10.11 -// XFAIL: use_system_cxx_lib && x86_64-apple-macosx10.10 -// XFAIL: use_system_cxx_lib && x86_64-apple-macosx10.9 - // // template class shared_lock; @@ -25,17 +20,24 @@ #include "test_macros.h" -std::shared_timed_mutex m; +struct M { + void lock_shared() {} + void unlock_shared() {} +}; int main(int, char**) { - std::shared_lock lk0; + static_assert(std::is_constructible>::value, ""); + static_assert(!std::is_convertible, bool>::value, ""); + + M m; + std::shared_lock lk0; assert(static_cast(lk0) == false); - std::shared_lock lk1(m); + std::shared_lock lk1(m); assert(static_cast(lk1) == true); lk1.unlock(); assert(static_cast(lk1) == false); - static_assert(noexcept(static_cast(lk0)), "explicit operator bool() must be noexcept"); + ASSERT_NOEXCEPT(static_cast(lk0)); - return 0; + return 0; } diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/op_bool.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/op_bool.pass.cpp --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/op_bool.pass.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/op_bool.pass.cpp @@ -12,10 +12,11 @@ // template class unique_lock; -// explicit operator bool() const; +// explicit operator bool() const noexcept; #include #include +#include #include "test_macros.h" @@ -23,12 +24,16 @@ int main(int, char**) { + static_assert(std::is_constructible >::value, ""); + static_assert(!std::is_convertible, bool>::value, ""); + std::unique_lock lk0; assert(static_cast(lk0) == false); std::unique_lock lk1(m); assert(static_cast(lk1) == true); lk1.unlock(); assert(static_cast(lk1) == false); + ASSERT_NOEXCEPT(static_cast(lk0)); return 0; } diff --git a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.cap/operator_bool.pass.cpp b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.cap/operator_bool.pass.cpp --- a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.cap/operator_bool.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.cap/operator_bool.pass.cpp @@ -17,6 +17,7 @@ #include #include +#include #include "test_macros.h" @@ -24,6 +25,9 @@ int main(int, char**) { + static_assert(std::is_constructible >::value, ""); + static_assert(!std::is_convertible, bool>::value, ""); + { std::function f; assert(!f); diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/op_bool.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/op_bool.pass.cpp --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/op_bool.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/op_bool.pass.cpp @@ -14,6 +14,7 @@ #include #include +#include #include "test_macros.h" @@ -25,6 +26,9 @@ int main(int, char**) { + static_assert(std::is_constructible >::value, ""); + static_assert(!std::is_convertible, bool>::value, ""); + { const std::shared_ptr p(new int(32)); assert(p);