Skip to content
This repository has been archived by the owner on Apr 23, 2020. It is now read-only.

Commit

Permalink
Rework fix for PR19460 - Use explicit bool as an extension instead.
Browse files Browse the repository at this point in the history
In the previous fix I used a PMF type as a semi-safe bool type in C++03.
However immediately after committing I realized clang offered explicit
conversion operators as an extension. This patch removes the old fix and
enables _LIBCPP_EXPLICIT using __has_extension instead.

This change also affects the following other classes, which have
'_LIBCPP_EXPLICIT operator bool()'.

* shared_ptr
* unique_ptr
* error_condition
* basic_ios
* function (already C++11 only)
* istream::sentry
* experimental::string_view.

In all of the above cases I believe it is safe to enable the extension, except
in the experimental::string_view case. There seem to be some Clang bugs
affecting the experimental::string_view conversion to std::basic_string. To
work around that I manually disabled _LIBCPP_EXPLICIT in that case.

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@290831 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
EricWF committed Jan 2, 2017
1 parent b3f4bdf commit 3a1b90a
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 19 deletions.
2 changes: 1 addition & 1 deletion include/__config
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ template <unsigned> struct __static_assert_check {};
#define _NOALIAS
#endif

#if __has_feature(cxx_explicit_conversions) || defined(__IBMCPP__) || \
#if __has_extension(cxx_explicit_conversions) || defined(__IBMCPP__) || \
(!defined(_LIBCPP_CXX03_LANG) && defined(__GNUC__)) // All supported GCC versions
# define _LIBCPP_EXPLICIT explicit
#else
Expand Down
7 changes: 6 additions & 1 deletion include/experimental/string_view
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,12 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS
// [string.view.ops], string operations:
template<class _Allocator>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_EXPLICIT operator basic_string<_CharT, _Traits, _Allocator>() const
// Clang's extended C++11 explict conversions don't work with
// string_view in C++03.
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_EXPLICIT
#endif
operator basic_string<_CharT, _Traits, _Allocator>() const
{ return basic_string<_CharT, _Traits, _Allocator>( begin(), end()); }

template<class _Allocator = allocator<_CharT> >
Expand Down
17 changes: 0 additions & 17 deletions include/ios
Original file line number Diff line number Diff line change
Expand Up @@ -572,13 +572,6 @@ ios_base::exceptions(iostate __iostate)
clear(__rdstate_);
}

#if defined(_LIBCPP_CXX03_LANG)
struct _LIBCPP_TYPE_VIS_ONLY __cxx03_bool {
typedef void (__cxx03_bool::*__bool_type)();
void __true_value() {}
};
#endif

template <class _CharT, class _Traits>
class _LIBCPP_TYPE_VIS_ONLY basic_ios
: public ios_base
Expand All @@ -592,18 +585,8 @@ public:
typedef typename traits_type::pos_type pos_type;
typedef typename traits_type::off_type off_type;

// __true_value will generate undefined references when linking unless
// we give it internal linkage.

#if defined(_LIBCPP_CXX03_LANG)
_LIBCPP_ALWAYS_INLINE
operator __cxx03_bool::__bool_type() const {
return !fail() ? &__cxx03_bool::__true_value : nullptr;
}
#else
_LIBCPP_ALWAYS_INLINE
_LIBCPP_EXPLICIT operator bool() const {return !fail();}
#endif

_LIBCPP_ALWAYS_INLINE bool operator!() const {return fail();}
_LIBCPP_ALWAYS_INLINE iostate rdstate() const {return ios_base::rdstate();}
Expand Down

0 comments on commit 3a1b90a

Please sign in to comment.