diff options
author | Ville Voutilainen <ville.voutilainen@gmail.com> | 2016-11-30 11:59:50 +0200 |
---|---|---|
committer | Ville Voutilainen <ville@gcc.gnu.org> | 2016-11-30 11:59:50 +0200 |
commit | a7da4881303a7bc9a59014f0d03cd946a9cdecec (patch) | |
tree | a174bba7556763a15e784ab3eaadd32609000ff2 /libstdc++-v3/include/std/ostream | |
parent | 40109581065366e04c547d2bff6e8f7ff5646fb8 (diff) | |
download | gcc-a7da4881303a7bc9a59014f0d03cd946a9cdecec.zip gcc-a7da4881303a7bc9a59014f0d03cd946a9cdecec.tar.gz gcc-a7da4881303a7bc9a59014f0d03cd946a9cdecec.tar.bz2 |
Implement LWG 2534, Constrain rvalue stream operators.
* include/std/istream (__is_convertible_to_basic_istream): New.
(__is_extractable): Likewise.
(operator>>(basic_istream<_CharT, _Traits>&&, _Tp&&)):
Turn the stream parameter into a template parameter
and constrain.
* include/std/ostream (__is_convertible_to_basic_ostream): New.
(__is_insertable): Likewise.
(operator<<(basic_ostream<_CharT, _Traits>&&, const _Tp&)):
Turn the stream parameter into a template parameter
and constrain.
* testsuite/27_io/basic_istream/extractors_other/char/4.cc: New.
* testsuite/27_io/basic_istream/extractors_other/wchar_t/4.cc:
Likewise.
* testsuite/27_io/basic_ostream/inserters_other/char/6.cc: Likewise.
* testsuite/27_io/basic_ostream/inserters_other/wchar_t/6.cc: Likewise.
From-SVN: r243006
Diffstat (limited to 'libstdc++-v3/include/std/ostream')
-rw-r--r-- | libstdc++-v3/include/std/ostream | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream index 0bf53f0..a1fe892 100644 --- a/libstdc++-v3/include/std/ostream +++ b/libstdc++-v3/include/std/ostream @@ -613,6 +613,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __os.flush(); } #if __cplusplus >= 201103L + template<typename _Tp> + struct __is_convertible_to_basic_ostream + { + template<typename _Ch, typename _Up> + static true_type __check(basic_ostream<_Ch, _Up>*); + + static false_type __check(void*); + public: + using type = decltype(__check(declval<_Tp*>())); + constexpr static bool value = type::value; + }; + + template<typename _Ostream, typename _Tp, typename = void> + struct __is_insertable : false_type {}; + + template<typename _Ostream, typename _Tp> + struct __is_insertable<_Ostream, _Tp, + __void_t<decltype(declval<_Ostream&>() + << declval<const _Tp&>())>> + : true_type {}; + /** * @brief Generic inserter for rvalue stream * @param __os An input stream. @@ -623,9 +644,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * rvalue streams since they won't bind to the inserter functions * that take an lvalue reference. */ - template<typename _CharT, typename _Traits, typename _Tp> - inline basic_ostream<_CharT, _Traits>& - operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x) + template<typename _Ostream, typename _Tp> + inline + typename enable_if<__and_<__not_<is_lvalue_reference<_Ostream>>, + __is_convertible_to_basic_ostream< + typename remove_reference<_Ostream>::type>, + __is_insertable<_Ostream&, const _Tp&>>::value, + _Ostream&>::type + //basic_ostream<_CharT, _Traits>& + operator<<(_Ostream&& __os, const _Tp& __x) { __os << __x; return __os; |