NeBuild dev
Loading...
Searching...
No Matches
forward_declarations.hpp
Go to the documentation of this file.
1//# This file is a part of toml++ and is subject to the the terms of the MIT license.
2//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
3//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
4// SPDX-License-Identifier: MIT
5#pragma once
6
7#include "std_string.hpp"
8#include "std_new.hpp"
10#include <cstdint>
11#include <cstddef>
12#include <cstring>
13#include <cfloat>
14#include <climits>
15#include <cmath>
16#include <limits>
17#include <memory>
18#include <iosfwd>
19#include <type_traits>
21#include "header_start.hpp"
22
23//#---------------------------------------------------------------------------------------------------------------------
24//# ENVIRONMENT GROUND-TRUTHS
25//#---------------------------------------------------------------------------------------------------------------------
27
28#ifndef TOML_DISABLE_ENVIRONMENT_CHECKS
29#define TOML_ENV_MESSAGE \
30 "If you're seeing this error it's because you're building toml++ for an environment that doesn't conform to " \
31 "one of the 'ground truths' assumed by the library. Essentially this just means that I don't have the " \
32 "resources to test on more platforms, but I wish I did! You can try disabling the checks by defining " \
33 "TOML_DISABLE_ENVIRONMENT_CHECKS, but your mileage may vary. Please consider filing an issue at " \
34 "https://github.com/marzer/tomlplusplus/issues to help me improve support for your target environment. " \
35 "Thanks!"
36
37static_assert(CHAR_BIT == 8, TOML_ENV_MESSAGE);
38#ifdef FLT_RADIX
39static_assert(FLT_RADIX == 2, TOML_ENV_MESSAGE);
40#endif
41static_assert('A' == 65, TOML_ENV_MESSAGE);
42static_assert(sizeof(double) == 8, TOML_ENV_MESSAGE);
43static_assert(std::numeric_limits<double>::is_iec559, TOML_ENV_MESSAGE);
44static_assert(std::numeric_limits<double>::digits == 53, TOML_ENV_MESSAGE);
45static_assert(std::numeric_limits<double>::digits10 == 15, TOML_ENV_MESSAGE);
46static_assert(std::numeric_limits<double>::radix == 2, TOML_ENV_MESSAGE);
47
48#undef TOML_ENV_MESSAGE
49#endif // !TOML_DISABLE_ENVIRONMENT_CHECKS
50
52
53//#---------------------------------------------------------------------------------------------------------------------
54//# UNDOCUMENTED TYPEDEFS AND FORWARD DECLARATIONS
55//#---------------------------------------------------------------------------------------------------------------------
57// undocumented forward declarations are hidden from doxygen because they fuck it up =/
58
59namespace toml // non-abi namespace; this is not an error
60{
61 using ::std::size_t;
62 using ::std::intptr_t;
63 using ::std::uintptr_t;
64 using ::std::ptrdiff_t;
65 using ::std::nullptr_t;
66 using ::std::int8_t;
67 using ::std::int16_t;
68 using ::std::int32_t;
69 using ::std::int64_t;
70 using ::std::uint8_t;
71 using ::std::uint16_t;
72 using ::std::uint32_t;
73 using ::std::uint64_t;
74 using ::std::uint_least32_t;
75 using ::std::uint_least64_t;
76}
77
79{
80 struct date;
81 struct time;
82 struct time_offset;
83
85 struct date_time;
87
88 struct source_position;
89 struct source_region;
90
91 class node;
92 template <typename>
93 class node_view;
94
95 class key;
96 class array;
97 class table;
98 template <typename>
99 class value;
100
101 class path;
102
103 class toml_formatter;
104 class json_formatter;
105 class yaml_formatter;
106
108#if TOML_EXCEPTIONS
109 using parse_result = table;
110#else
111 class parse_result;
112#endif
113 TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS
114}
116
118{
119 using node_ptr = std::unique_ptr<node>;
120
121 TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, impl_ex, impl_noex);
122 class parser;
123 TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS
124
125 // clang-format off
126
127 inline constexpr std::string_view control_char_escapes[] =
128 {
129 "\\u0000"sv,
130 "\\u0001"sv,
131 "\\u0002"sv,
132 "\\u0003"sv,
133 "\\u0004"sv,
134 "\\u0005"sv,
135 "\\u0006"sv,
136 "\\u0007"sv,
137 "\\b"sv,
138 "\\t"sv,
139 "\\n"sv,
140 "\\u000B"sv,
141 "\\f"sv,
142 "\\r"sv,
143 "\\u000E"sv,
144 "\\u000F"sv,
145 "\\u0010"sv,
146 "\\u0011"sv,
147 "\\u0012"sv,
148 "\\u0013"sv,
149 "\\u0014"sv,
150 "\\u0015"sv,
151 "\\u0016"sv,
152 "\\u0017"sv,
153 "\\u0018"sv,
154 "\\u0019"sv,
155 "\\u001A"sv,
156 "\\u001B"sv,
157 "\\u001C"sv,
158 "\\u001D"sv,
159 "\\u001E"sv,
160 "\\u001F"sv,
161 };
162
163 inline constexpr std::string_view node_type_friendly_names[] =
164 {
165 "none"sv,
166 "table"sv,
167 "array"sv,
168 "string"sv,
169 "integer"sv,
170 "floating-point"sv,
171 "boolean"sv,
172 "date"sv,
173 "time"sv,
174 "date-time"sv
175 };
176
177 // clang-format on
178}
180
181#if TOML_ABI_NAMESPACES
182#if TOML_EXCEPTIONS
183#define TOML_PARSER_TYPENAME TOML_NAMESPACE::impl::impl_ex::parser
184#else
185#define TOML_PARSER_TYPENAME TOML_NAMESPACE::impl::impl_noex::parser
186#endif
187#else
188#define TOML_PARSER_TYPENAME TOML_NAMESPACE::impl::parser
189#endif
190
192
193//#---------------------------------------------------------------------------------------------------------------------
194//# DOCUMENTED TYPEDEFS AND FORWARD DECLARATIONS
195//#---------------------------------------------------------------------------------------------------------------------
196
198namespace toml
199{
200}
201
202TOML_NAMESPACE_START // abi namespace
203{
222 inline namespace literals
223 {
224 }
225
227 enum class TOML_CLOSED_ENUM node_type : uint8_t
228 {
229 none,
230 table,
231 array,
232 string,
233 integer,
234 floating_point,
235 boolean,
236 date,
237 time,
238 date_time
239 };
240
255 template <typename Char>
256 inline std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& lhs, node_type rhs)
257 {
258 const auto str = impl::node_type_friendly_names[static_cast<std::underlying_type_t<node_type>>(rhs)];
259 using str_char_t = decltype(str)::value_type;
260 if constexpr (std::is_same_v<Char, str_char_t>)
261 return lhs << str;
262 else
263 {
264 if constexpr (sizeof(Char) == sizeof(str_char_t))
265 return lhs << std::basic_string_view<Char>{ reinterpret_cast<const Char*>(str.data()), str.length() };
266 else
267 return lhs << str.data();
268 }
269 }
270
272 enum class TOML_OPEN_FLAGS_ENUM value_flags : uint16_t // being an "OPEN" flags enum is not an error
273 {
275 none,
276
279
282
285 };
287
291 POXY_IMPLEMENTATION_DETAIL(value_flags{ static_cast<std::underlying_type_t<value_flags>>(-1) });
292
298 {
300 none,
301
304
307
310
313
316
319
322
324 allow_octal_integers = (1ull << 7),
325
328
330 indent_sub_tables = (1ull << 9),
331
333 indent_array_elements = (1ull << 10),
334
337
343
345 terse_key_value_pairs = (1ull << 12),
346 };
348
364 template <typename T>
366 {
367 static_assert(std::is_reference_v<T>);
368
370 };
371 template <typename T>
373 template <typename T>
375
378 using default_formatter = toml_formatter;
379}
381
382//#---------------------------------------------------------------------------------------------------------------------
383//# METAFUNCTIONS & TYPE TRAITS
384//#---------------------------------------------------------------------------------------------------------------------
387{
388 template <typename T>
389 using remove_cvref = std::remove_cv_t<std::remove_reference_t<T>>;
390
391 template <typename... T>
392 using common_signed_type = std::common_type_t<std::make_signed_t<T>...>;
393
394 template <typename T, typename... U>
395 inline constexpr bool is_one_of = (false || ... || std::is_same_v<T, U>);
396
397 template <typename... T>
398 inline constexpr bool all_integral = (std::is_integral_v<T> && ...);
399
400 template <typename T>
401 inline constexpr bool is_cvref = std::is_reference_v<T> || std::is_const_v<T> || std::is_volatile_v<T>;
402
403 template <typename T>
404 inline constexpr bool is_wide_string =
405 is_one_of<std::decay_t<T>, const wchar_t*, wchar_t*, std::wstring_view, std::wstring>;
406
407 template <typename T>
408 inline constexpr bool value_retrieval_is_nothrow = !std::is_same_v<remove_cvref<T>, std::string>
409#if TOML_HAS_CHAR8
410 && !std::is_same_v<remove_cvref<T>, std::u8string>
411#endif
412
413 && !is_wide_string<T>;
414
415 template <typename, typename>
416 struct copy_ref_;
417 template <typename Dest, typename Src>
418 using copy_ref = typename copy_ref_<Dest, Src>::type;
419
420 template <typename Dest, typename Src>
421 struct copy_ref_
422 {
423 using type = Dest;
424 };
425
426 template <typename Dest, typename Src>
427 struct copy_ref_<Dest, Src&>
428 {
429 using type = std::add_lvalue_reference_t<Dest>;
430 };
431
432 template <typename Dest, typename Src>
433 struct copy_ref_<Dest, Src&&>
434 {
435 using type = std::add_rvalue_reference_t<Dest>;
436 };
437
438 template <typename, typename>
439 struct copy_cv_;
440 template <typename Dest, typename Src>
441 using copy_cv = typename copy_cv_<Dest, Src>::type;
442
443 template <typename Dest, typename Src>
444 struct copy_cv_
445 {
446 using type = Dest;
447 };
448
449 template <typename Dest, typename Src>
450 struct copy_cv_<Dest, const Src>
451 {
452 using type = std::add_const_t<Dest>;
453 };
454
455 template <typename Dest, typename Src>
456 struct copy_cv_<Dest, volatile Src>
457 {
458 using type = std::add_volatile_t<Dest>;
459 };
460
461 template <typename Dest, typename Src>
462 struct copy_cv_<Dest, const volatile Src>
463 {
464 using type = std::add_cv_t<Dest>;
465 };
466
467 template <typename Dest, typename Src>
468 using copy_cvref =
469 copy_ref<copy_ref<copy_cv<std::remove_reference_t<Dest>, std::remove_reference_t<Src>>, Dest>, Src>;
470
471 template <typename...>
472 inline constexpr bool always_false = false;
473
474 template <typename T, typename... U>
475 inline constexpr bool first_is_same = false;
476 template <typename T, typename... U>
477 inline constexpr bool first_is_same<T, T, U...> = true;
478
479 template <typename T, bool = std::is_enum_v<T>>
480 struct underlying_type_
481 {
482 using type = std::underlying_type_t<T>;
483 };
484 template <typename T>
485 struct underlying_type_<T, false>
486 {
487 using type = T;
488 };
489 template <typename T>
490 using underlying_type = typename underlying_type_<T>::type;
491
492 // general value traits
493 // (as they relate to their equivalent native TOML type)
494 struct default_value_traits
495 {
496 using native_type = void;
497 static constexpr bool is_native = false;
498 static constexpr bool is_losslessly_convertible_to_native = false;
499 static constexpr bool can_represent_native = false;
500 static constexpr bool can_partially_represent_native = false;
501 static constexpr auto type = node_type::none;
502 };
503
504 template <typename T>
505 struct value_traits;
506
507 template <typename T, bool = std::is_enum_v<T>>
508 struct value_traits_base_selector
509 {
510 static_assert(!is_cvref<T>);
511
512 using type = default_value_traits;
513 };
514 template <typename T>
515 struct value_traits_base_selector<T, true>
516 {
517 static_assert(!is_cvref<T>);
518
519 using type = value_traits<underlying_type<T>>;
520 };
521
522 template <typename T>
523 struct value_traits : value_traits_base_selector<T>::type
524 {};
525 template <typename T>
526 struct value_traits<const T> : value_traits<T>
527 {};
528 template <typename T>
529 struct value_traits<volatile T> : value_traits<T>
530 {};
531 template <typename T>
532 struct value_traits<const volatile T> : value_traits<T>
533 {};
534 template <typename T>
535 struct value_traits<T&> : value_traits<T>
536 {};
537 template <typename T>
538 struct value_traits<T&&> : value_traits<T>
539 {};
540
541 // integer value_traits specializations - standard types
542 template <typename T>
543 struct integer_limits
544 {
545 static constexpr T min = T{ (std::numeric_limits<underlying_type<T>>::min)() };
546 static constexpr T max = T{ (std::numeric_limits<underlying_type<T>>::max)() };
547 };
548 template <typename T>
549 struct integer_traits_base : integer_limits<T>
550 {
551 using native_type = int64_t;
552 static constexpr bool is_native = std::is_same_v<underlying_type<T>, native_type>;
553 static constexpr bool is_signed = static_cast<underlying_type<T>>(-1) < underlying_type<T>{};
554 static constexpr auto type = node_type::integer;
555 static constexpr bool can_partially_represent_native = true;
556 };
557 template <typename T>
558 struct unsigned_integer_traits : integer_traits_base<T>
559 {
560 static constexpr bool is_losslessly_convertible_to_native =
561 integer_limits<underlying_type<T>>::max <= 9223372036854775807ULL;
562 static constexpr bool can_represent_native = false;
563 };
564 template <typename T>
565 struct signed_integer_traits : integer_traits_base<T>
566 {
567 using native_type = int64_t;
568 static constexpr bool is_losslessly_convertible_to_native =
569 integer_limits<underlying_type<T>>::min >= (-9223372036854775807LL - 1LL)
570 && integer_limits<underlying_type<T>>::max <= 9223372036854775807LL;
571 static constexpr bool can_represent_native =
572 integer_limits<underlying_type<T>>::min <= (-9223372036854775807LL - 1LL)
573 && integer_limits<underlying_type<T>>::max >= 9223372036854775807LL;
574 };
575 template <typename T, bool S = integer_traits_base<T>::is_signed>
576 struct integer_traits : signed_integer_traits<T>
577 {};
578 template <typename T>
579 struct integer_traits<T, false> : unsigned_integer_traits<T>
580 {};
581 template <>
582 struct value_traits<signed char> : integer_traits<signed char>
583 {};
584 template <>
585 struct value_traits<unsigned char> : integer_traits<unsigned char>
586 {};
587 template <>
588 struct value_traits<signed short> : integer_traits<signed short>
589 {};
590 template <>
591 struct value_traits<unsigned short> : integer_traits<unsigned short>
592 {};
593 template <>
594 struct value_traits<signed int> : integer_traits<signed int>
595 {};
596 template <>
597 struct value_traits<unsigned int> : integer_traits<unsigned int>
598 {};
599 template <>
600 struct value_traits<signed long> : integer_traits<signed long>
601 {};
602 template <>
603 struct value_traits<unsigned long> : integer_traits<unsigned long>
604 {};
605 template <>
606 struct value_traits<signed long long> : integer_traits<signed long long>
607 {};
608 template <>
609 struct value_traits<unsigned long long> : integer_traits<unsigned long long>
610 {};
611 static_assert(value_traits<int64_t>::is_native);
612 static_assert(value_traits<int64_t>::is_signed);
613 static_assert(value_traits<int64_t>::is_losslessly_convertible_to_native);
614 static_assert(value_traits<int64_t>::can_represent_native);
615 static_assert(value_traits<int64_t>::can_partially_represent_native);
616
617 // integer value_traits specializations - non-standard types
618#ifdef TOML_INT128
619 template <>
620 struct integer_limits<TOML_INT128>
621 {
622 static constexpr TOML_INT128 max =
623 static_cast<TOML_INT128>((TOML_UINT128{ 1u } << ((__SIZEOF_INT128__ * CHAR_BIT) - 1)) - 1);
624 static constexpr TOML_INT128 min = -max - TOML_INT128{ 1 };
625 };
626 template <>
627 struct integer_limits<TOML_UINT128>
628 {
629 static constexpr TOML_UINT128 min = TOML_UINT128{};
630 static constexpr TOML_UINT128 max = (2u * static_cast<TOML_UINT128>(integer_limits<TOML_INT128>::max)) + 1u;
631 };
632 template <>
633 struct value_traits<TOML_INT128> : integer_traits<TOML_INT128>
634 {};
635 template <>
636 struct value_traits<TOML_UINT128> : integer_traits<TOML_UINT128>
637 {};
638#endif
639#ifdef TOML_SMALL_INT_TYPE
640 template <>
641 struct value_traits<TOML_SMALL_INT_TYPE> : signed_integer_traits<TOML_SMALL_INT_TYPE>
642 {};
643#endif
644
645 // floating-point traits base
646 template <typename T, int MantissaDigits, int DecimalDigits>
647 struct float_traits_base
648 {
649 static constexpr auto type = node_type::floating_point;
650 using native_type = double;
651 static constexpr bool is_native = std::is_same_v<T, native_type>;
652 static constexpr bool is_signed = true;
653
654 static constexpr int bits = static_cast<int>(sizeof(T) * CHAR_BIT);
655 static constexpr int digits = MantissaDigits;
656 static constexpr int digits10 = DecimalDigits;
657
658 static constexpr bool is_losslessly_convertible_to_native = bits <= 64 //
659 && digits <= 53 // DBL_MANT_DIG
660 && digits10 <= 15; // DBL_DIG
661
662 static constexpr bool can_represent_native = digits >= 53 // DBL_MANT_DIG
663 && digits10 >= 15; // DBL_DIG
664
665 static constexpr bool can_partially_represent_native = digits > 0 && digits10 > 0;
666 };
667 template <typename T>
668 struct float_traits : float_traits_base<T, std::numeric_limits<T>::digits, std::numeric_limits<T>::digits10>
669 {};
670#if TOML_ENABLE_FLOAT16
671 template <>
672 struct float_traits<_Float16> : float_traits_base<_Float16, __FLT16_MANT_DIG__, __FLT16_DIG__>
673 {};
674#endif
675#ifdef TOML_FLOAT128
676 template <>
677 struct float_traits<TOML_FLOAT128> : float_traits_base<TOML_FLOAT128, __FLT128_MANT_DIG__, __FLT128_DIG__>
678 {};
679#endif
680
681 // floating-point traits
682 template <>
683 struct value_traits<float> : float_traits<float>
684 {};
685 template <>
686 struct value_traits<double> : float_traits<double>
687 {};
688 template <>
689 struct value_traits<long double> : float_traits<long double>
690 {};
691#if TOML_ENABLE_FLOAT16
692 template <>
693 struct value_traits<_Float16> : float_traits<_Float16>
694 {};
695#endif
696#ifdef TOML_FLOAT128
697 template <>
698 struct value_traits<TOML_FLOAT128> : float_traits<TOML_FLOAT128>
699 {};
700#endif
701#ifdef TOML_SMALL_FLOAT_TYPE
702 template <>
703 struct value_traits<TOML_SMALL_FLOAT_TYPE> : float_traits<TOML_SMALL_FLOAT_TYPE>
704 {};
705#endif
706 static_assert(value_traits<double>::is_native);
707 static_assert(value_traits<double>::is_losslessly_convertible_to_native);
708 static_assert(value_traits<double>::can_represent_native);
709 static_assert(value_traits<double>::can_partially_represent_native);
710
711 // string value_traits specializations - char-based strings
712 template <typename T>
713 struct string_traits
714 {
715 using native_type = std::string;
716 static constexpr bool is_native = std::is_same_v<T, native_type>;
717 static constexpr bool is_losslessly_convertible_to_native = true;
718 static constexpr bool can_represent_native =
719 !std::is_array_v<T> && (!std::is_pointer_v<T> || std::is_const_v<std::remove_pointer_t<T>>);
720 static constexpr bool can_partially_represent_native = can_represent_native;
721 static constexpr auto type = node_type::string;
722 };
723 template <>
724 struct value_traits<std::string> : string_traits<std::string>
725 {};
726 template <>
727 struct value_traits<std::string_view> : string_traits<std::string_view>
728 {};
729 template <>
730 struct value_traits<const char*> : string_traits<const char*>
731 {};
732 template <size_t N>
733 struct value_traits<const char[N]> : string_traits<const char[N]>
734 {};
735 template <>
736 struct value_traits<char*> : string_traits<char*>
737 {};
738 template <size_t N>
739 struct value_traits<char[N]> : string_traits<char[N]>
740 {};
741
742 // string value_traits specializations - char8_t-based strings
743#if TOML_HAS_CHAR8
744 template <>
745 struct value_traits<std::u8string> : string_traits<std::u8string>
746 {};
747 template <>
748 struct value_traits<std::u8string_view> : string_traits<std::u8string_view>
749 {};
750 template <>
751 struct value_traits<const char8_t*> : string_traits<const char8_t*>
752 {};
753 template <size_t N>
754 struct value_traits<const char8_t[N]> : string_traits<const char8_t[N]>
755 {};
756 template <>
757 struct value_traits<char8_t*> : string_traits<char8_t*>
758 {};
759 template <size_t N>
760 struct value_traits<char8_t[N]> : string_traits<char8_t[N]>
761 {};
762#endif
763
764 // string value_traits specializations - wchar_t-based strings on Windows
765#if TOML_ENABLE_WINDOWS_COMPAT
766 template <typename T>
767 struct wstring_traits
768 {
769 using native_type = std::string;
770 static constexpr bool is_native = false;
771 static constexpr bool is_losslessly_convertible_to_native = true; // narrow
772 static constexpr bool can_represent_native = std::is_same_v<T, std::wstring>; // widen
773 static constexpr bool can_partially_represent_native = can_represent_native;
774 static constexpr auto type = node_type::string;
775 };
776 template <>
777 struct value_traits<std::wstring> : wstring_traits<std::wstring>
778 {};
779 template <>
780 struct value_traits<std::wstring_view> : wstring_traits<std::wstring_view>
781 {};
782 template <>
783 struct value_traits<const wchar_t*> : wstring_traits<const wchar_t*>
784 {};
785 template <size_t N>
786 struct value_traits<const wchar_t[N]> : wstring_traits<const wchar_t[N]>
787 {};
788 template <>
789 struct value_traits<wchar_t*> : wstring_traits<wchar_t*>
790 {};
791 template <size_t N>
792 struct value_traits<wchar_t[N]> : wstring_traits<wchar_t[N]>
793 {};
794#endif
795
796 // other 'native' value_traits specializations
797 template <typename T, node_type NodeType>
798 struct native_value_traits
799 {
800 using native_type = T;
801 static constexpr bool is_native = true;
802 static constexpr bool is_losslessly_convertible_to_native = true;
803 static constexpr bool can_represent_native = true;
804 static constexpr bool can_partially_represent_native = true;
805 static constexpr auto type = NodeType;
806 };
807 template <>
808 struct value_traits<bool> : native_value_traits<bool, node_type::boolean>
809 {};
810 template <>
811 struct value_traits<date> : native_value_traits<date, node_type::date>
812 {};
813 template <>
814 struct value_traits<time> : native_value_traits<time, node_type::time>
815 {};
816 template <>
817 struct value_traits<date_time> : native_value_traits<date_time, node_type::date_time>
818 {};
819
820 // native value category queries
821 template <typename T>
822 using native_type_of = typename value_traits<T>::native_type;
823 template <typename T>
824 inline constexpr bool is_native = value_traits<T>::is_native;
825 template <typename T>
826 inline constexpr bool can_represent_native = value_traits<T>::can_represent_native;
827 template <typename T>
828 inline constexpr bool can_partially_represent_native = value_traits<T>::can_partially_represent_native;
829 template <typename T>
830 inline constexpr bool is_losslessly_convertible_to_native = value_traits<T>::is_losslessly_convertible_to_native;
831 template <typename T, typename... U>
832 inline constexpr bool is_natively_one_of = is_one_of<native_type_of<T>, U...>;
833
834 // native value types => nodes
835 template <typename T>
836 struct node_wrapper
837 {
838 using type = T;
839 };
840 template <typename T>
841 struct node_wrapper<const T>
842 {
843 using type = std::add_const_t<typename node_wrapper<T>::type>;
844 };
845 template <typename T>
846 struct node_wrapper<volatile T>
847 {
848 using type = std::add_volatile_t<typename node_wrapper<T>::type>;
849 };
850 template <typename T>
851 struct node_wrapper<const volatile T>
852 {
853 using type = std::add_const_t<std::add_volatile_t<typename node_wrapper<T>::type>>;
854 };
855 template <>
856 struct node_wrapper<std::string>
857 {
858 using type = value<std::string>;
859 };
860 template <>
861 struct node_wrapper<int64_t>
862 {
863 using type = value<int64_t>;
864 };
865 template <>
866 struct node_wrapper<double>
867 {
868 using type = value<double>;
869 };
870 template <>
871 struct node_wrapper<bool>
872 {
873 using type = value<bool>;
874 };
875 template <>
876 struct node_wrapper<date>
877 {
878 using type = value<date>;
879 };
880 template <>
881 struct node_wrapper<time>
882 {
883 using type = value<time>;
884 };
885 template <>
886 struct node_wrapper<date_time>
887 {
888 using type = value<date_time>;
889 };
890 template <typename T>
891 using wrap_node = typename node_wrapper<std::remove_reference_t<T>>::type;
892
893 // nodes => native value types
894 template <typename T>
895 struct node_unwrapper
896 {
897 using type = T;
898 };
899 template <typename T>
900 struct node_unwrapper<value<T>>
901 {
902 using type = T;
903 };
904 template <typename T>
905 struct node_unwrapper<const value<T>>
906 {
907 using type = std::add_const_t<T>;
908 };
909 template <typename T>
910 struct node_unwrapper<volatile value<T>>
911 {
912 using type = std::add_volatile_t<T>;
913 };
914 template <typename T>
915 struct node_unwrapper<const volatile value<T>>
916 {
917 using type = std::add_volatile_t<std::add_const_t<T>>;
918 };
919 template <typename T>
920 using unwrap_node = typename node_unwrapper<std::remove_reference_t<T>>::type;
921
922 template <typename T>
923 struct node_type_getter
924 {
925 static constexpr auto value = value_traits<T>::type;
926 };
927 template <>
928 struct node_type_getter<table>
929 {
930 static constexpr auto value = node_type::table;
931 };
932 template <>
933 struct node_type_getter<array>
934 {
935 static constexpr auto value = node_type::array;
936 };
937 template <>
938 struct node_type_getter<void>
939 {
940 static constexpr auto value = node_type::none;
941 };
942 template <typename T>
943 inline constexpr node_type node_type_of = node_type_getter<unwrap_node<remove_cvref<T>>>::value;
944
945 template <typename T, typename ConvertFrom>
946 inline constexpr bool is_constructible_or_convertible = std::is_constructible_v<T, ConvertFrom> //
947 || std::is_convertible_v<ConvertFrom, T>;
948}
951
953{
955 template <typename T>
956 inline constexpr bool is_table = std::is_same_v<impl::remove_cvref<T>, table>;
957
959 template <typename T>
960 inline constexpr bool is_array = std::is_same_v<impl::remove_cvref<T>, array>;
961
963 template <typename T>
964 inline constexpr bool is_container = is_table<T> || is_array<T>;
965
967 template <typename T>
968 inline constexpr bool is_string = std::is_same_v< //
969 impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
970 value<std::string>>;
971
973 template <typename T>
974 inline constexpr bool is_integer = std::is_same_v< //
975 impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
976 value<int64_t>>;
977
979 template <typename T>
980 inline constexpr bool is_floating_point = std::is_same_v< //
981 impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
982 value<double>>;
983
985 template <typename T>
986 inline constexpr bool is_number = is_integer<T> || is_floating_point<T>;
987
989 template <typename T>
990 inline constexpr bool is_boolean = std::is_same_v< //
991 impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
992 value<bool>>;
993
995 template <typename T>
996 inline constexpr bool is_date = std::is_same_v< //
997 impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
998 value<date>>;
999
1001 template <typename T>
1002 inline constexpr bool is_time = std::is_same_v< //
1003 impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
1004 value<time>>;
1005
1007 template <typename T>
1008 inline constexpr bool is_date_time = std::is_same_v< //
1009 impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
1010 value<date_time>>;
1011
1013 template <typename T>
1014 inline constexpr bool is_chronological = is_date<T> || is_time<T> || is_date_time<T>;
1015
1017 template <typename T>
1018 inline constexpr bool is_value = is_string<T> || is_number<T> || is_boolean<T> || is_chronological<T>;
1019
1021 template <typename T>
1022 inline constexpr bool is_node = std::is_same_v<toml::node, impl::remove_cvref<T>> //
1023 || std::is_base_of_v<toml::node, impl::remove_cvref<T>>;
1024
1026 template <typename T>
1027 inline constexpr bool is_node_view = impl::is_one_of<impl::remove_cvref<T>, node_view<node>, node_view<const node>>;
1028}
1030
1031//#---------------------------------------------------------------------------------------------------------------------
1032//# INTERNAL HELPERS
1033//#---------------------------------------------------------------------------------------------------------------------
1036{
1037 template <typename T>
1039 constexpr std::underlying_type_t<T> unwrap_enum(T val) noexcept
1040 {
1041 return static_cast<std::underlying_type_t<T>>(val);
1042 }
1043
1044 // Q: "why not use std::fpclassify?"
1045 // A: Because it gets broken by -ffast-math and friends
1046 enum class TOML_CLOSED_ENUM fp_class : unsigned
1047 {
1048 ok,
1049 neg_inf,
1050 pos_inf,
1051 nan
1052 };
1053
1055 inline fp_class fpclassify(const double& val) noexcept
1056 {
1057 static_assert(sizeof(uint64_t) == sizeof(double));
1058
1059 static constexpr uint64_t sign = 0b1000000000000000000000000000000000000000000000000000000000000000ull;
1060 static constexpr uint64_t exponent = 0b0111111111110000000000000000000000000000000000000000000000000000ull;
1061 static constexpr uint64_t mantissa = 0b0000000000001111111111111111111111111111111111111111111111111111ull;
1062
1063 uint64_t val_bits;
1064 std::memcpy(&val_bits, &val, sizeof(val));
1065 if ((val_bits & exponent) != exponent)
1066 return fp_class::ok;
1067 if ((val_bits & mantissa))
1068 return fp_class::nan;
1069 return (val_bits & sign) ? fp_class::neg_inf : fp_class::pos_inf;
1070 }
1071
1072 // Q: "why not use std::find and std::min?"
1073 // A: Because <algorithm> is _huge_ and these would be the only things I used from it.
1074 // I don't want to impose such a heavy compile-time burden on users.
1075
1076 template <typename Iterator, typename T>
1078 inline auto find(Iterator start, Iterator end, const T& needle) noexcept //
1079 ->decltype(&(*start))
1080 {
1081 for (; start != end; start++)
1082 if (*start == needle)
1083 return &(*start);
1084 return nullptr;
1085 }
1086
1087 template <typename T>
1089 constexpr const T& min(const T& a, const T& b) noexcept //
1090 {
1091 return a < b ? a : b;
1092 }
1093}
1096
1097#include "header_end.hpp"
A TOML array.
Definition array.hpp:285
The result of a parsing operation.
Definition parse_result.hpp:53
Definition parser.inl:887
A TOML path.
Definition path.hpp:239
A TOML table.
Definition table.hpp:220
enum TOML_OPEN_FLAGS_ENUM format_as_hexadecimal
Format integer values as hexadecimal.
Definition forward_declarations.hpp:284
toml_formatter default_formatter
The 'default' formatter used by TOML objects when they are printed to a stream. \detail This is an al...
Definition forward_declarations.hpp:378
enum TOML_OPEN_FLAGS_ENUM value_flags
Metadata associated with TOML values.
Definition forward_declarations.hpp:272
constexpr bool is_number
Metafunction for determining if a type satisfies either toml::is_integer or toml::is_floating_point.
Definition forward_declarations.hpp:986
enum TOML_OPEN_FLAGS_ENUM format_as_octal
Format integer values as octal.
Definition forward_declarations.hpp:281
enum TOML_CLOSED_FLAGS_ENUM allow_multi_line_strings
Strings containing newlines will be emitted as triple-quoted 'multi-line' strings where possible.
Definition forward_declarations.hpp:312
TOML_NAMESPACE_START
Definition forward_declarations.hpp:203
enum TOML_CLOSED_FLAGS_ENUM quote_dates_and_times
Dates and times will be emitted as quoted strings.
Definition forward_declarations.hpp:303
enum TOML_CLOSED_FLAGS_ENUM allow_unicode_strings
Allow non-ASCII characters in strings (as opposed to their escaped form, e.g. \u00DA).
Definition forward_declarations.hpp:318
constexpr bool is_boolean
Metafunction for determining if a type is, or is a reference to, a bool or toml::value<bool>.
Definition forward_declarations.hpp:990
enum TOML_CLOSED_FLAGS_ENUM allow_real_tabs_in_strings
Allow real tab characters in string literals (as opposed to the escaped form \t).
Definition forward_declarations.hpp:315
constexpr bool is_floating_point
Metafunction for determining if a type is, or is a reference to, a double or toml::value<double>.
Definition forward_declarations.hpp:980
constexpr bool is_date
Metafunction for determining if a type is, or is a reference to, a toml::date or toml::value<date>.
Definition forward_declarations.hpp:996
enum TOML_CLOSED_FLAGS_ENUM allow_octal_integers
Allow integers with #value_flags::format_as_octal to be emitted as octal.
Definition forward_declarations.hpp:324
TOML_ENABLE_WARNINGS
Definition forward_declarations.hpp:20
enum TOML_CLOSED_FLAGS_ENUM allow_binary_integers
Allow integers with #value_flags::format_as_binary to be emitted as binary.
Definition forward_declarations.hpp:321
constexpr bool is_string
Metafunction for determining if a type is, or is a reference to, a std::string or toml::value<std::st...
Definition forward_declarations.hpp:968
TOML_DISABLE_WARNINGS
Definition forward_declarations.hpp:9
constexpr bool is_array
Metafunction for determining if a type is, or is a reference to, a toml::array.
Definition forward_declarations.hpp:960
enum TOML_CLOSED_FLAGS_ENUM quote_infinities_and_nans
Infinities and NaNs will be emitted as quoted strings.
Definition forward_declarations.hpp:306
constexpr bool is_chronological
Metafunction for determining if a type satisfies any of toml::is_date, toml::is_time or toml::is_date...
Definition forward_declarations.hpp:1014
constexpr bool is_date_time
Metafunction for determining if a type is, or is a reference to, a toml::date_time or toml::value<dat...
Definition forward_declarations.hpp:1008
enum TOML_CLOSED_FLAGS_ENUM allow_hexadecimal_integers
Allow integers with #value_flags::format_as_hexadecimal to be emitted as hexadecimal.
Definition forward_declarations.hpp:327
enum TOML_CLOSED_FLAGS_ENUM allow_literal_strings
Strings will be emitted as single-quoted literal strings where possible.
Definition forward_declarations.hpp:309
constexpr bool is_integer
Metafunction for determining if a type is, or is a reference to, a int64_t or toml::value<int64_t>.
Definition forward_declarations.hpp:974
enum TOML_CLOSED_FLAGS_ENUM terse_key_value_pairs
Avoids the use of whitespace around key-value pairs.
Definition forward_declarations.hpp:345
constexpr bool is_container
Metafunction for determining if a type satisfies either toml::is_table or toml::is_array.
Definition forward_declarations.hpp:964
constexpr value_flags preserve_source_value_flags
Special #toml::value_flags constant used for array + table insert functions to specify that any value...
Definition forward_declarations.hpp:290
enum TOML_CLOSED_FLAGS_ENUM relaxed_float_precision
Emit floating-point values with relaxed (human-friendly) precision.
Definition forward_declarations.hpp:342
enum TOML_OPEN_FLAGS_ENUM format_as_binary
Format integer values as binary.
Definition forward_declarations.hpp:278
constexpr bool is_node_view
Metafunction for determining if a type is, or is a reference to, a toml::node_view.
Definition forward_declarations.hpp:1027
enum TOML_CLOSED_FLAGS_ENUM format_flags
Format flags for modifying how TOML data is printed to streams.
Definition forward_declarations.hpp:297
constexpr bool is_node
Metafunction for determining if a type is, or is a reference to, a toml::node (or one of its subclass...
Definition forward_declarations.hpp:1022
std::basic_ostream< Char > & operator<<(std::basic_ostream< Char > &lhs, node_type rhs)
Pretty-prints the value of a node_type to a stream.
Definition forward_declarations.hpp:256
enum TOML_CLOSED_FLAGS_ENUM indent_sub_tables
Apply indentation to tables nested within other tables/arrays.
Definition forward_declarations.hpp:330
constexpr bool is_time
Metafunction for determining if a type is, or is a reference to, a toml::time or toml::value<time>.
Definition forward_declarations.hpp:1002
enum TOML_CLOSED_FLAGS_ENUM indentation
Combination mask of all indentation-enabling flags.
Definition forward_declarations.hpp:336
enum TOML_CLOSED_FLAGS_ENUM indent_array_elements
Apply indentation to array elements when the array is forced to wrap over multiple lines.
Definition forward_declarations.hpp:333
TOML_NAMESPACE_END
Definition forward_declarations.hpp:380
constexpr bool is_value
Metafunction for determining if a type is, or is a reference to, any of the toml value types....
Definition forward_declarations.hpp:1018
#define TOML_HAS_CUSTOM_OPTIONAL_TYPE
Definition preprocessor.hpp:1101
#define TOML_EXCEPTIONS
Sets whether the library uses exceptions to report parsing failures. \detail Defaults to 1 or 0 accor...
Definition preprocessor.hpp:1126
@ value
the parser finished reading a JSON value
@ key
the parser read a key of a value in an object
Definition json.h:24463
Definition json.h:5363
The root namespace for all toml++ functions and types.
Definition forward_declarations.hpp:199
#define TOML_TRIVIAL_ABI
Definition preprocessor.hpp:430
#define POXY_IMPLEMENTATION_DETAIL(...)
Definition preprocessor.hpp:633
#define TOML_ABI_NAMESPACE_BOOL(cond, T, F)
Definition preprocessor.hpp:1323
#define TOML_ABI_NAMESPACE_END
Definition preprocessor.hpp:1324
#define TOML_CLOSED_ENUM
Definition preprocessor.hpp:557
#define TOML_PURE_GETTER
Definition preprocessor.hpp:474
#define TOML_OPEN_FLAGS_ENUM
Definition preprocessor.hpp:561
#define TOML_CLOSED_FLAGS_ENUM
Definition preprocessor.hpp:562
#define TOML_PURE_INLINE_GETTER
Definition preprocessor.hpp:479
#define TOML_IMPL_NAMESPACE_END
Definition preprocessor.hpp:1334
#define TOML_IMPL_NAMESPACE_START
Definition preprocessor.hpp:1333
#define TOML_CONST_INLINE_GETTER
Definition preprocessor.hpp:490
#define TOML_MAKE_FLAGS(T)
Definition preprocessor.hpp:601
A date-time.
Definition date_time.hpp:327
Helper class for suppressing move-construction in single-argument array constructors.
Definition forward_declarations.hpp:366
T value
Definition forward_declarations.hpp:369
A source document line-and-column pair.
Definition source_region.hpp:43
A source document region.
Definition source_region.hpp:167
A timezone offset.
Definition date_time.hpp:221
A local time-of-day.
Definition date_time.hpp:113