Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:10

0001 // Copyright 2015-2017 Hans Dembinski
0002 //
0003 // Distributed under the Boost Software License, Version 1.0.
0004 // (See accompanying file LICENSE_1_0.txt
0005 // or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // String representations here evaluate correctly in Python.
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   \file boost/histogram/axis/ostream.hpp
0027   Simple streaming operators for the builtin axis types.
0028 
0029   The text representation is not guaranteed to be stable between versions of
0030   Boost.Histogram. This header is only included by
0031   [boost/histogram/ostream.hpp](histogram/reference.html#header.boost.histogram.ostream_hpp).
0032   To use your own, include your own implementation instead of this header and do not
0033   include
0034   [boost/histogram/ostream.hpp](histogram/reference.html#header.boost.histogram.ostream_hpp).
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 } // namespace detail
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; // do nothing
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 } // namespace transform
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 } // namespace axis
0215 } // namespace histogram
0216 } // namespace boost
0217 
0218 #endif // BOOST_HISTOGRAM_DOXYGEN_INVOKED
0219 
0220 #endif