rapidyaml  0.13.0
parse and emit YAML, and do it fast
common.hpp
Go to the documentation of this file.
1 #ifndef _C4_YML_COMMON_HPP_
2 #define _C4_YML_COMMON_HPP_
3 
4 /** @file common.hpp Common utilities and infrastructure used by ryml. */
5 
6 #include <cstddef>
7 #include <c4/substr.hpp>
8 #include <c4/charconv.hpp>
9 #include <c4/yml/export.hpp>
10 
11 
12 //-----------------------------------------------------------------------------
13 
14 #ifndef RYML_DEFAULT_TREE_CAPACITY
15 /// default capacity for the tree when not set explicitly
16 #define RYML_DEFAULT_TREE_CAPACITY (16)
17 #endif
18 
19 #ifndef RYML_DEFAULT_TREE_ARENA_CAPACITY
20 /// default capacity for the tree's arena when not set explicitly
21 #define RYML_DEFAULT_TREE_ARENA_CAPACITY (0)
22 #endif
23 
24 
25 #ifndef RYML_LOCATIONS_SMALL_THRESHOLD
26 /// threshold at which a location search will revert from linear to
27 /// binary search.
28 #define RYML_LOCATIONS_SMALL_THRESHOLD (30)
29 #endif
30 
31 
32 #ifndef RYML_ERRMSG_SIZE
33 /// size for the error message buffer
34 #define RYML_ERRMSG_SIZE (1024)
35 #endif
36 
37 
38 #ifndef RYML_LOGBUF_SIZE
39 /// size for the buffer used to format individual values to string
40 /// while preparing an error message. This is only used for formatting
41 /// individual values in the message; final messages will be larger
42 /// than this value (see @ref RYML_ERRMSG_SIZE). This is also used for
43 /// the detailed debug log messages when RYML_DBG is defined.
44 #define RYML_LOGBUF_SIZE (256)
45 #endif
46 
47 
48 #ifndef RYML_LOGBUF_SIZE
49 /// size for the buffer used to format individual values to string
50 /// while preparing an error message. This is only used for formatting
51 /// individual values in the message; final messages will be larger
52 /// than this value (see @ref RYML_ERRMSG_SIZE). This size is also
53 /// used for the detailed debug log messages when RYML_DBG is defined.
54 #define RYML_LOGBUF_SIZE (256)
55 #endif
56 static_assert(RYML_LOGBUF_SIZE < RYML_ERRMSG_SIZE, "invalid size");
57 
58 
59 #ifndef RYML_LOGBUF_SIZE_MAX
60 /// size for the fallback larger log buffer. When @ref
61 /// RYML_LOGBUF_SIZE is not large enough to convert a value to string,
62 /// then temporary stack memory is allocated up to
63 /// RYML_LOGBUF_SIZE_MAX. This limit is in place to prevent a stack
64 /// overflow. If the printed value requires more than
65 /// RYML_LOGBUF_SIZE_MAX, the value is silently skipped.
66 #define RYML_LOGBUF_SIZE_MAX (1024)
67 #endif
68 
69 
70 //-----------------------------------------------------------------------------
71 // Specify groups to have a predefined topic order in doxygen:
72 
73 /** @defgroup doc_quickstart Quickstart
74  *
75  * Example code for every feature.
76  */
77 
78 /** @defgroup doc_parse Parse utilities
79  * @see sample::sample_parse_in_place
80  * @see sample::sample_parse_in_arena
81  * @see sample::sample_parse_file
82  * @see sample::sample_parse_reuse_tree
83  * @see sample::sample_parse_reuse_parser
84  * @see sample::sample_parse_reuse_tree_and_parser
85  * @see sample::sample_location_tracking
86  */
87 
88 /** @defgroup doc_emit Emit utilities
89  *
90  * Utilities to emit YAML and JSON, either to a memory buffer or to a
91  * file or ostream-like class.
92  *
93  * @see sample::sample_emit_to_container
94  * @see sample::sample_emit_to_stream
95  * @see sample::sample_emit_to_file
96  * @see sample::sample_emit_nested_node
97  * @see sample::sample_emit_style
98  */
99 
100 /** @defgroup doc_node_type Node types
101  */
102 
103 /** @defgroup doc_tree Tree utilities
104  * @see sample::sample_quick_overview
105  * @see sample::sample_iterate_trees
106  * @see sample::sample_create_trees
107  * @see sample::sample_tree_arena
108  *
109  * @see sample::sample_static_trees
110  * @see sample::sample_location_tracking
111  *
112  * @see sample::sample_docs
113  * @see sample::sample_anchors_and_aliases
114  * @see sample::sample_tags
115  */
116 
117 /** @defgroup doc_node_classes Node classes
118  *
119  * High-level node classes.
120  *
121  * @see sample::sample_quick_overview
122  * @see sample::sample_iterate_trees
123  * @see sample::sample_create_trees
124  * @see sample::sample_tree_arena
125  */
126 
127 /** @defgroup doc_error_handling Error handling
128  *
129  * Utilities to report handle errors, and to build and report error
130  * messages.
131  *
132  * @see sample::sample_error_handler
133  */
134 
135 /** @defgroup doc_callbacks Callbacks for errors and allocation
136  *
137  * Functions called by ryml to allocate/free memory and to report
138  * errors.
139  *
140  * @see sample::sample_error_handler
141  * @see sample::sample_global_allocator
142  * @see sample::sample_per_tree_allocator
143  */
144 
145 /** @defgroup doc_serialization Serialization/deserialization
146  *
147  * Contains information on how to serialize and deserialize
148  * fundamental types, user scalar types, user container types and
149  * interop with std scalar/container types.
150  *
151  */
152 
153 /** @defgroup doc_ref_utils Anchor/Reference utilities
154  *
155  * @see sample::sample_anchors_and_aliases
156  * */
157 
158 /** @defgroup doc_tag_utils Tag utilities
159  * @see sample::sample_tags
160  */
161 
162 /** @defgroup doc_preprocessors Preprocessors
163  *
164  * Functions for preprocessing YAML prior to parsing.
165  */
166 
167 
168 //-----------------------------------------------------------------------------
169 
170 // document macros for doxygen
171 #ifdef __DOXYGEN__ // defined in Doxyfile::PREDEFINED
172 
173 /** define this macro with a boolean value to enable/disable
174  * assertions to check preconditions and assumptions throughout the
175  * codebase; this causes a slowdown of the code, and larger code
176  * size. By default, this macro is defined unless NDEBUG is defined
177  * (see C4_USE_ASSERT); as a result, by default this macro is truthy
178  * only in debug builds. */
179 # define RYML_USE_ASSERT
180 
181 /** (Undefined by default) Define this macro to disable ryml's default
182  * implementation of the callback functions. See @ref doc_callbacks. */
183 # define RYML_NO_DEFAULT_CALLBACKS
184 
185 /** (Undefined by default) When this macro is defined (and
186  * @ref RYML_NO_DEFAULT_CALLBACKS is not defined), the default error
187  * handler will throw exceptions. See @ref doc_error_handling. */
188 # define RYML_DEFAULT_CALLBACK_USES_EXCEPTIONS
189 
190 /** Conditionally expands to `noexcept` when @ref RYML_USE_ASSERT is 0 and
191  * is empty otherwise. The user is unable to override this macro. */
192 # define RYML_NOEXCEPT
193 
194 /** (Undefined by default) Use shorter error message from
195  * checks/asserts: do not show the check condition in the error
196  * message. */
197 # defined RYML_SHORT_CHECK_MSG
198 
199 #endif
200 
201 
202 //-----------------------------------------------------------------------------
203 
204 /** @cond dev */
205 
206 #ifndef RYML_USE_ASSERT
207 # define RYML_USE_ASSERT C4_USE_ASSERT
208 #endif
209 
210 #if RYML_USE_ASSERT
211 # define RYML_NOEXCEPT
212 #else
213 # define RYML_NOEXCEPT noexcept
214 #endif
215 
216 #define RYML_DEPRECATED(msg) C4_DEPRECATED(msg)
217 
218 /** @endcond */
219 
220 
221 //-----------------------------------------------------------------------------
222 //-----------------------------------------------------------------------------
223 //-----------------------------------------------------------------------------
224 
225 namespace c4 {
226 namespace yml {
227 
228 C4_SUPPRESS_WARNING_GCC_CLANG_WITH_PUSH("-Wold-style-cast")
229 
230 class Tree;
231 
232 
233 #ifndef RYML_ID_TYPE
234 /** The type of a node id in the YAML tree. In the future, the default
235  * will likely change to int32_t, which was observed to be faster.
236  * @see id_type */
237 #define RYML_ID_TYPE size_t
238 #endif
239 
240 
241 /** The type of a node id in the YAML tree; to override the default
242  * type, define the macro @ref RYML_ID_TYPE to a suitable integer
243  * type. */
245 static_assert(std::is_integral<id_type>::value, "id_type must be an integer type");
246 
247 
248 C4_SUPPRESS_WARNING_GCC_WITH_PUSH("-Wuseless-cast")
249 enum : id_type { // NOLINT
250  /** an index to none */
251  NONE = id_type(-1), // NOLINT
252 };
253 C4_SUPPRESS_WARNING_GCC_CLANG_POP
254 
255 
256 enum : size_t { // NOLINT
257  /** a null string position */
258  npos = size_t(-1) // NOLINT
259 };
260 
261 
262 typedef enum Encoding_ { // NOLINT
263  NOBOM, //!< No Byte Order Mark was found
264  UTF8, //!< UTF8
265  UTF16LE, //!< UTF16, Little-Endian
266  UTF16BE, //!< UTF16, Big-Endian
267  UTF32LE, //!< UTF32, Little-Endian
268  UTF32BE, //!< UTF32, Big-Endian
270 
271 
272 //-----------------------------------------------------------------------------
273 //-----------------------------------------------------------------------------
274 //-----------------------------------------------------------------------------
275 
276 C4_SUPPRESS_WARNING_MSVC_WITH_PUSH(4251) // csubstr needs to have dll-interface to be used by clients of Location
277 
278 /** holds a source or yaml file position, for example when an error is
279  * detected; See also @ref location_format() and @ref
280  * location_format_with_context().
281  *
282  * @ingroup doc_error_handling */
284 {
285  size_t offset; ///< number of bytes from the beginning of the source buffer
286  size_t line; ///< line
287  size_t col; ///< column
288  csubstr name; ///< name of the file
289 
290  operator bool () const noexcept { return !name.empty() || line != npos || offset != npos || col != npos; }
291 
292  C4_NO_INLINE Location() noexcept : offset(npos), line(npos), col(npos), name() {};
293  C4_NO_INLINE Location( size_t l ) noexcept : offset(npos), line(l), col(npos), name() {}
294  C4_NO_INLINE Location( size_t l, size_t c) noexcept : offset(npos), line(l), col(c ), name() {}
295  C4_NO_INLINE Location( size_t b, size_t l, size_t c) noexcept : offset(b ), line(l), col(c ), name() {}
296  C4_NO_INLINE Location( csubstr n, size_t l ) noexcept : offset(npos), line(l), col(npos), name(n) {}
297  C4_NO_INLINE Location( csubstr n, size_t l, size_t c) noexcept : offset(npos), line(l), col(c ), name(n) {}
298  C4_NO_INLINE Location( csubstr n, size_t b, size_t l, size_t c) noexcept : offset(b ), line(l), col(c ), name(n) {}
299  C4_NO_INLINE Location(const char *n, size_t l ) noexcept : offset(npos), line(l), col(npos), name(to_csubstr(n)) {}
300  C4_NO_INLINE Location(const char *n, size_t l, size_t c) noexcept : offset(npos), line(l), col(c ), name(to_csubstr(n)) {}
301  C4_NO_INLINE Location(const char *n, size_t b, size_t l, size_t c) noexcept : offset(b ), line(l), col(c ), name(to_csubstr(n)) {}
302 };
303 static_assert(std::is_standard_layout<Location>::value, "Location not trivial");
304 
305 C4_SUPPRESS_WARNING_MSVC_POP
306 
307 /// @cond dev
308 #define RYML_LOC_HERE() (::c4::yml::Location(__FILE__, static_cast<size_t>(__LINE__)))
309 /// @endcond
310 
311 
312 /** Data for a basic error.
313  * @ingroup doc_error_handling */
315 {
316  Location location; ///< location where the error was detected (may be from YAML or C++ source code)
317  ErrorDataBasic() noexcept = default;
318  ErrorDataBasic(Location const& cpploc_) noexcept : location(cpploc_) {}
319 };
320 
321 /** Data for a parse error.
322  * @ingroup doc_error_handling */
324 {
325  Location cpploc; ///< location in the C++ source file where the error was detected.
326  Location ymlloc; ///< location in the YAML source buffer where the error was detected.
327  ErrorDataParse() noexcept = default;
328  ErrorDataParse(Location const& cpploc_, Location const& ymlloc_) noexcept : cpploc(cpploc_), ymlloc(ymlloc_) {}
329 };
330 
331 /** Data for a visit error.
332  * @ingroup doc_error_handling */
334 {
335  Location cpploc; ///< location in the C++ source file where the error was detected.
336  Tree const* tree; ///< tree where the error was detected
337  id_type node; ///< node where the error was detected
338  ErrorDataVisit() noexcept = default;
339  ErrorDataVisit(Location const& cpploc_, Tree const *tree_ , id_type node_) noexcept : cpploc(cpploc_), tree(tree_), node(node_) {}
340 };
341 
342 
343 
344 //-----------------------------------------------------------------------------
345 //-----------------------------------------------------------------------------
346 //-----------------------------------------------------------------------------
347 
348 /** Options to give to the parser to control its behavior. */
350 {
351 private:
352 
353  typedef enum : uint32_t { // NOLINT
354  DETECT_FLOW_ML = (1u << 0u),
355  RESOLVE_TAGS = (1u << 1u),
356  RESOLVE_TAGS_ALL = (1u << 2u),
357  SCALAR_FILTERING = (1u << 3u),
358  LOCATIONS = (1u << 4u),
359  DEFAULTS = SCALAR_FILTERING|DETECT_FLOW_ML,
360  } Flags_e;
361 
362  uint32_t flags = DEFAULTS;
363 
364  ParserOptions& set_flags_(bool enabled, Flags_e f)
365  {
366  if(enabled)
367  flags |= f;
368  else
369  flags &= ~f;
370  return *this;
371  }
372 
373 public:
374 
375  ParserOptions() = default;
376 
377 public:
378 
379  /** @name detection of @ref FLOW_ML container style */
380  /** @{ */
381 
382  /** enable/disable detection of @ref FLOW_ML container style. When
383  * enabled, the parser will set @ref FLOW_ML as the style of flow
384  * containers which have the terminating bracket on a line
385  * different from that of the opening bracket. */
386  ParserOptions& detect_flow_ml(bool enabled) noexcept
387  {
388  return set_flags_(enabled, DETECT_FLOW_ML);
389  }
390  /** query status of detection of @ref FLOW_ML container style. */
391  C4_ALWAYS_INLINE bool detect_flow_ml() const noexcept { return (flags & DETECT_FLOW_ML); }
392 
393  /** @} */
394 
395 public:
396 
397  /** @name resolution of tags */
398  /** @{ */
399 
400  /** enable/disable resolution of YAML tags during parsing. When
401  * enabled, tags are resolved according to existing tag
402  * directives. Disabled by default. See also @ref
403  * ParserOptions::resolve_tags_all(). */
404  ParserOptions& resolve_tags(bool enabled) noexcept
405  {
406  return set_flags_(enabled, RESOLVE_TAGS);
407  }
408  /** query status of tag resolution setting. */
409  C4_ALWAYS_INLINE bool resolve_tags() const noexcept { return (flags & RESOLVE_TAGS); }
410 
411  /** When resolve_tags() is enabled, resolve not just prefixed tags
412  * of the form <pre>!handle!tag</pre>, but also non-prefixed tags
413  * (<pre>!!tag</pre> and <pre>!tag!</pre>). Disabled by default. */
414  ParserOptions& resolve_tags_all(bool enabled) noexcept
415  {
416  return set_flags_(enabled, RESOLVE_TAGS_ALL);
417  }
418  /** query status of non-prefixed tag resolution setting. */
419  C4_ALWAYS_INLINE bool resolve_tags_all() const noexcept { return (flags & RESOLVE_TAGS_ALL); }
420 
421  /** @} */
422 
423 public:
424 
425  /** @name source location tracking */
426  /** @{ */
427 
428  /** enable/disable source location tracking */
429  ParserOptions& locations(bool enabled) noexcept
430  {
431  return set_flags_(enabled, LOCATIONS);
432  }
433  /** query source location tracking status */
434  C4_ALWAYS_INLINE bool locations() const noexcept { return (flags & LOCATIONS); }
435 
436  /** @} */
437 
438 public:
439 
440  /** @name scalar filtering status (experimental; disable at your discretion) */
441  /** @{ */
442 
443  /** enable/disable scalar filtering while parsing */
444  ParserOptions& scalar_filtering(bool enabled) noexcept
445  {
446  return set_flags_(enabled, SCALAR_FILTERING);
447  }
448  /** query scalar filtering status */
449  C4_ALWAYS_INLINE bool scalar_filtering() const noexcept { return (flags & SCALAR_FILTERING); }
450 
451  /** @} */
452 };
453 
454 
455 //-----------------------------------------------------------------------------
456 
457 /** @addtogroup doc_callbacks
458  *
459  * @{ */
460 
461 struct Callbacks;
462 
463 
464 /** set the global callbacks for the library; after a call to this
465  * function, these callbacks will be used by newly created objects
466  * (unless they are copying older objects with different
467  * callbacks). If @ref RYML_NO_DEFAULT_CALLBACKS is defined, it is
468  * mandatory to call this function prior to using any other library
469  * facility.
470  *
471  * @warning This function is NOT thread-safe, because it sets global static data
472  * */
473 RYML_EXPORT void set_callbacks(Callbacks const& c);
474 
475 /** get the global callbacks
476  *
477  * @warning This function is NOT thread-safe, because it reads global static data
478  * */
479 RYML_EXPORT Callbacks const& get_callbacks();
480 
481 /** set the global callbacks back to their defaults.
482  *
483  * @warning This function is NOT thread-safe, because it sets global static data
484  * */
486 
487 
488 /** the type of the function used to allocate memory; ryml will only
489  * allocate memory through this callback. */
490 using pfn_allocate = void* (*)(size_t len, void* hint, void *user_data);
491 
492 
493 /** the type of the function used to free memory; ryml will only free
494  * memory through this callback. */
495 using pfn_free = void (*)(void* mem, size_t size, void *user_data);
496 
497 
498 /** the type of the function used to report basic errors.
499  *
500  * @warning Must not return. When implemented by the user, this
501  * function MUST interrupt execution (and ideally be marked with
502  * `[[noreturn]]`). If the function returned, the caller could enter
503  * into an infinite loop, or the program may crash. It is up to the
504  * user to choose the interruption mechanism; typically by either
505  * throwing an exception, or using `std::longjmp()` ([see
506  * documentation](https://en.cppreference.com/w/cpp/utility/program/setjmp))
507  * or ultimately by calling `std::abort()`. */
508 using pfn_error_basic = void (*) (csubstr msg, ErrorDataBasic const& errdata, void *user_data);
509 /** the type of the function used to report parse errors.
510  *
511  * @warning Must not return. When implemented by the user, this
512  * function MUST interrupt execution (and ideally be marked with
513  * `[[noreturn]]`). If the function returned, the caller could enter
514  * into an infinite loop, or the program may crash. It is up to the
515  * user to choose the interruption mechanism; typically by either
516  * throwing an exception, or using `std::longjmp()` ([see
517  * documentation](https://en.cppreference.com/w/cpp/utility/program/setjmp))
518  * or ultimately by calling `std::abort()`. */
519 using pfn_error_parse = void (*) (csubstr msg, ErrorDataParse const& errdata, void *user_data);
520 /** the type of the function used to report visit errors.
521  *
522  * @warning Must not return. When implemented by the user, this
523  * function MUST interrupt execution (and ideally be marked with
524  * `[[noreturn]]`). If the function returned, the caller could enter
525  * into an infinite loop, or the program may crash. It is up to the
526  * user to choose the interruption mechanism; typically by either
527  * throwing an exception, or using `std::longjmp()` ([see
528  * documentation](https://en.cppreference.com/w/cpp/utility/program/setjmp))
529  * or ultimately by calling `std::abort()`. */
530 using pfn_error_visit = void (*) (csubstr msg, ErrorDataVisit const& errdata, void *user_data);
531 
532 /// @cond dev
533 using pfn_error RYML_DEPRECATED("use a more specific error type: `basic`, `parse` or `visit`") = void (*) (const char* msg, size_t msg_len, Location const& cpploc, void *user_data);
534 /// @endcond
535 
536 
537 /** A c-style callbacks class to customize behavior on errors or
538  * allocation. Can be used globally by the library and/or locally by
539  * @ref Tree and @ref Parser objects. */
541 {
542  void * m_user_data; ///< data to be forwarded in every call to a callback
543  pfn_allocate m_allocate; ///< a pointer to an allocate handler function
544  pfn_free m_free; ///< a pointer to a free handler function
545  pfn_error_basic m_error_basic; ///< a pointer to a basic error handler function
546  pfn_error_parse m_error_parse; ///< a pointer to a parse error handler function
547  pfn_error_visit m_error_visit; ///< a pointer to a visit error handler function
548 
549 public:
550 
551  /** Construct an object with the default callbacks. If
552  * @ref RYML_NO_DEFAULT_CALLBACKS is defined, the object will be set with null
553  * members.*/
554  Callbacks() noexcept;
555 
556  RYML_DEPRECATED("use the default constructor, followed by the appropriate setters")
557  Callbacks(void *user_data, pfn_allocate alloc, pfn_free free, pfn_error_basic error_basic);
558 
559 public:
560 
561  /** Set the user data. */
562  Callbacks& set_user_data(void* user_data);
563 
564  /** Set or reset the allocate callback. When the parameter is
565  * null, m_allocate will fall back to ryml's default allocate
566  * implementation, unless @ref RYML_NO_DEFAULT_CALLBACKS is
567  * defined. */
568  Callbacks& set_allocate(pfn_allocate allocate=nullptr);
569 
570  /** Set or reset the free callback. When the parameter is null,
571  * m_free will fall back to ryml's default free implementation,
572  * unless @ref RYML_NO_DEFAULT_CALLBACKS is defined. */
573  Callbacks& set_free(pfn_free free=nullptr);
574 
575  /** Set or reset the error_basic callback. When the parameter is null,
576  * m_error_basic will fall back to ryml's default error_basic implementation,
577  * unless @ref RYML_NO_DEFAULT_CALLBACKS is defined. */
578  Callbacks& set_error_basic(pfn_error_basic error_basic=nullptr);
579 
580  /** Set or reset the error_parse callback. When the parameter is null,
581  * m_error_parse will fall back to ryml's default error_parse implementation,
582  * unless @ref RYML_NO_DEFAULT_CALLBACKS is defined. */
583  Callbacks& set_error_parse(pfn_error_parse error_parse=nullptr);
584 
585  /** Set or reset the error_visit callback. When the parameter is null,
586  * m_error_visit will fall back to ryml's default error_visit implementation,
587  * unless @ref RYML_NO_DEFAULT_CALLBACKS is defined. */
588  Callbacks& set_error_visit(pfn_error_visit error_visit=nullptr);
589 
590 public:
591 
592  bool operator!= (Callbacks const& that) const { return !operator==(that); }
593  bool operator== (Callbacks const& that) const
594  {
595  return (m_user_data == that.m_user_data &&
596  m_allocate == that.m_allocate &&
597  m_free == that.m_free &&
598  m_error_basic == that.m_error_basic &&
599  m_error_parse == that.m_error_parse &&
600  m_error_visit == that.m_error_visit);
601  }
602 };
603 
604 
605 /** @} */
606 
607 
608 //-----------------------------------------------------------------------------
609 //-----------------------------------------------------------------------------
610 //-----------------------------------------------------------------------------
611 
612 /// @cond dev
613 
614 #define _RYML_CB_ALLOC_HINT(cb, T, num, hint) (T*) (cb).m_allocate((num) * sizeof(T), (hint), (cb).m_user_data)
615 #define _RYML_CB_ALLOC(cb, T, num) _RYML_CB_ALLOC_HINT((cb), T, (num), nullptr)
616 #define _RYML_CB_FREE(cb, buf, T, num) \
617  do { \
618  (cb).m_free((buf), (num) * sizeof(T), (cb).m_user_data); \
619  (buf) = nullptr; \
620  } while(false)
621 
622 namespace detail {
623 template<int8_t signedval, uint8_t unsignedval>
624 struct _charconstant_t // is there a better way to do this?
625  : public std::conditional<std::is_signed<char>::value,
626  std::integral_constant<int8_t, static_cast<int8_t>(unsignedval)>,
627  std::integral_constant<uint8_t, unsignedval>>::type
628 {};
629 #define _RYML_CHCONST(signedval, unsignedval) ::c4::yml::detail::_charconstant_t<INT8_C(signedval), UINT8_C(unsignedval)>::value
630 } // namespace detail
631 
632 inline csubstr _c4prc(const char &C4_RESTRICT c) // pass by reference!
633 {
634  switch(c)
635  {
636  case '\n': return csubstr("\\n");
637  case '\t': return csubstr("\\t");
638  case '\0': return csubstr("\\0");
639  case '\r': return csubstr("\\r");
640  case '\f': return csubstr("\\f");
641  case '\b': return csubstr("\\b");
642  case '\v': return csubstr("\\v");
643  case '\a': return csubstr("\\a");
644  default: return csubstr(&c, 1);
645  }
646 }
647 
648 /// @endcond
649 
650 C4_SUPPRESS_WARNING_GCC_POP
651 
652 } // namespace yml
653 } // namespace c4
654 
655 #endif /* _C4_YML_COMMON_HPP_ */
Lightweight generic type-safe wrappers for converting individual values to/from strings.
#define RYML_ID_TYPE
The type of a node id in the YAML tree.
Definition: common.hpp:237
#define RYML_ERRMSG_SIZE
size for the error message buffer
Definition: common.hpp:34
#define RYML_LOGBUF_SIZE
size for the buffer used to format individual values to string while preparing an error message....
Definition: common.hpp:44
#define RYML_EXPORT
Definition: export.hpp:18
void reset_callbacks()
set the global callbacks back to their defaults.
Definition: common.cpp:99
void set_callbacks(Callbacks const &c)
set the global callbacks for the library; after a call to this function, these callbacks will be used...
Definition: common.cpp:89
void(*)(csubstr msg, ErrorDataVisit const &errdata, void *user_data) pfn_error_visit
the type of the function used to report visit errors.
Definition: common.hpp:530
void *(*)(size_t len, void *hint, void *user_data) pfn_allocate
the type of the function used to allocate memory; ryml will only allocate memory through this callbac...
Definition: common.hpp:490
void(*)(csubstr msg, ErrorDataParse const &errdata, void *user_data) pfn_error_parse
the type of the function used to report parse errors.
Definition: common.hpp:519
Callbacks const & get_callbacks()
get the global callbacks
Definition: common.cpp:94
void(*)(csubstr msg, ErrorDataBasic const &errdata, void *user_data) pfn_error_basic
the type of the function used to report basic errors.
Definition: common.hpp:508
void(*)(void *mem, size_t size, void *user_data) pfn_free
the type of the function used to free memory; ryml will only free memory through this callback.
Definition: common.hpp:495
csubstr to_csubstr(substr s) noexcept
neutral version for use in generic code
Definition: substr.hpp:2204
bool operator==(const char(&s)[N], basic_substring< C > const that) noexcept
Definition: substr.hpp:2282
RYML_ID_TYPE id_type
The type of a node id in the YAML tree; to override the default type, define the macro RYML_ID_TYPE t...
Definition: common.hpp:244
@ npos
a null string position
Definition: common.hpp:258
@ UTF16BE
UTF16, Big-Endian.
Definition: common.hpp:266
@ UTF8
UTF8.
Definition: common.hpp:264
@ UTF16LE
UTF16, Little-Endian.
Definition: common.hpp:265
@ NOBOM
No Byte Order Mark was found.
Definition: common.hpp:263
@ UTF32BE
UTF32, Big-Endian.
Definition: common.hpp:268
@ UTF32LE
UTF32, Little-Endian.
Definition: common.hpp:267
enum c4::yml::Encoding_ Encoding_e
@ NONE
an index to none
Definition: common.hpp:251
(Undefined by default) Use shorter error message from checks/asserts: do not show the check condition...
Definition: common.cpp:14
A c-style callbacks class to customize behavior on errors or allocation.
Definition: common.hpp:541
pfn_error_basic m_error_basic
a pointer to a basic error handler function
Definition: common.hpp:545
pfn_error_parse m_error_parse
a pointer to a parse error handler function
Definition: common.hpp:546
void * m_user_data
data to be forwarded in every call to a callback
Definition: common.hpp:542
pfn_allocate m_allocate
a pointer to an allocate handler function
Definition: common.hpp:543
pfn_error_visit m_error_visit
a pointer to a visit error handler function
Definition: common.hpp:547
pfn_free m_free
a pointer to a free handler function
Definition: common.hpp:544
Data for a basic error.
Definition: common.hpp:315
ErrorDataBasic() noexcept=default
Location location
location where the error was detected (may be from YAML or C++ source code)
Definition: common.hpp:316
Data for a parse error.
Definition: common.hpp:324
Location cpploc
location in the C++ source file where the error was detected.
Definition: common.hpp:325
ErrorDataParse() noexcept=default
Location ymlloc
location in the YAML source buffer where the error was detected.
Definition: common.hpp:326
Data for a visit error.
Definition: common.hpp:334
ErrorDataVisit() noexcept=default
Location cpploc
location in the C++ source file where the error was detected.
Definition: common.hpp:335
Tree const * tree
tree where the error was detected
Definition: common.hpp:336
id_type node
node where the error was detected
Definition: common.hpp:337
holds a source or yaml file position, for example when an error is detected; See also location_format...
Definition: common.hpp:284
Location(const char *n, size_t l) noexcept
Definition: common.hpp:299
size_t col
column
Definition: common.hpp:287
size_t line
line
Definition: common.hpp:286
Location(csubstr n, size_t l) noexcept
Definition: common.hpp:296
Location(const char *n, size_t l, size_t c) noexcept
Definition: common.hpp:300
Location(csubstr n, size_t l, size_t c) noexcept
Definition: common.hpp:297
Location(size_t l, size_t c) noexcept
Definition: common.hpp:294
size_t offset
number of bytes from the beginning of the source buffer
Definition: common.hpp:285
Location(size_t b, size_t l, size_t c) noexcept
Definition: common.hpp:295
csubstr name
name of the file
Definition: common.hpp:288
Location(csubstr n, size_t b, size_t l, size_t c) noexcept
Definition: common.hpp:298
Location(const char *n, size_t b, size_t l, size_t c) noexcept
Definition: common.hpp:301
Location(size_t l) noexcept
Definition: common.hpp:293
Location() noexcept
Definition: common.hpp:292
Options to give to the parser to control its behavior.
Definition: common.hpp:350
ParserOptions & scalar_filtering(bool enabled) noexcept
enable/disable scalar filtering while parsing
Definition: common.hpp:444
ParserOptions & resolve_tags_all(bool enabled) noexcept
When resolve_tags() is enabled, resolve not just prefixed tags of the form.
Definition: common.hpp:414
bool scalar_filtering() const noexcept
query scalar filtering status
Definition: common.hpp:449
ParserOptions & resolve_tags(bool enabled) noexcept
enable/disable resolution of YAML tags during parsing.
Definition: common.hpp:404
bool resolve_tags_all() const noexcept
query status of non-prefixed tag resolution setting.
Definition: common.hpp:419
bool locations() const noexcept
query source location tracking status
Definition: common.hpp:434
bool detect_flow_ml() const noexcept
query status of detection of FLOW_ML container style.
Definition: common.hpp:391
ParserOptions & locations(bool enabled) noexcept
enable/disable source location tracking
Definition: common.hpp:429
bool resolve_tags() const noexcept
query status of tag resolution setting.
Definition: common.hpp:409
ParserOptions & detect_flow_ml(bool enabled) noexcept
enable/disable detection of FLOW_ML container style.
Definition: common.hpp:386
read+write string views