File indexing completed on 2025-01-18 09:38:10
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_HISTOGRAM_AXIS_OSTREAM_HPP
0010 #define BOOST_HISTOGRAM_AXIS_OSTREAM_HPP
0011
0012 #include <boost/histogram/axis/regular.hpp>
0013 #include <boost/histogram/detail/counting_streambuf.hpp>
0014 #include <boost/histogram/detail/priority.hpp>
0015 #include <boost/histogram/detail/type_name.hpp>
0016 #include <boost/histogram/fwd.hpp>
0017 #include <boost/throw_exception.hpp>
0018 #include <cassert>
0019 #include <iomanip>
0020 #include <iosfwd>
0021 #include <sstream>
0022 #include <stdexcept>
0023 #include <type_traits>
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #ifndef BOOST_HISTOGRAM_DOXYGEN_INVOKED
0038
0039 namespace boost {
0040 namespace histogram {
0041
0042 namespace detail {
0043
0044 template <class OStream, class T>
0045 auto ostream_any_impl(OStream& os, const T& t, priority<1>) -> decltype(os << t) {
0046 return os << t;
0047 }
0048
0049 template <class OStream, class T>
0050 OStream& ostream_any_impl(OStream& os, const T&, priority<0>) {
0051 return os << type_name<T>();
0052 }
0053
0054 template <class OStream, class T>
0055 OStream& ostream_any(OStream& os, const T& t) {
0056 return ostream_any_impl(os, t, priority<1>{});
0057 }
0058
0059 template <class OStream, class... Ts>
0060 OStream& ostream_any_quoted(OStream& os, const std::basic_string<Ts...>& s) {
0061 return os << std::quoted(s);
0062 }
0063
0064 template <class OStream, class T>
0065 OStream& ostream_any_quoted(OStream& os, const T& t) {
0066 return ostream_any(os, t);
0067 }
0068
0069 template <class... Ts, class T>
0070 std::basic_ostream<Ts...>& ostream_metadata(std::basic_ostream<Ts...>& os, const T& t,
0071 const char* prefix = ", ") {
0072 std::streamsize count = 0;
0073 {
0074 auto g = make_count_guard(os, count);
0075 ostream_any(os, t);
0076 }
0077 if (!count) return os;
0078 os << prefix << "metadata=";
0079 return ostream_any_quoted(os, t);
0080 }
0081
0082 template <class OStream>
0083 void ostream_options(OStream& os, const unsigned bits) {
0084 bool first = true;
0085 os << ", options=";
0086
0087 #define BOOST_HISTOGRAM_AXIS_OPTION_OSTREAM(x) \
0088 if (bits & axis::option::x) { \
0089 if (first) \
0090 first = false; \
0091 else { \
0092 os << " | "; \
0093 } \
0094 os << #x; \
0095 }
0096
0097 BOOST_HISTOGRAM_AXIS_OPTION_OSTREAM(underflow);
0098 BOOST_HISTOGRAM_AXIS_OPTION_OSTREAM(overflow);
0099 BOOST_HISTOGRAM_AXIS_OPTION_OSTREAM(circular);
0100 BOOST_HISTOGRAM_AXIS_OPTION_OSTREAM(growth);
0101
0102 #undef BOOST_HISTOGRAM_AXIS_OPTION_OSTREAM
0103
0104 if (first) os << "none";
0105 }
0106
0107 }
0108
0109 namespace axis {
0110
0111 template <class T>
0112 class polymorphic_bin;
0113
0114 template <class... Ts>
0115 std::basic_ostream<Ts...>& operator<<(std::basic_ostream<Ts...>& os, const null_type&) {
0116 return os;
0117 }
0118
0119 template <class... Ts, class U>
0120 std::basic_ostream<Ts...>& operator<<(std::basic_ostream<Ts...>& os,
0121 const interval_view<U>& i) {
0122 return os << "[" << i.lower() << ", " << i.upper() << ")";
0123 }
0124
0125 template <class... Ts, class U>
0126 std::basic_ostream<Ts...>& operator<<(std::basic_ostream<Ts...>& os,
0127 const polymorphic_bin<U>& i) {
0128 if (i.is_discrete()) return os << static_cast<double>(i);
0129 return os << "[" << i.lower() << ", " << i.upper() << ")";
0130 }
0131
0132 namespace transform {
0133 template <class... Ts>
0134 std::basic_ostream<Ts...>& operator<<(std::basic_ostream<Ts...>& os, const id&) {
0135 return os;
0136 }
0137
0138 template <class... Ts>
0139 std::basic_ostream<Ts...>& operator<<(std::basic_ostream<Ts...>& os, const log&) {
0140 return os << "transform::log{}";
0141 }
0142
0143 template <class... Ts>
0144 std::basic_ostream<Ts...>& operator<<(std::basic_ostream<Ts...>& os, const sqrt&) {
0145 return os << "transform::sqrt{}";
0146 }
0147
0148 template <class... Ts>
0149 std::basic_ostream<Ts...>& operator<<(std::basic_ostream<Ts...>& os, const pow& p) {
0150 return os << "transform::pow{" << p.power << "}";
0151 }
0152 }
0153
0154 template <class... Ts, class... Us>
0155 std::basic_ostream<Ts...>& operator<<(std::basic_ostream<Ts...>& os,
0156 const regular<Us...>& a) {
0157 os << "regular(";
0158 const auto pos = os.tellp();
0159 os << a.transform();
0160 if (os.tellp() > pos) os << ", ";
0161 os << a.size() << ", " << a.value(0) << ", " << a.value(a.size());
0162 detail::ostream_metadata(os, a.metadata());
0163 detail::ostream_options(os, a.options());
0164 return os << ")";
0165 }
0166
0167 template <class... Ts, class... Us>
0168 std::basic_ostream<Ts...>& operator<<(std::basic_ostream<Ts...>& os,
0169 const integer<Us...>& a) {
0170 os << "integer(" << a.value(0) << ", " << a.value(a.size());
0171 detail::ostream_metadata(os, a.metadata());
0172 detail::ostream_options(os, a.options());
0173 return os << ")";
0174 }
0175
0176 template <class... Ts, class... Us>
0177 std::basic_ostream<Ts...>& operator<<(std::basic_ostream<Ts...>& os,
0178 const variable<Us...>& a) {
0179 os << "variable(" << a.value(0);
0180 for (index_type i = 1, n = a.size(); i <= n; ++i) { os << ", " << a.value(i); }
0181 detail::ostream_metadata(os, a.metadata());
0182 detail::ostream_options(os, a.options());
0183 return os << ")";
0184 }
0185
0186 template <class... Ts, class... Us>
0187 std::basic_ostream<Ts...>& operator<<(std::basic_ostream<Ts...>& os,
0188 const category<Us...>& a) {
0189 os << "category(";
0190 for (index_type i = 0, n = a.size(); i < n; ++i) {
0191 detail::ostream_any_quoted(os, a.value(i));
0192 os << (i == (a.size() - 1) ? "" : ", ");
0193 }
0194 detail::ostream_metadata(os, a.metadata());
0195 detail::ostream_options(os, a.options());
0196 return os << ")";
0197 }
0198
0199 template <class... Ts, class M>
0200 std::basic_ostream<Ts...>& operator<<(std::basic_ostream<Ts...>& os,
0201 const boolean<M>& a) {
0202 os << "boolean(";
0203 detail::ostream_metadata(os, a.metadata(), "");
0204 return os << ")";
0205 }
0206
0207 template <class... Ts, class... Us>
0208 std::basic_ostream<Ts...>& operator<<(std::basic_ostream<Ts...>& os,
0209 const variant<Us...>& v) {
0210 visit([&os](const auto& x) { detail::ostream_any(os, x); }, v);
0211 return os;
0212 }
0213
0214 }
0215 }
0216 }
0217
0218 #endif
0219
0220 #endif