mirror of
https://github.com/marzer/tomlplusplus.git
synced 2024-09-15 15:13:21 +00:00
fixed is_unicode_XXXXXX
functions being wrong in some cases
also: - added tests for unicode functions - changed `TOML_LIKELY` semantics to work with gcc-style intrinsics - greatly improved unicode-related codegen - parser refactoring
This commit is contained in:
parent
0c2279d15a
commit
5e683e9a73
@ -218,6 +218,15 @@
|
||||
/// If the default error formatting is not be suitable for your use-case you can access the error's
|
||||
/// toml::source_region and description directly from the error object (as in the examples above).
|
||||
///
|
||||
/// \m_class{m-note m-warning}
|
||||
///
|
||||
/// \parblock
|
||||
/// <h3>Don't forget <fstream>!</h3>
|
||||
/// Not everyone who uses the library is going to work directly from files, so not everybody is forced to pay
|
||||
/// the compilation overhead of including `<fstream>`. You need to explicitly include it if you're going to be calling
|
||||
/// toml::parse_file().
|
||||
/// \endparblock
|
||||
///
|
||||
/// \see
|
||||
/// - toml::parse_file()
|
||||
/// - toml::parse_result
|
||||
|
@ -49,11 +49,11 @@ namespace toml::impl
|
||||
s += TOML_STRING_PREFIX('"');
|
||||
for (auto c : str)
|
||||
{
|
||||
if (c >= TOML_STRING_PREFIX('\x00') && c <= TOML_STRING_PREFIX('\x1F')) TOML_UNLIKELY
|
||||
if TOML_UNLIKELY(c >= TOML_STRING_PREFIX('\x00') && c <= TOML_STRING_PREFIX('\x1F'))
|
||||
s.append(low_character_escape_table[c]);
|
||||
else if (c == TOML_STRING_PREFIX('\x7F')) TOML_UNLIKELY
|
||||
else if TOML_UNLIKELY(c == TOML_STRING_PREFIX('\x7F'))
|
||||
s.append(TOML_STRING_PREFIX("\\u007F"sv));
|
||||
else if (c == TOML_STRING_PREFIX('"')) TOML_UNLIKELY
|
||||
else if TOML_UNLIKELY(c == TOML_STRING_PREFIX('"'))
|
||||
s.append(TOML_STRING_PREFIX("\\\""sv));
|
||||
else
|
||||
s += c;
|
||||
|
@ -95,9 +95,9 @@ namespace TOML_INTERNAL_NAMESPACE
|
||||
else if constexpr (std::is_same_v<arg_t, utf8_codepoint>)
|
||||
{
|
||||
string_view cp_view;
|
||||
if (arg.value <= U'\x1F') TOML_UNLIKELY
|
||||
if TOML_UNLIKELY(arg.value <= U'\x1F')
|
||||
cp_view = low_character_escape_table[arg.value];
|
||||
else if (arg.value == U'\x7F') TOML_UNLIKELY
|
||||
else if TOML_UNLIKELY(arg.value == U'\x7F')
|
||||
cp_view = TOML_STRING_PREFIX("\\u007F"sv);
|
||||
else
|
||||
cp_view = arg.template as_view<string_char>();
|
||||
@ -635,7 +635,7 @@ namespace toml::impl
|
||||
if (!skipped_escaped_codepoint)
|
||||
advance_and_return_if_error_or_eof({});
|
||||
}
|
||||
else TOML_LIKELY
|
||||
else
|
||||
{
|
||||
// handle closing delimiters
|
||||
if (*cp == U'"')
|
||||
@ -1661,11 +1661,24 @@ namespace toml::impl
|
||||
assert_or_assume(!is_value_terminator(*cp));
|
||||
push_parse_scope("value"sv);
|
||||
|
||||
// check if it begins with some control character
|
||||
// (note that this will also fail for whitespace but we're assuming we've
|
||||
// called consume_leading_whitespace() before calling parse_value())
|
||||
if TOML_UNLIKELY(is_control_character(*cp))
|
||||
set_error_and_return_default("unexpected control character"sv);
|
||||
|
||||
// underscores at the beginning
|
||||
else if (*cp == U'_')
|
||||
set_error_and_return_default("values may not begin with underscores"sv);
|
||||
|
||||
const auto begin_pos = cp->position;
|
||||
std::unique_ptr<node> val;
|
||||
|
||||
do
|
||||
{
|
||||
assert_or_assume(!is_control_character(*cp));
|
||||
assert_or_assume(*cp != U'_');
|
||||
|
||||
// detect the value type and parse accordingly,
|
||||
// starting with value types that can be detected
|
||||
// unambiguously from just one character.
|
||||
@ -1704,10 +1717,6 @@ namespace toml::impl
|
||||
else if (is_match(*cp, U'i', U'n', U'I', U'N'))
|
||||
val = std::make_unique<value<double>>(parse_inf_or_nan());
|
||||
|
||||
// underscores at the beginning
|
||||
else if (*cp == U'_')
|
||||
set_error_and_return_default("values may not begin with underscores"sv);
|
||||
|
||||
return_if_error({});
|
||||
if (val)
|
||||
break;
|
||||
@ -1760,26 +1769,28 @@ namespace toml::impl
|
||||
bool eof_while_scanning = false;
|
||||
const auto scan = [&]() TOML_MAY_THROW
|
||||
{
|
||||
while (advance_count < utf8_buffered_reader::max_history_length)
|
||||
{
|
||||
if (!cp || is_value_terminator(*cp))
|
||||
{
|
||||
eof_while_scanning = !cp;
|
||||
break;
|
||||
}
|
||||
if (is_eof())
|
||||
return;
|
||||
assert_or_assume(!is_value_terminator(*cp));
|
||||
|
||||
if (*cp != U'_')
|
||||
do
|
||||
{
|
||||
chars[char_count++] = *cp;
|
||||
switch (*cp)
|
||||
if (const auto c = **cp; c != U'_')
|
||||
{
|
||||
chars[char_count++] = c;
|
||||
|
||||
if (is_decimal_digit(c))
|
||||
add_trait(has_digits);
|
||||
else if (is_ascii_letter(c))
|
||||
{
|
||||
assert_or_assume((c >= U'a' && c <= U'z') || (c >= U'A' && c <= U'Z'));
|
||||
switch (static_cast<char32_t>(c | 32u))
|
||||
{
|
||||
case U'B': [[fallthrough]];
|
||||
case U'b':
|
||||
if (char_count == 2_sz && has_any(begins_zero))
|
||||
add_trait(has_b);
|
||||
break;
|
||||
|
||||
case U'E': [[fallthrough]];
|
||||
case U'e':
|
||||
if (char_count > 1_sz
|
||||
&& has_none(has_b | has_o | has_p | has_t | has_x | has_z | has_colon)
|
||||
@ -1787,41 +1798,47 @@ namespace toml::impl
|
||||
add_trait(has_e);
|
||||
break;
|
||||
|
||||
case U'O': [[fallthrough]];
|
||||
case U'o':
|
||||
if (char_count == 2_sz && has_any(begins_zero))
|
||||
add_trait(has_o);
|
||||
break;
|
||||
|
||||
case U'P': [[fallthrough]];
|
||||
case U'p':
|
||||
if (has_any(has_x))
|
||||
add_trait(has_p);
|
||||
break;
|
||||
|
||||
case U'X': [[fallthrough]];
|
||||
case U'x':
|
||||
if ((char_count == 2_sz && has_any(begins_zero))
|
||||
|| (char_count == 3_sz && has_any(begins_sign) && chars[1] == U'0'))
|
||||
add_trait(has_x);
|
||||
break;
|
||||
|
||||
case U'T': add_trait(has_t); break;
|
||||
case U'Z': add_trait(has_z); break;
|
||||
case U't': add_trait(has_t); break;
|
||||
case U'z': add_trait(has_z); break;
|
||||
}
|
||||
}
|
||||
else if (c <= U':')
|
||||
{
|
||||
assert_or_assume(c < U'0' || c > U'9');
|
||||
switch (c)
|
||||
{
|
||||
case U'+': add_trait(has_plus); break;
|
||||
case U'-': add_trait(has_minus); break;
|
||||
case U'.': add_trait(has_dot); break;
|
||||
case U':': add_trait(has_colon); break;
|
||||
|
||||
default:
|
||||
if (is_decimal_digit(*cp))
|
||||
add_trait(has_digits);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
advance_and_return_if_error();
|
||||
advance_count++;
|
||||
eof_while_scanning = is_eof();
|
||||
}
|
||||
while (advance_count < utf8_buffered_reader::max_history_length
|
||||
&& !is_eof()
|
||||
&& !is_value_terminator(*cp)
|
||||
);
|
||||
};
|
||||
scan();
|
||||
return_if_error({});
|
||||
@ -1831,7 +1848,7 @@ namespace toml::impl
|
||||
&& traits == (bdigit_msk | has_minus)
|
||||
&& chars[4] == U'-'
|
||||
&& chars[7] == U'-'
|
||||
&& cp
|
||||
&& !is_eof()
|
||||
&& *cp == U' ')
|
||||
{
|
||||
const auto pre_advance_count = advance_count;
|
||||
@ -1850,7 +1867,7 @@ namespace toml::impl
|
||||
advance_and_return_if_error({});
|
||||
advance_count++;
|
||||
|
||||
if (!cp || !is_decimal_digit(*cp))
|
||||
if (is_eof() || !is_decimal_digit(*cp))
|
||||
backpedal();
|
||||
else
|
||||
{
|
||||
|
@ -96,6 +96,8 @@
|
||||
#else
|
||||
#define TOML_COMPILER_EXCEPTIONS 0
|
||||
#endif
|
||||
#define TOML_LIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 1) )
|
||||
#define TOML_UNLIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 0) )
|
||||
|
||||
//floating-point from_chars and to_chars are not implemented in any version of clang as of 1/1/2020
|
||||
#ifndef TOML_FLOAT_CHARCONV
|
||||
@ -158,10 +160,8 @@
|
||||
#else
|
||||
#define TOML_COMPILER_EXCEPTIONS 0
|
||||
#endif
|
||||
|
||||
// these pass the __has_attribute() test but cause warnings on if/else branches =/
|
||||
#define TOML_LIKELY
|
||||
#define TOML_UNLIKELY
|
||||
#define TOML_LIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 1) )
|
||||
#define TOML_UNLIKELY(...) (__builtin_expect(!!(__VA_ARGS__), 0) )
|
||||
|
||||
// floating-point from_chars and to_chars are not implemented in any version of gcc as of 1/1/2020
|
||||
#ifndef TOML_FLOAT_CHARCONV
|
||||
@ -284,10 +284,10 @@
|
||||
|
||||
#if !TOML_DOXYGEN && !defined(__INTELLISENSE__)
|
||||
#if !defined(TOML_LIKELY) && __has_cpp_attribute(likely)
|
||||
#define TOML_LIKELY [[likely]]
|
||||
#define TOML_LIKELY(...) (__VA_ARGS__) [[likely]]
|
||||
#endif
|
||||
#if !defined(TOML_UNLIKELY) && __has_cpp_attribute(unlikely)
|
||||
#define TOML_UNLIKELY [[unlikely]]
|
||||
#define TOML_UNLIKELY(...) (__VA_ARGS__) [[unlikely]]
|
||||
#endif
|
||||
#if __has_cpp_attribute(nodiscard) >= 201907L
|
||||
#define TOML_NODISCARD_CTOR [[nodiscard]]
|
||||
@ -295,10 +295,10 @@
|
||||
#endif
|
||||
|
||||
#ifndef TOML_LIKELY
|
||||
#define TOML_LIKELY
|
||||
#define TOML_LIKELY(...) (__VA_ARGS__)
|
||||
#endif
|
||||
#ifndef TOML_UNLIKELY
|
||||
#define TOML_UNLIKELY
|
||||
#define TOML_UNLIKELY(...) (__VA_ARGS__)
|
||||
#endif
|
||||
#ifndef TOML_NODISCARD_CTOR
|
||||
#define TOML_NODISCARD_CTOR
|
||||
|
@ -343,13 +343,13 @@ namespace toml::impl
|
||||
static_assert(sizeof(Char) == 1);
|
||||
for (auto c : str)
|
||||
{
|
||||
if (c >= TOML_STRING_PREFIX('\x00') && c <= TOML_STRING_PREFIX('\x1F')) TOML_UNLIKELY
|
||||
if TOML_UNLIKELY(c >= TOML_STRING_PREFIX('\x00') && c <= TOML_STRING_PREFIX('\x1F'))
|
||||
print_to_stream(low_character_escape_table[c], stream);
|
||||
else if (c == TOML_STRING_PREFIX('\x7F')) TOML_UNLIKELY
|
||||
else if TOML_UNLIKELY(c == TOML_STRING_PREFIX('\x7F'))
|
||||
print_to_stream(TOML_STRING_PREFIX("\\u007F"sv), stream);
|
||||
else if (c == TOML_STRING_PREFIX('"')) TOML_UNLIKELY
|
||||
else if TOML_UNLIKELY(c == TOML_STRING_PREFIX('"'))
|
||||
print_to_stream(TOML_STRING_PREFIX("\\\""sv), stream);
|
||||
else if (c == TOML_STRING_PREFIX('\\')) TOML_UNLIKELY
|
||||
else if TOML_UNLIKELY(c == TOML_STRING_PREFIX('\\'))
|
||||
print_to_stream(TOML_STRING_PREFIX("\\\\"sv), stream);
|
||||
else
|
||||
print_to_stream(c, stream);
|
||||
|
@ -121,16 +121,6 @@ namespace toml::impl
|
||||
return (codepoint >= U'0' && codepoint <= U'9');
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
constexpr bool is_hexadecimal_digit(char32_t codepoint) noexcept
|
||||
{
|
||||
return (codepoint >= U'a' && codepoint <= U'f')
|
||||
|| (codepoint >= U'A' && codepoint <= U'F')
|
||||
|| is_decimal_digit(codepoint)
|
||||
;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
@ -185,6 +175,14 @@ namespace toml::impl
|
||||
;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr bool is_control_character(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint <= U'\u001F' || codepoint == U'\u007F';
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -162,6 +162,14 @@ namespace toml::impl
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_GNU_ATTR(pure)
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr const char32_t& operator* () const noexcept
|
||||
{
|
||||
return value;
|
||||
}
|
||||
};
|
||||
static_assert(std::is_trivial_v<utf8_codepoint>);
|
||||
static_assert(std::is_standard_layout_v<utf8_codepoint>);
|
||||
@ -399,13 +407,13 @@ namespace toml::impl
|
||||
else
|
||||
{
|
||||
// first character read from stream
|
||||
if (!history.count && !head) TOML_UNLIKELY
|
||||
if TOML_UNLIKELY(!history.count && !head)
|
||||
head = reader.read_next();
|
||||
|
||||
// subsequent characters and not eof
|
||||
else if (head)
|
||||
{
|
||||
if (history.count < history_buffer_size) TOML_UNLIKELY
|
||||
if TOML_UNLIKELY(history.count < history_buffer_size)
|
||||
history.buffer[history.count++] = *head;
|
||||
else
|
||||
history.buffer[(history.first++ + history_buffer_size) % history_buffer_size] = *head;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,7 @@ TEST_CASE("arrays - moving")
|
||||
parsing_should_succeed(
|
||||
FILE_LINE_ARGS,
|
||||
S(R"(test = [ "foo" ])"sv),
|
||||
[&](table&& tbl) noexcept
|
||||
[&](table&& tbl)
|
||||
{
|
||||
CHECK(tbl.source().begin == source_position{ 1, 1 });
|
||||
CHECK(tbl.source().end == source_position{ 1, 17 });
|
||||
|
@ -7,7 +7,7 @@ TEST_CASE("tables - moving")
|
||||
parsing_should_succeed(
|
||||
FILE_LINE_ARGS,
|
||||
S(R"(test = { val1 = "foo" })"sv),
|
||||
[&](table&& tbl) noexcept
|
||||
[&](table&& tbl)
|
||||
{
|
||||
CHECK(tbl.source().begin == source_position{ 1, 1 });
|
||||
CHECK(tbl.source().end == source_position{ 1, 24 });
|
||||
@ -136,7 +136,7 @@ TEST_CASE("tables - equality")
|
||||
namespace
|
||||
{
|
||||
template <typename T>
|
||||
static auto advance(T iter, ptrdiff_t offset) noexcept
|
||||
static auto advance(T iter, ptrdiff_t offset)
|
||||
{
|
||||
while (offset > 0)
|
||||
{
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
TEST_CASE("values - printing")
|
||||
{
|
||||
static constexpr auto print_value = [](auto&& raw) noexcept
|
||||
static constexpr auto print_value = [](auto&& raw)
|
||||
{
|
||||
auto val = toml::value{ std::forward<decltype(raw)>(raw) };
|
||||
std::stringstream ss;
|
||||
|
@ -15,6 +15,8 @@ test_sources = [
|
||||
'manipulating_arrays.cpp',
|
||||
'manipulating_tables.cpp',
|
||||
'manipulating_values.cpp',
|
||||
'unicode.cpp',
|
||||
'unicode_generated.cpp',
|
||||
]
|
||||
|
||||
compiler_supports_char8_strings = compiler.compiles('''
|
||||
|
@ -18,7 +18,7 @@ nested_array_of_int = [ [ 1, 2 ], [3, 4, 5] ]
|
||||
nested_mixed_array = [ [ 1, 2 ], ["a", "b", "c"] ]
|
||||
string_array = [ "all", 'strings', """are the same""", '''type''' ]
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
REQUIRE(tbl[S("integers")].as<array>());
|
||||
CHECK(tbl[S("integers")].as<array>()->is_homogeneous());
|
||||
@ -106,7 +106,7 @@ contributors = [
|
||||
{ name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" }
|
||||
]
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
REQUIRE(tbl[S("numbers")].as<array>());
|
||||
CHECK(!tbl[S("numbers")].as<array>()->is_homogeneous());
|
||||
|
@ -8,7 +8,7 @@ TEST_CASE("parsing - booleans")
|
||||
bool1 = true
|
||||
bool2 = false
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
CHECK(tbl[S("bool1")] == true);
|
||||
CHECK(tbl[S("bool2")] == false);
|
||||
|
@ -9,7 +9,7 @@ TEST_CASE("parsing - comments")
|
||||
key = "value" # This is a comment at the end of a line
|
||||
another = "# This is not a comment"
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
CHECK(tbl.size() == 2);
|
||||
CHECK(tbl[S("key")] == S("value"sv));
|
||||
@ -20,7 +20,7 @@ another = "# This is not a comment"
|
||||
parsing_should_succeed(
|
||||
FILE_LINE_ARGS,
|
||||
S(R"(# this = "looks like a KVP but is commented out)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
CHECK(tbl.size() == 0);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ ld1 = 1979-05-27
|
||||
lt1 = 07:32:00
|
||||
lt2 = 00:32:00.999999
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
static constexpr auto odt1 = date_time{ { 1979, 5, 27 }, { 7, 32 }, {} };
|
||||
CHECK(tbl[S("odt1")] == odt1);
|
||||
|
@ -22,7 +22,7 @@ flt7 = 6.626e-34
|
||||
|
||||
flt8 = 224_617.445_991_228
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
CHECK(tbl[S("flt1")] == 1.0);
|
||||
CHECK(tbl[S("flt2")] == 3.1415);
|
||||
@ -44,7 +44,7 @@ flt8 = 224_617.445_991_228
|
||||
parsing_should_succeed(
|
||||
FILE_LINE_ARGS,
|
||||
S(R"(zeroes = [-0.0, +0.0])"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
CHECK(tbl[S("zeroes")][0] == -0.0);
|
||||
CHECK(tbl[S("zeroes")][1] == +0.0);
|
||||
@ -188,7 +188,7 @@ sf4 = nan # actual sNaN/qNaN encoding is implementation specific
|
||||
sf5 = +nan # same as `nan`
|
||||
sf6 = -nan # valid, actual encoding is implementation specific
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
CHECK(tbl[S("sf1")] == std::numeric_limits<double>::infinity());
|
||||
CHECK(tbl[S("sf2")] == std::numeric_limits<double>::infinity());
|
||||
|
@ -13,7 +13,7 @@ int5 = 1_000
|
||||
int6 = 5_349_221
|
||||
int7 = 1_2_3_4_5 # VALID but discouraged
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
CHECK(tbl[S("int1")] == 99);
|
||||
CHECK(tbl[S("int2")] == 42);
|
||||
@ -43,7 +43,7 @@ int7 = 1_2_3_4_5 # VALID but discouraged
|
||||
parsing_should_succeed(
|
||||
FILE_LINE_ARGS,
|
||||
S("zeroes = [-0, +0]"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
CHECK(tbl[S("zeroes")][0] == 0);
|
||||
CHECK(tbl[S("zeroes")][1] == 0);
|
||||
@ -87,7 +87,7 @@ oct2 = 0o755 # useful for Unix file permissions
|
||||
# binary with prefix `0b`
|
||||
bin1 = 0b11010110
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
CHECK(tbl[S("hex1")] == 0xDEADBEEF);
|
||||
CHECK(tbl[S("hex2")] == 0xDEADBEEF);
|
||||
@ -118,7 +118,7 @@ oct1 = 0o0001234567
|
||||
oct2 = 0o000755
|
||||
bin1 = 0b0000011010110
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
CHECK(tbl[S("hex1")] == 0xDEADBEEF);
|
||||
CHECK(tbl[S("hex2")] == 0xDEADBEEF);
|
||||
|
@ -11,7 +11,7 @@ bare-key = "value"
|
||||
1234 = "value"
|
||||
"" = "blank"
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
CHECK(tbl.size() == 5);
|
||||
CHECK(tbl[S("key")] == S("value"sv));
|
||||
@ -34,7 +34,7 @@ bare-key = "value"
|
||||
'quoted "value"' = "value"
|
||||
'' = 'blank'
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
CHECK(tbl[S("127.0.0.1")] == S("value"sv));
|
||||
CHECK(tbl[S("character encoding")] == S("value"sv));
|
||||
@ -66,7 +66,7 @@ physical.shape = "round"
|
||||
site."google.com" = true
|
||||
3.14159 = "pi"
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
CHECK(tbl.size() == 4);
|
||||
CHECK(tbl[S("name")] == S("Orange"sv));
|
||||
@ -84,7 +84,7 @@ site."google.com" = true
|
||||
fruit.apple.smooth = true
|
||||
fruit.orange = 2
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
CHECK(tbl[S("fruit")][S("apple")][S("smooth")] == true);
|
||||
CHECK(tbl[S("fruit")][S("orange")] == 2);
|
||||
@ -111,7 +111,7 @@ orange.skin = "thick"
|
||||
apple.color = "red"
|
||||
orange.color = "orange"
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
CHECK(tbl[S("apple")][S("type")] == S("fruit"sv));
|
||||
CHECK(tbl[S("apple")][S("skin")] == S("thin"sv));
|
||||
@ -135,7 +135,7 @@ orange.type = "fruit"
|
||||
orange.skin = "thick"
|
||||
orange.color = "orange"
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
CHECK(tbl[S("apple")][S("type")] == S("fruit"sv));
|
||||
CHECK(tbl[S("apple")][S("skin")] == S("thin"sv));
|
||||
@ -154,7 +154,7 @@ orange.color = "orange"
|
||||
key+1 = 0
|
||||
ʎǝʞ2 = 0
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
CHECK(tbl.size() == 2);
|
||||
CHECK(tbl[S("key+1")] == 0);
|
||||
|
@ -43,7 +43,7 @@ hosts = [
|
||||
parsing_should_succeed(
|
||||
FILE_LINE_ARGS,
|
||||
toml_text,
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
CHECK(tbl.size() == 5);
|
||||
|
||||
|
@ -16,7 +16,7 @@ str2 = """
|
||||
Roses are red
|
||||
Violets are blue"""
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
CHECK(tbl[S("str")] == S("I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."sv));
|
||||
CHECK(tbl[S("str1")] == S("Roses are red\nViolets are blue"sv));
|
||||
@ -51,7 +51,7 @@ str6 = """Here are fifteen quotation marks: ""\"""\"""\"""\"""\"."""
|
||||
# "This," she said, "is just a pointless statement."
|
||||
str7 = """"This," she said, "is just a pointless statement.""""
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
static constexpr auto quick_brown_fox = S("The quick brown fox jumps over the lazy dog."sv);
|
||||
CHECK(tbl[S("str1")] == quick_brown_fox);
|
||||
@ -89,7 +89,7 @@ trimmed in raw strings.
|
||||
is preserved.
|
||||
'''
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
CHECK(tbl[S("winpath")] == S(R"(C:\Users\nodejs\templates)"sv));
|
||||
CHECK(tbl[S("winpath2")] == S(R"(\\ServerX\admin$\system32\)"sv));
|
||||
@ -121,7 +121,7 @@ apos15 = "Here are fifteen apostrophes: '''''''''''''''"
|
||||
# 'That's still pointless', she said.
|
||||
str = ''''That's still pointless', she said.'''
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
CHECK(tbl[S("quot15")] == S(R"(Here are fifteen quotation marks: """"""""""""""")"sv));
|
||||
CHECK(tbl[S("apos15")] == S(R"(Here are fifteen apostrophes: ''''''''''''''')"sv));
|
||||
|
@ -38,7 +38,7 @@ apple.taste.sweet = true
|
||||
smooth = true
|
||||
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
REQUIRE(tbl[S("table")].as<table>());
|
||||
CHECK(tbl[S("table")].as<table>()->size() == 0_sz);
|
||||
@ -128,7 +128,7 @@ apple.taste.sweet = true
|
||||
[animal]
|
||||
[fruit.orange]
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
REQUIRE(tbl[S("animal")].as<table>());
|
||||
CHECK(tbl[S("animal")].as<table>()->size() == 0_sz);
|
||||
@ -150,7 +150,7 @@ apple.taste.sweet = true
|
||||
[fruit.orange]
|
||||
[animal]
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
REQUIRE(tbl[S("animal")].as<table>());
|
||||
CHECK(tbl[S("animal")].as<table>()->size() == 0_sz);
|
||||
@ -176,7 +176,7 @@ animal = { type.name = "pug" }
|
||||
[product]
|
||||
type = { name = "Nail" }
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
REQUIRE(tbl[S("name")].as<table>());
|
||||
CHECK(tbl[S("name")].as<table>()->size() == 2_sz);
|
||||
@ -223,7 +223,7 @@ test = { val1 = "foo", val2 = [
|
||||
3
|
||||
], val3 = "bar" }
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
REQUIRE(tbl[S("test")].as<table>());
|
||||
CHECK(tbl[S("test")].as<table>()->size() == 3_sz);
|
||||
@ -248,7 +248,7 @@ name = {
|
||||
last = "Preston-Werner",
|
||||
}
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
REQUIRE(tbl[S("name")].as<table>());
|
||||
CHECK(tbl[S("name")].as<table>()->size() == 2_sz);
|
||||
@ -317,7 +317,7 @@ color = "gray"
|
||||
name = "plantain"
|
||||
|
||||
)"sv),
|
||||
[](table&& tbl) noexcept
|
||||
[](table&& tbl)
|
||||
{
|
||||
REQUIRE(tbl[S("points")].as<array>());
|
||||
CHECK(tbl[S("points")].as<array>()->size() == 3_sz);
|
||||
|
@ -1,11 +1,11 @@
|
||||
#include "tests.h"
|
||||
|
||||
template void parse_expected_value(std::string_view, uint32_t, std::string_view, const int&) noexcept;
|
||||
template void parse_expected_value(std::string_view, uint32_t, std::string_view, const unsigned int&) noexcept;
|
||||
template void parse_expected_value(std::string_view, uint32_t, std::string_view, const bool&) noexcept;
|
||||
template void parse_expected_value(std::string_view, uint32_t, std::string_view, const float&) noexcept;
|
||||
template void parse_expected_value(std::string_view, uint32_t, std::string_view, const double&) noexcept;
|
||||
template void parse_expected_value(std::string_view, uint32_t, std::string_view, const toml::string_view&) noexcept;
|
||||
template void parse_expected_value(std::string_view, uint32_t, std::string_view, const int&);
|
||||
template void parse_expected_value(std::string_view, uint32_t, std::string_view, const unsigned int&);
|
||||
template void parse_expected_value(std::string_view, uint32_t, std::string_view, const bool&);
|
||||
template void parse_expected_value(std::string_view, uint32_t, std::string_view, const float&);
|
||||
template void parse_expected_value(std::string_view, uint32_t, std::string_view, const double&);
|
||||
template void parse_expected_value(std::string_view, uint32_t, std::string_view, const toml::string_view&);
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
@ -46,14 +46,14 @@ inline void parsing_should_succeed(
|
||||
uint32_t test_line,
|
||||
std::basic_string_view<Char> toml_str,
|
||||
Func&& func = {},
|
||||
std::string_view source_path = {}) noexcept
|
||||
std::string_view source_path = {})
|
||||
{
|
||||
INFO(
|
||||
"["sv << test_file << ", line "sv << test_line << "] "sv
|
||||
<< "parsing_should_succeed('"sv << std::string_view(reinterpret_cast<const char*>(toml_str.data()), toml_str.length()) << "')"sv
|
||||
)
|
||||
|
||||
constexpr auto validate_table = [](table&& tabl, std::string_view path) noexcept -> table&&
|
||||
constexpr auto validate_table = [](table&& tabl, std::string_view path) -> table&&
|
||||
{
|
||||
INFO("Validating table source information"sv)
|
||||
CHECK(tabl.source().begin != source_position{});
|
||||
@ -155,7 +155,7 @@ template <typename Char>
|
||||
inline void parsing_should_fail(
|
||||
std::string_view test_file,
|
||||
uint32_t test_line,
|
||||
std::basic_string_view<Char> toml_str) noexcept
|
||||
std::basic_string_view<Char> toml_str)
|
||||
{
|
||||
INFO(
|
||||
"["sv << test_file << ", line "sv << test_line << "] "sv
|
||||
@ -164,7 +164,7 @@ inline void parsing_should_fail(
|
||||
|
||||
#if TOML_EXCEPTIONS
|
||||
|
||||
static constexpr auto run_tests = [](auto&& fn) noexcept
|
||||
static constexpr auto run_tests = [](auto&& fn)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -196,7 +196,7 @@ inline void parsing_should_fail(
|
||||
|
||||
#else
|
||||
|
||||
static constexpr auto run_tests = [](auto&& fn) noexcept
|
||||
static constexpr auto run_tests = [](auto&& fn)
|
||||
{
|
||||
parse_result result = fn();
|
||||
if (result)
|
||||
@ -212,8 +212,8 @@ inline void parsing_should_fail(
|
||||
}
|
||||
};
|
||||
|
||||
if (run_tests([=]() noexcept { return toml::parse(toml_str); }))
|
||||
run_tests([=]() noexcept
|
||||
if (run_tests([=]() { return toml::parse(toml_str); }))
|
||||
run_tests([=]()
|
||||
{
|
||||
std::basic_stringstream<Char, std::char_traits<Char>, std::allocator<Char>> ss;
|
||||
ss.write(toml_str.data(), static_cast<std::streamsize>(toml_str.length()));
|
||||
@ -228,7 +228,7 @@ inline void parse_expected_value(
|
||||
std::string_view test_file,
|
||||
uint32_t test_line,
|
||||
std::string_view value_str,
|
||||
const T& expected) noexcept
|
||||
const T& expected)
|
||||
{
|
||||
INFO("["sv << test_file << ", line "sv << test_line << "] "sv << "parse_expected_value('"sv << value_str << "')"sv)
|
||||
|
||||
@ -238,7 +238,7 @@ inline void parse_expected_value(
|
||||
val.append(key);
|
||||
val.append(value_str);
|
||||
|
||||
static constexpr auto is_val = [](char32_t codepoint) noexcept
|
||||
static constexpr auto is_val = [](char32_t codepoint)
|
||||
{
|
||||
if constexpr (std::is_same_v<string, impl::promoted<T>>)
|
||||
return codepoint == U'"' || codepoint == U'\'';
|
||||
@ -287,7 +287,7 @@ inline void parse_expected_value(
|
||||
test_file,
|
||||
test_line,
|
||||
std::string_view{ val },
|
||||
[&](table&& tbl) noexcept
|
||||
[&](table&& tbl)
|
||||
{
|
||||
REQUIRE(tbl.size() == 1);
|
||||
auto nv = tbl[S("val"sv)];
|
||||
@ -347,7 +347,7 @@ inline void parse_expected_value(
|
||||
test_file,
|
||||
test_line,
|
||||
std::string_view{ str },
|
||||
[&](table&& tbl) noexcept
|
||||
[&](table&& tbl)
|
||||
{
|
||||
REQUIRE(tbl.size() == 1);
|
||||
auto nv = tbl[S("val"sv)];
|
||||
@ -368,12 +368,12 @@ inline void parse_expected_value(
|
||||
}
|
||||
|
||||
// manually instantiate some templates to reduce test compilation time (chosen using ClangBuildAnalyzer)
|
||||
extern template void parse_expected_value(std::string_view, uint32_t, std::string_view, const int&) noexcept;
|
||||
extern template void parse_expected_value(std::string_view, uint32_t, std::string_view, const unsigned int&) noexcept;
|
||||
extern template void parse_expected_value(std::string_view, uint32_t, std::string_view, const bool&) noexcept;
|
||||
extern template void parse_expected_value(std::string_view, uint32_t, std::string_view, const float&) noexcept;
|
||||
extern template void parse_expected_value(std::string_view, uint32_t, std::string_view, const double&) noexcept;
|
||||
extern template void parse_expected_value(std::string_view, uint32_t, std::string_view, const toml::string_view&) noexcept;
|
||||
extern template void parse_expected_value(std::string_view, uint32_t, std::string_view, const int&);
|
||||
extern template void parse_expected_value(std::string_view, uint32_t, std::string_view, const unsigned int&);
|
||||
extern template void parse_expected_value(std::string_view, uint32_t, std::string_view, const bool&);
|
||||
extern template void parse_expected_value(std::string_view, uint32_t, std::string_view, const float&);
|
||||
extern template void parse_expected_value(std::string_view, uint32_t, std::string_view, const double&);
|
||||
extern template void parse_expected_value(std::string_view, uint32_t, std::string_view, const toml::string_view&);
|
||||
namespace std
|
||||
{
|
||||
extern template class unique_ptr<const Catch::IExceptionTranslator>;
|
||||
|
86
tests/unicode.cpp
Normal file
86
tests/unicode.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
#include "tests.h"
|
||||
#include "unicode.h"
|
||||
using namespace toml::impl;
|
||||
|
||||
TEST_CASE("unicode - is_ascii_letter")
|
||||
{
|
||||
constexpr auto fn = is_ascii_letter;
|
||||
REQUIRE(not_in(fn, { U'\0', U'@' }));
|
||||
REQUIRE(in_only(fn, { U'A', U'Z' }));
|
||||
REQUIRE(not_in(fn, { U'[', U'`' }));
|
||||
REQUIRE(in_only(fn, { U'a', U'z' }));
|
||||
REQUIRE(not_in(fn, { U'{', unimax }));
|
||||
}
|
||||
|
||||
TEST_CASE("unicode - is_ascii_whitespace")
|
||||
{
|
||||
constexpr auto fn = is_ascii_whitespace;
|
||||
REQUIRE(not_in(fn, { U'\0', U'\u0008' }));
|
||||
REQUIRE(in_only(fn, U'\t' ));
|
||||
REQUIRE(not_in(fn, { U'\n', U'\u001F' }));
|
||||
REQUIRE(in_only(fn, U' ' ));
|
||||
REQUIRE(not_in(fn, { U'!', unimax }));
|
||||
}
|
||||
|
||||
TEST_CASE("unicode - is_ascii_line_break")
|
||||
{
|
||||
constexpr auto fn = is_ascii_line_break<true>;
|
||||
REQUIRE(not_in(fn, { U'\0', U'\t' }));
|
||||
REQUIRE(in_only(fn, { U'\n', U'\r' }));
|
||||
REQUIRE(not_in(fn, { U'\u000E', unimax }));
|
||||
}
|
||||
|
||||
TEST_CASE("unicode - is_decimal_digit")
|
||||
{
|
||||
constexpr auto fn = is_decimal_digit;
|
||||
REQUIRE(not_in(fn, { U'\0', U'/' }));
|
||||
REQUIRE(in_only(fn, { U'0', U'9' }));
|
||||
REQUIRE(not_in(fn, { U':', unimax }));
|
||||
}
|
||||
|
||||
TEST_CASE("unicode - is_string_delimiter")
|
||||
{
|
||||
constexpr auto fn = is_string_delimiter;
|
||||
REQUIRE(not_in(fn, { U'\0', U'!' }));
|
||||
REQUIRE(in_only(fn, U'"' ));
|
||||
REQUIRE(not_in(fn, { U'#', U'&' }));
|
||||
REQUIRE(in_only(fn, U'\'' ));
|
||||
REQUIRE(not_in(fn, { U'(', unimax }));
|
||||
}
|
||||
|
||||
TEST_CASE("unicode - is_unicode_whitespace")
|
||||
{
|
||||
constexpr auto fn = is_unicode_whitespace;
|
||||
REQUIRE(not_in(fn, { U'\0', U'\u009F' }));
|
||||
REQUIRE(in_only(fn, U'\u00A0' ));
|
||||
REQUIRE(not_in(fn, { U'\u00A1', U'\u167F' }));
|
||||
REQUIRE(in_only(fn, U'\u1680' ));
|
||||
REQUIRE(not_in(fn, { U'\u1681', U'\u1FFF' }));
|
||||
REQUIRE(in_only(fn, { U'\u2000', U'\u200A' }));
|
||||
REQUIRE(not_in(fn, { U'\u200B', U'\u202E' }));
|
||||
REQUIRE(in_only(fn, U'\u202F' ));
|
||||
REQUIRE(not_in(fn, { U'\u2030', U'\u205E' }));
|
||||
REQUIRE(in_only(fn, U'\u205F' ));
|
||||
REQUIRE(not_in(fn, { U'\u2060', U'\u2FFF' }));
|
||||
REQUIRE(in_only(fn, U'\u3000' ));
|
||||
REQUIRE(not_in(fn, { U'\u3001', unimax }));
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("unicode - is_unicode_line_break")
|
||||
{
|
||||
constexpr auto fn = is_unicode_line_break;
|
||||
REQUIRE(not_in(fn, { U'\0', U'\u0084' }));
|
||||
REQUIRE(in_only(fn, U'\u0085' ));
|
||||
REQUIRE(not_in(fn, { U'\u0086', U'\u2027' }));
|
||||
REQUIRE(in_only(fn, { U'\u2028', U'\u2029' }));
|
||||
REQUIRE(not_in(fn, { U'\u202A', unimax }));
|
||||
}
|
||||
|
||||
TEST_CASE("unicode - is_unicode_surrogate")
|
||||
{
|
||||
constexpr auto fn = is_unicode_surrogate;
|
||||
REQUIRE(not_in(fn, { U'\0', 0xD7FFu }));
|
||||
REQUIRE(in_only(fn, { 0xD800u, 0xDFFF }));
|
||||
REQUIRE(not_in(fn, { 0xE000, unimax }));
|
||||
}
|
84
tests/unicode.h
Normal file
84
tests/unicode.h
Normal file
@ -0,0 +1,84 @@
|
||||
#pragma once
|
||||
#include "tests.h"
|
||||
|
||||
using func_type = bool(char32_t);
|
||||
inline constexpr func_type* funcs[] =
|
||||
{
|
||||
// these must be mutually-exclusive
|
||||
|
||||
impl::is_ascii_letter,
|
||||
impl::is_ascii_whitespace,
|
||||
impl::is_ascii_line_break<true>,
|
||||
impl::is_decimal_digit,
|
||||
impl::is_string_delimiter,
|
||||
impl::is_unicode_whitespace,
|
||||
impl::is_unicode_line_break,
|
||||
impl::is_unicode_surrogate,
|
||||
#if TOML_LANG_UNRELEASED
|
||||
impl::is_unicode_letter,
|
||||
impl::is_unicode_number,
|
||||
impl::is_unicode_combining_mark,
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline bool in_only(func_type* fptr, T cp) noexcept
|
||||
{
|
||||
if (!fptr(static_cast<char32_t>(cp)))
|
||||
return false;
|
||||
for (auto fn : funcs)
|
||||
{
|
||||
if (fn == fptr)
|
||||
continue;
|
||||
if (fn(static_cast<char32_t>(cp)))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline constexpr uint32_t unimax = 0x10FFFFu;
|
||||
|
||||
struct codepoint_range
|
||||
{
|
||||
char32_t first;
|
||||
char32_t last;
|
||||
|
||||
template <typename T, typename U>
|
||||
codepoint_range(T first_, U last_) noexcept
|
||||
: first{ static_cast<char32_t>(first_) },
|
||||
last{ static_cast<char32_t>(last_) }
|
||||
{
|
||||
if (last < first)
|
||||
std::swap(first, last);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
codepoint_range(T first_) noexcept
|
||||
: first{ static_cast<char32_t>(first_) },
|
||||
last{ first }
|
||||
{}
|
||||
};
|
||||
|
||||
inline bool in(func_type* fptr, codepoint_range range) noexcept
|
||||
{
|
||||
for (auto cp = range.first; cp <= range.last; cp++)
|
||||
if (!fptr(cp))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool in_only(func_type* fptr, codepoint_range range) noexcept
|
||||
{
|
||||
for (auto cp = range.first; cp <= range.last; cp++)
|
||||
if (!in_only(fptr, cp))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool not_in(func_type* fptr, codepoint_range range) noexcept
|
||||
{
|
||||
for (auto cp = range.first; cp <= range.last; cp++)
|
||||
if (fptr(cp))
|
||||
return false;
|
||||
return true;
|
||||
}
|
2040
tests/unicode_generated.cpp
Normal file
2040
tests/unicode_generated.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -84,12 +84,15 @@
|
||||
<ClCompile Include="..\tests\tests.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\tests\tests.h" />
|
||||
<ClInclude Include="..\tests\unicode.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
@ -84,6 +84,8 @@
|
||||
<ClCompile Include="..\tests\tests.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -86,6 +86,8 @@
|
||||
<ClCompile Include="..\tests\tests.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -84,6 +84,8 @@
|
||||
<ClCompile Include="..\tests\tests.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -86,6 +86,8 @@
|
||||
<ClCompile Include="..\tests\tests.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -86,6 +86,8 @@
|
||||
<ClCompile Include="..\tests\tests.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -84,6 +84,8 @@
|
||||
<ClCompile Include="..\tests\tests.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -86,6 +86,8 @@
|
||||
<ClCompile Include="..\tests\tests.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -84,6 +84,8 @@
|
||||
<ClCompile Include="..\tests\tests.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -84,6 +84,8 @@
|
||||
<ClCompile Include="..\tests\tests.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -86,6 +86,8 @@
|
||||
<ClCompile Include="..\tests\tests.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -84,6 +84,8 @@
|
||||
<ClCompile Include="..\tests\tests.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -86,6 +86,8 @@
|
||||
<ClCompile Include="..\tests\tests.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -86,6 +86,8 @@
|
||||
<ClCompile Include="..\tests\tests.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -84,6 +84,8 @@
|
||||
<ClCompile Include="..\tests\tests.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
@ -86,6 +86,8 @@
|
||||
<ClCompile Include="..\tests\tests.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\tests\unicode_generated.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
Loading…
Reference in New Issue
Block a user