WireCellToolkit
Wire Cell Simulation, Signal Process and Reconstruction Toolki for Liquid Argon Detectors
ostream.h
Go to the documentation of this file.
1 // Formatting library for C++ - std::ostream support
2 //
3 // Copyright (c) 2012 - present, Victor Zverovich
4 // All rights reserved.
5 //
6 // For the license information refer to format.h.
7 
8 #ifndef FMT_OSTREAM_H_
9 #define FMT_OSTREAM_H_
10 
11 #include "format.h"
12 #include <ostream>
13 
15 namespace internal {
16 
17 template <class Char>
18 class formatbuf : public std::basic_streambuf<Char> {
19  private:
20  typedef typename std::basic_streambuf<Char>::int_type int_type;
21  typedef typename std::basic_streambuf<Char>::traits_type traits_type;
22 
23  basic_buffer<Char> &buffer_;
24 
25  public:
26  formatbuf(basic_buffer<Char> &buffer) : buffer_(buffer) {}
27 
28  protected:
29  // The put-area is actually always empty. This makes the implementation
30  // simpler and has the advantage that the streambuf and the buffer are always
31  // in sync and sputc never writes into uninitialized memory. The obvious
32  // disadvantage is that each call to sputc always results in a (virtual) call
33  // to overflow. There is no disadvantage here for sputn since this always
34  // results in a call to xsputn.
35 
36  int_type overflow(int_type ch = traits_type::eof()) FMT_OVERRIDE {
37  if (!traits_type::eq_int_type(ch, traits_type::eof()))
38  buffer_.push_back(static_cast<Char>(ch));
39  return ch;
40  }
41 
42  std::streamsize xsputn(const Char *s, std::streamsize count) FMT_OVERRIDE {
43  buffer_.append(s, s + count);
44  return count;
45  }
46 };
47 
48 template <typename Char>
49 struct test_stream : std::basic_ostream<Char> {
50  private:
51  struct null;
52  // Hide all operator<< from std::basic_ostream<Char>.
53  void operator<<(null);
54 };
55 
56 // Checks if T has a user-defined operator<< (e.g. not a member of std::ostream).
57 template <typename T, typename Char>
59  private:
60  template <typename U>
61  static decltype(
63  << internal::declval<U>(), std::true_type()) test(int);
64 
65  template <typename>
66  static std::false_type test(...);
67 
68  typedef decltype(test<T>(0)) result;
69 
70  public:
71  static const bool value = result::value;
72 };
73 
74 // Write the content of buf to os.
75 template <typename Char>
76 void write(std::basic_ostream<Char> &os, basic_buffer<Char> &buf) {
77  const Char *data = buf.data();
78  typedef std::make_unsigned<std::streamsize>::type UnsignedStreamSize;
79  UnsignedStreamSize size = buf.size();
80  UnsignedStreamSize max_size =
81  internal::to_unsigned((std::numeric_limits<std::streamsize>::max)());
82  do {
83  UnsignedStreamSize n = size <= max_size ? size : max_size;
84  os.write(data, static_cast<std::streamsize>(n));
85  data += n;
86  size -= n;
87  } while (size != 0);
88 }
89 
90 template <typename Char, typename T>
92  internal::formatbuf<Char> format_buf(buffer);
93  std::basic_ostream<Char> output(&format_buf);
94  output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
95  output << value;
96  buffer.resize(buffer.size());
97 }
98 } // namespace internal
99 
100 // Disable conversion to int if T has an overloaded operator<< which is a free
101 // function (not a member of std::ostream).
102 template <typename T, typename Char>
103 struct convert_to_int<T, Char, void> {
104  static const bool value =
107 };
108 
109 // Formats an object of type T that has an overloaded ostream operator<<.
110 template <typename T, typename Char>
111 struct formatter<T, Char,
112  typename std::enable_if<
113  internal::is_streamable<T, Char>::value &&
114  !internal::format_type<
115  typename buffer_context<Char>::type, T>::value>::type>
116  : formatter<basic_string_view<Char>, Char> {
117 
118  template <typename Context>
119  auto format(const T &value, Context &ctx) -> decltype(ctx.out()) {
121  internal::format_value(buffer, value);
122  basic_string_view<Char> str(buffer.data(), buffer.size());
123  return formatter<basic_string_view<Char>, Char>::format(str, ctx);
124  }
125 };
126 
127 template <typename Char>
128 inline void vprint(std::basic_ostream<Char> &os,
132  internal::vformat_to(buffer, format_str, args);
133  internal::write(os, buffer);
134 }
144 template <typename S, typename... Args>
145 inline typename std::enable_if<internal::is_string<S>::value>::type
146 print(std::basic_ostream<FMT_CHAR(S)> &os, const S &format_str,
147  const Args & ... args) {
148  internal::checked_args<S, Args...> ca(format_str, args...);
149  vprint(os, to_string_view(format_str), *ca);
150 }
152 
153 #endif // FMT_OSTREAM_H_
std::ostream & operator<<(std::ostream &os, const WireCell::Binning &bins)
Definition: Binning.h:124
void append(const U *begin, const U *end)
Definition: format.h:394
std::add_rvalue_reference< T >::type declval() FMT_NOEXCEPT
const S & format_str
Definition: format.h:3342
If we are still before C++14, supply the fodder for doing the "indices trick".
Definition: format.h:297
void resize(std::size_t new_size)
Definition: core.h:264
void write(std::basic_ostream< Char > &os, basic_buffer< Char > &buf)
Definition: ostream.h:76
#define FMT_END_NAMESPACE
Definition: core.h:153
std::basic_string< FMT_CHAR(S)> format(const S &format_str, const Args &... args)
Definition: core.h:1454
T * data() FMT_NOEXCEPT
Definition: core.h:256
buffer_context< Char >::type::iterator vformat_to(internal::basic_buffer< Char > &buf, basic_string_view< Char > format_str, basic_format_args< typename buffer_context< Char >::type > args)
Definition: format.h:3233
dummy_string_view to_string_view(...)
void vprint(std::basic_ostream< Char > &os, basic_string_view< Char > format_str, basic_format_args< typename buffer_context< Char >::type > args)
Definition: ostream.h:128
typedef FMT_CHAR(S) Char
std::size_t size() const FMT_NOEXCEPT
Definition: core.h:250
void push_back(const T &value)
Definition: core.h:278
basic_buffer< char > buffer
Definition: core.h:291
std::streamsize xsputn(const Char *s, std::streamsize count) FMT_OVERRIDE
Definition: ostream.h:42
std::enable_if< internal::is_string< S >::value >::type print(std::basic_ostream< FMT_CHAR(S)> &os, const S &format_str, const Args &... args)
Definition: ostream.h:146
FMT_CONSTEXPR std::make_unsigned< Int >::type to_unsigned(Int value)
Definition: core.h:208
int_type overflow(int_type ch=traits_type::eof()) FMT_OVERRIDE
Definition: ostream.h:36
void format_value(basic_buffer< Char > &buffer, const T &value)
Definition: ostream.h:91
formatbuf(basic_buffer< Char > &buffer)
Definition: ostream.h:26
#define FMT_OVERRIDE
Definition: core.h:88
std::size_t n
Definition: format.h:3399
const Args & args
Definition: core.h:1496
type
Definition: core.h:530