Fix PR19460 - std::ios is convertible to int.

std::basic_ios has an operator bool(). In C++11 and later
it is explicit, and only allows contextual implicit conversions.

However explicit isn't available in C++03 which causes std::istream (et al)
to have an implicit conversion to int. This can easily cause ambiguities
when calling operator<< and operator>>.

This patch uses a "bool-like" type in C++03 to work around this. The
"bool-like" type is an arbitrary pointer to member function type. It
will not convert to either int or void*, but will convert to bool.

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@290750 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/ios b/include/ios
index cbea478..dfeb1f6 100644
--- a/include/ios
+++ b/include/ios
@@ -585,9 +585,22 @@
     typedef typename traits_type::pos_type pos_type;
     typedef typename traits_type::off_type off_type;
 
+#if defined(_LIBCPP_CXX03_LANG)
+private:
+    struct __bool_tag {};
+    typedef void (basic_ios::*_BoolType)(__bool_tag) const;
+    void __true_value(__bool_tag) const {}
+
+public:
     _LIBCPP_ALWAYS_INLINE
-        _LIBCPP_EXPLICIT
-        operator bool() const {return !fail();}
+    operator _BoolType() const {
+        return !fail() ? &basic_ios::__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();}
     _LIBCPP_ALWAYS_INLINE void clear(iostate __state = goodbit) {ios_base::clear(__state);}
diff --git a/test/std/input.output/iostreams.base/ios/iostate.flags/bool.pass.cpp b/test/std/input.output/iostreams.base/ios/iostate.flags/bool.pass.cpp
index 0de889e..5f49c65 100644
--- a/test/std/input.output/iostreams.base/ios/iostate.flags/bool.pass.cpp
+++ b/test/std/input.output/iostreams.base/ios/iostate.flags/bool.pass.cpp
@@ -14,6 +14,7 @@
 // operator unspecified-bool-type() const;
 
 #include <ios>
+#include <type_traits>
 #include <cassert>
 
 int main()
@@ -22,4 +23,10 @@
     assert(static_cast<bool>(ios) == !ios.fail());
     ios.setstate(std::ios::failbit);
     assert(static_cast<bool>(ios) == !ios.fail());
+    static_assert((!std::is_convertible<std::ios, void*>::value), "");
+    static_assert((!std::is_convertible<std::ios, int>::value), "");
+    static_assert((!std::is_convertible<std::ios const&, int>::value), "");
+#if TEST_STD_VER >= 11
+    static_assert((!std::is_convertible<std::ios, bool>::value), "");
+#endif
 }