source: trunk/GDE/SINA/builddir/include/spdlog/fmt/bundled/ostream.h

Last change on this file was 19170, checked in by westram, 2 years ago
  • sina source
    • unpack + remove tarball
    • no longer ignore sina builddir.
File size: 4.7 KB
Line 
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
14FMT_BEGIN_NAMESPACE
15namespace internal {
16
17template <class Char>
18class 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
48template <typename Char>
49struct 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).
57template <typename T, typename Char>
58class is_streamable {
59 private:
60  template <typename U>
61  static decltype(
62    internal::declval<test_stream<Char>&>()
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.
75template <typename Char>
76void 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
90template <typename Char, typename T>
91void format_value(basic_buffer<Char> &buffer, const T &value) {
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).
102template <typename T, typename Char>
103struct convert_to_int<T, Char, void> {
104  static const bool value =
105    convert_to_int<T, Char, int>::value &&
106    !internal::is_streamable<T, Char>::value;
107};
108
109// Formats an object of type T that has an overloaded ostream operator<<.
110template <typename T, typename Char>
111struct 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()) {
120    basic_memory_buffer<Char> buffer;
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
127template <typename Char>
128inline void vprint(std::basic_ostream<Char> &os,
129                   basic_string_view<Char> format_str,
130                   basic_format_args<typename buffer_context<Char>::type> args) {
131  basic_memory_buffer<Char> buffer;
132  internal::vformat_to(buffer, format_str, args);
133  internal::write(os, buffer);
134}
135/**
136  \rst
137  Prints formatted data to the stream *os*.
138
139  **Example**::
140
141    fmt::print(cerr, "Don't {}!", "panic");
142  \endrst
143 */
144template <typename S, typename... Args>
145inline typename std::enable_if<internal::is_string<S>::value>::type
146print(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}
151FMT_END_NAMESPACE
152
153#endif  // FMT_OSTREAM_H_
Note: See TracBrowser for help on using the repository browser.