Opened 6 years ago

Closed 6 years ago

#12778 closed Bugs (fixed)

Boost.Test is broken against left shift operator in certain cases

Reported by: anonymous Owned by: Raffi Enficiaud
Milestone: Boost 1.64.0 Component: test
Version: Boost 1.63.0 Severity: Showstopper
Keywords: Cc:

Description

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.

Change History (4)

comment:1 by Raffi Enficiaud, 6 years ago

Owner: changed from Gennadiy Rozental to Raffi Enficiaud

I believe the problems rather comes from nullptr which does not seem to be supported.

comment:2 by anonymous, 6 years ago

I've actually fixed the first problem with nullptr. Apparently, there was some problem with ADL in between. However, the second problem is there. Any ideas on it?

comment:3 by Raffi Enficiaud, 6 years ago

Sorry for not having posted an update. I fixed the issue on branch origin/topic/12778-nullptr. Would you please give a try?

comment:4 by Raffi Enficiaud, 6 years ago

Resolution: fixed
Status: newclosed

Merged to master, rev a2b73f5d7568e69162dfac213fab87eea0021ec5

Note: See TracTickets for help on using tickets.