reduced usage of ostringstream in exceptions

This commit is contained in:
Hans Dembinski 2019-10-28 20:08:37 +01:00 committed by GitHub
parent 3b18d9075b
commit 9669df7432
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 106 additions and 127 deletions

View File

@ -10,10 +10,8 @@
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/histogram/axis/traits.hpp> #include <boost/histogram/axis/traits.hpp>
#include <boost/histogram/detail/axes.hpp> #include <boost/histogram/detail/axes.hpp>
#include <boost/histogram/detail/cat.hpp>
#include <boost/histogram/detail/make_default.hpp> #include <boost/histogram/detail/make_default.hpp>
#include <boost/histogram/detail/static_if.hpp> #include <boost/histogram/detail/static_if.hpp>
#include <boost/histogram/detail/type_name.hpp>
#include <boost/histogram/fwd.hpp> #include <boost/histogram/fwd.hpp>
#include <boost/histogram/indexed.hpp> #include <boost/histogram/indexed.hpp>
#include <boost/histogram/unsafe_access.hpp> #include <boost/histogram/unsafe_access.hpp>
@ -21,6 +19,7 @@
#include <cmath> #include <cmath>
#include <initializer_list> #include <initializer_list>
#include <stdexcept> #include <stdexcept>
#include <string>
namespace boost { namespace boost {
namespace histogram { namespace histogram {
@ -250,10 +249,9 @@ decltype(auto) reduce(const Histogram& hist, const Iterable& options) {
o.end -= (o.end - o.begin) % o.merge; o.end -= (o.end - o.begin) % o.merge;
aout = A(ain, o.begin, o.end, o.merge); aout = A(ain, o.begin, o.end, o.merge);
}, },
[](auto&&, const auto& ain) { [iaxis](auto&&, const auto&) {
using A = std::decay_t<decltype(ain)>; BOOST_THROW_EXCEPTION(std::invalid_argument("axis " + std::to_string(iaxis) +
BOOST_THROW_EXCEPTION(std::invalid_argument( " is not reducible"));
detail::cat(detail::type_name<A>(), " is not reducible")));
}, },
axis::get<A>(detail::axis_get(axes, iaxis)), a); axis::get<A>(detail::axis_get(axes, iaxis)), a);
} else { } else {

View File

@ -11,13 +11,13 @@
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/histogram/axis/regular.hpp> #include <boost/histogram/axis/regular.hpp>
#include <boost/histogram/detail/cat.hpp>
#include <boost/histogram/detail/static_if.hpp> #include <boost/histogram/detail/static_if.hpp>
#include <boost/histogram/detail/type_name.hpp> #include <boost/histogram/detail/type_name.hpp>
#include <boost/histogram/fwd.hpp> #include <boost/histogram/fwd.hpp>
#include <boost/throw_exception.hpp> #include <boost/throw_exception.hpp>
#include <iomanip> #include <iomanip>
#include <iosfwd> #include <iosfwd>
#include <sstream>
#include <stdexcept> #include <stdexcept>
#include <type_traits> #include <type_traits>

View File

@ -10,7 +10,6 @@
#include <boost/core/ignore_unused.hpp> #include <boost/core/ignore_unused.hpp>
#include <boost/histogram/axis/option.hpp> #include <boost/histogram/axis/option.hpp>
#include <boost/histogram/detail/args_type.hpp> #include <boost/histogram/detail/args_type.hpp>
#include <boost/histogram/detail/cat.hpp>
#include <boost/histogram/detail/detect.hpp> #include <boost/histogram/detail/detect.hpp>
#include <boost/histogram/detail/static_if.hpp> #include <boost/histogram/detail/static_if.hpp>
#include <boost/histogram/detail/try_cast.hpp> #include <boost/histogram/detail/try_cast.hpp>
@ -22,6 +21,7 @@
#include <boost/throw_exception.hpp> #include <boost/throw_exception.hpp>
#include <boost/variant2/variant.hpp> #include <boost/variant2/variant.hpp>
#include <stdexcept> #include <stdexcept>
#include <string>
#include <utility> #include <utility>
namespace boost { namespace boost {
@ -56,7 +56,7 @@ double value_method_switch_impl1(std::false_type, I&&, D&&, const A&) {
// comma trick to make all compilers happy; some would complain about // comma trick to make all compilers happy; some would complain about
// unreachable code after the throw, others about a missing return // unreachable code after the throw, others about a missing return
return BOOST_THROW_EXCEPTION( return BOOST_THROW_EXCEPTION(
std::runtime_error(cat(type_name<A>(), " has no value method"))), std::runtime_error(type_name<A>() + " has no value method")),
double{}; double{};
} }

View File

@ -83,12 +83,14 @@ public:
vec_.reserve(std::distance(begin, end)); vec_.reserve(std::distance(begin, end));
vec_.emplace_back(*begin++); vec_.emplace_back(*begin++);
bool strictly_ascending = true;
while (begin != end) { while (begin != end) {
if (*begin <= vec_.back()) if (*begin <= vec_.back()) strictly_ascending = false;
BOOST_THROW_EXCEPTION(
std::invalid_argument("input sequence must be strictly ascending"));
vec_.emplace_back(*begin++); vec_.emplace_back(*begin++);
} }
if (!strictly_ascending)
BOOST_THROW_EXCEPTION(
std::invalid_argument("input sequence must be strictly ascending"));
} }
/** Construct variable axis from iterable range of bin edges. /** Construct variable axis from iterable range of bin edges.

View File

@ -11,7 +11,6 @@
#include <boost/histogram/axis/iterator.hpp> #include <boost/histogram/axis/iterator.hpp>
#include <boost/histogram/axis/polymorphic_bin.hpp> #include <boost/histogram/axis/polymorphic_bin.hpp>
#include <boost/histogram/axis/traits.hpp> #include <boost/histogram/axis/traits.hpp>
#include <boost/histogram/detail/cat.hpp>
#include <boost/histogram/detail/relaxed_equal.hpp> #include <boost/histogram/detail/relaxed_equal.hpp>
#include <boost/histogram/detail/static_if.hpp> #include <boost/histogram/detail/static_if.hpp>
#include <boost/histogram/detail/type_name.hpp> #include <boost/histogram/detail/type_name.hpp>
@ -20,7 +19,6 @@
#include <boost/mp11/list.hpp> // mp_first #include <boost/mp11/list.hpp> // mp_first
#include <boost/throw_exception.hpp> #include <boost/throw_exception.hpp>
#include <boost/variant2/variant.hpp> #include <boost/variant2/variant.hpp>
#include <ostream>
#include <stdexcept> #include <stdexcept>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
@ -74,9 +72,9 @@ public:
detail::static_if<is_bounded_type<U>>( detail::static_if<is_bounded_type<U>>(
[this](const auto& u) { this->operator=(u); }, [this](const auto& u) { this->operator=(u); },
[](const auto&) { [](const auto&) {
BOOST_THROW_EXCEPTION(std::runtime_error(detail::cat( BOOST_THROW_EXCEPTION(std::runtime_error(
detail::type_name<U>(), " is not convertible to a bounded type of ", detail::type_name<U>() + " is not convertible to a bounded type of " +
detail::type_name<variant>()))); detail::type_name<variant>()));
}, },
u); u);
}, },
@ -109,11 +107,11 @@ public:
[](const auto& a) -> const metadata_type& { return traits::metadata(a); }, [](const auto& a) -> const metadata_type& { return traits::metadata(a); },
[](const auto&) -> const metadata_type& { [](const auto&) -> const metadata_type& {
BOOST_THROW_EXCEPTION(std::runtime_error( BOOST_THROW_EXCEPTION(std::runtime_error(
detail::cat("cannot return metadata of type ", detail::type_name<M>(), "cannot return metadata of type " + detail::type_name<M>() +
" through axis::variant interface which uses type ", " through axis::variant interface which uses type " +
detail::type_name<metadata_type>(), detail::type_name<metadata_type>() +
"; use boost::histogram::axis::get to obtain a reference " "; use boost::histogram::axis::get to obtain a reference "
"of this axis type"))); "of this axis type"));
}, },
a); a);
}, },
@ -130,11 +128,11 @@ public:
[](auto& a) -> metadata_type& { return traits::metadata(a); }, [](auto& a) -> metadata_type& { return traits::metadata(a); },
[](auto&) -> metadata_type& { [](auto&) -> metadata_type& {
BOOST_THROW_EXCEPTION(std::runtime_error( BOOST_THROW_EXCEPTION(std::runtime_error(
detail::cat("cannot return metadata of type ", detail::type_name<M>(), "cannot return metadata of type " + detail::type_name<M>() +
" through axis::variant interface which uses type ", " through axis::variant interface which uses type " +
detail::type_name<metadata_type>(), detail::type_name<metadata_type>() +
"; use boost::histogram::axis::get to obtain a reference " "; use boost::histogram::axis::get to obtain a reference "
"of this axis type"))); "of this axis type"));
}, },
a); a);
}, },

View File

@ -22,6 +22,7 @@
#include <boost/mp11/utility.hpp> #include <boost/mp11/utility.hpp>
#include <boost/throw_exception.hpp> #include <boost/throw_exception.hpp>
#include <stdexcept> #include <stdexcept>
#include <string>
#include <tuple> #include <tuple>
#include <type_traits> #include <type_traits>
@ -57,9 +58,10 @@ template <class T>
void throw_if_axes_is_too_large(const T& axes) { void throw_if_axes_is_too_large(const T& axes) {
if (axes_rank(axes) > BOOST_HISTOGRAM_DETAIL_AXES_LIMIT) if (axes_rank(axes) > BOOST_HISTOGRAM_DETAIL_AXES_LIMIT)
BOOST_THROW_EXCEPTION( BOOST_THROW_EXCEPTION(
std::invalid_argument(cat("length of axis vector exceeds internal buffers, " std::invalid_argument("length of axis vector exceeds internal buffers, "
"recompile with -DBOOST_HISTOGRAM_DETAIL_AXES_LIMIT=", "recompile with "
axes_rank(axes), " to increase internal buffers"))); "-DBOOST_HISTOGRAM_DETAIL_AXES_LIMIT=<new max size> "
"to increase internal buffers"));
} }
// tuple is never too large because internal buffers adapt to size of tuple // tuple is never too large because internal buffers adapt to size of tuple

View File

@ -1,34 +0,0 @@
// Copyright 2015-2017 Hans Dembinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_HISTOGRAM_DETAIL_CAT_HPP
#define BOOST_HISTOGRAM_DETAIL_CAT_HPP
#include <boost/config.hpp>
#include <sstream>
namespace boost {
namespace histogram {
namespace detail {
BOOST_ATTRIBUTE_UNUSED inline void cat_impl(std::ostringstream&) {}
template <typename T, typename... Ts>
void cat_impl(std::ostringstream& os, const T& t, const Ts&... ts) {
os << t;
cat_impl(os, ts...);
}
template <typename... Ts>
std::string cat(const Ts&... args) {
std::ostringstream os;
cat_impl(os, args...);
return os.str();
}
} // namespace detail
} // namespace histogram
} // namespace boost
#endif

View File

@ -9,11 +9,11 @@
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/core/demangle.hpp> #include <boost/core/demangle.hpp>
#include <boost/histogram/detail/cat.hpp>
#include <boost/histogram/detail/type_name.hpp> #include <boost/histogram/detail/type_name.hpp>
#include <boost/mp11/integral.hpp> #include <boost/mp11/integral.hpp>
#include <boost/throw_exception.hpp> #include <boost/throw_exception.hpp>
#include <stdexcept> #include <stdexcept>
#include <string>
#include <type_traits> #include <type_traits>
namespace boost { namespace boost {
@ -21,7 +21,7 @@ namespace histogram {
namespace detail { namespace detail {
template <class T, class E, class U> template <class T, class E, class U>
BOOST_NORETURN T try_cast_impl(mp11::mp_int<0>, U&&) { BOOST_NORETURN T try_cast_impl(mp11::mp_int<0>, U&&) {
BOOST_THROW_EXCEPTION(E(cat("cannot cast ", type_name<T>(), " to ", type_name<U>()))); BOOST_THROW_EXCEPTION(E("cannot cast " + type_name<T>() + " to " + type_name<U>()));
} }
template <class T, class E, class U> template <class T, class E, class U>

View File

@ -9,7 +9,6 @@
#include <boost/core/typeinfo.hpp> #include <boost/core/typeinfo.hpp>
#include <boost/type.hpp> #include <boost/type.hpp>
#include <sstream>
#include <string> #include <string>
namespace boost { namespace boost {
@ -17,31 +16,28 @@ namespace histogram {
namespace detail { namespace detail {
template <class T> template <class T>
std::ostream& type_name_impl(std::ostream& os, boost::type<T>) { std::string type_name_impl(boost::type<T>) {
os << boost::core::demangled_name(BOOST_CORE_TYPEID(T)); return boost::core::demangled_name(BOOST_CORE_TYPEID(T));
return os;
} }
template <class T> template <class T>
std::ostream& type_name_impl(std::ostream& os, boost::type<const T>) { std::string type_name_impl(boost::type<const T>) {
return type_name_impl(os, boost::type<T>{}) << " const"; return type_name_impl(boost::type<T>{}) + " const";
} }
template <class T> template <class T>
std::ostream& type_name_impl(std::ostream& os, boost::type<T&>) { std::string type_name_impl(boost::type<T&>) {
return type_name_impl(os, boost::type<T>{}) << "&"; return type_name_impl(boost::type<T>{}) + " &";
} }
template <class T> template <class T>
std::ostream& type_name_impl(std::ostream& os, boost::type<T&&>) { std::string type_name_impl(boost::type<T&&>) {
return type_name_impl(os, boost::type<T>{}) << "&&"; return type_name_impl(boost::type<T>{}) + " &&";
} }
template <class T> template <class T>
std::string type_name() { std::string type_name() {
std::ostringstream os; return type_name_impl(boost::type<T>{});
type_name_impl(os, boost::type<T>{});
return os.str();
} }
} // namespace detail } // namespace detail

View File

@ -10,7 +10,6 @@
#include <algorithm> #include <algorithm>
#include <boost/core/nvp.hpp> #include <boost/core/nvp.hpp>
#include <boost/histogram/detail/array_wrapper.hpp> #include <boost/histogram/detail/array_wrapper.hpp>
#include <boost/histogram/detail/cat.hpp>
#include <boost/histogram/detail/detect.hpp> #include <boost/histogram/detail/detect.hpp>
#include <boost/histogram/detail/iterator_adaptor.hpp> #include <boost/histogram/detail/iterator_adaptor.hpp>
#include <boost/histogram/detail/safe_comparison.hpp> #include <boost/histogram/detail/safe_comparison.hpp>
@ -90,20 +89,19 @@ struct array_impl : T {
template <class U, class = requires_iterable<U>> template <class U, class = requires_iterable<U>>
array_impl& operator=(const U& u) { array_impl& operator=(const U& u) {
if (u.size() > T::max_size()) // for std::arra
BOOST_THROW_EXCEPTION(std::length_error("argument size exceeds maximum capacity"));
size_ = u.size(); size_ = u.size();
if (size_ > T::max_size()) // for std::array using std::begin;
BOOST_THROW_EXCEPTION(std::length_error( using std::end;
detail::cat("size ", size_, " exceeds maximum capacity ", T::max_size()))); std::copy(begin(u), end(u), T::begin());
auto it = T::begin();
for (auto&& x : u) *it++ = x;
return *this; return *this;
} }
void reset(std::size_t n) { void reset(std::size_t n) {
using value_type = typename T::value_type; using value_type = typename T::value_type;
if (n > T::max_size()) // for std::array if (n > T::max_size()) // for std::array
BOOST_THROW_EXCEPTION(std::length_error( BOOST_THROW_EXCEPTION(std::length_error("argument size exceeds maximum capacity"));
detail::cat("size ", n, " exceeds maximum capacity ", T::max_size())));
std::fill_n(T::begin(), n, value_type()); std::fill_n(T::begin(), n, value_type());
size_ = n; size_ = n;
} }

View File

@ -9,7 +9,6 @@
#include <boost/histogram/axis/category.hpp> #include <boost/histogram/axis/category.hpp>
#include <boost/histogram/axis/ostream.hpp> #include <boost/histogram/axis/ostream.hpp>
#include <boost/histogram/axis/traits.hpp> #include <boost/histogram/axis/traits.hpp>
#include <boost/histogram/detail/cat.hpp>
#include <limits> #include <limits>
#include <sstream> #include <sstream>
#include <string> #include <string>
@ -17,10 +16,11 @@
#include "std_ostream.hpp" #include "std_ostream.hpp"
#include "throw_exception.hpp" #include "throw_exception.hpp"
#include "utility_axis.hpp" #include "utility_axis.hpp"
#include "utility_str.hpp"
using namespace boost::histogram;
int main() { int main() {
using namespace boost::histogram;
BOOST_TEST(std::is_nothrow_move_constructible<axis::category<int>>::value); BOOST_TEST(std::is_nothrow_move_constructible<axis::category<int>>::value);
BOOST_TEST(std::is_nothrow_move_constructible<axis::category<std::string>>::value); BOOST_TEST(std::is_nothrow_move_constructible<axis::category<std::string>>::value);
BOOST_TEST(std::is_nothrow_move_assignable<axis::category<int>>::value); BOOST_TEST(std::is_nothrow_move_assignable<axis::category<int>>::value);
@ -69,7 +69,7 @@ int main() {
BOOST_TEST_EQ(a.value(2), C); BOOST_TEST_EQ(a.value(2), C);
BOOST_TEST_THROWS(a.value(3), std::out_of_range); BOOST_TEST_THROWS(a.value(3), std::out_of_range);
BOOST_TEST_EQ(detail::cat(a), BOOST_TEST_EQ(str(a),
"category(\"A\", \"B\", \"C\", metadata=\"bar\", options=overflow)"); "category(\"A\", \"B\", \"C\", metadata=\"bar\", options=overflow)");
} }
@ -131,7 +131,7 @@ int main() {
BOOST_TEST_EQ(a.update(10), std::make_pair(2, 0)); BOOST_TEST_EQ(a.update(10), std::make_pair(2, 0));
BOOST_TEST_EQ(a.size(), 3); BOOST_TEST_EQ(a.size(), 3);
BOOST_TEST_EQ(detail::cat(a), "category(5, 1, 10, options=growth)"); BOOST_TEST_EQ(str(a), "category(5, 1, 10, options=growth)");
} }
// iterators // iterators

View File

@ -7,16 +7,17 @@
#include <boost/core/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#include <boost/histogram/axis/integer.hpp> #include <boost/histogram/axis/integer.hpp>
#include <boost/histogram/axis/ostream.hpp> #include <boost/histogram/axis/ostream.hpp>
#include <boost/histogram/detail/cat.hpp>
#include <limits> #include <limits>
#include <sstream>
#include <type_traits> #include <type_traits>
#include "std_ostream.hpp" #include "std_ostream.hpp"
#include "throw_exception.hpp" #include "throw_exception.hpp"
#include "utility_axis.hpp" #include "utility_axis.hpp"
#include "utility_str.hpp"
using namespace boost::histogram;
int main() { int main() {
using namespace boost::histogram;
BOOST_TEST(std::is_nothrow_move_assignable<axis::integer<>>::value); BOOST_TEST(std::is_nothrow_move_assignable<axis::integer<>>::value);
BOOST_TEST(std::is_nothrow_move_constructible<axis::integer<>>::value); BOOST_TEST(std::is_nothrow_move_constructible<axis::integer<>>::value);
@ -44,7 +45,7 @@ int main() {
BOOST_TEST_EQ(a.index(10), 3); BOOST_TEST_EQ(a.index(10), 3);
BOOST_TEST_EQ(a.index(std::numeric_limits<double>::quiet_NaN()), 3); BOOST_TEST_EQ(a.index(std::numeric_limits<double>::quiet_NaN()), 3);
BOOST_TEST_EQ(detail::cat(a), BOOST_TEST_EQ(str(a),
"integer(-1, 2, metadata=\"bar\", options=underflow | overflow)"); "integer(-1, 2, metadata=\"bar\", options=underflow | overflow)");
axis::integer<double> b; axis::integer<double> b;
@ -72,7 +73,7 @@ int main() {
BOOST_TEST_EQ(a.index(2), 3); BOOST_TEST_EQ(a.index(2), 3);
BOOST_TEST_EQ(a.index(10), 3); BOOST_TEST_EQ(a.index(10), 3);
BOOST_TEST_EQ(detail::cat(a), "integer(-1, 2, options=underflow | overflow)"); BOOST_TEST_EQ(str(a), "integer(-1, 2, options=underflow | overflow)");
} }
// axis::integer int,circular // axis::integer int,circular
@ -89,7 +90,7 @@ int main() {
BOOST_TEST_EQ(a.index(1), 0); BOOST_TEST_EQ(a.index(1), 0);
BOOST_TEST_EQ(a.index(2), 1); BOOST_TEST_EQ(a.index(2), 1);
BOOST_TEST_EQ(detail::cat(a), "integer(-1, 1, options=circular)"); BOOST_TEST_EQ(str(a), "integer(-1, 1, options=circular)");
} }
// axis::integer double,circular // axis::integer double,circular

View File

@ -7,7 +7,6 @@
#include <boost/core/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#include <boost/histogram/axis/ostream.hpp> #include <boost/histogram/axis/ostream.hpp>
#include <boost/histogram/axis/regular.hpp> #include <boost/histogram/axis/regular.hpp>
#include <boost/histogram/detail/cat.hpp>
#include <limits> #include <limits>
#include <sstream> #include <sstream>
#include <type_traits> #include <type_traits>
@ -15,12 +14,13 @@
#include "std_ostream.hpp" #include "std_ostream.hpp"
#include "throw_exception.hpp" #include "throw_exception.hpp"
#include "utility_axis.hpp" #include "utility_axis.hpp"
#include "utility_str.hpp"
using namespace boost::histogram;
namespace tr = axis::transform;
using def = use_default;
int main() { int main() {
using namespace boost::histogram;
using def = use_default;
namespace tr = axis::transform;
BOOST_TEST(std::is_nothrow_move_assignable<axis::regular<>>::value); BOOST_TEST(std::is_nothrow_move_assignable<axis::regular<>>::value);
BOOST_TEST(std::is_nothrow_move_constructible<axis::regular<>>::value); BOOST_TEST(std::is_nothrow_move_constructible<axis::regular<>>::value);
@ -73,7 +73,7 @@ int main() {
BOOST_TEST_EQ(a.index(std::numeric_limits<double>::infinity()), 4); BOOST_TEST_EQ(a.index(std::numeric_limits<double>::infinity()), 4);
BOOST_TEST_EQ(a.index(std::numeric_limits<double>::quiet_NaN()), 4); BOOST_TEST_EQ(a.index(std::numeric_limits<double>::quiet_NaN()), 4);
BOOST_TEST_EQ(detail::cat(a), BOOST_TEST_EQ(str(a),
"regular(4, -2, 2, metadata=\"bar\", options=underflow | overflow)"); "regular(4, -2, 2, metadata=\"bar\", options=underflow | overflow)");
} }
@ -116,7 +116,7 @@ int main() {
BOOST_TEST_THROWS((axis::regular<double, tr::log>{2, -1, 0}), std::invalid_argument); BOOST_TEST_THROWS((axis::regular<double, tr::log>{2, -1, 0}), std::invalid_argument);
BOOST_TEST_EQ(detail::cat(a), "regular_log(2, 1, 100, options=underflow | overflow)"); BOOST_TEST_EQ(str(a), "regular_log(2, 1, 100, options=underflow | overflow)");
} }
// with sqrt transform // with sqrt transform
@ -138,7 +138,7 @@ int main() {
BOOST_TEST_EQ(a.index(100), 2); BOOST_TEST_EQ(a.index(100), 2);
BOOST_TEST_EQ(a.index(std::numeric_limits<double>::infinity()), 2); BOOST_TEST_EQ(a.index(std::numeric_limits<double>::infinity()), 2);
BOOST_TEST_EQ(detail::cat(a), "regular_sqrt(2, 0, 4, options=underflow | overflow)"); BOOST_TEST_EQ(str(a), "regular_sqrt(2, 0, 4, options=underflow | overflow)");
} }
// with pow transform // with pow transform
@ -160,7 +160,7 @@ int main() {
BOOST_TEST_EQ(a.index(100), 2); BOOST_TEST_EQ(a.index(100), 2);
BOOST_TEST_EQ(a.index(std::numeric_limits<double>::infinity()), 2); BOOST_TEST_EQ(a.index(std::numeric_limits<double>::infinity()), 2);
BOOST_TEST_EQ(detail::cat(a), BOOST_TEST_EQ(str(a),
"regular_pow(2, 0, 4, options=underflow | overflow, power=0.5)"); "regular_pow(2, 0, 4, options=underflow | overflow, power=0.5)");
} }
@ -244,7 +244,7 @@ int main() {
// null_type streamable // null_type streamable
{ {
auto a = axis::regular<float, def, axis::null_type>(2, 0, 1); auto a = axis::regular<float, def, axis::null_type>(2, 0, 1);
BOOST_TEST_EQ(detail::cat(a), "regular(2, 0, 1, options=underflow | overflow)"); BOOST_TEST_EQ(str(a), "regular(2, 0, 1, options=underflow | overflow)");
} }
// shrink and rebin // shrink and rebin

View File

@ -7,14 +7,15 @@
#include <boost/core/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#include <boost/histogram/axis/ostream.hpp> #include <boost/histogram/axis/ostream.hpp>
#include <boost/histogram/axis/variable.hpp> #include <boost/histogram/axis/variable.hpp>
#include <boost/histogram/detail/cat.hpp>
#include <limits> #include <limits>
#include <sstream>
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
#include "is_close.hpp" #include "is_close.hpp"
#include "std_ostream.hpp" #include "std_ostream.hpp"
#include "throw_exception.hpp" #include "throw_exception.hpp"
#include "utility_axis.hpp" #include "utility_axis.hpp"
#include "utility_str.hpp"
using namespace boost::histogram; using namespace boost::histogram;
@ -24,9 +25,9 @@ int main() {
// bad_ctors // bad_ctors
{ {
auto empty = std::vector<double>(0); BOOST_TEST_THROWS(axis::variable<>(std::vector<double>{}), std::invalid_argument);
BOOST_TEST_THROWS((axis::variable<>(empty)), std::invalid_argument);
BOOST_TEST_THROWS(axis::variable<>({1.0}), std::invalid_argument); BOOST_TEST_THROWS(axis::variable<>({1.0}), std::invalid_argument);
BOOST_TEST_THROWS(axis::variable<>({1.0, 1.0}), std::invalid_argument);
BOOST_TEST_THROWS(axis::variable<>({1.0, -1.0}), std::invalid_argument); BOOST_TEST_THROWS(axis::variable<>({1.0, -1.0}), std::invalid_argument);
} }
@ -54,7 +55,7 @@ int main() {
BOOST_TEST_EQ(a.index(std::numeric_limits<double>::infinity()), 2); BOOST_TEST_EQ(a.index(std::numeric_limits<double>::infinity()), 2);
BOOST_TEST_EQ(a.index(std::numeric_limits<double>::quiet_NaN()), 2); BOOST_TEST_EQ(a.index(std::numeric_limits<double>::quiet_NaN()), 2);
BOOST_TEST_EQ(detail::cat(a), BOOST_TEST_EQ(str(a),
"variable(-1, 0, 1, metadata=\"bar\", options=underflow | overflow)"); "variable(-1, 0, 1, metadata=\"bar\", options=underflow | overflow)");
axis::variable<> b; axis::variable<> b;

View File

@ -11,21 +11,22 @@
#include <boost/histogram/axis/ostream.hpp> #include <boost/histogram/axis/ostream.hpp>
#include <boost/histogram/axis/regular.hpp> #include <boost/histogram/axis/regular.hpp>
#include <boost/histogram/axis/variant.hpp> #include <boost/histogram/axis/variant.hpp>
#include <boost/histogram/detail/cat.hpp>
#include <boost/histogram/detail/type_name.hpp> #include <boost/histogram/detail/type_name.hpp>
#include <sstream>
#include <string> #include <string>
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
#include "throw_exception.hpp" #include "throw_exception.hpp"
#include "utility_allocator.hpp" #include "utility_allocator.hpp"
#include "utility_axis.hpp" #include "utility_axis.hpp"
#include "utility_str.hpp"
using namespace boost::histogram;
namespace tr = axis::transform;
int main() { int main() {
{ (void)axis::variant<>{}; } using namespace boost::histogram;
namespace tr = axis::transform;
{
(void)axis::variant<>{};
}
{ {
using meta_type = std::vector<int>; using meta_type = std::vector<int>;
@ -124,15 +125,15 @@ int main() {
auto test = [](auto&& a, const char* ref) { auto test = [](auto&& a, const char* ref) {
using T = std::decay_t<decltype(a)>; using T = std::decay_t<decltype(a)>;
axis::variant<T> axis(std::move(a)); axis::variant<T> axis(std::move(a));
BOOST_TEST_CSTR_EQ(detail::cat(axis).c_str(), ref); BOOST_TEST_CSTR_EQ(str(axis).c_str(), ref);
}; };
test(axis::regular<>(2, -1, 1, "regular1"), test(axis::regular<>(2, -1, 1, "regular1"),
"regular(2, -1, 1, metadata=\"regular1\", options=underflow | overflow)"); "regular(2, -1, 1, metadata=\"regular1\", options=underflow | overflow)");
struct user_defined {}; struct user_defined {};
const auto ref = detail::cat( const auto ref = "integer(-1, 1, metadata=" + detail::type_name<user_defined>() +
"integer(-1, 1, metadata=", detail::type_name<user_defined>(), ", options=none)"); ", options=none)";
test(axis::integer<int, user_defined, axis::option::none_t>(-1, 1), ref.c_str()); test(axis::integer<int, user_defined, axis::option::none_t>(-1, 1), ref.c_str());
} }
@ -141,7 +142,7 @@ int main() {
auto test = [](auto&& a, const char* ref) { auto test = [](auto&& a, const char* ref) {
using T = std::decay_t<decltype(a)>; using T = std::decay_t<decltype(a)>;
axis::variant<T> axis(std::move(a)); axis::variant<T> axis(std::move(a));
BOOST_TEST_CSTR_EQ(detail::cat(axis.bin(0)).c_str(), ref); BOOST_TEST_CSTR_EQ(str(axis.bin(0)).c_str(), ref);
}; };
test(axis::regular<>(2, 1, 2), "[1, 1.5)"); test(axis::regular<>(2, 1, 2), "[1, 1.5)");
@ -190,7 +191,7 @@ int main() {
BOOST_TEST_EQ(axis.index(9), 1); BOOST_TEST_EQ(axis.index(9), 1);
BOOST_TEST_EQ(axis.size(), 2); BOOST_TEST_EQ(axis.size(), 2);
BOOST_TEST_EQ(axis.metadata(), axis::null_type{}); BOOST_TEST_EQ(axis.metadata(), axis::null_type{});
BOOST_TEST_CSTR_EQ(detail::cat(axis).c_str(), "<unstreamable>"); BOOST_TEST_CSTR_EQ(str(axis).c_str(), "<unstreamable>");
BOOST_TEST_THROWS(axis.value(0), std::runtime_error); BOOST_TEST_THROWS(axis.value(0), std::runtime_error);
axis = axis::category<std::string>({"A", "B"}, "category"); axis = axis::category<std::string>({"A", "B"}, "category");

View File

@ -7,7 +7,6 @@
#include <boost/core/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#include <boost/core/lightweight_test_trait.hpp> #include <boost/core/lightweight_test_trait.hpp>
#include <boost/histogram/accumulators/weighted_sum.hpp> #include <boost/histogram/accumulators/weighted_sum.hpp>
#include <boost/histogram/detail/cat.hpp>
#include <boost/histogram/detail/common_type.hpp> #include <boost/histogram/detail/common_type.hpp>
#include <boost/histogram/detail/counting_streambuf.hpp> #include <boost/histogram/detail/counting_streambuf.hpp>
#include <boost/histogram/detail/non_member_container_access.hpp> #include <boost/histogram/detail/non_member_container_access.hpp>
@ -23,9 +22,6 @@ using namespace boost::histogram::literals;
namespace dtl = boost::histogram::detail; namespace dtl = boost::histogram::detail;
int main() { int main() {
// cat
{ BOOST_TEST_EQ(dtl::cat("foo", 1, "bar"), "foo1bar"); }
// literals // literals
{ {
BOOST_TEST_TRAIT_SAME(std::integral_constant<unsigned, 0>, decltype(0_c)); BOOST_TEST_TRAIT_SAME(std::integral_constant<unsigned, 0>, decltype(0_c));

20
test/utility_str.hpp Normal file
View File

@ -0,0 +1,20 @@
// Copyright 2019 Hans Dembinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_HISTOGRAM_TEST_UTILITY_STR_HPP
#define BOOST_HISTOGRAM_TEST_UTILITY_STR_HPP
#include <sstream>
#include <string>
template <class T>
std::string str(const T& t) {
std::ostringstream os;
os << t;
return os.str();
}
#endif