string value serialization now emits literals where possible (closes #43)
also added support for wide strings on Windows (closes #42): - added wide-string path arg overloads of `parse()` and `parse_file()` - added wide-string support to all relevant `table` and `array` ops - added `std::wstring` support to `node::value()` and `node::value_or()` - added `std::wstring` support to `node_view::value()` and `node_view::value_or()` - added wide-string overloads of `table::operator[]` - added wide-string overloads of `node_view::operator[]` - added `source_region::wide_path()` - added `TOML_WINDOWS_COMPAT` switch for explicitly enabling/disabling this stuff also: - fixed internal macro `assert_or_assume` leaking out of `toml_parser.hpp` - deprecated `node_view::get()` in favour of `node_view::node()` - minor documentation fixes - minor cleanup
This commit is contained in:
parent
8d958fcc54
commit
de07ba7187
@ -10,10 +10,13 @@ end_of_line = lf
|
||||
[*.{gitattributes, yml, props, vcxproj}]
|
||||
indent_style = space
|
||||
|
||||
[{Doxyfile, Doxyfile-mcss}]
|
||||
indent_style = space
|
||||
|
||||
[*.{natvis, props, vcxproj, sln, runsettings}]
|
||||
end_of_line = crlf
|
||||
|
||||
[*.{c, cpp, cxx, h, hpp, hxx, inl, toml, xml, py, natvis, props, build, vcxproj, runsettings, yml, ini, json}]
|
||||
[*.{c, cpp, cxx, dox, h, hpp, hxx, inl, toml, xml, py, natvis, props, build, vcxproj, runsettings, yml, ini, json}]
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
|
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -2,6 +2,7 @@
|
||||
*.c text encoding=UTF-8 eol=lf
|
||||
*.cpp text encoding=UTF-8 eol=lf
|
||||
*.cxx text encoding=UTF-8 eol=lf
|
||||
*.dox text encoding=UTF-8 eol=lf
|
||||
*.h text encoding=UTF-8 eol=lf
|
||||
*.hpp text encoding=UTF-8 eol=lf
|
||||
*.hxx text encoding=UTF-8 eol=lf
|
||||
|
32
README.md
32
README.md
@ -113,21 +113,22 @@ single-header flavour, however specifying the option `"multiple_headers": True`
|
||||
A number of configurable options are exposed in the form of preprocessor `#defines`. Most likely you
|
||||
won't need to mess with these at all, but if you do, set them before including toml++.
|
||||
|
||||
| Option | Type | Default | Description |
|
||||
|----------------------------|:--------------:|-----------------------------------|------------------------------------------------------------------------------------------------------------|
|
||||
| `TOML_ALL_INLINE` | boolean | `1` | Disable this to explicitly control where toml++'s implementation is compiled (e.g. as part of a library). |
|
||||
| `TOML_API` | define | undefined | API annotation to add to public symbols (e.g. `__declspec(dllexport)` on Windows). |
|
||||
| `TOML_ASSERT(expr)` | function macro | `assert(expr)`<br>(or undefined) | Sets the assert function used by the library. |
|
||||
| `TOML_CHAR_8_STRINGS` | boolean | `0` | Uses C++20 [char8_t]-based strings as the toml string data type. **_Experimental!_** |
|
||||
| `TOML_CONFIG_HEADER` | string literal | undefined | Includes the given header file before the rest of the library. |
|
||||
| `TOML_EXCEPTIONS` | boolean | per your compiler's settings | Sets whether the library uses exceptions. |
|
||||
| `TOML_IMPLEMENTATION` | define | undefined | Define this to enable compilation of the library's implementation. Meaningless if `TOML_ALL_INLINE` is `1`.|
|
||||
| `TOML_LARGE_FILES` | boolean | `0` | Uses 32-bit integers for line and column indices (instead of 16-bit). |
|
||||
| `TOML_OPTIONAL_TYPE` | type name | undefined | Overrides the `optional<T>` type used by the library if you need [something better than std::optional]. |
|
||||
| `TOML_PARSER` | boolean | `1` | Disable this to prevent inclusion of the parser-related parts of the library if you don't need them. |
|
||||
| `TOML_SMALL_FLOAT_TYPE` | type name | undefined | If your codebase has an additional 'small' float type (e.g. half-precision), this tells toml++ about it. |
|
||||
| `TOML_SMALL_INT_TYPE` | type name | undefined | If your codebase has an additional 'small' integer type (e.g. 24-bits), this tells toml++ about it. |
|
||||
| `TOML_UNRELEASED_FEATURES` | boolean | `0` | Enables support for [unreleased TOML language features] not yet part of a [numbered version]. |
|
||||
| Option | Type | Default | Description |
|
||||
|----------------------------|:--------------:|-----------------------------------|----------------------------------------------------------------------------------------------------------------------|
|
||||
| `TOML_ALL_INLINE` | boolean | `1` | Disable this to explicitly control where toml++'s implementation is compiled (e.g. as part of a library). |
|
||||
| `TOML_API` | define | undefined | API annotation to add to public symbols (e.g. `__declspec(dllexport)` on Windows). |
|
||||
| `TOML_ASSERT(expr)` | function macro | `assert(expr)`<br>(or undefined) | Sets the assert function used by the library. |
|
||||
| `TOML_CHAR_8_STRINGS` | boolean | `0` | Uses C++20 [char8_t]-based strings as the toml string data type. **_Experimental!_** |
|
||||
| `TOML_CONFIG_HEADER` | string literal | undefined | Includes the given header file before the rest of the library. |
|
||||
| `TOML_EXCEPTIONS` | boolean | per your compiler's settings | Sets whether the library uses exceptions. |
|
||||
| `TOML_IMPLEMENTATION` | define | undefined | Define this to enable compilation of the library's implementation. Meaningless if `TOML_ALL_INLINE` is `1`. |
|
||||
| `TOML_LARGE_FILES` | boolean | `0` | Uses 32-bit integers for line and column indices (instead of 16-bit). |
|
||||
| `TOML_OPTIONAL_TYPE` | type name | undefined | Overrides the `optional<T>` type used by the library if you need [something better than std::optional]. |
|
||||
| `TOML_PARSER` | boolean | `1` | Disable this to prevent inclusion of the parser-related parts of the library if you don't need them. |
|
||||
| `TOML_SMALL_FLOAT_TYPE` | type name | undefined | If your codebase has an additional 'small' float type (e.g. half-precision), this tells toml++ about it. |
|
||||
| `TOML_SMALL_INT_TYPE` | type name | undefined | If your codebase has an additional 'small' integer type (e.g. 24-bits), this tells toml++ about it. |
|
||||
| `TOML_UNRELEASED_FEATURES` | boolean | `0` | Enables support for [unreleased TOML language features] not yet part of a [numbered version]. |
|
||||
| `TOML_WINDOWS_COMPAT` | boolean | `1` on Windows | Enables support for transparent conversion between wide and narrow strings in some places when building for Windows. |
|
||||
|
||||
> ℹ _A number of these have ABI implications; the library uses inline namespaces to prevent you from accidentally
|
||||
linking incompatible combinations together._
|
||||
@ -180,6 +181,7 @@ UTF-8 decoding is performed using a state machine based on Bjoern Hoehrmann's '[
|
||||
- **[@bjadamson](https://github.com/bjadamson)** - Reported some bugs and helped design a new feature
|
||||
- **[@bobfang1992](https://github.com/bobfang1992)** - Reported a bug and created a [wrapper in python](https://github.com/bobfang1992/pytomlpp)
|
||||
- **[@GiulioRomualdi](https://github.com/GiulioRomualdi)** - Added cmake+meson support
|
||||
- **[@levicki](https://github.com/levicki)** - Helped design some new features
|
||||
- **[@mosra](https://github.com/mosra)** - Created the awesome [m.css] used to generate the API docs
|
||||
- **[@ned14](https://github.com/ned14)** - Reported a bunch of bugs and helped design some new features
|
||||
- **[@okureta](https://github.com/okureta)** - Reported a bug
|
||||
|
@ -40,26 +40,26 @@ INHERIT_DOCS = YES
|
||||
SEPARATE_MEMBER_PAGES = NO
|
||||
TAB_SIZE = 4
|
||||
ALIASES = \
|
||||
"cpp=@code{.cpp}" \
|
||||
"ecpp=@endcode" \
|
||||
"out=@code{.shell-session}" \
|
||||
"eout=@endcode" \
|
||||
"bash=@code{.sh}" \
|
||||
"ebash=@endcode" \
|
||||
"detail=@details" \
|
||||
"gh{1}=<a href=\"https://github.com/\1\" target=\"_blank\">\1</a>" \
|
||||
"gh2{2}=<a href=\"https://github.com/\1\" target=\"_blank\">\2</a>" \
|
||||
"godbolt{1}=<a href=\"https://godbolt.org/z/\1\" target=\"_blank\">Try this code on Compiler Explorer</a>" \
|
||||
"m_div{1}=@xmlonly<mcss:div xmlns:mcss=\"http://mcss.mosra.cz/doxygen/\" mcss:class=\"\1\">@endxmlonly" \
|
||||
"m_enddiv=@xmlonly</mcss:div>@endxmlonly" \
|
||||
"m_span{1}=@xmlonly<mcss:span xmlns:mcss=\"http://mcss.mosra.cz/doxygen/\" mcss:class=\"\1\">@endxmlonly" \
|
||||
"m_endspan=@xmlonly</mcss:span>@endxmlonly" \
|
||||
"m_class{1}=@xmlonly<mcss:class xmlns:mcss=\"http://mcss.mosra.cz/doxygen/\" mcss:class=\"\1\" />@endxmlonly" \
|
||||
"m_footernavigation=@xmlonly<mcss:footernavigation xmlns:mcss=\"http://mcss.mosra.cz/doxygen/\" />@endxmlonly" \
|
||||
"m_examplenavigation{2}=@xmlonly<mcss:examplenavigation xmlns:mcss=\"http://mcss.mosra.cz/doxygen/\" mcss:page=\"\1\" mcss:prefix=\"\2\" />@endxmlonly" \
|
||||
"m_keywords{1}=@xmlonly<mcss:search xmlns:mcss=\"http://mcss.mosra.cz/doxygen/\" mcss:keywords=\"\1\" />@endxmlonly" \
|
||||
"m_keyword{3}=@xmlonly<mcss:search xmlns:mcss=\"http://mcss.mosra.cz/doxygen/\" mcss:keyword=\"\1\" mcss:title=\"\2\" mcss:suffix-length=\"\3\" />@endxmlonly" \
|
||||
"m_enum_values_as_keywords=@xmlonly<mcss:search xmlns:mcss=\"http://mcss.mosra.cz/doxygen/\" mcss:enum-values-as-keywords=\"true\" />@endxmlonly"
|
||||
"cpp=@code{.cpp}" \
|
||||
"ecpp=@endcode" \
|
||||
"out=@code{.shell-session}" \
|
||||
"eout=@endcode" \
|
||||
"bash=@code{.sh}" \
|
||||
"ebash=@endcode" \
|
||||
"detail=@details" \
|
||||
"gh{1}=<a href=\"https://github.com/\1\" target=\"_blank\">\1</a>" \
|
||||
"gh2{2}=<a href=\"https://github.com/\1\" target=\"_blank\">\2</a>" \
|
||||
"godbolt{1}=<a href=\"https://godbolt.org/z/\1\" target=\"_blank\">Try this code on Compiler Explorer</a>" \
|
||||
"m_div{1}=@xmlonly<mcss:div xmlns:mcss=\"http://mcss.mosra.cz/doxygen/\" mcss:class=\"\1\">@endxmlonly" \
|
||||
"m_enddiv=@xmlonly</mcss:div>@endxmlonly" \
|
||||
"m_span{1}=@xmlonly<mcss:span xmlns:mcss=\"http://mcss.mosra.cz/doxygen/\" mcss:class=\"\1\">@endxmlonly" \
|
||||
"m_endspan=@xmlonly</mcss:span>@endxmlonly" \
|
||||
"m_class{1}=@xmlonly<mcss:class xmlns:mcss=\"http://mcss.mosra.cz/doxygen/\" mcss:class=\"\1\" />@endxmlonly" \
|
||||
"m_footernavigation=@xmlonly<mcss:footernavigation xmlns:mcss=\"http://mcss.mosra.cz/doxygen/\" />@endxmlonly" \
|
||||
"m_examplenavigation{2}=@xmlonly<mcss:examplenavigation xmlns:mcss=\"http://mcss.mosra.cz/doxygen/\" mcss:page=\"\1\" mcss:prefix=\"\2\" />@endxmlonly" \
|
||||
"m_keywords{1}=@xmlonly<mcss:search xmlns:mcss=\"http://mcss.mosra.cz/doxygen/\" mcss:keywords=\"\1\" />@endxmlonly" \
|
||||
"m_keyword{3}=@xmlonly<mcss:search xmlns:mcss=\"http://mcss.mosra.cz/doxygen/\" mcss:keyword=\"\1\" mcss:title=\"\2\" mcss:suffix-length=\"\3\" />@endxmlonly" \
|
||||
"m_enum_values_as_keywords=@xmlonly<mcss:search xmlns:mcss=\"http://mcss.mosra.cz/doxygen/\" mcss:enum-values-as-keywords=\"true\" />@endxmlonly"
|
||||
TCL_SUBST =
|
||||
OPTIMIZE_OUTPUT_FOR_C = NO
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
@ -309,30 +309,32 @@ EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = NO
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED = TOML_DOXYGEN=1 \
|
||||
TOML_ALWAYS_INLINE=inline \
|
||||
TOML_MAY_THROW= \
|
||||
TOML_NODISCARD_CTOR= \
|
||||
TOML_EXTERNAL_LINKAGE= \
|
||||
TOML_API= \
|
||||
TOML_ABI_NAMESPACE_START(x)= \
|
||||
TOML_ABI_NAMESPACE_END= \
|
||||
TOML_ATTR(...)= \
|
||||
TOML_PUSH_WARNINGS= \
|
||||
TOML_DISABLE_SWITCH_WARNINGS= \
|
||||
TOML_DISABLE_INIT_WARNINGS= \
|
||||
TOML_DISABLE_VTABLE_WARNINGS= \
|
||||
TOML_DISABLE_PADDING_WARNINGS= \
|
||||
TOML_DISABLE_FLOAT_WARNINGS= \
|
||||
TOML_DISABLE_SHADOW_WARNINGS= \
|
||||
TOML_DISABLE_SUGGEST_WARNINGS= \
|
||||
TOML_DISABLE_ALL_WARNINGS= \
|
||||
TOML_POP_WARNINGS= \
|
||||
TOML_ASYMMETRICAL_EQUALITY_OPS(...)= \
|
||||
__cplusplus=201703L \
|
||||
__has_include(x)=0 \
|
||||
__has_attribute(x)=0 \
|
||||
__cpp_lib_char8_t=201811L
|
||||
PREDEFINED = DOXYGEN=1 \
|
||||
NDEBUG=1 \
|
||||
__cplusplus=201703L \
|
||||
__has_include(x)=0 \
|
||||
__has_attribute(x)=0 \
|
||||
__cpp_lib_char8_t=201811L \
|
||||
TOML_ALWAYS_INLINE=inline \
|
||||
TOML_MAY_THROW= \
|
||||
TOML_NODISCARD_CTOR= \
|
||||
TOML_EXTERNAL_LINKAGE= \
|
||||
TOML_API= \
|
||||
TOML_ABI_NAMESPACE_START(...)= \
|
||||
TOML_ABI_NAMESPACE_BOOL(...)= \
|
||||
TOML_ABI_NAMESPACE_END= \
|
||||
TOML_ATTR(...)= \
|
||||
TOML_PUSH_WARNINGS= \
|
||||
TOML_DISABLE_SWITCH_WARNINGS= \
|
||||
TOML_DISABLE_INIT_WARNINGS= \
|
||||
TOML_DISABLE_VTABLE_WARNINGS= \
|
||||
TOML_DISABLE_PADDING_WARNINGS= \
|
||||
TOML_DISABLE_FLOAT_WARNINGS= \
|
||||
TOML_DISABLE_SHADOW_WARNINGS= \
|
||||
TOML_DISABLE_SUGGEST_WARNINGS= \
|
||||
TOML_DISABLE_ALL_WARNINGS= \
|
||||
TOML_POP_WARNINGS= \
|
||||
TOML_ASYMMETRICAL_EQUALITY_OPS(...)=
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
|
@ -227,10 +227,10 @@
|
||||
///
|
||||
/// // different ways of directly querying data
|
||||
/// std::optional<std::string_view> str1 = tbl["str"].value<std::string_view>();
|
||||
/// std::optional<std::string> str2 = tbl["str"].value<std::string>();
|
||||
/// std::string_view str3 = tbl["str"].value_or("");
|
||||
/// std::string str4 = tbl["str"].value_or(std::string{});
|
||||
/// std::string& str5 = tbl["str"].ref<std::string>(); // ~~dangerous~~, but fast
|
||||
/// std::optional<std::string> str2 = tbl["str"].value<std::string>();
|
||||
/// std::string_view str3 = tbl["str"].value_or("");
|
||||
/// std::string str4 = tbl["str"].value_or(std::string{});
|
||||
/// std::string& str5 = tbl["str"].ref<std::string>(); // ~~dangerous~~, but fast
|
||||
///
|
||||
/// std::cout << *str1 << "\n";
|
||||
/// std::cout << *str2 << "\n";
|
||||
@ -443,7 +443,7 @@
|
||||
///
|
||||
/// \subsection mainpage-adding-lib-conan Conan
|
||||
/// Add `tomlplusplus/1.3.3` to your conanfile. This adds the single-header version by default, but you can specify the
|
||||
/// regular version using `multiple_headers": True`.
|
||||
/// regular version using `"multiple_headers": True`.
|
||||
///
|
||||
//////////////////////////////////
|
||||
///
|
||||
|
@ -34,8 +34,15 @@ odt1 = 1979-05-27T07:32:00Z
|
||||
odt2 = 1979-05-27T00:32:00-07:00
|
||||
odt3 = 1979-05-27T00:32:00.999999-07:00
|
||||
|
||||
# unicode
|
||||
kosme = "κόσμε"
|
||||
# strings
|
||||
str1 = """
|
||||
This is a
|
||||
multi-line
|
||||
string.
|
||||
"""
|
||||
str2 = "This is also\na multi-line\nstring."
|
||||
str3 = 'C:\highway\to\the\danger\zone'
|
||||
kosme = "κόσμε" # unicode!
|
||||
|
||||
arr = [ 'this', 'is', 'a', 'long', 'array', 'with', 16, 'elements.', 'it', 'should', 'be', 'printed', 'as', 'a', 'multiline', 'array.']
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
#define NOMETAFILE // - typedef METAFILEPICT
|
||||
#define NOMINMAX // - Macros min(a,b) and max(a,b)
|
||||
#define NOMSG // - typedef MSG and associated routines
|
||||
#define NONLS // - All NLS defines and routines
|
||||
//#define NONLS // - All NLS defines and routines
|
||||
#define NOOPENFILE // - OpenFile(), OemToAnsi, AnsiToOem, and OF_*
|
||||
#define NOPROFILER // - Profiler interface.
|
||||
#define NORASTEROPS // - Binary and Tertiary raster ops
|
||||
|
@ -69,7 +69,6 @@
|
||||
#undef TOML_UNREACHABLE
|
||||
#undef TOML_INTERFACE
|
||||
#undef TOML_EMPTY_BASES
|
||||
#undef TOML_CPP_VERSION
|
||||
#undef TOML_CPP
|
||||
#undef TOML_MAY_THROW
|
||||
#undef TOML_NO_DEFAULT_CASE
|
||||
@ -82,7 +81,6 @@
|
||||
#undef TOML_LANG_HIGHER_THAN
|
||||
#undef TOML_LANG_AT_LEAST
|
||||
#undef TOML_LANG_UNRELEASED
|
||||
#undef TOML_STRING_PREFIX_1
|
||||
#undef TOML_STRING_PREFIX
|
||||
#undef TOML_UNDEF_MACROS
|
||||
#undef TOML_RELOPS_REORDERING
|
||||
@ -96,9 +94,15 @@
|
||||
#undef TOML_TRIVIAL_ABI
|
||||
#undef TOML_ABI_NAMESPACES
|
||||
#undef TOML_ABI_NAMESPACE_START
|
||||
#undef TOML_ABI_NAMESPACE_BOOL
|
||||
#undef TOML_ABI_NAMESPACE_END
|
||||
#undef TOML_PARSER_TYPENAME
|
||||
#undef TOML_LAUNDER
|
||||
#undef TOML_CONCAT_1
|
||||
#undef TOML_CONCAT
|
||||
#undef TOML_EVAL_BOOL_1
|
||||
#undef TOML_EVAL_BOOL_0
|
||||
#undef TOML_HAS_CUSTOM_OPTIONAL_TYPE
|
||||
#endif
|
||||
|
||||
//# {{
|
||||
|
@ -185,11 +185,20 @@ namespace toml::impl
|
||||
}
|
||||
else
|
||||
{
|
||||
static_assert(
|
||||
!is_wide_string<T> || TOML_WINDOWS_COMPAT,
|
||||
"Instantiating values from wide-character strings is only supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
);
|
||||
static_assert(
|
||||
is_value_or_promotable<type>,
|
||||
"Value initializers must be (or be promotable to) one of the TOML value types"
|
||||
);
|
||||
return new value{ std::forward<T>(val) };
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
if constexpr (is_wide_string<T>)
|
||||
return new value{ narrow(std::forward<T>(val)) };
|
||||
else
|
||||
#endif
|
||||
return new value{ std::forward<T>(val) };
|
||||
}
|
||||
}
|
||||
|
||||
@ -656,7 +665,6 @@ namespace toml
|
||||
/// \returns Iterator to the first node immediately following the last removed node.
|
||||
iterator erase(const_iterator first, const_iterator last) noexcept;
|
||||
|
||||
|
||||
/// \brief Resizes the array.
|
||||
///
|
||||
/// \detail \cpp
|
||||
@ -943,6 +951,7 @@ namespace toml
|
||||
return static_cast<toml::array&&>(static_cast<toml::array&>(*this).flatten());
|
||||
}
|
||||
|
||||
/// \brief Prints the array out to a stream as formatted TOML.
|
||||
template <typename Char>
|
||||
friend std::basic_ostream<Char>& operator << (std::basic_ostream<Char>&, const array&);
|
||||
};
|
||||
|
@ -22,7 +22,7 @@ TOML_DISABLE_ALL_WARNINGS
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <iosfwd>
|
||||
#ifndef TOML_OPTIONAL_TYPE
|
||||
#if !TOML_HAS_CUSTOM_OPTIONAL_TYPE
|
||||
#include <optional>
|
||||
#endif
|
||||
|
||||
@ -40,6 +40,10 @@ TOML_POP_WARNINGS
|
||||
|
||||
////////// FORWARD DECLARATIONS & TYPEDEFS
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_PADDING_WARNINGS
|
||||
TOML_DISABLE_SHADOW_WARNINGS
|
||||
|
||||
/// \brief The root namespace for all toml++ functions and types.
|
||||
namespace toml
|
||||
{
|
||||
@ -78,9 +82,30 @@ namespace toml
|
||||
|
||||
#endif
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_PADDING_WARNINGS
|
||||
TOML_DISABLE_SHADOW_WARNINGS // false positive on gcc
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
namespace impl
|
||||
{
|
||||
[[nodiscard]] TOML_API std::string narrow_char(std::wstring_view) noexcept;
|
||||
#ifdef __cpp_lib_char8_t
|
||||
[[nodiscard]] TOML_API std::u8string narrow_char8(std::wstring_view) noexcept;
|
||||
#endif
|
||||
template <typename Char = string_char>
|
||||
[[nodiscard]] auto narrow(std::wstring_view str) noexcept
|
||||
{
|
||||
#ifdef __cpp_lib_char8_t
|
||||
if constexpr (std::is_same_v<Char, char8_t>)
|
||||
return narrow_char8(str);
|
||||
else
|
||||
#endif
|
||||
return narrow_char(str);
|
||||
}
|
||||
|
||||
[[nodiscard]] TOML_API std::wstring widen(std::string_view) noexcept;
|
||||
#ifdef __cpp_lib_char8_t
|
||||
[[nodiscard]] TOML_API std::wstring widen(std::u8string_view) noexcept;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !TOML_DOXYGEN
|
||||
|
||||
@ -97,15 +122,11 @@ namespace toml
|
||||
template <typename> class default_formatter;
|
||||
template <typename> class json_formatter;
|
||||
|
||||
#ifdef TOML_OPTIONAL_TYPE
|
||||
TOML_ABI_NAMESPACE_START(custopt)
|
||||
#else
|
||||
TOML_ABI_NAMESPACE_START(stdopt)
|
||||
#endif
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_HAS_CUSTOM_OPTIONAL_TYPE, custopt, stdopt)
|
||||
|
||||
struct date_time;
|
||||
|
||||
TOML_ABI_NAMESPACE_END // TOML_OPTIONAL_TYPE
|
||||
TOML_ABI_NAMESPACE_END // TOML_HAS_CUSTOM_OPTIONAL_TYPE
|
||||
|
||||
#endif // !TOML_DOXYGEN
|
||||
|
||||
@ -124,9 +145,7 @@ namespace toml
|
||||
date_time ///< The node is a toml::value<date_time>.
|
||||
};
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_PADDING_WARNINGS, TOML_DISABLE_SHADOW_WARNINGS
|
||||
|
||||
#ifdef TOML_OPTIONAL_TYPE
|
||||
#if TOML_HAS_CUSTOM_OPTIONAL_TYPE
|
||||
|
||||
template <typename T>
|
||||
using optional = TOML_OPTIONAL_TYPE<T>;
|
||||
@ -157,11 +176,7 @@ namespace toml
|
||||
/// \brief A pointer to a shared string resource containing a source path.
|
||||
using source_path_ptr = std::shared_ptr<const std::string>;
|
||||
|
||||
#if TOML_LARGE_FILES
|
||||
TOML_ABI_NAMESPACE_START(lf)
|
||||
#else
|
||||
TOML_ABI_NAMESPACE_START(sf)
|
||||
#endif
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_LARGE_FILES, lf, sf)
|
||||
|
||||
/// \brief A source document line-and-column pair.
|
||||
///
|
||||
@ -276,6 +291,23 @@ namespace toml
|
||||
///
|
||||
/// \remarks This will be `nullptr` if no path was provided to toml::parse().
|
||||
source_path_ptr path;
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief The path to the corresponding source document as a wide-string.
|
||||
///
|
||||
/// \remarks This will return an empty optional if no path was provided to toml::parse().
|
||||
///
|
||||
/// \attention This function is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
[[nodiscard]]
|
||||
optional<std::wstring> wide_path() const noexcept
|
||||
{
|
||||
if (!path || path->empty())
|
||||
return {};
|
||||
return { impl::widen(*path) };
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
TOML_ABI_NAMESPACE_END // TOML_LARGE_FILES
|
||||
@ -346,6 +378,15 @@ namespace toml::impl
|
||||
|| std::is_same_v<T, time>
|
||||
|| std::is_same_v<T, date_time>;
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_wide_string = is_one_of<
|
||||
std::decay_t<T>,
|
||||
const wchar_t*,
|
||||
wchar_t*,
|
||||
std::wstring_view,
|
||||
std::wstring
|
||||
>;
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_value_or_promotable =
|
||||
is_value<T>
|
||||
@ -358,6 +399,9 @@ namespace toml::impl
|
||||
|| std::is_same_v<T, uint16_t>
|
||||
|| std::is_same_v<T, uint8_t>
|
||||
|| std::is_same_v<T, float>
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|| is_wide_string<T>
|
||||
#endif
|
||||
#ifdef TOML_SMALL_FLOAT_TYPE
|
||||
|| std::is_same_v<T, TOML_SMALL_FLOAT_TYPE>
|
||||
#endif
|
||||
@ -399,6 +443,18 @@ namespace toml::impl
|
||||
template <size_t N> struct value_promoter<string_char(&&)[N]> { using type = string; };
|
||||
template <> struct value_promoter<string_char*> { using type = string; };
|
||||
template <> struct value_promoter<string_view> { using type = string; };
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
template <size_t N> struct value_promoter<const wchar_t[N]> { using type = string; };
|
||||
template <size_t N> struct value_promoter<const wchar_t(&)[N]> { using type = string; };
|
||||
template <size_t N> struct value_promoter<const wchar_t(&&)[N]> { using type = string; };
|
||||
template <> struct value_promoter<const wchar_t*> { using type = string; };
|
||||
template <size_t N> struct value_promoter<wchar_t[N]> { using type = string; };
|
||||
template <size_t N> struct value_promoter<wchar_t(&)[N]> { using type = string; };
|
||||
template <size_t N> struct value_promoter<wchar_t(&&)[N]> { using type = string; };
|
||||
template <> struct value_promoter<wchar_t*> { using type = string; };
|
||||
template <> struct value_promoter<std::wstring_view> { using type = string; };
|
||||
template <> struct value_promoter<std::wstring> { using type = string; };
|
||||
#endif
|
||||
template <> struct value_promoter<int32_t> { using type = int64_t; };
|
||||
template <> struct value_promoter<int16_t> { using type = int64_t; };
|
||||
template <> struct value_promoter<int8_t> { using type = int64_t; };
|
||||
@ -592,3 +648,5 @@ namespace toml
|
||||
};
|
||||
template <typename T> inserter(T&&) -> inserter<T>;
|
||||
}
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_PADDING_WARNINGS, TOML_DISABLE_SHADOW_WARNINGS
|
||||
|
@ -300,11 +300,7 @@ namespace toml
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const time_offset&);
|
||||
#endif
|
||||
|
||||
#ifdef TOML_OPTIONAL_TYPE
|
||||
TOML_ABI_NAMESPACE_START(custopt)
|
||||
#else
|
||||
TOML_ABI_NAMESPACE_START(stdopt)
|
||||
#endif
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_HAS_CUSTOM_OPTIONAL_TYPE, custopt, stdopt)
|
||||
|
||||
/// \brief A date-time.
|
||||
struct date_time
|
||||
@ -407,7 +403,7 @@ namespace toml
|
||||
}
|
||||
};
|
||||
|
||||
TOML_ABI_NAMESPACE_END // TOML_OPTIONAL_TYPE
|
||||
TOML_ABI_NAMESPACE_END // TOML_HAS_CUSTOM_OPTIONAL_TYPE
|
||||
|
||||
/// \brief Prints a date_time out to a stream in RFC 3339 format.
|
||||
/// \detail \cpp
|
||||
|
@ -88,7 +88,11 @@ namespace toml
|
||||
}
|
||||
|
||||
if (requiresQuotes)
|
||||
base::print_quoted_string(str);
|
||||
{
|
||||
impl::print_to_stream('"', base::stream());
|
||||
impl::print_to_stream_with_escapes(str, base::stream());
|
||||
impl::print_to_stream('"', base::stream());
|
||||
}
|
||||
else
|
||||
impl::print_to_stream(str, base::stream());
|
||||
}
|
||||
@ -320,12 +324,16 @@ namespace toml
|
||||
|
||||
public:
|
||||
|
||||
/// \brief The default flags for a default_formatter.
|
||||
static constexpr format_flags default_flags
|
||||
= format_flags::allow_literal_strings | format_flags::allow_multi_line_strings;
|
||||
|
||||
/// \brief Constructs a default formatter and binds it to a TOML object.
|
||||
///
|
||||
/// \param source The source TOML object.
|
||||
/// \param flags Format option flags.
|
||||
TOML_NODISCARD_CTOR
|
||||
explicit default_formatter(const toml::node& source, format_flags flags = {}) noexcept
|
||||
explicit default_formatter(const toml::node& source, format_flags flags = default_flags) noexcept
|
||||
: base{ source, flags }
|
||||
{}
|
||||
|
||||
@ -377,12 +385,27 @@ namespace toml
|
||||
return lhs << default_formatter<Char>{ rhs };
|
||||
}
|
||||
|
||||
template <typename Char, typename T>
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const value<T>& rhs)
|
||||
{
|
||||
return lhs << default_formatter<Char>{ rhs };
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, default_formatter<char>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, default_formatter<char>&&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const table&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const array&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<toml::string>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<int64_t>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<double>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<bool>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<toml::date>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<toml::time>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<toml::date_time>&);
|
||||
#endif
|
||||
}
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_SWITCH_WARNINGS, TOML_DISABLE_PADDING_WARNINGS
|
||||
|
||||
|
@ -206,3 +206,91 @@ namespace toml
|
||||
}
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_SWITCH_WARNINGS, TOML_DISABLE_FLOAT_WARNINGS
|
||||
|
||||
// implementations of windows wide string nonsense
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_ALL_WARNINGS
|
||||
#include <Windows.h> // fuckkkk :(
|
||||
TOML_POP_WARNINGS
|
||||
|
||||
namespace toml::impl
|
||||
{
|
||||
TOML_API
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::string narrow_char(std::wstring_view str) noexcept
|
||||
{
|
||||
if (str.empty())
|
||||
return {};
|
||||
|
||||
std::string s;
|
||||
const auto len = WideCharToMultiByte(
|
||||
65001, 0, str.data(), static_cast<int>(str.length()), nullptr, 0, nullptr, nullptr
|
||||
);
|
||||
if (len)
|
||||
{
|
||||
s.resize(static_cast<size_t>(len));
|
||||
WideCharToMultiByte(65001, 0, str.data(), static_cast<int>(str.length()), s.data(), len, nullptr, nullptr);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
#ifdef __cpp_lib_char8_t
|
||||
|
||||
TOML_API
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::u8string narrow_char8(std::wstring_view str) noexcept
|
||||
{
|
||||
if (str.empty())
|
||||
return {};
|
||||
|
||||
std::u8string s;
|
||||
const auto len = WideCharToMultiByte(
|
||||
65001, 0, str.data(), static_cast<int>(str.length()), nullptr, 0, nullptr, nullptr
|
||||
);
|
||||
if (len)
|
||||
{
|
||||
s.resize(static_cast<size_t>(len));
|
||||
WideCharToMultiByte(
|
||||
65001, 0, str.data(), static_cast<int>(str.length()), reinterpret_cast<char*>(s.data()), len, nullptr, nullptr
|
||||
);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
#endif // __cpp_lib_char8_t
|
||||
|
||||
TOML_API
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::wstring widen(std::string_view str) noexcept
|
||||
{
|
||||
if (str.empty())
|
||||
return {};
|
||||
|
||||
std::wstring s;
|
||||
const auto len = MultiByteToWideChar(65001, 0, str.data(), static_cast<int>(str.length()), nullptr, 0);
|
||||
if (len)
|
||||
{
|
||||
s.resize(static_cast<size_t>(len));
|
||||
MultiByteToWideChar(65001, 0, str.data(), static_cast<int>(str.length()), s.data(), len);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
#ifdef __cpp_lib_char8_t
|
||||
|
||||
TOML_API
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::wstring widen(std::u8string_view str) noexcept
|
||||
{
|
||||
if (str.empty())
|
||||
return {};
|
||||
|
||||
return widen(std::string_view{ reinterpret_cast<const char*>(str.data()), str.length() });
|
||||
}
|
||||
|
||||
#endif // __cpp_lib_char8_t
|
||||
}
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
@ -15,8 +15,17 @@ namespace toml
|
||||
/// \brief Format flags for modifying how TOML data is printed to streams.
|
||||
enum class format_flags : uint8_t
|
||||
{
|
||||
/// \brief None.
|
||||
none,
|
||||
quote_dates_and_times = 1
|
||||
|
||||
/// \brief Sates and times will be emitted as quoted strings.
|
||||
quote_dates_and_times = 1,
|
||||
|
||||
/// \brief Strings will be emitted as single-quoted literal strings where possible.
|
||||
allow_literal_strings = 2,
|
||||
|
||||
/// \brief Strings containing newlines will be emitted as triple-quoted 'multi-line' strings where possible.
|
||||
allow_multi_line_strings = 4,
|
||||
};
|
||||
|
||||
[[nodiscard]]
|
||||
@ -51,7 +60,6 @@ namespace toml::impl
|
||||
protected:
|
||||
|
||||
[[nodiscard]] const toml::node& source() const noexcept { return *source_; }
|
||||
[[nodiscard]] format_flags flags() const noexcept { return flags_; }
|
||||
[[nodiscard]] std::basic_ostream<Char>& stream() const noexcept { return *stream_; }
|
||||
|
||||
static constexpr size_t indent_columns = 4;
|
||||
@ -61,8 +69,28 @@ namespace toml::impl
|
||||
void increase_indent() noexcept { indent_++; }
|
||||
void decrease_indent() noexcept { indent_--; }
|
||||
|
||||
TOML_ALWAYS_INLINE
|
||||
void clear_naked_newline() noexcept { naked_newline_ = false; }
|
||||
[[nodiscard]]
|
||||
bool quote_dates_and_times() const noexcept
|
||||
{
|
||||
return (flags_ & format_flags::quote_dates_and_times) != format_flags::none;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
bool literal_strings_allowed() const noexcept
|
||||
{
|
||||
return (flags_ & format_flags::allow_literal_strings) != format_flags::none;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
bool multi_line_strings_allowed() const noexcept
|
||||
{
|
||||
return (flags_ & format_flags::allow_multi_line_strings) != format_flags::none;
|
||||
}
|
||||
|
||||
void clear_naked_newline() noexcept
|
||||
{
|
||||
naked_newline_ = false;
|
||||
}
|
||||
|
||||
void attach(std::basic_ostream<Char>& stream) noexcept
|
||||
{
|
||||
@ -94,17 +122,62 @@ namespace toml::impl
|
||||
}
|
||||
}
|
||||
|
||||
void print_quoted_string(toml::string_view str)
|
||||
void print_quoted_string(toml::string_view str, bool allow_multi_line = true)
|
||||
{
|
||||
auto literals = literal_strings_allowed();
|
||||
if (str.empty())
|
||||
print_to_stream("\"\""sv, *stream_);
|
||||
{
|
||||
print_to_stream(literals ? "''"sv : "\"\""sv, *stream_);
|
||||
clear_naked_newline();
|
||||
return;
|
||||
}
|
||||
|
||||
auto multi_line = allow_multi_line && multi_line_strings_allowed();
|
||||
if (multi_line || literals)
|
||||
{
|
||||
utf8_decoder decoder;
|
||||
bool has_line_breaks = false;
|
||||
bool has_control_chars = false;
|
||||
bool has_single_quotes = false;
|
||||
for (size_t i = 0; i < str.length() && !(has_line_breaks && has_control_chars && has_single_quotes); i++)
|
||||
{
|
||||
decoder(static_cast<uint8_t>(str[i]));
|
||||
if (decoder.error())
|
||||
{
|
||||
has_line_breaks = false;
|
||||
has_control_chars = true; //force ""
|
||||
has_single_quotes = true;
|
||||
break;
|
||||
}
|
||||
else if (decoder.has_code_point())
|
||||
{
|
||||
if (is_line_break(decoder.codepoint))
|
||||
has_line_breaks = true;
|
||||
else if (is_nontab_control_character(decoder.codepoint))
|
||||
has_control_chars = true;
|
||||
else if (decoder.codepoint == U'\'')
|
||||
has_single_quotes = true;
|
||||
}
|
||||
}
|
||||
multi_line = multi_line && has_line_breaks;
|
||||
literals = literals && !has_control_chars && !(!multi_line && has_single_quotes);
|
||||
}
|
||||
|
||||
if (literals)
|
||||
{
|
||||
const auto quot = multi_line ? "'''"sv : "'"sv;
|
||||
print_to_stream(quot, *stream_);
|
||||
print_to_stream(str, *stream_);
|
||||
print_to_stream(quot, *stream_);
|
||||
}
|
||||
else
|
||||
{
|
||||
print_to_stream('"', *stream_);
|
||||
const auto quot = multi_line ? R"(""")"sv : R"(")"sv;
|
||||
print_to_stream(quot, *stream_);
|
||||
print_to_stream_with_escapes(str, *stream_);
|
||||
print_to_stream('"', *stream_);
|
||||
print_to_stream(quot, *stream_);
|
||||
}
|
||||
naked_newline_ = false;
|
||||
clear_naked_newline();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -123,17 +196,18 @@ namespace toml::impl
|
||||
|
||||
if constexpr (is_dt)
|
||||
{
|
||||
if ((flags_ & format_flags::quote_dates_and_times) != format_flags::none)
|
||||
print_to_stream('"', *stream_);
|
||||
}
|
||||
|
||||
*stream_ << val;
|
||||
|
||||
if constexpr (is_dt)
|
||||
{
|
||||
if ((flags_ & format_flags::quote_dates_and_times) != format_flags::none)
|
||||
print_to_stream('"', *stream_);
|
||||
if (quote_dates_and_times())
|
||||
{
|
||||
const auto quot = literal_strings_allowed() ? '\'' : '"';
|
||||
print_to_stream(quot, *stream_);
|
||||
print_to_stream(*val, *stream_);
|
||||
print_to_stream(quot, *stream_);
|
||||
}
|
||||
else
|
||||
print_to_stream(*val, *stream_);
|
||||
}
|
||||
else
|
||||
print_to_stream(*val, *stream_);
|
||||
|
||||
naked_newline_ = false;
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ TOML_POP_WARNINGS
|
||||
#include "toml_default_formatter.h"
|
||||
#include "toml_json_formatter.h"
|
||||
|
||||
// template instantiations
|
||||
namespace toml
|
||||
{
|
||||
// value<>
|
||||
@ -77,26 +78,32 @@ namespace toml
|
||||
template TOML_API void print_floating_point_to_stream(float, std::ostream&, bool);
|
||||
template TOML_API void print_floating_point_to_stream(double, std::ostream&, bool);
|
||||
}
|
||||
|
||||
// parser machinery
|
||||
#if TOML_PARSER
|
||||
|
||||
// parse error ostream
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const parse_error&);
|
||||
|
||||
// parse() and parse_file()
|
||||
#if TOML_EXCEPTIONS
|
||||
TOML_ABI_NAMESPACE_START(parse_ex)
|
||||
#else
|
||||
TOML_ABI_NAMESPACE_START(parse_noex)
|
||||
#endif
|
||||
template TOML_API parse_result parse(std::istream&, std::string_view) TOML_MAY_THROW;
|
||||
template TOML_API parse_result parse(std::istream&, std::string&&) TOML_MAY_THROW;
|
||||
template TOML_API parse_result parse_file(std::string_view) TOML_MAY_THROW;
|
||||
#ifdef __cpp_lib_char8_t
|
||||
template TOML_API parse_result parse_file(std::u8string_view) TOML_MAY_THROW;
|
||||
#endif
|
||||
TOML_ABI_NAMESPACE_END // TOML_EXCEPTIONS
|
||||
|
||||
#endif // TOML_PARSER
|
||||
}
|
||||
|
||||
|
||||
// parser instantiations
|
||||
#if TOML_PARSER
|
||||
|
||||
#include "toml_parser.h"
|
||||
|
||||
namespace toml
|
||||
{
|
||||
// parse error ostream
|
||||
template TOML_API std::ostream& operator << (std::ostream&, const parse_error&);
|
||||
|
||||
// parse() and parse_file()
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, parse_ex, parse_noex)
|
||||
|
||||
template TOML_API parse_result parse(std::istream&, std::string_view) TOML_MAY_THROW;
|
||||
template TOML_API parse_result parse(std::istream&, std::string&&) TOML_MAY_THROW;
|
||||
template TOML_API parse_result parse_file(std::string_view) TOML_MAY_THROW;
|
||||
#ifdef __cpp_lib_char8_t
|
||||
template TOML_API parse_result parse_file(std::u8string_view) TOML_MAY_THROW;
|
||||
#endif
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
template TOML_API parse_result parse_file(std::wstring_view) TOML_MAY_THROW;
|
||||
#endif
|
||||
|
||||
TOML_ABI_NAMESPACE_END // TOML_EXCEPTIONS
|
||||
}
|
||||
#endif // TOML_PARSER
|
||||
|
@ -104,13 +104,16 @@ namespace toml
|
||||
|
||||
public:
|
||||
|
||||
/// \brief The default flags for a json_formatter.
|
||||
static constexpr format_flags default_flags = format_flags::quote_dates_and_times;
|
||||
|
||||
/// \brief Constructs a JSON formatter and binds it to a TOML object.
|
||||
///
|
||||
/// \param source The source TOML object.
|
||||
/// \param flags Format option flags.
|
||||
TOML_NODISCARD_CTOR
|
||||
explicit json_formatter(const toml::node& source, format_flags flags = {}) noexcept
|
||||
: base{ source, flags | format_flags::quote_dates_and_times }
|
||||
explicit json_formatter(const toml::node& source, format_flags flags = default_flags) noexcept
|
||||
: base{ source, flags }
|
||||
{}
|
||||
|
||||
template <typename T, typename U>
|
||||
|
@ -37,7 +37,7 @@ namespace toml
|
||||
base::print_newline(true);
|
||||
base::print_indent();
|
||||
|
||||
base::print_quoted_string(k);
|
||||
base::print_quoted_string(k, false);
|
||||
impl::print_to_stream(" : "sv, base::stream());
|
||||
|
||||
const auto type = v.type();
|
||||
|
@ -48,7 +48,7 @@ namespace toml
|
||||
/// std::cout << tbl["products"][0]["keywords"] << std::endl;
|
||||
/// std::cout << "has product[2]: "sv << !!tbl["products"][2] << std::endl;
|
||||
/// std::cout << "product[2]: "sv << tbl["products"][2] << std::endl;
|
||||
/// \ecpp
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// "my hardware store"
|
||||
@ -89,7 +89,10 @@ namespace toml
|
||||
/// \brief Returns true if the view references a node.
|
||||
[[nodiscard]] explicit operator bool() const noexcept { return node_ != nullptr; }
|
||||
/// \brief Returns the node that's being referenced by the view.
|
||||
[[nodiscard]] viewed_type* get() const noexcept { return node_; }
|
||||
[[nodiscard]] viewed_type* node() const noexcept { return node_; }
|
||||
|
||||
[[nodiscard, deprecated("use node_view::node() instead (the name is better)")]]
|
||||
viewed_type* get() const noexcept { return node_; }
|
||||
|
||||
/// \brief Returns the type identifier for the viewed node.
|
||||
[[nodiscard]] node_type type() const noexcept { return node_ ? node_->type() : node_type::none; }
|
||||
@ -296,13 +299,25 @@ namespace toml
|
||||
template <typename U, typename = std::enable_if_t<impl::is_value_or_promotable<U>>>
|
||||
[[nodiscard]] friend bool operator == (const node_view& lhs, const U& rhs) noexcept
|
||||
{
|
||||
const auto val = lhs.as<impl::promoted<U>>();
|
||||
return val && *val == rhs;
|
||||
static_assert(
|
||||
!impl::is_wide_string<U> || TOML_WINDOWS_COMPAT,
|
||||
"Comparison with wide-character strings is only supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
);
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
if constexpr (impl::is_wide_string<U>)
|
||||
return lhs == impl::narrow(rhs);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
const auto val = lhs.as<impl::promoted<U>>();
|
||||
return val && *val == rhs;
|
||||
}
|
||||
}
|
||||
TOML_ASYMMETRICAL_EQUALITY_OPS(
|
||||
const node_view&,
|
||||
const U&,
|
||||
template <typename U, typename = std::enable_if_t<impl::is_value_or_promotable<U>>>
|
||||
const node_view&,
|
||||
const U&,
|
||||
template <typename U, typename = std::enable_if_t<impl::is_value_or_promotable<U>>>
|
||||
)
|
||||
|
||||
/// \brief Returns true if the viewed node is an array with the same contents as the RHS initializer list.
|
||||
@ -336,6 +351,25 @@ namespace toml
|
||||
return { nullptr };
|
||||
}
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Returns a view of the selected subnode.
|
||||
///
|
||||
/// \param key The key of the node to retrieve
|
||||
///
|
||||
/// \returns A view of the selected node if this node represented a table and it contained a
|
||||
/// value at the given key, or an empty view.
|
||||
///
|
||||
/// \attention This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
[[nodiscard]] node_view operator[] (std::wstring_view key) const noexcept
|
||||
{
|
||||
if (auto tbl = this->as_table())
|
||||
return { tbl->get(key) };
|
||||
return { nullptr };
|
||||
}
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Returns a view of the selected subnode.
|
||||
///
|
||||
/// \param index The index of the node to retrieve
|
||||
|
@ -23,11 +23,7 @@ TOML_DISABLE_VTABLE_WARNINGS
|
||||
|
||||
namespace toml
|
||||
{
|
||||
#if TOML_LARGE_FILES
|
||||
TOML_ABI_NAMESPACE_START(lf)
|
||||
#else
|
||||
TOML_ABI_NAMESPACE_START(sf)
|
||||
#endif
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_LARGE_FILES, lf, sf)
|
||||
|
||||
#if TOML_DOXYGEN || !TOML_EXCEPTIONS
|
||||
|
||||
|
@ -86,7 +86,7 @@ namespace toml
|
||||
[[nodiscard]] bool succeeded() const noexcept { return !is_err; }
|
||||
/// \brief Returns true if parsing failed.
|
||||
[[nodiscard]] bool failed() const noexcept { return is_err; }
|
||||
/// \brief Returns true if parsing succeeeded.
|
||||
/// \brief Returns true if parsing succeeded.
|
||||
[[nodiscard]] explicit operator bool() const noexcept { return !is_err; }
|
||||
|
||||
/// \brief Returns the internal toml::table.
|
||||
@ -208,11 +208,52 @@ namespace toml
|
||||
}
|
||||
|
||||
/// \brief Gets a node_view for the selected key-value pair in the wrapped table (const overload).
|
||||
///
|
||||
/// \param key The key used for the lookup.
|
||||
///
|
||||
/// \returns A view of the value at the given key if parsing was successful and a matching key existed,
|
||||
/// or an empty node view.
|
||||
///
|
||||
/// \see toml::node_view
|
||||
[[nodiscard]] node_view<const node> operator[] (string_view key) const noexcept
|
||||
{
|
||||
return is_err ? node_view<const node>{} : get()[key];
|
||||
}
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Gets a node_view for the selected key-value pair in the wrapped table.
|
||||
///
|
||||
/// \param key The key used for the lookup.
|
||||
///
|
||||
/// \returns A view of the value at the given key if parsing was successful and a matching key existed,
|
||||
/// or an empty node view.
|
||||
///
|
||||
/// \see toml::node_view
|
||||
///
|
||||
/// \attention This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
[[nodiscard]] node_view<node> operator[] (std::wstring_view key) noexcept
|
||||
{
|
||||
return is_err ? node_view<node>{} : get()[key];
|
||||
}
|
||||
|
||||
/// \brief Gets a node_view for the selected key-value pair in the wrapped table (const overload).
|
||||
///
|
||||
/// \param key The key used for the lookup.
|
||||
///
|
||||
/// \returns A view of the value at the given key if parsing was successful and a matching key existed,
|
||||
/// or an empty node view.
|
||||
///
|
||||
/// \see toml::node_view
|
||||
///
|
||||
/// \attention This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
[[nodiscard]] node_view<const node> operator[] (std::wstring_view key) const noexcept
|
||||
{
|
||||
return is_err ? node_view<const node>{} : get()[key];
|
||||
}
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Returns an iterator to the first key-value pair in the wrapped table.
|
||||
/// \remarks Returns a default-constructed 'nothing' iterator if the parsing failed.
|
||||
[[nodiscard]] table_iterator begin() noexcept
|
||||
@ -265,14 +306,9 @@ namespace toml
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
namespace toml::impl
|
||||
{
|
||||
#if TOML_EXCEPTIONS
|
||||
TOML_ABI_NAMESPACE_START(impl_ex)
|
||||
#else
|
||||
TOML_ABI_NAMESPACE_START(impl_noex)
|
||||
#endif
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, impl_ex, impl_noex)
|
||||
|
||||
[[nodiscard]] TOML_API
|
||||
parse_result do_parse(utf8_reader_interface&&) TOML_MAY_THROW;
|
||||
@ -280,14 +316,21 @@ namespace toml::impl
|
||||
TOML_ABI_NAMESPACE_END // TOML_EXCEPTIONS
|
||||
}
|
||||
|
||||
#if TOML_EXCEPTIONS
|
||||
#define TOML_THROW_PARSE_ERROR(msg, path) \
|
||||
throw parse_error{ \
|
||||
msg, source_position{}, std::make_shared<const std::string>(std::move(path)) \
|
||||
}
|
||||
#else
|
||||
#define TOML_THROW_PARSE_ERROR(msg, path) \
|
||||
return parse_result{ parse_error{ \
|
||||
msg, source_position{}, std::make_shared<const std::string>(std::move(path)) \
|
||||
}}
|
||||
#endif
|
||||
|
||||
namespace toml
|
||||
{
|
||||
#if TOML_EXCEPTIONS
|
||||
TOML_ABI_NAMESPACE_START(parse_ex)
|
||||
#else
|
||||
TOML_ABI_NAMESPACE_START(parse_noex)
|
||||
#endif
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, parse_ex, parse_noex)
|
||||
|
||||
/// \brief Parses a TOML document from a string view.
|
||||
///
|
||||
@ -326,6 +369,8 @@ namespace toml
|
||||
///
|
||||
/// \param doc The TOML document to parse. Must be valid UTF-8.
|
||||
/// \param source_path The path used to initialize each node's `source().path`.
|
||||
/// If you don't have a path (or you have no intention of using paths in diagnostics)
|
||||
/// then this parameter can safely be left blank.
|
||||
///
|
||||
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
|
||||
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
|
||||
@ -333,6 +378,35 @@ namespace toml
|
||||
TOML_API
|
||||
parse_result parse(std::string_view doc, std::string&& source_path) TOML_MAY_THROW;
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Parses a TOML document from a string view.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::parse("a = 3"sv, L"foo.toml");
|
||||
/// std::cout << tbl["a"] << std::endl;
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// 3
|
||||
/// \eout
|
||||
///
|
||||
/// \param doc The TOML document to parse. Must be valid UTF-8.
|
||||
/// \param source_path The path used to initialize each node's `source().path`.
|
||||
/// If you don't have a path (or you have no intention of using paths in diagnostics)
|
||||
/// then this parameter can safely be left blank.
|
||||
///
|
||||
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
|
||||
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
|
||||
///
|
||||
/// \attention This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
[[nodiscard]]
|
||||
TOML_API
|
||||
parse_result parse(std::string_view doc, std::wstring_view source_path) TOML_MAY_THROW;
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
#ifdef __cpp_lib_char8_t
|
||||
|
||||
/// \brief Parses a TOML document from a char8_t string view.
|
||||
@ -374,6 +448,8 @@ namespace toml
|
||||
///
|
||||
/// \param doc The TOML document to parse. Must be valid UTF-8.
|
||||
/// \param source_path The path used to initialize each node's `source().path`.
|
||||
/// If you don't have a path (or you have no intention of using paths in diagnostics)
|
||||
/// then this parameter can safely be left blank.
|
||||
///
|
||||
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
|
||||
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
|
||||
@ -383,6 +459,36 @@ namespace toml
|
||||
TOML_API
|
||||
parse_result parse(std::u8string_view doc, std::string&& source_path) TOML_MAY_THROW;
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Parses a TOML document from a char8_t string view.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// auto tbl = toml::parse(u8"a = 3"sv, L"foo.toml");
|
||||
/// std::cout << tbl["a"] << std::endl;
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// 3
|
||||
/// \eout
|
||||
///
|
||||
/// \param doc The TOML document to parse. Must be valid UTF-8.
|
||||
/// \param source_path The path used to initialize each node's `source().path`.
|
||||
/// If you don't have a path (or you have no intention of using paths in diagnostics)
|
||||
/// then this parameter can safely be left blank.
|
||||
///
|
||||
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
|
||||
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
|
||||
///
|
||||
/// \attention This overload is only available when #TOML_WINDOWS_COMPAT is enabled and your compiler
|
||||
/// supports char8_t-based strings.
|
||||
[[nodiscard]]
|
||||
TOML_API
|
||||
parse_result parse(std::u8string_view doc, std::wstring_view source_path) TOML_MAY_THROW;
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
#endif // __cpp_lib_char8_t
|
||||
|
||||
/// \brief Parses a TOML document from a stream.
|
||||
@ -439,6 +545,8 @@ namespace toml
|
||||
/// \tparam Char The stream's underlying character type. Must be 1 byte in size.
|
||||
/// \param doc The TOML document to parse. Must be valid UTF-8.
|
||||
/// \param source_path The path used to initialize each node's `source().path`.
|
||||
/// If you don't have a path (or you have no intention of using paths in diagnostics)
|
||||
/// then this parameter can safely be left blank.
|
||||
///
|
||||
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
|
||||
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
|
||||
@ -455,6 +563,43 @@ namespace toml
|
||||
return impl::do_parse(impl::utf8_reader{ doc, std::move(source_path) });
|
||||
}
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Parses a TOML document from a stream.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// std::stringstream ss;
|
||||
/// ss << "a = 3"sv;
|
||||
///
|
||||
/// auto tbl = toml::parse(ss);
|
||||
/// std::cout << tbl["a"] << std::endl;
|
||||
///
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// 3
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam Char The stream's underlying character type. Must be 1 byte in size.
|
||||
/// \param doc The TOML document to parse. Must be valid UTF-8.
|
||||
/// \param source_path The path used to initialize each node's `source().path`.
|
||||
/// If you don't have a path (or you have no intention of using paths in diagnostics)
|
||||
/// then this parameter can safely be left blank.
|
||||
///
|
||||
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
|
||||
/// <strong><em>Without exceptions:</em></strong> A toml::parse_result detailing the parsing outcome.
|
||||
///
|
||||
/// \attention This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
template <typename Char>
|
||||
[[nodiscard]]
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
parse_result parse(std::basic_istream<Char>& doc, std::wstring_view source_path) TOML_MAY_THROW
|
||||
{
|
||||
return parse(doc, impl::narrow<char>(source_path));
|
||||
}
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
|
||||
// Q: "why are the parse_file functions templated??"
|
||||
// A: I don't want to force users to drag in <fstream> if they're not going to do
|
||||
@ -474,7 +619,7 @@ namespace toml
|
||||
/// }
|
||||
/// \ecpp
|
||||
///
|
||||
/// \tparam Char The path's character type. Must be 1 byte in size.
|
||||
/// \tparam Char The path's character type.
|
||||
/// \param file_path The TOML document to parse. Must be valid UTF-8.
|
||||
///
|
||||
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
|
||||
@ -487,25 +632,32 @@ namespace toml
|
||||
parse_result parse_file(std::basic_string_view<Char> file_path) TOML_MAY_THROW
|
||||
{
|
||||
static_assert(
|
||||
sizeof(Char) == 1,
|
||||
"The path's character type must be 1 byte in size."
|
||||
!std::is_same_v<Char, wchar_t> || TOML_WINDOWS_COMPAT,
|
||||
"Wide-character file paths are only supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
);
|
||||
static_assert(
|
||||
sizeof(StreamChar) == 1,
|
||||
"The stream's character type must be 1 byte in size."
|
||||
);
|
||||
|
||||
#if TOML_EXCEPTIONS
|
||||
#define TOML_PARSE_FILE_ERROR(msg, pos) \
|
||||
throw parse_error{ msg, pos, std::make_shared<const std::string>(std::move(file_path_str)) }
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
static_assert(
|
||||
sizeof(Char) == 1 || std::is_same_v<Char, wchar_t>,
|
||||
"The file path's underlying character type must be wchar_t or be 1 byte in size."
|
||||
);
|
||||
#else
|
||||
#define TOML_PARSE_FILE_ERROR(msg, pos) \
|
||||
return parse_result{ \
|
||||
parse_error{ msg, pos, std::make_shared<const std::string>(std::move(file_path_str)) } \
|
||||
}
|
||||
static_assert(
|
||||
sizeof(Char) == 1,
|
||||
"The file path's underlying character type must be 1 byte in size."
|
||||
);
|
||||
#endif
|
||||
static_assert(
|
||||
std::is_same_v<StreamChar, char>,
|
||||
"StreamChar must be 'char' (it is as an instantiation-delaying hack and is not user-configurable)."
|
||||
);
|
||||
|
||||
auto file_path_str = std::string(reinterpret_cast<const char*>(file_path.data()), file_path.length());
|
||||
std::string file_path_str;
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
if constexpr (std::is_same_v<Char, wchar_t>)
|
||||
file_path_str = impl::narrow<char>(file_path);
|
||||
else
|
||||
#endif
|
||||
file_path_str = std::string_view{ reinterpret_cast<const char*>(file_path.data()), file_path.length() };
|
||||
|
||||
// open file with a custom-sized stack buffer
|
||||
using ifstream = std::basic_ifstream<StreamChar>;
|
||||
@ -514,12 +666,12 @@ namespace toml
|
||||
file.rdbuf()->pubsetbuf(file_buffer, sizeof(file_buffer));
|
||||
file.open(file_path_str, ifstream::in | ifstream::binary | ifstream::ate);
|
||||
if (!file.is_open())
|
||||
TOML_PARSE_FILE_ERROR("File could not be opened for reading", source_position{});
|
||||
TOML_THROW_PARSE_ERROR("File could not be opened for reading", file_path_str);
|
||||
|
||||
// get size
|
||||
const auto file_size = file.tellg();
|
||||
if (file_size == -1)
|
||||
TOML_PARSE_FILE_ERROR("Could not determine file size", source_position{});
|
||||
TOML_THROW_PARSE_ERROR("Could not determine file size", file_path_str);
|
||||
file.seekg(0, std::ios::beg);
|
||||
|
||||
// read the whole file into memory first if the file isn't too large
|
||||
@ -535,8 +687,6 @@ namespace toml
|
||||
// otherwise parse it using the streams
|
||||
else
|
||||
return parse(file, std::move(file_path_str));
|
||||
|
||||
#undef TOML_PARSE_FILE_ERROR
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
@ -546,6 +696,9 @@ namespace toml
|
||||
#ifdef __cpp_lib_char8_t
|
||||
extern template TOML_API parse_result parse_file(std::u8string_view) TOML_MAY_THROW;
|
||||
#endif
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
extern template TOML_API parse_result parse_file(std::wstring_view) TOML_MAY_THROW;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
template <typename Char>
|
||||
@ -584,13 +737,9 @@ namespace toml
|
||||
///
|
||||
inline namespace literals
|
||||
{
|
||||
#if TOML_EXCEPTIONS
|
||||
TOML_ABI_NAMESPACE_START(lit_ex)
|
||||
#else
|
||||
TOML_ABI_NAMESPACE_START(lit_noex)
|
||||
#endif
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, lit_ex, lit_noex)
|
||||
|
||||
/// \brief Parses TOML data from a string.
|
||||
/// \brief Parses TOML data from a string literal.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// using namespace toml::literals;
|
||||
@ -604,7 +753,7 @@ namespace toml
|
||||
/// 3
|
||||
/// \eout
|
||||
///
|
||||
/// \param str The string data.
|
||||
/// \param str The string data. Must be valid UTF-8.
|
||||
/// \param len The string length.
|
||||
///
|
||||
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
|
||||
@ -615,7 +764,7 @@ namespace toml
|
||||
|
||||
#ifdef __cpp_lib_char8_t
|
||||
|
||||
/// \brief Parses TOML data from a string.
|
||||
/// \brief Parses TOML data from a utf8 string literal.
|
||||
///
|
||||
/// \detail \cpp
|
||||
/// using namespace toml::literals;
|
||||
@ -629,7 +778,7 @@ namespace toml
|
||||
/// 3
|
||||
/// \eout
|
||||
///
|
||||
/// \param str The string data.
|
||||
/// \param str The string data. Must be valid UTF-8.
|
||||
/// \param len The string length.
|
||||
///
|
||||
/// \returns <strong><em>With exceptions:</em></strong> A toml::table. <br>
|
||||
@ -644,6 +793,9 @@ namespace toml
|
||||
|
||||
TOML_ABI_NAMESPACE_END // TOML_EXCEPTIONS
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#undef TOML_THROW_PARSE_ERROR
|
||||
|
||||
TOML_POP_WARNINGS // TOML_DISABLE_PADDING_WARNINGS
|
||||
|
@ -257,12 +257,6 @@ namespace TOML_INTERNAL_NAMESPACE
|
||||
|
||||
namespace toml::impl
|
||||
{
|
||||
#if defined(NDEBUG) || !defined(_DEBUG)
|
||||
#define assert_or_assume(cond) TOML_ASSUME(cond)
|
||||
#else
|
||||
#define assert_or_assume(cond) TOML_ASSERT(cond)
|
||||
#endif
|
||||
|
||||
// Q: "what the fuck is this? MACROS????"
|
||||
// A: The parser needs to work in exceptionless mode (returning error objects directly)
|
||||
// and exception mode (reporting parse failures by throwing). Two totally different control flows.
|
||||
@ -271,6 +265,12 @@ namespace toml::impl
|
||||
// They're all #undef'd at the bottom of the parser's implementation so they should be harmless outside
|
||||
// of toml++.
|
||||
|
||||
#if defined(NDEBUG) || !defined(_DEBUG)
|
||||
#define assert_or_assume(cond) TOML_ASSUME(cond)
|
||||
#else
|
||||
#define assert_or_assume(cond) TOML_ASSERT(cond)
|
||||
#endif
|
||||
|
||||
#define is_eof() !cp
|
||||
#define assert_not_eof() assert_or_assume(cp)
|
||||
#define return_if_eof(...) do { if (is_eof()) return __VA_ARGS__; } while(false)
|
||||
@ -302,11 +302,7 @@ namespace toml::impl
|
||||
set_error_and_return_if_eof(__VA_ARGS__); \
|
||||
} while (false)
|
||||
|
||||
#if TOML_EXCEPTIONS
|
||||
TOML_ABI_NAMESPACE_START(impl_ex)
|
||||
#else
|
||||
TOML_ABI_NAMESPACE_START(impl_noex)
|
||||
#endif
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, impl_ex, impl_noex)
|
||||
|
||||
class parser final
|
||||
{
|
||||
@ -2909,33 +2905,30 @@ namespace toml::impl
|
||||
|
||||
TOML_ABI_NAMESPACE_END // TOML_EXCEPTIONS
|
||||
|
||||
#undef push_parse_scope_2
|
||||
#undef push_parse_scope_1
|
||||
#undef push_parse_scope
|
||||
#undef TOML_RETURNS_BY_THROWING
|
||||
#undef is_eof
|
||||
#undef assert_not_eof
|
||||
#undef return_if_eof
|
||||
#undef is_error
|
||||
#undef return_after_error
|
||||
#undef assert_not_error
|
||||
#undef return_if_error
|
||||
#undef return_if_error_or_eof
|
||||
#undef set_error_and_return
|
||||
#undef set_error_and_return_default
|
||||
#undef set_error_and_return_if_eof
|
||||
#undef advance_and_return_if_error
|
||||
#undef advance_and_return_if_error_or_eof
|
||||
#undef assert_or_assume
|
||||
}
|
||||
|
||||
#undef push_parse_scope_2
|
||||
#undef push_parse_scope_1
|
||||
#undef push_parse_scope
|
||||
#undef TOML_RETURNS_BY_THROWING
|
||||
#undef is_eof
|
||||
#undef assert_not_eof
|
||||
#undef return_if_eof
|
||||
#undef is_error
|
||||
#undef return_after_error
|
||||
#undef assert_not_error
|
||||
#undef return_if_error
|
||||
#undef return_if_error_or_eof
|
||||
#undef set_error_and_return
|
||||
#undef set_error_and_return_default
|
||||
#undef set_error_and_return_if_eof
|
||||
#undef advance_and_return_if_error
|
||||
#undef advance_and_return_if_error_or_eof
|
||||
|
||||
namespace toml
|
||||
{
|
||||
#if TOML_EXCEPTIONS
|
||||
TOML_ABI_NAMESPACE_START(parse_ex)
|
||||
#else
|
||||
TOML_ABI_NAMESPACE_START(parse_noex)
|
||||
#endif
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, parse_ex, parse_noex)
|
||||
|
||||
TOML_API
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
@ -2951,6 +2944,17 @@ namespace toml
|
||||
return impl::do_parse(impl::utf8_reader{ doc, std::move(source_path) });
|
||||
}
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
TOML_API
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
parse_result parse(std::string_view doc, std::wstring_view source_path) TOML_MAY_THROW
|
||||
{
|
||||
return impl::do_parse(impl::utf8_reader{ doc, impl::narrow<char>(source_path) });
|
||||
}
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
#ifdef __cpp_lib_char8_t
|
||||
|
||||
TOML_API
|
||||
@ -2967,17 +2971,24 @@ namespace toml
|
||||
return impl::do_parse(impl::utf8_reader{ doc, std::move(source_path) });
|
||||
}
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
TOML_API
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
parse_result parse(std::u8string_view doc, std::wstring_view source_path) TOML_MAY_THROW
|
||||
{
|
||||
return impl::do_parse(impl::utf8_reader{ doc, impl::narrow<char>(source_path) });
|
||||
}
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
#endif // __cpp_lib_char8_t
|
||||
|
||||
TOML_ABI_NAMESPACE_END // TOML_EXCEPTIONS
|
||||
|
||||
inline namespace literals
|
||||
{
|
||||
#if TOML_EXCEPTIONS
|
||||
TOML_ABI_NAMESPACE_START(lit_ex)
|
||||
#else
|
||||
TOML_ABI_NAMESPACE_START(lit_noex)
|
||||
#endif
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, lit_ex, lit_noex)
|
||||
|
||||
TOML_API
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
|
@ -48,11 +48,29 @@
|
||||
#define TOML_PARSER 1
|
||||
#endif
|
||||
|
||||
#if (defined(_WIN32) || defined(DOXYGEN)) && !defined(TOML_WINDOWS_COMPAT)
|
||||
#define TOML_WINDOWS_COMPAT 1
|
||||
#endif
|
||||
#if !(defined(_WIN32) || defined(DOXYGEN)) || !defined(TOML_WINDOWS_COMPAT)
|
||||
#undef TOML_WINDOWS_COMPAT
|
||||
#define TOML_WINDOWS_COMPAT 0
|
||||
#endif
|
||||
|
||||
#ifdef TOML_OPTIONAL_TYPE
|
||||
#define TOML_HAS_CUSTOM_OPTIONAL_TYPE 1
|
||||
#else
|
||||
#define TOML_HAS_CUSTOM_OPTIONAL_TYPE 0
|
||||
#endif
|
||||
|
||||
////////// COMPILER & ENVIRONMENT
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error toml++ is a C++ library.
|
||||
#endif
|
||||
#ifdef DOXYGEN
|
||||
#undef TOML_DOXYGEN
|
||||
#define TOML_DOXYGEN 1
|
||||
#endif
|
||||
#ifndef TOML_DOXYGEN
|
||||
#define TOML_DOXYGEN 0
|
||||
#endif
|
||||
@ -192,7 +210,6 @@
|
||||
#ifndef TOML_CPP_VERSION
|
||||
#define TOML_CPP_VERSION __cplusplus
|
||||
#endif
|
||||
|
||||
#if TOML_CPP_VERSION < 201103L
|
||||
#error toml++ requires C++17 or higher. For a TOML library supporting pre-C++11 see https://github.com/ToruNiina/Boost.toml
|
||||
#elif TOML_CPP_VERSION < 201703L
|
||||
@ -206,12 +223,14 @@
|
||||
#elif TOML_CPP_VERSION >= 201703L
|
||||
#define TOML_CPP 17
|
||||
#endif
|
||||
#undef TOML_CPP_VERSION
|
||||
|
||||
#ifndef TOML_COMPILER_EXCEPTIONS
|
||||
#define TOML_COMPILER_EXCEPTIONS 1
|
||||
#endif
|
||||
#if TOML_COMPILER_EXCEPTIONS
|
||||
#ifndef TOML_EXCEPTIONS
|
||||
#if !defined(TOML_EXCEPTIONS) || (defined(TOML_EXCEPTIONS) && TOML_EXCEPTIONS)
|
||||
#undef TOML_EXCEPTIONS
|
||||
#define TOML_EXCEPTIONS 1
|
||||
#endif
|
||||
#else
|
||||
@ -381,13 +400,21 @@
|
||||
#define TOML_LANG_UNRELEASED \
|
||||
TOML_LANG_HIGHER_THAN(TOML_LANG_MAJOR, TOML_LANG_MINOR, TOML_LANG_PATCH)
|
||||
|
||||
#define TOML_CONCAT_1(x, y) x##y
|
||||
#define TOML_CONCAT(x, y) TOML_CONCAT_1(x, y)
|
||||
|
||||
#define TOML_EVAL_BOOL_1(T, F) T
|
||||
#define TOML_EVAL_BOOL_0(T, F) F
|
||||
|
||||
#if TOML_DOXYGEN || defined(__INTELLISENSE__)
|
||||
#define TOML_ABI_NAMESPACES 0
|
||||
#define TOML_ABI_NAMESPACE_BOOL(cond, T, F)
|
||||
#define TOML_ABI_NAMESPACE_START(name)
|
||||
#define TOML_ABI_NAMESPACE_END
|
||||
#else
|
||||
#define TOML_ABI_NAMESPACES 1
|
||||
#define TOML_ABI_NAMESPACE_START(name) inline namespace abi_##name {
|
||||
#define TOML_ABI_NAMESPACE_START(name) inline namespace TOML_CONCAT(abi_, name) {
|
||||
#define TOML_ABI_NAMESPACE_BOOL(cond, T, F) TOML_ABI_NAMESPACE_START(TOML_CONCAT(TOML_EVAL_BOOL_, cond)(T, F))
|
||||
#define TOML_ABI_NAMESPACE_END }
|
||||
#endif
|
||||
|
||||
@ -404,8 +431,7 @@ TOML_DISABLE_ALL_WARNINGS
|
||||
TOML_POP_WARNINGS
|
||||
|
||||
#if TOML_CHAR_8_STRINGS
|
||||
#define TOML_STRING_PREFIX_1(S) u8##S
|
||||
#define TOML_STRING_PREFIX(S) TOML_STRING_PREFIX_1(S)
|
||||
#define TOML_STRING_PREFIX(S) TOML_CONCAT(u8, S)
|
||||
#else
|
||||
#define TOML_STRING_PREFIX(S) S
|
||||
#endif
|
||||
@ -424,7 +450,7 @@ TOML_POP_WARNINGS
|
||||
/// \def TOML_ALL_INLINE
|
||||
/// \brief Sets whether the library is entirely inline.
|
||||
/// \detail Defaults to `1`.
|
||||
/// \remark Disabling this means that you must define `TOML_IMPLEMENTATION` in
|
||||
/// \remark Disabling this means that you must define #TOML_IMPLEMENTATION in
|
||||
/// <strong><em>exactly one</em></strong> translation unit in your project:
|
||||
/// \cpp
|
||||
/// // global_header_that_includes_toml++.h
|
||||
@ -512,6 +538,20 @@ TOML_POP_WARNINGS
|
||||
/// \see [TOML Language Support](https://github.com/marzer/tomlplusplus/blob/master/README.md#toml-language-support)
|
||||
|
||||
|
||||
/// \def TOML_WINDOWS_COMPAT
|
||||
/// \brief Enables the use of wide strings (wchar_t, std::wstring) in various places throughout the library
|
||||
/// when building for Windows.
|
||||
/// \detail Defaults to `1` when building for Windows, `0` otherwise. Has no effect when building for anything other
|
||||
/// than Windows.
|
||||
/// \attention This <strong>does not</strong> change the underlying string type used to represent TOML keys and string values;
|
||||
/// that will still be std::string or std::u8string according to whatever #TOML_CHAR_8_STRINGS is set to.
|
||||
/// This setting simply enables some narrow <=> wide string conversions when necessary at
|
||||
/// various interface boundaries.
|
||||
/// <br><br>
|
||||
/// If you're building for Windows and you have no need for Windows' "Pretends-to-be-unicode" wide strings,
|
||||
/// you can safely set this to `0`.
|
||||
|
||||
|
||||
/// @}
|
||||
#endif // TOML_DOXYGEN
|
||||
//# }}
|
||||
|
@ -68,7 +68,7 @@ namespace toml::impl
|
||||
stream.write(reinterpret_cast<const Char*>(str), static_cast<std::streamsize>(len));
|
||||
}
|
||||
|
||||
#if defined(__cpp_lib_char8_t)
|
||||
#ifdef __cpp_lib_char8_t
|
||||
|
||||
template <typename Char>
|
||||
TOML_ALWAYS_INLINE
|
||||
|
@ -145,23 +145,45 @@ namespace toml::impl
|
||||
string key;
|
||||
std::unique_ptr<node> value;
|
||||
|
||||
template <typename T>
|
||||
table_init_pair(string&& k, T && v) noexcept
|
||||
template <typename V>
|
||||
table_init_pair(string&& k, V&& v) noexcept
|
||||
: key{ std::move(k) },
|
||||
value{ make_node(std::forward<T>(v)) }
|
||||
value{ make_node(std::forward<V>(v)) }
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
table_init_pair(string_view k, T&& v) noexcept
|
||||
template <typename V>
|
||||
table_init_pair(string_view k, V&& v) noexcept
|
||||
: key{ k },
|
||||
value{ make_node(std::forward<T>(v)) }
|
||||
value{ make_node(std::forward<V>(v)) }
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
table_init_pair(const string_char* k, T&& v) noexcept
|
||||
template <typename V>
|
||||
table_init_pair(const string_char* k, V&& v) noexcept
|
||||
: key{ k },
|
||||
value{ make_node(std::forward<T>(v)) }
|
||||
value{ make_node(std::forward<V>(v)) }
|
||||
{}
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
template <typename V>
|
||||
table_init_pair(std::wstring&& k, V&& v) noexcept
|
||||
: key{ narrow(k) },
|
||||
value{ make_node(std::forward<V>(v)) }
|
||||
{}
|
||||
|
||||
template <typename V>
|
||||
table_init_pair(std::wstring_view k, V&& v) noexcept
|
||||
: key{ narrow(k) },
|
||||
value{ make_node(std::forward<V>(v)) }
|
||||
{}
|
||||
|
||||
template <typename V>
|
||||
table_init_pair(const wchar_t* k, V&& v) noexcept
|
||||
: key{ narrow(std::wstring_view{ k }) },
|
||||
value{ make_node(std::forward<V>(v)) }
|
||||
{}
|
||||
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
@ -319,8 +341,52 @@ namespace toml
|
||||
[[nodiscard]] node_view<node> operator[] (string_view key) noexcept;
|
||||
|
||||
/// \brief Gets a node_view for the selected key-value pair (const overload).
|
||||
///
|
||||
/// \param key The key used for the lookup.
|
||||
///
|
||||
/// \returns A view of the value at the given key if one existed, or an empty node view.
|
||||
///
|
||||
/// \remarks std::map::operator[]'s behaviour of default-constructing a value at a key if it
|
||||
/// didn't exist is a crazy bug factory so I've deliberately chosen not to emulate it.
|
||||
/// <strong>This is not an error.</strong>
|
||||
///
|
||||
/// \see toml::node_view
|
||||
[[nodiscard]] node_view<const node> operator[] (string_view key) const noexcept;
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Gets a node_view for the selected key-value pair.
|
||||
///
|
||||
/// \param key The key used for the lookup.
|
||||
///
|
||||
/// \returns A view of the value at the given key if one existed, or an empty node view.
|
||||
///
|
||||
/// \remarks std::map::operator[]'s behaviour of default-constructing a value at a key if it
|
||||
/// didn't exist is a crazy bug factory so I've deliberately chosen not to emulate it.
|
||||
/// <strong>This is not an error.</strong>
|
||||
///
|
||||
/// \see toml::node_view
|
||||
///
|
||||
/// \attention This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
[[nodiscard]] node_view<node> operator[] (std::wstring_view key) noexcept;
|
||||
|
||||
/// \brief Gets a node_view for the selected key-value pair (const overload).
|
||||
///
|
||||
/// \param key The key used for the lookup.
|
||||
///
|
||||
/// \returns A view of the value at the given key if one existed, or an empty node view.
|
||||
///
|
||||
/// \remarks std::map::operator[]'s behaviour of default-constructing a value at a key if it
|
||||
/// didn't exist is a crazy bug factory so I've deliberately chosen not to emulate it.
|
||||
/// <strong>This is not an error.</strong>
|
||||
///
|
||||
/// \see toml::node_view
|
||||
///
|
||||
/// \attention This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
[[nodiscard]] node_view<const node> operator[] (std::wstring_view key) const noexcept;
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Returns an iterator to the first key-value pair.
|
||||
[[nodiscard]] iterator begin() noexcept;
|
||||
/// \brief Returns an iterator to the first key-value pair.
|
||||
@ -378,16 +444,29 @@ namespace toml
|
||||
/// - A boolean indicating if the insertion was successful.
|
||||
template <typename K, typename V, typename = std::enable_if_t<
|
||||
std::is_convertible_v<K&&, string_view>
|
||||
|| impl::is_wide_string<K>
|
||||
>>
|
||||
std::pair<iterator, bool> insert(K&& key, V&& val) noexcept
|
||||
{
|
||||
auto ipos = values.lower_bound(key);
|
||||
if (ipos == values.end() || ipos->first != key)
|
||||
static_assert(
|
||||
!impl::is_wide_string<K> || TOML_WINDOWS_COMPAT,
|
||||
"Insertion using wide-character keys is only supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
);
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
if constexpr (impl::is_wide_string<K>)
|
||||
return insert(impl::narrow(std::forward<K>(key)), std::forward<V>(val));
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ipos = values.emplace_hint(ipos, std::forward<K>(key), impl::make_node(std::forward<V>(val)));
|
||||
return { ipos, true };
|
||||
auto ipos = values.lower_bound(key);
|
||||
if (ipos == values.end() || ipos->first != key)
|
||||
{
|
||||
ipos = values.emplace_hint(ipos, std::forward<K>(key), impl::make_node(std::forward<V>(val)));
|
||||
return { ipos, true };
|
||||
}
|
||||
return { ipos, false };
|
||||
}
|
||||
return { ipos, false };
|
||||
}
|
||||
|
||||
/// \brief Inserts a series of key-value pairs into the table.
|
||||
@ -422,7 +501,8 @@ namespace toml
|
||||
/// key-value pair covered by the iterator range, so any values with keys already found in the
|
||||
/// table will not be replaced.
|
||||
template <typename Iter, typename = std::enable_if_t<
|
||||
!std::is_convertible_v<Iter&&, string_view>
|
||||
!std::is_convertible_v<Iter, string_view>
|
||||
&& !impl::is_wide_string<Iter>
|
||||
>>
|
||||
void insert(Iter first, Iter last) noexcept
|
||||
{
|
||||
@ -475,16 +555,28 @@ namespace toml
|
||||
template <typename K, typename V>
|
||||
std::pair<iterator, bool> insert_or_assign(K&& key, V&& val) noexcept
|
||||
{
|
||||
auto ipos = values.lower_bound(key);
|
||||
if (ipos == values.end() || ipos->first != key)
|
||||
{
|
||||
ipos = values.emplace_hint(ipos, std::forward<K>(key), impl::make_node(std::forward<V>(val)));
|
||||
return { ipos, true };
|
||||
}
|
||||
static_assert(
|
||||
!impl::is_wide_string<K> || TOML_WINDOWS_COMPAT,
|
||||
"Insertion using wide-character keys is only supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
);
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
if constexpr (impl::is_wide_string<K>)
|
||||
return insert_or_assign(impl::narrow(std::forward<K>(key)), std::forward<V>(val));
|
||||
else
|
||||
#endif
|
||||
{
|
||||
(*ipos).second.reset(impl::make_node(std::forward<V>(val)));
|
||||
return { ipos, false };
|
||||
auto ipos = values.lower_bound(key);
|
||||
if (ipos == values.end() || ipos->first != key)
|
||||
{
|
||||
ipos = values.emplace_hint(ipos, std::forward<K>(key), impl::make_node(std::forward<V>(val)));
|
||||
return { ipos, true };
|
||||
}
|
||||
else
|
||||
{
|
||||
(*ipos).second.reset(impl::make_node(std::forward<V>(val)));
|
||||
return { ipos, false };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -529,23 +621,36 @@ namespace toml
|
||||
template <typename U, typename K, typename... V>
|
||||
std::pair<iterator, bool> emplace(K&& key, V&&... args) noexcept
|
||||
{
|
||||
using type = impl::unwrapped<U>;
|
||||
static_assert(
|
||||
impl::is_value_or_node<type>,
|
||||
"Emplacement type parameter must be one of the basic value types, a toml::table, or a toml::array"
|
||||
!impl::is_wide_string<K> || TOML_WINDOWS_COMPAT,
|
||||
"Emplacement using wide-character keys is only supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
);
|
||||
|
||||
auto ipos = values.lower_bound(key);
|
||||
if (ipos == values.end() || ipos->first != key)
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
if constexpr (impl::is_wide_string<K>)
|
||||
return emplace<U>(impl::narrow(std::forward<K>(key)), std::forward<V>(args)...);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ipos = values.emplace_hint(
|
||||
ipos,
|
||||
std::forward<K>(key),
|
||||
new impl::node_of<type>{ std::forward<V>(args)... }
|
||||
|
||||
using type = impl::unwrapped<U>;
|
||||
static_assert(
|
||||
impl::is_value_or_node<type>,
|
||||
"Emplacement type parameter must be one of the basic value types, a toml::table, or a toml::array"
|
||||
);
|
||||
return { ipos, true };
|
||||
|
||||
auto ipos = values.lower_bound(key);
|
||||
if (ipos == values.end() || ipos->first != key)
|
||||
{
|
||||
ipos = values.emplace_hint(
|
||||
ipos,
|
||||
std::forward<K>(key),
|
||||
new impl::node_of<type>{ std::forward<V>(args)... }
|
||||
);
|
||||
return { ipos, true };
|
||||
}
|
||||
return { ipos, false };
|
||||
}
|
||||
return { ipos, false };
|
||||
}
|
||||
|
||||
/// \brief Removes the specified key-value pair from the table.
|
||||
@ -653,20 +758,40 @@ namespace toml
|
||||
/// \returns True if any values with matching keys were found and erased.
|
||||
bool erase(string_view key) noexcept;
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Removes the value with the given key from the table.
|
||||
///
|
||||
/// \param key Key to erase.
|
||||
///
|
||||
/// \returns True if any values with matching keys were found and erased.
|
||||
///
|
||||
/// \attention This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
bool erase(std::wstring_view key) noexcept;
|
||||
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
template <typename Map, typename Key>
|
||||
[[nodiscard]] static auto do_get(Map& vals, const Key& key) noexcept
|
||||
-> std::conditional_t<std::is_const_v<Map>, const node*, node*>
|
||||
{
|
||||
using return_type = std::conditional_t<
|
||||
std::is_const_v<Map>,
|
||||
const node*,
|
||||
node*
|
||||
>;
|
||||
static_assert(
|
||||
!impl::is_wide_string<Key> || TOML_WINDOWS_COMPAT,
|
||||
"Retrieval using wide-character keys is only supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
);
|
||||
|
||||
if (auto it = vals.find(key); it != vals.end())
|
||||
return return_type{ it->second.get() };
|
||||
return return_type{};
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
if constexpr (impl::is_wide_string<Key>)
|
||||
return do_get(vals, impl::narrow(key));
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (auto it = vals.find(key); it != vals.end())
|
||||
return { it->second.get() };
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename Map, typename Key>
|
||||
@ -680,11 +805,7 @@ namespace toml
|
||||
[[nodiscard]] TOML_ALWAYS_INLINE
|
||||
static bool do_contains(Map& vals, const Key& key) noexcept
|
||||
{
|
||||
#if TOML_CPP >= 20
|
||||
return vals.contains(key);
|
||||
#else
|
||||
return do_get(vals, key) != nullptr;
|
||||
#endif
|
||||
return do_get(vals, key) != nullptr;
|
||||
}
|
||||
|
||||
public:
|
||||
@ -723,9 +844,68 @@ namespace toml
|
||||
/// \returns A pointer to the node at the specified key, or nullptr.
|
||||
[[nodiscard]] const node* get(string_view key) const noexcept;
|
||||
|
||||
/// \brief Gets an iterator to the node at a specific key.
|
||||
///
|
||||
/// \param key The node's key.
|
||||
///
|
||||
/// \returns An iterator to the node at the specified key, or end().
|
||||
[[nodiscard]] iterator find(string_view key) noexcept;
|
||||
|
||||
/// \brief Gets an iterator to the node at a specific key (const overload)
|
||||
///
|
||||
/// \param key The node's key.
|
||||
///
|
||||
/// \returns A const iterator to the node at the specified key, or cend().
|
||||
[[nodiscard]] const_iterator find(string_view key) const noexcept;
|
||||
|
||||
/// \brief Returns true if the table contains a node at the given key.
|
||||
[[nodiscard]] bool contains(string_view key) const noexcept;
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Gets the node at a specific key.
|
||||
///
|
||||
/// \param key The node's key.
|
||||
///
|
||||
/// \returns A pointer to the node at the specified key, or nullptr.
|
||||
///
|
||||
/// \attention This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
[[nodiscard]] node* get(std::wstring_view key) noexcept;
|
||||
|
||||
/// \brief Gets the node at a specific key (const overload).
|
||||
///
|
||||
/// \param key The node's key.
|
||||
///
|
||||
/// \returns A pointer to the node at the specified key, or nullptr.
|
||||
///
|
||||
/// \attention This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
[[nodiscard]] const node* get(std::wstring_view key) const noexcept;
|
||||
|
||||
/// \brief Gets an iterator to the node at a specific key.
|
||||
///
|
||||
/// \param key The node's key.
|
||||
///
|
||||
/// \returns An iterator to the node at the specified key, or end().
|
||||
///
|
||||
/// \attention This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
[[nodiscard]] iterator find(std::wstring_view key) noexcept;
|
||||
|
||||
/// \brief Gets an iterator to the node at a specific key (const overload).
|
||||
///
|
||||
/// \param key The node's key.
|
||||
///
|
||||
/// \returns A const iterator to the node at the specified key, or cend().
|
||||
///
|
||||
/// \attention This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
[[nodiscard]] const_iterator find(std::wstring_view key) const noexcept;
|
||||
|
||||
/// \brief Returns true if the table contains a node at the given key.
|
||||
///
|
||||
/// \attention This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
[[nodiscard]] bool contains(std::wstring_view key) const noexcept;
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Gets the node at a specific key if it is a particular type.
|
||||
///
|
||||
/// \detail \cpp
|
||||
@ -764,8 +944,37 @@ namespace toml
|
||||
return do_get_as<T>(values, key);
|
||||
}
|
||||
|
||||
/// \brief Returns true if the table contains a node at the given key.
|
||||
[[nodiscard]] bool contains(string_view key) const noexcept;
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Gets the node at a specific key if it is a particular type.
|
||||
///
|
||||
/// \tparam T The node's type.
|
||||
/// \param key The node's key.
|
||||
///
|
||||
/// \returns A pointer to the node at the specified key if it was of the given type, or nullptr.
|
||||
///
|
||||
/// \attention This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
template <typename T>
|
||||
[[nodiscard]] impl::node_of<T>* get_as(std::wstring_view key) noexcept
|
||||
{
|
||||
return get_as<T>(impl::narrow(key));
|
||||
}
|
||||
|
||||
/// \brief Gets the node at a specific key if it is a particular type (const overload).
|
||||
///
|
||||
/// \tparam T The node's type.
|
||||
/// \param key The node's key.
|
||||
///
|
||||
/// \returns A pointer to the node at the specified key if it was of the given type, or nullptr.
|
||||
///
|
||||
/// \attention This overload is only available when #TOML_WINDOWS_COMPAT is enabled.
|
||||
template <typename T>
|
||||
[[nodiscard]] const impl::node_of<T>* get_as(std::wstring_view key) const noexcept
|
||||
{
|
||||
return get_as<T>(impl::narrow(key));
|
||||
}
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Equality operator.
|
||||
///
|
||||
@ -783,6 +992,7 @@ namespace toml
|
||||
/// \returns True if the tables did not contain the same keys and values.
|
||||
friend bool operator != (const table& lhs, const table& rhs) noexcept;
|
||||
|
||||
/// \brief Prints the table out to a stream as formatted TOML.
|
||||
template <typename Char>
|
||||
friend std::basic_ostream<Char>& operator << (std::basic_ostream<Char>&, const table&);
|
||||
};
|
||||
|
@ -145,6 +145,57 @@ namespace toml
|
||||
return do_contains(values, key);
|
||||
}
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node_view<node> table::operator[] (std::wstring_view key) noexcept
|
||||
{
|
||||
return { this->get(key) };
|
||||
}
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node_view<const node> table::operator[] (std::wstring_view key) const noexcept
|
||||
{
|
||||
return { this->get(key) };
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool table::erase(std::wstring_view key) noexcept
|
||||
{
|
||||
return erase(impl::narrow(key));
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
node* table::get(std::wstring_view key) noexcept
|
||||
{
|
||||
return get(impl::narrow(key));
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
const node* table::get(std::wstring_view key) const noexcept
|
||||
{
|
||||
return get(impl::narrow(key));
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::iterator table::find(std::wstring_view key) noexcept
|
||||
{
|
||||
return find(impl::narrow(key));
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table::const_iterator table::find(std::wstring_view key) const noexcept
|
||||
{
|
||||
return find(impl::narrow(key));
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool table::contains(std::wstring_view key) const noexcept
|
||||
{
|
||||
return contains(impl::narrow(key));
|
||||
}
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
|
||||
TOML_API
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool operator == (const table& lhs, const table& rhs) noexcept
|
||||
|
@ -135,11 +135,7 @@ namespace toml::impl
|
||||
}
|
||||
};
|
||||
|
||||
#if TOML_LARGE_FILES
|
||||
TOML_ABI_NAMESPACE_START(impl_lf)
|
||||
#else
|
||||
TOML_ABI_NAMESPACE_START(impl_sf)
|
||||
#endif
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_LARGE_FILES, impl_lf, impl_sf)
|
||||
|
||||
struct utf8_codepoint final
|
||||
{
|
||||
@ -369,13 +365,10 @@ namespace toml::impl
|
||||
|
||||
template <typename Char>
|
||||
utf8_reader(std::basic_string_view<Char>, std::string_view) -> utf8_reader<std::basic_string_view<Char>>;
|
||||
|
||||
template <typename Char>
|
||||
utf8_reader(std::basic_istream<Char>&, std::string_view) -> utf8_reader<std::basic_istream<Char>>;
|
||||
|
||||
template <typename Char>
|
||||
utf8_reader(std::basic_string_view<Char>, std::string&&) -> utf8_reader<std::basic_string_view<Char>>;
|
||||
|
||||
template <typename Char>
|
||||
utf8_reader(std::basic_istream<Char>&, std::string_view) -> utf8_reader<std::basic_istream<Char>>;
|
||||
template <typename Char>
|
||||
utf8_reader(std::basic_istream<Char>&, std::string&&) -> utf8_reader<std::basic_istream<Char>>;
|
||||
|
||||
|
@ -172,6 +172,7 @@ namespace toml
|
||||
/// \brief Returns a reference to the underlying value (const overload).
|
||||
[[nodiscard]] explicit operator const T& () const& noexcept { return val_; }
|
||||
|
||||
/// \brief Prints the value out to a stream as formatted TOML.
|
||||
template <typename Char, typename U>
|
||||
friend std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const value<U>& rhs);
|
||||
|
||||
@ -366,36 +367,6 @@ namespace toml
|
||||
value(TOML_SMALL_INT_TYPE) -> value<int64_t>;
|
||||
#endif
|
||||
|
||||
/// \brief Prints the value out to a stream.
|
||||
template <typename Char, typename T>
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& lhs, const value<T>& rhs)
|
||||
{
|
||||
// this is the same behaviour as default_formatter, but it's so simple that there's
|
||||
// no need to spin up a new instance of it just for individual values.
|
||||
|
||||
if constexpr (std::is_same_v<T, string>)
|
||||
{
|
||||
impl::print_to_stream('"', lhs);
|
||||
impl::print_to_stream_with_escapes(rhs.val_, lhs);
|
||||
impl::print_to_stream('"', lhs);
|
||||
}
|
||||
else
|
||||
impl::print_to_stream(rhs.val_, lhs);
|
||||
|
||||
return lhs;
|
||||
}
|
||||
|
||||
#if !TOML_ALL_INLINE
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<toml::string>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<int64_t>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<double>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<bool>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<toml::date>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<toml::time>&);
|
||||
extern template TOML_API std::ostream& operator << (std::ostream&, const value<toml::date_time>&);
|
||||
#endif
|
||||
|
||||
TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_INIT_WARNINGS
|
||||
|
||||
@ -403,7 +374,13 @@ namespace toml
|
||||
inline optional<T> node::value() const noexcept
|
||||
{
|
||||
static_assert(
|
||||
impl::is_value<T> || std::is_same_v<T, string_view>,
|
||||
!impl::is_wide_string<T> || TOML_WINDOWS_COMPAT,
|
||||
"Retrieving values as wide-character strings is only supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
);
|
||||
static_assert(
|
||||
impl::is_value<T>
|
||||
|| std::is_same_v<T, string_view>
|
||||
|| (TOML_WINDOWS_COMPAT && std::is_same_v<T, std::wstring>),
|
||||
"Value type must be one of the TOML value types (or string_view)"
|
||||
);
|
||||
|
||||
@ -418,6 +395,12 @@ namespace toml
|
||||
{
|
||||
if constexpr (std::is_same_v<T, string> || std::is_same_v<T, string_view>)
|
||||
return { T{ ref_cast<string>().get() } };
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
else if constexpr (std::is_same_v<T, std::wstring>)
|
||||
return { impl::widen(ref_cast<string>().get()) };
|
||||
#endif
|
||||
|
||||
else
|
||||
return {};
|
||||
}
|
||||
@ -485,21 +468,36 @@ namespace toml
|
||||
template <typename T>
|
||||
inline auto node::value_or(T&& default_value) const noexcept
|
||||
{
|
||||
static_assert(
|
||||
!impl::is_wide_string<T> || TOML_WINDOWS_COMPAT,
|
||||
"Retrieving values as wide-character strings is only supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
);
|
||||
static_assert(
|
||||
impl::is_value_or_promotable<impl::remove_cvref_t<T>>,
|
||||
"Default value type must be (or be promotable to) one of the TOML value types"
|
||||
);
|
||||
|
||||
using value_type = impl::promoted<impl::remove_cvref_t<T>>;
|
||||
using return_type = std::conditional_t<
|
||||
std::is_same_v<value_type, string>,
|
||||
std::conditional_t<std::is_same_v<impl::remove_cvref_t<T>, string>, string, string_view>,
|
||||
value_type
|
||||
>;
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
if constexpr (impl::is_wide_string<T>)
|
||||
{
|
||||
if (this->type() == node_type::string)
|
||||
return impl::widen(ref_cast<string>().get());
|
||||
return std::wstring{ std::forward<T>(default_value) };
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
using value_type = impl::promoted<impl::remove_cvref_t<T>>;
|
||||
using return_type = std::conditional_t<
|
||||
std::is_same_v<value_type, string>,
|
||||
std::conditional_t<std::is_same_v<impl::remove_cvref_t<T>, string>, string, string_view>,
|
||||
value_type
|
||||
>;
|
||||
|
||||
if (auto val = this->value<return_type>())
|
||||
return *val;
|
||||
return return_type{ std::forward<T>(default_value) };
|
||||
if (auto val = this->value<return_type>())
|
||||
return *val;
|
||||
return return_type{ std::forward<T>(default_value) };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#define TOML_LIB_MAJOR 1
|
||||
#define TOML_LIB_MINOR 3
|
||||
#define TOML_LIB_PATCH 3
|
||||
#define TOML_LIB_PATCH 4
|
||||
|
||||
#define TOML_LANG_MAJOR 1
|
||||
#define TOML_LANG_MINOR 0
|
||||
|
@ -1,7 +1,7 @@
|
||||
project(
|
||||
'tomlplusplus',
|
||||
'cpp',
|
||||
version : '1.3.3',
|
||||
version : '1.3.4',
|
||||
license : 'MIT',
|
||||
default_options : [
|
||||
'cpp_std=c++17',
|
||||
|
@ -26,6 +26,10 @@
|
||||
#error TOML_EXCEPTIONS does not match TOML_COMPILER_EXCEPTIONS (default behaviour should be to match)
|
||||
#endif
|
||||
|
||||
#if (defined(_WIN32) && !TOML_WINDOWS_COMPAT) || (!defined(_WIN32) && TOML_WINDOWS_COMPAT)
|
||||
#error TOML_WINDOWS_COMPAT does not match _WIN32 (default behaviour should be to match)
|
||||
#endif
|
||||
|
||||
namespace toml
|
||||
{
|
||||
using std::declval;
|
||||
|
@ -47,6 +47,10 @@ TEST_CASE("values - printing")
|
||||
// large floats might get output as scientific notation and that's fine
|
||||
CHECK(print_value(10000000000) == "10000000000");
|
||||
CHECK(print_value(100000000000000) == "100000000000000");
|
||||
|
||||
}
|
||||
|
||||
static_assert(std::is_same_v<string, decltype(std::declval<node>().value_or(S(""s)))>);
|
||||
static_assert(std::is_same_v<string_view, decltype(std::declval<node>().value_or(S(""sv)))>);
|
||||
static_assert(std::is_same_v<string_view, decltype(std::declval<node>().value_or(S("")))>);
|
||||
|
||||
|
||||
|
@ -21,6 +21,7 @@ test_sources = [
|
||||
'manipulating_values.cpp',
|
||||
'unicode.cpp',
|
||||
'unicode_generated.cpp',
|
||||
'windows_compat.cpp'
|
||||
]
|
||||
|
||||
compiler_supports_char8_strings = compiler.compiles('''
|
||||
|
@ -65,7 +65,7 @@
|
||||
#define NOMETAFILE // - typedef METAFILEPICT
|
||||
#define NOMINMAX // - Macros min(a,b) and max(a,b)
|
||||
#define NOMSG // - typedef MSG and associated routines
|
||||
#define NONLS // - All NLS defines and routines
|
||||
//#define NONLS // - All NLS defines and routines
|
||||
#define NOOPENFILE // - OpenFile(), OemToAnsi, AnsiToOem, and OF_*
|
||||
#define NOPROFILER // - Profiler interface.
|
||||
#define NORASTEROPS // - Binary and Tertiary raster ops
|
||||
|
@ -168,16 +168,16 @@ inline bool parse_expected_value(
|
||||
auto nv = tbl[S("val"sv)];
|
||||
REQUIRE(nv);
|
||||
REQUIRE(nv.as<value_type>());
|
||||
REQUIRE(nv.get()->type() == impl::node_type_of<T>);
|
||||
REQUIRE(nv.node()->type() == impl::node_type_of<T>);
|
||||
|
||||
// check the raw value
|
||||
REQUIRE(nv.get()->value<value_type>() == expected);
|
||||
REQUIRE(nv.get()->value_or(T{}) == expected);
|
||||
REQUIRE(nv.node()->value<value_type>() == expected);
|
||||
REQUIRE(nv.node()->value_or(T{}) == expected);
|
||||
REQUIRE(nv.as<value_type>()->get() == expected);
|
||||
REQUIRE(nv.value<value_type>() == expected);
|
||||
REQUIRE(nv.value_or(T{}) == expected);
|
||||
REQUIRE(nv.ref<value_type>() == expected);
|
||||
REQUIRE(nv.get()->ref<value_type>() == expected);
|
||||
REQUIRE(nv.node()->ref<value_type>() == expected);
|
||||
|
||||
// check the table relops
|
||||
REQUIRE(tbl == table{ { { S("val"sv), expected } } });
|
||||
@ -196,8 +196,8 @@ inline bool parse_expected_value(
|
||||
REQUIRE(!(expected != nv));
|
||||
|
||||
// make sure source info is correct
|
||||
REQUIRE(nv.get()->source().begin == begin);
|
||||
REQUIRE(nv.get()->source().end == end);
|
||||
REQUIRE(nv.node()->source().begin == begin);
|
||||
REQUIRE(nv.node()->source().end == end);
|
||||
|
||||
// steal the val for round-trip tests
|
||||
if (!stolen_value)
|
||||
@ -235,7 +235,7 @@ inline bool parse_expected_value(
|
||||
auto nv = tbl[S("val"sv)];
|
||||
REQUIRE(nv);
|
||||
REQUIRE(nv.as<value_type>());
|
||||
REQUIRE(nv.get()->type() == impl::node_type_of<T>);
|
||||
REQUIRE(nv.node()->type() == impl::node_type_of<T>);
|
||||
|
||||
if (value_ok && nv.ref<value_type>() != expected)
|
||||
{
|
||||
|
77
tests/windows_compat.cpp
Normal file
77
tests/windows_compat.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
// This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
// Copyright (c) 2019-2020 Mark Gillard <mark.gillard@outlook.com.au>
|
||||
// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
TEST_CASE("windows compat")
|
||||
{
|
||||
static constexpr auto toml_text = R"(
|
||||
[library]
|
||||
name = "toml++"
|
||||
authors = ["Mark Gillard <mark.gillard@outlook.com.au>"]
|
||||
|
||||
[dependencies]
|
||||
cpp = 17
|
||||
)"sv;
|
||||
|
||||
auto res = toml::parse(toml_text, L"kek.toml");
|
||||
#if !TOML_EXCEPTIONS
|
||||
REQUIRE(res.succeeded());
|
||||
#endif
|
||||
toml::table& tbl = res;
|
||||
|
||||
// source paths
|
||||
REQUIRE(tbl.source().path != nullptr);
|
||||
CHECK(*tbl.source().path == "kek.toml"sv);
|
||||
CHECK(tbl.source().wide_path().has_value());
|
||||
CHECK(tbl.source().wide_path().value() == L"kek.toml"sv);
|
||||
|
||||
// direct lookups from tables
|
||||
REQUIRE(tbl.get(S("library")) != nullptr);
|
||||
CHECK(tbl.get(S("library")) == tbl.get(S("library"sv)));
|
||||
CHECK(tbl.get(S("library")) == tbl.get(S("library"s)));
|
||||
CHECK(tbl.get(L"library") != nullptr);
|
||||
CHECK(tbl.get(L"library") == tbl.get(L"library"sv));
|
||||
CHECK(tbl.get(L"library") == tbl.get(L"library"s));
|
||||
CHECK(tbl.get(L"library") == tbl.get(S("library")));
|
||||
|
||||
// node-view lookups
|
||||
CHECK(tbl[L"library"].node() != nullptr);
|
||||
CHECK(tbl[L"library"].node() == tbl.get(L"library"));
|
||||
|
||||
// value queries
|
||||
REQUIRE(tbl[L"library"][L"name"].as_string() != nullptr);
|
||||
CHECK(tbl[L"library"][L"name"].value<std::wstring>() == L"toml++"s);
|
||||
CHECK(tbl[L"library"][L"name"].value_or(L""sv) == L"toml++"s);
|
||||
CHECK(tbl[L"library"][L"name"].value_or(L""s) == L"toml++"s);
|
||||
CHECK(tbl[L"library"][L"name"].value_or(L"") == L"toml++"s);
|
||||
|
||||
// node-view comparisons
|
||||
CHECK(tbl[L"library"][L"name"] == S("toml++"sv));
|
||||
CHECK(tbl[L"library"][L"name"] == S("toml++"s));
|
||||
CHECK(tbl[L"library"][L"name"] == S("toml++"));
|
||||
CHECK(tbl[L"library"][L"name"] == L"toml++"sv);
|
||||
CHECK(tbl[L"library"][L"name"] == L"toml++"s);
|
||||
CHECK(tbl[L"library"][L"name"] == L"toml++");
|
||||
|
||||
// table manipulation
|
||||
tbl.insert(L"foo", L"bar");
|
||||
REQUIRE(tbl.contains(S("foo")));
|
||||
REQUIRE(tbl.contains(L"foo"));
|
||||
CHECK(tbl[S("foo")] == S("bar"));
|
||||
tbl.insert_or_assign(L"foo", L"kek");
|
||||
CHECK(tbl[S("foo")] == S("kek"));
|
||||
tbl.erase(L"foo");
|
||||
REQUIRE(!tbl.contains(S("foo")));
|
||||
REQUIRE(!tbl.contains(L"foo"));
|
||||
}
|
||||
|
||||
static_assert(std::is_same_v<std::wstring, decltype(std::declval<toml::node>().value_or(L""s))>);
|
||||
static_assert(std::is_same_v<std::wstring, decltype(std::declval<toml::node>().value_or(L""sv))>);
|
||||
static_assert(std::is_same_v<std::wstring, decltype(std::declval<toml::node>().value_or(L""))>);
|
||||
|
||||
#endif // TOML_WINDOWS_COMPAT
|
@ -90,6 +90,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -90,6 +90,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -92,6 +92,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -90,6 +90,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -92,6 +92,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -92,6 +92,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -90,6 +90,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -92,6 +92,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -90,6 +90,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -90,6 +90,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -92,6 +92,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -90,6 +90,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -92,6 +92,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -92,6 +92,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -90,6 +90,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -92,6 +92,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
Loading…
Reference in New Issue
Block a user