bind.h
Go to the documentation of this file.
1 #ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_BIND_H_
2 #define ABSL_STRINGS_INTERNAL_STR_FORMAT_BIND_H_
3 
4 #include <array>
5 #include <cstdio>
6 #include <sstream>
7 #include <string>
8 
9 #include "absl/base/port.h"
14 #include "absl/types/span.h"
15 
16 namespace absl {
17 
18 class UntypedFormatSpec;
19 
20 namespace str_format_internal {
21 
23  public:
24  const FormatArgImpl* arg() const { return arg_; }
25  void set_arg(const FormatArgImpl* a) { arg_ = a; }
26 
27  private:
29 };
30 
31 // This is the type-erased class that the implementation uses.
33  public:
34  UntypedFormatSpecImpl() = delete;
35 
37  : data_(s.data()), size_(s.size()) {}
40  : data_(pc), size_(~size_t{}) {}
41 
42  bool has_parsed_conversion() const { return size_ == ~size_t{}; }
43 
44  string_view str() const {
45  assert(!has_parsed_conversion());
46  return string_view(static_cast<const char*>(data_), size_);
47  }
49  assert(has_parsed_conversion());
50  return static_cast<const str_format_internal::ParsedFormatBase*>(data_);
51  }
52 
53  template <typename T>
54  static const UntypedFormatSpecImpl& Extract(const T& s) {
55  return s.spec_;
56  }
57 
58  private:
59  const void* data_;
60  size_t size_;
61 };
62 
63 template <typename T, typename...>
64 struct MakeDependent {
65  using type = T;
66 };
67 
68 // Implicitly convertible from `const char*`, `string_view`, and the
69 // `ExtendedParsedFormat` type. This abstraction allows all format functions to
70 // operate on any without providing too many overloads.
71 template <typename... Args>
73  : public MakeDependent<UntypedFormatSpec, Args...>::type {
74  using Base = typename MakeDependent<UntypedFormatSpec, Args...>::type;
75 
76  public:
77 #if ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
78 
79  // Honeypot overload for when the std::string is not constexpr.
80  // We use the 'unavailable' attribute to give a better compiler error than
81  // just 'method is deleted'.
82  FormatSpecTemplate(...) // NOLINT
83  __attribute__((unavailable("Format std::string is not constexpr.")));
84 
85  // Honeypot overload for when the format is constexpr and invalid.
86  // We use the 'unavailable' attribute to give a better compiler error than
87  // just 'method is deleted'.
88  // To avoid checking the format twice, we just check that the format is
89  // constexpr. If is it valid, then the overload below will kick in.
90  // We add the template here to make this overload have lower priority.
91  template <typename = void>
92  FormatSpecTemplate(const char* s) // NOLINT
93  __attribute__((
94  enable_if(str_format_internal::EnsureConstexpr(s), "constexpr trap"),
95  unavailable(
96  "Format specified does not match the arguments passed.")));
97 
98  template <typename T = void>
99  FormatSpecTemplate(string_view s) // NOLINT
100  __attribute__((enable_if(str_format_internal::EnsureConstexpr(s),
101  "constexpr trap"))) {
102  static_assert(sizeof(T*) == 0,
103  "Format specified does not match the arguments passed.");
104  }
105 
106  // Good format overload.
107  FormatSpecTemplate(const char* s) // NOLINT
108  __attribute__((enable_if(ValidFormatImpl<ArgumentToConv<Args>()...>(s),
109  "bad format trap")))
110  : Base(s) {}
111 
112  FormatSpecTemplate(string_view s) // NOLINT
113  __attribute__((enable_if(ValidFormatImpl<ArgumentToConv<Args>()...>(s),
114  "bad format trap")))
115  : Base(s) {}
116 
117 #else // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
118 
119  FormatSpecTemplate(const char* s) : Base(s) {} // NOLINT
120  FormatSpecTemplate(string_view s) : Base(s) {} // NOLINT
121 
122 #endif // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
123 
124  template <Conv... C, typename = typename std::enable_if<
125  sizeof...(C) == sizeof...(Args) &&
126  AllOf(Contains(ArgumentToConv<Args>(),
127  C)...)>::type>
129  : Base(&pc) {}
130 };
131 
132 template <typename... Args>
134  using type = FormatSpecTemplate<Args...>;
135 };
136 
137 class Streamable {
138  public:
141  : format_(format), args_(args.begin(), args.end()) {}
142 
143  std::ostream& Print(std::ostream& os) const;
144 
145  friend std::ostream& operator<<(std::ostream& os, const Streamable& l) {
146  return l.Print(os);
147  }
148 
149  private:
152 };
153 
154 // for testing
157 bool BindWithPack(const UnboundConversion* props,
159 
160 bool FormatUntyped(FormatRawSinkImpl raw_sink,
163 
166 
170  AppendPack(&out, format, args);
171  return out;
172 }
173 
174 int FprintF(std::FILE* output, UntypedFormatSpecImpl format,
176 int SnprintF(char* output, size_t size, UntypedFormatSpecImpl format,
178 
179 // Returned by Streamed(v). Converts via '%s' to the std::string created
180 // by std::ostream << v.
181 template <typename T>
182 class StreamedWrapper {
183  public:
184  explicit StreamedWrapper(const T& v) : v_(v) { }
185 
186  private:
187  template <typename S>
191  const T& v_;
192 };
193 
194 } // namespace str_format_internal
195 } // namespace absl
196 
197 #endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_BIND_H_
int v
Definition: variant_test.cc:81
int FprintF(std::FILE *output, const UntypedFormatSpecImpl format, absl::Span< const FormatArgImpl > args)
Definition: bind.cc:199
char * begin
friend std::ostream & operator<<(std::ostream &os, const Streamable &l)
Definition: bind.h:145
UntypedFormatSpecImpl(const str_format_internal::ParsedFormatBase *pc)
Definition: bind.h:38
void set_arg(const FormatArgImpl *a)
Definition: bind.h:25
const UntypedFormatSpecImpl & format_
Definition: bind.h:150
absl::InlinedVector< FormatArgImpl, 4 > args_
Definition: bind.h:151
std::string Summarize(const UntypedFormatSpecImpl format, absl::Span< const FormatArgImpl > args)
Definition: bind.cc:162
char * end
std::vector< std::string > args_
Definition: parse.cc:130
Definition: algorithm.h:29
const FormatArgImpl * arg() const
Definition: bind.h:24
const FormatArgImpl * arg_
Definition: bind.h:28
const str_format_internal::ParsedFormatBase * parsed_conversion() const
Definition: bind.h:48
const char * data_
Definition: test_util.cc:98
bool Format(FormatRawSink raw_sink, const FormatSpec< Args... > &format, const Args &... args)
Definition: str_format.h:454
int SnprintF(char *output, size_t size, const UntypedFormatSpecImpl format, absl::Span< const FormatArgImpl > args)
Definition: bind.cc:217
static char data[kDataSize]
Definition: city_test.cc:31
std::string format(const std::string &, const time_point< seconds > &, const femtoseconds &, const time_zone &)
typename MakeDependent< UntypedFormatSpec, Args... >::type Base
Definition: bind.h:74
bool BindWithPack(const UnboundConversion *props, absl::Span< const FormatArgImpl > pack, BoundConversion *bound)
Definition: bind.cc:156
ConvertResult< Conv::s > FormatConvertImpl(const std::string &v, const ConversionSpec conv, FormatSinkImpl *sink)
Definition: arg.cc:255
static const UntypedFormatSpecImpl & Extract(const T &s)
Definition: bind.h:54
uintptr_t size
bool FormatUntyped(FormatRawSinkImpl raw_sink, const UntypedFormatSpecImpl format, absl::Span< const FormatArgImpl > args)
Definition: bind.cc:177
constexpr bool Contains(Conv set, char c)
Definition: extension.h:381
constexpr bool AllOf()
Definition: checker.h:20
constexpr bool EnsureConstexpr(string_view s)
Definition: parser.h:173
std::string & AppendPack(std::string *out, const UntypedFormatSpecImpl format, absl::Span< const FormatArgImpl > args)
Definition: bind.cc:190
std::string FormatPack(const UntypedFormatSpecImpl format, absl::Span< const FormatArgImpl > args)
Definition: bind.h:167
int size_
Definition: arg.cc:107
FormatSpecTemplate(const ExtendedParsedFormat< C... > &pc)
Definition: bind.h:128
std::ostream & Print(std::ostream &os) const
Definition: bind.cc:185
char * out
Definition: mutex.h:1013
Streamable(const UntypedFormatSpecImpl &format, absl::Span< const FormatArgImpl > args)
Definition: bind.h:139
#define C(x)
Definition: city_test.cc:47


abseil_cpp
Author(s):
autogenerated on Mon Feb 28 2022 21:31:17