From 3fc75407332c8117d6fb281ab7e32667830db97a Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 9 Dec 2021 18:34:02 +0200 Subject: [PATCH] Only define operator<< when all contained types are streamable (refs #31) --- include/boost/variant2/variant.hpp | 12 +++++++++- test/Jamfile | 1 + test/is_output_streamable.cpp | 38 ++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 test/is_output_streamable.cpp diff --git a/include/boost/variant2/variant.hpp b/include/boost/variant2/variant.hpp index 77d5d16..d4d3d82 100644 --- a/include/boost/variant2/variant.hpp +++ b/include/boost/variant2/variant.hpp @@ -2253,9 +2253,19 @@ template struct ostream_insert_L } }; +template struct is_output_streamable: std::false_type +{ +}; + +template struct is_output_streamable() << std::declval(), (void)0 )>: std::true_type +{ +}; + } // namespace detail -template std::basic_ostream& operator<<( std::basic_ostream& os, variant const& v ) +template, T>... >::value >::type > +std::basic_ostream& operator<<( std::basic_ostream& os, variant const& v ) { return mp11::mp_with_index<1 + sizeof...(T)>( v.index(), detail::ostream_insert_L{ os, v } ); diff --git a/test/Jamfile b/test/Jamfile index 0cc5dd2..2fbb975 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -125,3 +125,4 @@ compile variant_derived_construct.cpp ; run variant_visit_by_index.cpp ; run variant_ostream_insert.cpp ; +run is_output_streamable.cpp ; diff --git a/test/is_output_streamable.cpp b/test/is_output_streamable.cpp new file mode 100644 index 0000000..6d0f0a2 --- /dev/null +++ b/test/is_output_streamable.cpp @@ -0,0 +1,38 @@ +// Copyright 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include + +struct X +{ +}; + +struct Y +{ +}; + +std::ostream& operator<<( std::ostream& os, Y const& /*y*/ ) +{ + os << "Y()"; + return os; +} + +int main() +{ + BOOST_TEST_TRAIT_TRUE((boost::variant2::detail::is_output_streamable)); + BOOST_TEST_TRAIT_TRUE((boost::variant2::detail::is_output_streamable)); + BOOST_TEST_TRAIT_TRUE((boost::variant2::detail::is_output_streamable)); + BOOST_TEST_TRAIT_FALSE((boost::variant2::detail::is_output_streamable)); + BOOST_TEST_TRAIT_FALSE((boost::variant2::detail::is_output_streamable)); + BOOST_TEST_TRAIT_TRUE((boost::variant2::detail::is_output_streamable)); + + BOOST_TEST_TRAIT_TRUE((boost::variant2::detail::is_output_streamable>)); + BOOST_TEST_TRAIT_FALSE((boost::variant2::detail::is_output_streamable>)); + BOOST_TEST_TRAIT_TRUE((boost::variant2::detail::is_output_streamable>)); + + return boost::report_errors(); +}