scnlib  0.1.2
FormattedinputformodernC++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
context.h
Go to the documentation of this file.
1 // Copyright 2017-2019 Elias Kosunen
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // This file is a part of scnlib:
16 // https://github.com/eliaskosunen/scnlib
17 
18 #ifndef SCN_DETAIL_CONTEXT_H
19 #define SCN_DETAIL_CONTEXT_H
20 
21 #include "args.h"
22 #include "locale.h"
23 #include "options.h"
24 
25 namespace scn {
27 
29  SCN_CLANG_IGNORE("-Wpadded")
30 
31  namespace detail {
32  template <typename LocaleRef, typename = void>
34  public:
35  context_locale_base(LocaleRef loc) : m_locale(std::move(loc)) {}
36 
37  SCN_CONSTEXPR14 LocaleRef& locale() noexcept
38  {
39  return m_locale;
40  }
41  SCN_CONSTEXPR const LocaleRef& locale() const noexcept
42  {
43  return m_locale;
44  }
45 
46  private:
47  LocaleRef m_locale;
48  };
49  template <typename ParseContext, typename = void>
51  public:
52  context_parse_context_base(ParseContext pctx)
53  : m_parse_ctx(std::move(pctx))
54  {
55  }
56 
57  SCN_CONSTEXPR14 ParseContext& parse_context() noexcept
58  {
59  return m_parse_ctx;
60  }
61  SCN_CONSTEXPR const ParseContext& parse_context() const noexcept
62  {
63  return m_parse_ctx;
64  }
65 
66  private:
67  ParseContext m_parse_ctx;
68  };
69  template <typename Options, typename = void>
71  public:
72  context_options_base(Options opt) : m_options(std::move(opt)) {}
73 
74  SCN_CONSTEXPR14 Options& get_options() noexcept
75  {
76  return m_options;
77  }
78  SCN_CONSTEXPR const Options& get_options() const noexcept
79  {
80  return m_options;
81  }
82 
83  SCN_CONSTEXPR method int_method() const noexcept
84  {
85  return m_options.template get_method_for<int>();
86  }
88  {
89  return m_options.template get_method_for<double>();
90  }
91 
92  private:
93  Options m_options;
94  };
95 
96  template <typename Stream,
97  typename FormatStringChar,
98  typename ParseContext,
99  typename Options,
100  typename LocaleRef>
101  class context_base : public context_locale_base<LocaleRef>,
102  public context_parse_context_base<ParseContext>,
103  public context_options_base<Options> {
104  public:
105  using stream_type = Stream;
107  using format_string_char_type = FormatStringChar;
108  using parse_context_type = ParseContext;
109  using options_type = Options;
110  using locale_type = LocaleRef;
111 
112  template <typename T>
114 
116  {
117  SCN_EXPECT(m_stream != nullptr);
118  return *m_stream;
119  }
120 
121  protected:
124  parse_context_type pctx,
125  locale_type loc,
126  options_type opt)
127  : context_locale_base<LocaleRef>(std::move(loc)),
128  context_parse_context_base<ParseContext>(std::move(pctx)),
129  context_options_base<Options>(std::move(opt)),
130  m_stream(std::addressof(s))
131  {
132  }
134 
135  private:
136  stream_type* m_stream;
137  };
138 
140  template <typename Stream,
141  typename ParseContext,
142  typename Locale,
143  typename Options>
145  : public detail::context_base<Stream,
146  typename Stream::char_type,
147  ParseContext,
148  Options,
149  Locale> {
150  using base = detail::context_base<Stream,
151  typename Stream::char_type,
152  ParseContext,
153  Options,
154  Locale>;
155 
156  public:
157  using stream_type = Stream;
161  using parse_context_type = ParseContext;
162  using locale_type = Locale;
165  using base::scanner_type;
166 
167  template <typename... Args>
169 
172  args_type args)
173  : base(s, std::move(p), locale_type{}, options_type{}),
174  m_args(std::move(args))
175  {
176  }
179  args_type args,
180  options_type opt)
181  : base(s,
182  std::move(p),
183  opt.template get_locale_ref<char_type>(),
184  std::move(opt)),
185  m_args(std::move(args))
186  {
187  }
188 
190  {
191  return this->do_get_arg(this->parse_context().next_arg_id());
192  }
194  {
195  return this->parse_context().check_arg_id(id) ? do_get_arg(id)
196  : arg_type();
197  }
198 
200  {
201  return arg_type{};
202  }
203 
204  private:
205  expected<arg_type> do_get_arg(size_t id)
206  {
207  auto a = this->m_args.get(id);
208  if (!a && !this->m_args.check_id(id - 1)) {
210  "Argument id out of range");
211  }
212  return a;
213  }
214 
215  args_type m_args;
216  //detail::arg_map<arg_context_base> m_map;
217  };
218  } // namespace detail
219 
220  template <typename Stream,
221  typename Locale =
222  basic_default_locale_ref<typename Stream::char_type>,
223  typename Options = default_options>
225  Stream,
226  basic_parse_context<typename Stream::char_type>,
227  Locale,
228  Options> {
230  Stream,
232  Locale,
233  Options>;
234 
235  public:
236  using stream_type = typename base::stream_type;
237  using char_type = typename base::char_type;
238  using args_type = typename base::args_type;
241 
244  args_type args)
245  : base(s, parse_context_type{f}, std::move(args))
246  {
247  }
250  args_type args,
251  options_type opt)
252  : base(s, parse_context_type{f}, std::move(args), std::move(opt))
253  {
254  }
255  };
256 
257  template <typename Stream,
258  typename Locale =
259  basic_default_locale_ref<typename Stream::char_type>,
260  typename Options = default_options>
262  : public detail::arg_context_base<
263  Stream,
264  basic_scanf_parse_context<typename Stream::char_type>,
265  Locale,
266  Options> {
268  Stream,
270  Locale,
271  Options>;
272 
273  public:
274  using stream_type = typename base::stream_type;
275  using char_type = typename base::char_type;
276  using args_type = typename base::args_type;
279 
282  args_type args)
283  : base(s, parse_context_type{f}, std::move(args))
284  {
285  }
288  args_type args,
289  options_type opt)
290  : base(s, parse_context_type{f}, std::move(args), std::move(opt))
291  {
292  }
293  };
294 
295  template <typename Stream,
296  typename Locale =
297  basic_default_locale_ref<typename Stream::char_type>,
298  typename Options = default_options>
300  : public detail::arg_context_base<
301  Stream,
302  basic_empty_parse_context<typename Stream::char_type>,
303  Locale,
304  Options> {
306  Stream,
308  Locale,
309  Options>;
310 
311  public:
312  using stream_type = typename base::stream_type;
313  using char_type = typename base::char_type;
314  using args_type = typename base::args_type;
317 
319  : base(s, parse_context_type{n_args}, std::move(args))
320  {
321  }
323  int n_args,
324  args_type args,
325  options_type opt)
326  : base(s,
327  parse_context_type{n_args},
328  std::move(args),
329  std::move(opt))
330  {
331  }
332  };
333 
335 
336  namespace detail {
337  template <typename CharT>
338  struct dummy_stream {
339  using char_type = CharT;
340  };
341  template <typename CharT>
342  struct dummy_context {
344  };
345 
346  template <typename CharT>
347  struct named_arg_base {
350  using storage_type =
351  typename std::aligned_storage<sizeof(arg_type),
352  alignof(arg_type)>::type;
353 
355 
356  template <typename Context>
358  {
359 #if SCN_GCC >= SCN_COMPILER(8, 0, 0)
361  SCN_GCC_IGNORE("-Wclass-memaccess")
362 #endif
364  std::memcpy(&arg, &data, sizeof(arg_type));
365  return arg;
366 #if SCN_GCC >= SCN_COMPILER(8, 0, 0)
368 #endif
369  }
370 
373  };
374 
375  template <typename T, typename CharT>
376  struct named_arg : named_arg_base<CharT> {
378 
380  : base(name), value(std::addressof(val))
381  {
382  }
383 
384  T* value;
385  };
386  } // namespace detail
387 
388  template <typename T>
390  {
391  return {name, std::addressof(arg)};
392  }
393  template <typename T>
395  {
396  return {name, std::addressof(arg)};
397  }
398 
399  template <typename S, typename T, typename Char>
400  void arg(S, detail::named_arg<T, Char>) = delete;
401 
403 } // namespace scn
404 
405 #endif // SCN_DETAIL_CONTEXT_H
typename base::options_type options_type
Definition: context.h:163
typename base::options_type options_type
Definition: context.h:239
SCN_CONSTEXPR method int_method() const noexcept
Definition: context.h:83
basic_empty_context(stream_type &s, int n_args, args_type args, options_type opt)
Definition: context.h:322
named_arg_base(basic_string_view< CharT > n)
Definition: context.h:354
basic_arg< context_type > arg_type
Definition: context.h:349
#define SCN_END_NAMESPACE
Definition: config.h:376
detail::named_arg< T, char > arg(string_view name, T &arg)
Definition: context.h:389
basic_scanf_context(stream_type &s, basic_string_view< char_type > f, args_type args, options_type opt)
Definition: context.h:286
basic_scanf_context(stream_type &s, basic_string_view< char_type > f, args_type args)
Definition: context.h:280
typename base::char_type char_type
Definition: context.h:313
basic_context(stream_type &s, basic_string_view< char_type > f, args_type args)
Definition: context.h:242
typename base::stream_type stream_type
Definition: context.h:312
context_parse_context_base(ParseContext pctx)
Definition: context.h:52
typename base::parse_context_type parse_context_type
Definition: context.h:278
SCN_CONSTEXPR const Options & get_options() const noexcept
Definition: context.h:78
SCN_CONSTEXPR const LocaleRef & locale() const noexcept
Definition: context.h:41
context_locale_base(LocaleRef loc)
Definition: context.h:35
SCN_CONSTEXPR14 LocaleRef & locale() noexcept
Definition: context.h:37
#define SCN_CLANG_IGNORE(x)
Definition: config.h:128
#define SCN_GCC_PUSH
Definition: config.h:103
typename std::aligned_storage< sizeof(arg_type), alignof(arg_type)>::type storage_type
Definition: context.h:352
SCN_CONSTEXPR14 ParseContext & parse_context() noexcept
Definition: context.h:57
expected-like type.
Definition: result.h:186
typename base::args_type args_type
Definition: context.h:238
typename base::args_type args_type
Definition: context.h:276
basic_string_view< CharT > name
Definition: context.h:371
typename base::options_type options_type
Definition: context.h:315
#define SCN_CLANG_POP
Definition: config.h:127
basic_empty_context(stream_type &s, int n_args, args_type args)
Definition: context.h:318
#define SCN_CLANG_POP_IGNORE_UNDEFINED_TEMPLATE
Definition: config.h:130
basic_args< arg_context_base > args_type
Definition: context.h:160
typename base::stream_type stream_type
Definition: context.h:274
typename base::options_type options_type
Definition: context.h:277
SCN_CONSTEXPR14 stream_type & stream() noexcept
Definition: context.h:115
typename stream_type::char_type char_type
Definition: context.h:158
Error class.
Definition: result.h:32
#define SCN_BEGIN_NAMESPACE
Definition: config.h:375
basic_context(stream_type &s, basic_string_view< char_type > f, args_type args, options_type opt)
Definition: context.h:248
context_options_base(Options opt)
Definition: context.h:72
Invalid argument given to operation.
Definition: result.h:51
arg_context_base(stream_type &s, parse_context_type p, args_type args)
Definition: context.h:170
#define SCN_GCC_POP
Definition: config.h:104
Scanning context.
Definition: context.h:144
expected< arg_type > arg(size_t id)
Definition: context.h:193
typename base::stream_type stream_type
Definition: context.h:236
typename dummy_context< CharT >::type context_type
Definition: context.h:348
ParseContext parse_context_type
Definition: context.h:161
arg_context_base(stream_type &s, parse_context_type p, args_type args, options_type opt)
Definition: context.h:177
#define SCN_CLANG_PUSH_IGNORE_UNDEFINED_TEMPLATE
Definition: config.h:129
named_arg(basic_string_view< CharT > name, T &val)
Definition: context.h:379
expected< arg_type > arg(basic_string_view< char_type >)
Definition: context.h:199
expected< arg_type > next_arg()
Definition: context.h:189
SCN_CLANG_PUSH_IGNORE_UNDEFINED_TEMPLATE context_base(stream_type &s, parse_context_type pctx, locale_type loc, options_type opt)
Definition: context.h:123
typename base::parse_context_type parse_context_type
Definition: context.h:240
#define SCN_CONSTEXPR
Definition: config.h:226
typename base::char_type char_type
Definition: context.h:237
basic_arg< Context > deserialize()
Definition: context.h:357
Type-erased scanning argument.
Definition: args.h:31
typename base::args_type args_type
Definition: context.h:314
method
Definition: options.h:36
SCN_CONSTEXPR method float_method() const noexcept
Definition: context.h:87
typename base::char_type char_type
Definition: context.h:275
typename base::parse_context_type parse_context_type
Definition: context.h:316
#define SCN_GCC_IGNORE(x)
Definition: config.h:105
#define SCN_EXPECT(cond)
Definition: config.h:371
#define SCN_CLANG_PUSH
Definition: config.h:126
SCN_CONSTEXPR const ParseContext & parse_context() const noexcept
Definition: context.h:61
#define SCN_CONSTEXPR14
Definition: config.h:227
SCN_CONSTEXPR14 Options & get_options() noexcept
Definition: context.h:74