[Boost-bugs] [Boost C++ Libraries] #12778: Boost.Test is broken against left shift operator in certain cases

Subject: [Boost-bugs] [Boost C++ Libraries] #12778: Boost.Test is broken against left shift operator in certain cases
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2017-01-22 22:12:39


#12778: Boost.Test is broken against left shift operator in certain cases
--------------------------+-------------------------
 Reporter: anonymous | Owner: rogeeff
     Type: Bugs | Status: new
Milestone: Boost 1.64.0 | Component: test
  Version: Boost 1.63.0 | Severity: Showstopper
 Keywords: |
--------------------------+-------------------------
 {{{
 BOOST_CHECK_EQUAL(nullptr, nullptr);
 }}}

 results in

 {{{
 /usr/include/boost/type_traits/detail/has_binary_operator.hpp: In
 instantiation of ‘const bool
 boost::detail::has_left_shift_impl::operator_exists<std::basic_ostream<char>,
 std::nullptr_t>::value’:
 /usr/include/boost/type_traits/detail/has_binary_operator.hpp:179:4:
 required from ‘const bool
 boost::detail::has_left_shift_impl::trait_impl1<std::basic_ostream<char>,
 std::nullptr_t, boost::detail::has_left_shift_impl::dont_care,
 false>::value’
 /usr/include/boost/type_traits/detail/has_binary_operator.hpp:208:4:
 required from ‘const bool
 boost::detail::has_left_shift_impl::trait_impl<std::basic_ostream<char>,
 std::nullptr_t, boost::detail::has_left_shift_impl::dont_care>::value’
 /usr/include/boost/type_traits/detail/has_binary_operator.hpp:216:8:
 required from ‘struct boost::has_left_shift<std::basic_ostream<char>,
 std::nullptr_t, boost::detail::has_left_shift_impl::dont_care>’
 /usr/include/boost/test/tools/detail/print_helper.hpp:47:5: required
 from ‘struct
 boost::test_tools::tt_detail::print_log_value<std::nullptr_t>’
 /usr/include/boost/test/tools/detail/print_helper.hpp:178:5: required
 from ‘std::ostream&
 boost::test_tools::tt_detail::operator<<(std::ostream&, const
 boost::test_tools::tt_detail::print_helper_t<T>&) [with T =
 std::nullptr_t; std::ostream = std::basic_ostream<char>]’
 /usr/include/boost/test/tools/assertion.hpp:163:1: required from ‘static
 void boost::test_tools::assertion::op::EQ<Lhs, Rhs,
 Enabler>::report(std::ostream&, const PrevExprType&, const Rhs&) [with
 PrevExprType =
 boost::test_tools::assertion::value_expr<firewall::deep_const_ptr<void*>&>;
 Lhs = firewall::deep_const_ptr<void*>; Rhs = std::nullptr_t; Enabler =
 void; std::ostream = std::basic_ostream<char>]’
 /usr/include/boost/test/tools/assertion.hpp:355:26: required from ‘void
 boost::test_tools::assertion::binary_expr<Lhs, Rhs,
 OP>::report(std::ostream&) const [with LExpr =
 boost::test_tools::assertion::value_expr<firewall::deep_const_ptr<void*>&>;
 Rhs = std::nullptr_t; OP =
 boost::test_tools::assertion::op::EQ<firewall::deep_const_ptr<void*>,
 std::nullptr_t, void>; std::ostream = std::basic_ostream<char>]’
 /usr/include/boost/test/tools/assertion.hpp:365:15: required from
 â€˜boost::test_tools::assertion_result
 boost::test_tools::assertion::binary_expr<Lhs, Rhs, OP>::evaluate(bool)
 const [with LExpr =
 boost::test_tools::assertion::value_expr<firewall::deep_const_ptr<void*>&>;
 Rhs = std::nullptr_t; OP =
 boost::test_tools::assertion::op::EQ<firewall::deep_const_ptr<void*>,
 std::nullptr_t, void>]’
 /usr/include/boost/type_traits/detail/has_binary_operator.hpp:158:70:
 error: ambiguous overload for ‘operator<<’ (operand types are
 â€˜std::basic_ostream<char>’ and ‘std::nullptr_t’)
     BOOST_STATIC_CONSTANT(bool, value = (sizeof(s_check(((make<Lhs>()
 BOOST_TT_TRAIT_OP
 make<Rhs>()),make<has_operator>())))==sizeof(::boost::type_traits::yes_type)));
 }}}

 no matter what I try to alleviate it, including:

 {{{
 #define BOOST_TEST_NO_OLD_TOOLS
 }}}

 {{{
 BOOST_TEST_DONT_PRINT_LOG_VALUE(::std::nullptr_t)
 }}}

 {{{
 template <class CharT, class TraitsT>
 inline ::std::basic_ostream<CharT, TraitsT>&
 operator<<(::std::basic_ostream<CharT, TraitsT>& os,
            std::nullptr_t const&) {
   return os;
 }
 }}}

 {{{
 namespace boost {
 namespace test_tools {
 namespace tt_detail {
 template <class CharT, class TraitsT>
 inline ::std::basic_ostream<CharT, TraitsT>&
 operator<<(::std::basic_ostream<CharT, TraitsT>& os,
            std::nullptr_t const&) {
   return os;
 }
 } // namespace tt_detail
 } // namespace test_tools
 } // namespace boost
 }}}

 {{{
 namespace my_namespace {
 template <class CharT, class TraitsT>
 inline ::std::basic_ostream<CharT, TraitsT>&
 operator<<(::std::basic_ostream<CharT, TraitsT>& os,
            std::nullptr_t const&) {
   return os;
 }
 } // namespace my_namespace
 }}}

 etc., etc., etc. I also cannot understand what's the problem. I mean
 theoretically it should work but it does not. Furthermore, I've
 discovered another problem. Doing

 {{{
 #define BOOST_TEST_NO_OLD_TOOLS
 }}}

 and then

 {{{
 ::std::ofstream ofs("xxx");
 BOOST_REQUIRE(ofs);
 }}}

 results in

 {{{
 /usr/include/boost/test/utils/wrap_stringstream.hpp: In instantiation of
 â€˜boost::basic_wrap_stringstream<CharT>&
 boost::operator<<(boost::basic_wrap_stringstream<CharT>&, const T&) [with
 CharT = char; T = std::basic_ofstream<char>]’:
 /usr/include/boost/test/tools/assertion.hpp:312:93: required from
 â€˜static void
 boost::test_tools::assertion::value_expr<T>::format_message(boost::wrap_stringstream&,
 const U&) [with U = std::basic_ofstream<char>; T =
 std::basic_ofstream<char>&; boost::wrap_stringstream =
 boost::basic_wrap_stringstream<char>]’
 /usr/include/boost/test/tools/assertion.hpp:305:23: required from
 â€˜boost::test_tools::assertion_result
 boost::test_tools::assertion::value_expr<T>::evaluate(bool) const [with T
 = std::basic_ofstream<char>&]’
 /usr/include/boost/test/utils/wrap_stringstream.hpp:66:19: error: no match
 for ‘operator<<’ (operand types are
 â€˜boost::basic_wrap_stringstream<char>::wrapped_stream {aka
 std::__cxx11::basic_ostringstream<char>}’ and ‘const
 std::basic_ofstream<char>’)
      targ.stream() << t;

 /usr/include/boost/test/utils/wrap_stringstream.hpp:66:19: note:
 candidate: operator<<(int, int) <built-in>
 /usr/include/boost/test/utils/wrap_stringstream.hpp:66:19: note: no
 known conversion for argument 2 from ‘const std::basic_ofstream<char>’ to
 â€˜int’
 In file included from /usr/include/c++/6.2.1/iterator:64:0,
                  from ../../include/process/args.hpp:42,
                  from ../../include/process/args:35,
                  from
 /home/aks/Projects/Bitbucket/Process/Source/test/source/process/stdi.t.cpp:38:
 /usr/include/c++/6.2.1/ostream:108:7: note: candidate:
 std::basic_ostream<_CharT, _Traits>::__ostream_type&
 std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT,
 _Traits>::__ostream_type& (*)(std::basic_ostream<_CharT,
 _Traits>::__ostream_type&)) [with _CharT = char; _Traits =
 std::char_traits<char>; std::basic_ostream<_CharT,
 _Traits>::__ostream_type = std::basic_ostream<char>]
        operator<<(__ostream_type& (*__pf)(__ostream_type&))
 }}}

 and the workaround it of course

 {{{
 BOOST_REQUIRE(bool(ofs));
 }}}

 which is a no go in the long run.

 Looking forward to your assistance. Regards.

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/12778>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:20 UTC