removed internal operator""_sz (ADL is a cruel mistress)

also:
- applied clang-format to tests
- added some missing `TOML_API`
This commit is contained in:
Mark Gillard 2021-10-26 16:49:23 +03:00
parent 7da912c45e
commit dbc078202d
78 changed files with 2165 additions and 2303 deletions

View File

@ -156,7 +156,6 @@ StatementMacros:
- TOML_ALWAYS_INLINE - TOML_ALWAYS_INLINE
- TOML_API - TOML_API
- TOML_ATTR - TOML_ATTR
- TOML_CONSTEVAL
- TOML_EXTERNAL_LINKAGE - TOML_EXTERNAL_LINKAGE
- TOML_INTERNAL_LINKAGE - TOML_INTERNAL_LINKAGE
- TOML_MEMBER_ATTR - TOML_MEMBER_ATTR

View File

@ -6,7 +6,6 @@
#define TOML_ABSTRACT_BASE #define TOML_ABSTRACT_BASE
#define TOML_EMPTY_BASES #define TOML_EMPTY_BASES
#define TOML_MAY_THROW #define TOML_MAY_THROW
#define TOML_CONSTEVAL constexpr
#define TOML_CONSTRAINED_TEMPLATE(cond, ...) template <__VA_ARGS__> #define TOML_CONSTRAINED_TEMPLATE(cond, ...) template <__VA_ARGS__>
#define TOML_LIKELY(...) (__VA_ARGS__) #define TOML_LIKELY(...) (__VA_ARGS__)
#define TOML_UNLIKELY(...) (__VA_ARGS__) #define TOML_UNLIKELY(...) (__VA_ARGS__)

View File

@ -356,14 +356,13 @@ TOML_NAMESPACE_START
/// \tparam ElemTypes One of the TOML node or value types (or a type promotable to one). /// \tparam ElemTypes One of the TOML node or value types (or a type promotable to one).
/// \param val The node or value used to initialize element 0. /// \param val The node or value used to initialize element 0.
/// \param vals The nodes or values used to initialize elements 1...N. /// \param vals The nodes or values used to initialize elements 1...N.
TOML_CONSTRAINED_TEMPLATE((sizeof...(ElemTypes) > 0_sz TOML_CONSTRAINED_TEMPLATE((sizeof...(ElemTypes) > 0 || !std::is_same_v<impl::remove_cvref_t<ElemType>, array>),
|| !std::is_same_v<impl::remove_cvref_t<ElemType>, array>),
typename ElemType, typename ElemType,
typename... ElemTypes) typename... ElemTypes)
TOML_NODISCARD_CTOR TOML_NODISCARD_CTOR
explicit array(ElemType&& val, ElemTypes&&... vals) explicit array(ElemType&& val, ElemTypes&&... vals)
{ {
elements.reserve(sizeof...(ElemTypes) + 1_sz); elements.reserve(sizeof...(ElemTypes) + 1u);
emplace_back_if_not_empty_view(static_cast<ElemType&&>(val)); emplace_back_if_not_empty_view(static_cast<ElemType&&>(val));
if constexpr (sizeof...(ElemTypes) > 0) if constexpr (sizeof...(ElemTypes) > 0)
{ {
@ -659,7 +658,7 @@ TOML_NAMESPACE_START
const auto start_idx = static_cast<size_t>(pos.raw_ - elements.cbegin()); const auto start_idx = static_cast<size_t>(pos.raw_ - elements.cbegin());
preinsertion_resize(start_idx, count); preinsertion_resize(start_idx, count);
size_t i = start_idx; size_t i = start_idx;
for (size_t e = start_idx + count - 1_sz; i < e; i++) for (size_t e = start_idx + count - 1u; i < e; i++)
elements[i].reset(impl::make_node(val)); elements[i].reset(impl::make_node(val));
//# potentially move the initial value into the last element //# potentially move the initial value into the last element
@ -1087,7 +1086,7 @@ TOML_NAMESPACE_START
if (lhs.size() != rhs.size()) if (lhs.size() != rhs.size())
return false; return false;
if (rhs.size() == 0_sz) if (rhs.size() == 0u)
return true; return true;
size_t i{}; size_t i{};

View File

@ -94,14 +94,14 @@ TOML_NAMESPACE_START
void array::preinsertion_resize(size_t idx, size_t count) noexcept void array::preinsertion_resize(size_t idx, size_t count) noexcept
{ {
TOML_ASSERT(idx <= elements.size()); TOML_ASSERT(idx <= elements.size());
TOML_ASSERT(count >= 1_sz); TOML_ASSERT(count >= 1u);
const auto old_size = elements.size(); const auto old_size = elements.size();
const auto new_size = old_size + count; const auto new_size = old_size + count;
const auto inserting_at_end = idx == old_size; const auto inserting_at_end = idx == old_size;
elements.resize(new_size); elements.resize(new_size);
if (!inserting_at_end) if (!inserting_at_end)
{ {
for (size_t left = old_size, right = new_size - 1_sz; left-- > idx; right--) for (size_t left = old_size, right = new_size - 1u; left-- > idx; right--)
elements[right] = std::move(elements[left]); elements[right] = std::move(elements[left]);
} }
} }
@ -165,7 +165,7 @@ TOML_NAMESPACE_START
for (size_t i = 0, e = elements.size(); i < e; i++) for (size_t i = 0, e = elements.size(); i < e; i++)
{ {
auto arr = elements[i]->as_array(); auto arr = elements[i]->as_array();
leaves += arr ? arr->total_leaf_count() : 1_sz; leaves += arr ? arr->total_leaf_count() : size_t{ 1 };
} }
return leaves; return leaves;
} }
@ -195,14 +195,14 @@ TOML_NAMESPACE_START
bool requires_flattening = false; bool requires_flattening = false;
size_t size_after_flattening = elements.size(); size_t size_after_flattening = elements.size();
for (size_t i = elements.size(); i-- > 0_sz;) for (size_t i = elements.size(); i-- > 0u;)
{ {
auto arr = elements[i]->as_array(); auto arr = elements[i]->as_array();
if (!arr) if (!arr)
continue; continue;
size_after_flattening--; // discount the array itself size_after_flattening--; // discount the array itself
const auto leaf_count = arr->total_leaf_count(); const auto leaf_count = arr->total_leaf_count();
if (leaf_count > 0_sz) if (leaf_count > 0u)
{ {
requires_flattening = true; requires_flattening = true;
size_after_flattening += leaf_count; size_after_flattening += leaf_count;
@ -228,8 +228,8 @@ TOML_NAMESPACE_START
std::unique_ptr<node> arr_storage = std::move(elements[i]); std::unique_ptr<node> arr_storage = std::move(elements[i]);
const auto leaf_count = arr->total_leaf_count(); const auto leaf_count = arr->total_leaf_count();
if (leaf_count > 1_sz) if (leaf_count > 1u)
preinsertion_resize(i + 1_sz, leaf_count - 1_sz); preinsertion_resize(i + 1u, leaf_count - 1u);
flatten_child(std::move(*arr), i); // increments i flatten_child(std::move(*arr), i); // increments i
} }

View File

@ -46,7 +46,7 @@ TOML_NAMESPACE_START
std::vector<std::string> key_path_; std::vector<std::string> key_path_;
bool pending_table_separator_ = false; bool pending_table_separator_ = false;
static constexpr size_t line_wrap_cols = 120_sz; static constexpr size_t line_wrap_cols = 120;
TOML_NODISCARD TOML_NODISCARD
TOML_API TOML_API

View File

@ -45,7 +45,7 @@ TOML_NAMESPACE_START
if (requires_quotes) if (requires_quotes)
{ {
std::string s; std::string s;
s.reserve(str.length() + 2_sz); s.reserve(str.length() + 2u);
s += '"'; s += '"';
for (auto c : str) for (auto c : str)
{ {
@ -75,11 +75,11 @@ TOML_NAMESPACE_START
{ {
auto& n = *reinterpret_cast<const table*>(&node); auto& n = *reinterpret_cast<const table*>(&node);
if (n.empty()) if (n.empty())
return 2_sz; // "{}" return 2u; // "{}"
size_t weight = 3_sz; // "{ }" size_t weight = 3u; // "{ }"
for (auto&& [k, v] : n) for (auto&& [k, v] : n)
{ {
weight += k.length() + count_inline_columns(v) + 2_sz; // + ", " weight += k.length() + count_inline_columns(v) + 2u; // + ", "
if (weight >= line_wrap_cols) if (weight >= line_wrap_cols)
break; break;
} }
@ -90,11 +90,11 @@ TOML_NAMESPACE_START
{ {
auto& n = *reinterpret_cast<const array*>(&node); auto& n = *reinterpret_cast<const array*>(&node);
if (n.empty()) if (n.empty())
return 2_sz; // "[]" return 2u; // "[]"
size_t weight = 3_sz; // "[ ]" size_t weight = 3u; // "[ ]"
for (auto& elem : n) for (auto& elem : n)
{ {
weight += count_inline_columns(elem) + 2_sz; // + ", " weight += count_inline_columns(elem) + 2u; // + ", "
if (weight >= line_wrap_cols) if (weight >= line_wrap_cols)
break; break;
} }
@ -104,7 +104,7 @@ TOML_NAMESPACE_START
case node_type::string: case node_type::string:
{ {
auto& n = *reinterpret_cast<const value<std::string>*>(&node); auto& n = *reinterpret_cast<const value<std::string>*>(&node);
return n.get().length() + 2_sz; // + "" return n.get().length() + 2u; // + ""
} }
case node_type::integer: case node_type::integer:
@ -112,14 +112,14 @@ TOML_NAMESPACE_START
auto& n = *reinterpret_cast<const value<int64_t>*>(&node); auto& n = *reinterpret_cast<const value<int64_t>*>(&node);
auto v = n.get(); auto v = n.get();
if (!v) if (!v)
return 1_sz; return 1u;
size_t weight = {}; size_t weight = {};
if (v < 0) if (v < 0)
{ {
weight += 1; weight += 1u;
v *= -1; v *= -1;
} }
return weight + static_cast<size_t>(log10(static_cast<double>(v))) + 1_sz; return weight + static_cast<size_t>(log10(static_cast<double>(v))) + 1u;
} }
case node_type::floating_point: case node_type::floating_point:
@ -127,21 +127,21 @@ TOML_NAMESPACE_START
auto& n = *reinterpret_cast<const value<double>*>(&node); auto& n = *reinterpret_cast<const value<double>*>(&node);
auto v = n.get(); auto v = n.get();
if (v == 0.0) if (v == 0.0)
return 3_sz; // "0.0" return 3u; // "0.0"
size_t weight = 2_sz; // ".0" size_t weight = 2u; // ".0"
if (v < 0.0) if (v < 0.0)
{ {
weight += 1; weight += 1u;
v *= -1.0; v *= -1.0;
} }
return weight + static_cast<size_t>(log10(v)) + 1_sz; return weight + static_cast<size_t>(log10(v)) + 1u;
break; break;
} }
case node_type::boolean: return 5_sz; case node_type::boolean: return 5u;
case node_type::date: [[fallthrough]]; case node_type::date: [[fallthrough]];
case node_type::time: return 10_sz; case node_type::time: return 10u;
case node_type::date_time: return 30_sz; case node_type::date_time: return 30u;
case node_type::none: TOML_UNREACHABLE; case node_type::none: TOML_UNREACHABLE;
default: TOML_UNREACHABLE; default: TOML_UNREACHABLE;
} }
@ -267,7 +267,7 @@ TOML_NAMESPACE_START
for (size_t i = 0; i < arr.size(); i++) for (size_t i = 0; i < arr.size(); i++)
{ {
if (i > 0_sz) if (i > 0u)
{ {
impl::print_to_stream(base::stream(), ','); impl::print_to_stream(base::stream(), ',');
if (!multiline) if (!multiline)
@ -309,7 +309,7 @@ TOML_NAMESPACE_START
static constexpr auto is_non_inline_array_of_tables = [](auto&& nde) noexcept static constexpr auto is_non_inline_array_of_tables = [](auto&& nde) noexcept
{ {
auto arr = nde.as_array(); auto arr = nde.as_array();
return arr && arr->is_array_of_tables() && !arr->template get_as<table>(0_sz)->is_inline(); return arr && arr->is_array_of_tables() && !arr->template get_as<table>(0u)->is_inline();
}; };
// values, arrays, and inline tables/table arrays // values, arrays, and inline tables/table arrays
@ -372,7 +372,7 @@ TOML_NAMESPACE_START
} }
} }
bool skip_self = false; bool skip_self = false;
if (child_value_count == 0_sz && (child_table_count > 0_sz || child_table_array_count > 0_sz)) if (child_value_count == 0u && (child_table_count > 0u || child_table_array_count > 0u))
skip_self = true; skip_self = true;
key_path_.push_back(make_key_segment(k)); key_path_.push_back(make_key_segment(k));

View File

@ -110,15 +110,6 @@ TOML_NAMESPACE_START
class parse_result; class parse_result;
#endif #endif
TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS
TOML_NODISCARD
TOML_ATTR(const)
TOML_ALWAYS_INLINE
TOML_CONSTEVAL
size_t operator"" _sz(unsigned long long n) noexcept
{
return static_cast<size_t>(n);
}
} }
TOML_NAMESPACE_END; TOML_NAMESPACE_END;

View File

@ -68,7 +68,7 @@ TOML_NAMESPACE_START
base::increase_indent(); base::increase_indent();
for (size_t i = 0; i < arr.size(); i++) for (size_t i = 0; i < arr.size(); i++)
{ {
if (i > 0_sz) if (i > 0u)
impl::print_to_stream(base::stream(), ','); impl::print_to_stream(base::stream(), ',');
base::print_newline(true); base::print_newline(true);
base::print_indent(); base::print_indent();

View File

@ -51,7 +51,7 @@ TOML_ANON_NAMESPACE_START
template <typename Char> template <typename Char>
class utf8_byte_stream<std::basic_string_view<Char>> class utf8_byte_stream<std::basic_string_view<Char>>
{ {
static_assert(sizeof(Char) == 1_sz); static_assert(sizeof(Char) == 1);
private: private:
std::basic_string_view<Char> source_; std::basic_string_view<Char> source_;
@ -65,20 +65,20 @@ TOML_ANON_NAMESPACE_START
// trim trailing nulls // trim trailing nulls
const size_t initial_len = source_.length(); const size_t initial_len = source_.length();
size_t actual_len = initial_len; size_t actual_len = initial_len;
for (size_t i = actual_len; i-- > 0_sz;) for (size_t i = actual_len; i-- > 0u;)
{ {
if (source_[i] != Char{}) // not '\0' if (source_[i] != Char{}) // not '\0'
{ {
actual_len = i + 1_sz; actual_len = i + 1u;
break; break;
} }
} }
if (initial_len != actual_len) if (initial_len != actual_len)
source_ = source_.substr(0_sz, actual_len); source_ = source_.substr(0u, actual_len);
// skip bom // skip bom
if (actual_len >= 3_sz && memcmp(utf8_byte_order_mark.data(), source_.data(), 3_sz) == 0) if (actual_len >= 3u && memcmp(utf8_byte_order_mark.data(), source_.data(), 3u) == 0)
position_ += 3_sz; position_ += 3u;
} }
TOML_NODISCARD TOML_NODISCARD
@ -114,7 +114,7 @@ TOML_ANON_NAMESPACE_START
template <typename Char> template <typename Char>
class utf8_byte_stream<std::basic_istream<Char>> class utf8_byte_stream<std::basic_istream<Char>>
{ {
static_assert(sizeof(Char) == 1_sz); static_assert(sizeof(Char) == 1);
private: private:
std::basic_istream<Char>* source_; std::basic_istream<Char>* source_;
@ -130,7 +130,7 @@ TOML_ANON_NAMESPACE_START
const auto initial_pos = source_->tellg(); const auto initial_pos = source_->tellg();
Char bom[3]; Char bom[3];
source_->read(bom, 3); source_->read(bom, 3);
if (source_->bad() || (source_->gcount() == 3 && memcmp(utf8_byte_order_mark.data(), bom, 3_sz) == 0)) if (source_->bad() || (source_->gcount() == 3 && memcmp(utf8_byte_order_mark.data(), bom, 3u) == 0))
return; return;
source_->clear(); source_->clear();
@ -178,7 +178,7 @@ TOML_ANON_NAMESPACE_START
TOML_NODISCARD TOML_NODISCARD
std::string_view as_view() const noexcept std::string_view as_view() const noexcept
{ {
return bytes[3] ? std::string_view{ bytes, 4_sz } : std::string_view{ bytes }; return bytes[3] ? std::string_view{ bytes, 4u } : std::string_view{ bytes };
} }
TOML_NODISCARD TOML_NODISCARD
@ -269,7 +269,7 @@ TOML_ANON_NAMESPACE_START
{ {
TOML_ERROR_CHECK; TOML_ERROR_CHECK;
auto& prev = codepoints_[(cp_idx_ - 1_sz) % 2_sz]; auto& prev = codepoints_[(cp_idx_ - 1u) % 2u];
if (stream_.eof()) if (stream_.eof())
return nullptr; return nullptr;
@ -333,7 +333,7 @@ TOML_ANON_NAMESPACE_START
TOML_ERROR_CHECK; TOML_ERROR_CHECK;
auto& current = codepoints_[cp_idx_ % 2_sz]; auto& current = codepoints_[cp_idx_ % 2u];
current.bytes[current_byte_count_++] = static_cast<char>(next_byte); current.bytes[current_byte_count_++] = static_cast<char>(next_byte);
if (decoder_.has_code_point()) if (decoder_.has_code_point())
{ {
@ -966,7 +966,7 @@ TOML_IMPL_NAMESPACE_START
TOML_NEVER_INLINE TOML_NEVER_INLINE
void set_error_at(source_position pos, const T&... reason) const TOML_MAY_THROW void set_error_at(source_position pos, const T&... reason) const TOML_MAY_THROW
{ {
static_assert(sizeof...(T) > 0_sz); static_assert(sizeof...(T) > 0);
#if !TOML_EXCEPTIONS #if !TOML_EXCEPTIONS
if (err) if (err)
return; return;
@ -991,7 +991,7 @@ TOML_IMPL_NAMESPACE_START
set_error_at(current_position(1), reason...); set_error_at(current_position(1), reason...);
} }
void go_back(size_t count = 1_sz) noexcept void go_back(size_t count = 1) noexcept
{ {
return_if_error(); return_if_error();
assert_or_assume(count); assert_or_assume(count);
@ -1034,7 +1034,7 @@ TOML_IMPL_NAMESPACE_START
recording_buffer.append(cp->as_view()); recording_buffer.append(cp->as_view());
} }
void stop_recording(size_t pop_bytes = 0_sz) noexcept void stop_recording(size_t pop_bytes = 0) noexcept
{ {
return_if_error(); return_if_error();
@ -1043,7 +1043,7 @@ TOML_IMPL_NAMESPACE_START
{ {
if (pop_bytes >= recording_buffer.length()) if (pop_bytes >= recording_buffer.length())
recording_buffer.clear(); recording_buffer.clear();
else if (pop_bytes == 1_sz) else if (pop_bytes == 1u)
recording_buffer.pop_back(); recording_buffer.pop_back();
else else
recording_buffer.erase(recording_buffer.begin() recording_buffer.erase(recording_buffer.begin()
@ -1322,7 +1322,7 @@ TOML_IMPL_NAMESPACE_START
if (multi_line) if (multi_line)
{ {
size_t lookaheads = {}; size_t lookaheads = {};
size_t consecutive_delimiters = 1_sz; size_t consecutive_delimiters = 1;
do do
{ {
advance_and_return_if_error({}); advance_and_return_if_error({});
@ -1332,30 +1332,30 @@ TOML_IMPL_NAMESPACE_START
else else
break; break;
} }
while (lookaheads < 4_sz); while (lookaheads < 4u);
switch (consecutive_delimiters) switch (consecutive_delimiters)
{ {
// """ " (one quote somewhere in a ML string) // """ " (one quote somewhere in a ML string)
case 1_sz: case 1:
str += '"'; str += '"';
skipping_whitespace = false; skipping_whitespace = false;
continue; continue;
// """ "" (two quotes somewhere in a ML string) // """ "" (two quotes somewhere in a ML string)
case 2_sz: case 2:
str.append("\"\""sv); str.append("\"\""sv);
skipping_whitespace = false; skipping_whitespace = false;
continue; continue;
// """ """ (the end of the string) // """ """ (the end of the string)
case 3_sz: return str; case 3: return str;
// """ """" (one at the end of the string) // """ """" (one at the end of the string)
case 4_sz: str += '"'; return str; case 4: str += '"'; return str;
// """ """"" (two quotes at the end of the string) // """ """"" (two quotes at the end of the string)
case 5_sz: case 5:
str.append("\"\""sv); str.append("\"\""sv);
advance_and_return_if_error({}); // skip the last '"' advance_and_return_if_error({}); // skip the last '"'
return str; return str;
@ -1451,7 +1451,7 @@ TOML_IMPL_NAMESPACE_START
if (multi_line) if (multi_line)
{ {
size_t lookaheads = {}; size_t lookaheads = {};
size_t consecutive_delimiters = 1_sz; size_t consecutive_delimiters = 1;
do do
{ {
advance_and_return_if_error({}); advance_and_return_if_error({});
@ -1461,24 +1461,24 @@ TOML_IMPL_NAMESPACE_START
else else
break; break;
} }
while (lookaheads < 4_sz); while (lookaheads < 4u);
switch (consecutive_delimiters) switch (consecutive_delimiters)
{ {
// ''' ' (one quote somewhere in a ML string) // ''' ' (one quote somewhere in a ML string)
case 1_sz: str += '\''; continue; case 1: str += '\''; continue;
// ''' '' (two quotes somewhere in a ML string) // ''' '' (two quotes somewhere in a ML string)
case 2_sz: str.append("''"sv); continue; case 2: str.append("''"sv); continue;
// ''' ''' (the end of the string) // ''' ''' (the end of the string)
case 3_sz: return str; case 3: return str;
// ''' '''' (one at the end of the string) // ''' '''' (one at the end of the string)
case 4_sz: str += '\''; return str; case 4: str += '\''; return str;
// ''' ''''' (two quotes at the end of the string) // ''' ''''' (two quotes at the end of the string)
case 5_sz: case 5:
str.append("''"sv); str.append("''"sv);
advance_and_return_if_error({}); // skip the last ' advance_and_return_if_error({}); // skip the last '
return str; return str;
@ -1561,7 +1561,7 @@ TOML_IMPL_NAMESPACE_START
{ {
// step back two characters so that the current // step back two characters so that the current
// character is the string delimiter // character is the string delimiter
go_back(2_sz); go_back(2u);
return { first == U'\'' ? parse_literal_string(false) : parse_basic_string(false), false }; return { first == U'\'' ? parse_literal_string(false) : parse_basic_string(false), false };
} }
@ -1871,7 +1871,7 @@ TOML_IMPL_NAMESPACE_START
set_error_and_return_default("expected exponent digit or sign, saw '"sv, to_sv(*cp), "'"sv); set_error_and_return_default("expected exponent digit or sign, saw '"sv, to_sv(*cp), "'"sv);
// 0x.p-0 (mantissa is just '.') // 0x.p-0 (mantissa is just '.')
else if (fragments[0].length == 0_sz && fragments[1].length == 0_sz) else if (fragments[0].length == 0u && fragments[1].length == 0u)
set_error_and_return_default("expected hexadecimal digit, saw '"sv, to_sv(*cp), "'"sv); set_error_and_return_default("expected hexadecimal digit, saw '"sv, to_sv(*cp), "'"sv);
else else
@ -1906,7 +1906,7 @@ TOML_IMPL_NAMESPACE_START
} }
// sanity-check ending state // sanity-check ending state
if (current_fragment != fragments + 2 || current_fragment->length == 0_sz) if (current_fragment != fragments + 2 || current_fragment->length == 0u)
{ {
set_error_and_return_if_eof({}); set_error_and_return_if_eof({});
set_error_and_return_default("missing exponent"sv); set_error_and_return_default("missing exponent"sv);
@ -1937,7 +1937,7 @@ TOML_IMPL_NAMESPACE_START
// calculate value // calculate value
auto place = 1u; auto place = 1u;
for (size_t i = 0; i < f.length - 1_sz; i++) for (size_t i = 0; i < f.length - 1u; i++)
place *= base; place *= base;
uint32_t val{}; uint32_t val{};
while (place) while (place)
@ -2051,7 +2051,7 @@ TOML_IMPL_NAMESPACE_START
} }
// single digits can be converted trivially // single digits can be converted trivially
if (length == 1_sz) if (length == 1u)
{ {
if constexpr (base == 16) if constexpr (base == 16)
return static_cast<int64_t>(hex_to_dec(chars[0])); return static_cast<int64_t>(hex_to_dec(chars[0]));
@ -2101,7 +2101,7 @@ TOML_IMPL_NAMESPACE_START
// "YYYY" // "YYYY"
uint32_t digits[4]; uint32_t digits[4];
if (!consume_digit_sequence(digits, 4_sz)) if (!consume_digit_sequence(digits, 4u))
set_error_and_return_default("expected 4-digit year, saw '"sv, to_sv(cp), "'"sv); set_error_and_return_default("expected 4-digit year, saw '"sv, to_sv(cp), "'"sv);
const auto year = digits[3] + digits[2] * 10u + digits[1] * 100u + digits[0] * 1000u; const auto year = digits[3] + digits[2] * 10u + digits[1] * 100u + digits[0] * 1000u;
const auto is_leap_year = (year % 4u == 0u) && ((year % 100u != 0u) || (year % 400u == 0u)); const auto is_leap_year = (year % 4u == 0u) && ((year % 100u != 0u) || (year % 400u == 0u));
@ -2113,7 +2113,7 @@ TOML_IMPL_NAMESPACE_START
advance_and_return_if_error_or_eof({}); advance_and_return_if_error_or_eof({});
// "MM" // "MM"
if (!consume_digit_sequence(digits, 2_sz)) if (!consume_digit_sequence(digits, 2u))
set_error_and_return_default("expected 2-digit month, saw '"sv, to_sv(cp), "'"sv); set_error_and_return_default("expected 2-digit month, saw '"sv, to_sv(cp), "'"sv);
const auto month = digits[1] + digits[0] * 10u; const auto month = digits[1] + digits[0] * 10u;
if (month == 0u || month > 12u) if (month == 0u || month > 12u)
@ -2130,7 +2130,7 @@ TOML_IMPL_NAMESPACE_START
advance_and_return_if_error_or_eof({}); advance_and_return_if_error_or_eof({});
// "DD" // "DD"
if (!consume_digit_sequence(digits, 2_sz)) if (!consume_digit_sequence(digits, 2u))
set_error_and_return_default("expected 2-digit day, saw '"sv, to_sv(cp), "'"sv); set_error_and_return_default("expected 2-digit day, saw '"sv, to_sv(cp), "'"sv);
const auto day = digits[1] + digits[0] * 10u; const auto day = digits[1] + digits[0] * 10u;
if (day == 0u || day > max_days_in_month) if (day == 0u || day > max_days_in_month)
@ -2153,11 +2153,11 @@ TOML_IMPL_NAMESPACE_START
assert_or_assume(is_decimal_digit(*cp)); assert_or_assume(is_decimal_digit(*cp));
push_parse_scope("time"sv); push_parse_scope("time"sv);
static constexpr auto max_digits = 9_sz; static constexpr size_t max_digits = 9;
uint32_t digits[max_digits]; uint32_t digits[max_digits];
// "HH" // "HH"
if (!consume_digit_sequence(digits, 2_sz)) if (!consume_digit_sequence(digits, 2u))
set_error_and_return_default("expected 2-digit hour, saw '"sv, to_sv(cp), "'"sv); set_error_and_return_default("expected 2-digit hour, saw '"sv, to_sv(cp), "'"sv);
const auto hour = digits[1] + digits[0] * 10u; const auto hour = digits[1] + digits[0] * 10u;
if (hour > 23u) if (hour > 23u)
@ -2171,7 +2171,7 @@ TOML_IMPL_NAMESPACE_START
advance_and_return_if_error_or_eof({}); advance_and_return_if_error_or_eof({});
// "MM" // "MM"
if (!consume_digit_sequence(digits, 2_sz)) if (!consume_digit_sequence(digits, 2u))
set_error_and_return_default("expected 2-digit minute, saw '"sv, to_sv(cp), "'"sv); set_error_and_return_default("expected 2-digit minute, saw '"sv, to_sv(cp), "'"sv);
const auto minute = digits[1] + digits[0] * 10u; const auto minute = digits[1] + digits[0] * 10u;
if (minute > 59u) if (minute > 59u)
@ -2195,7 +2195,7 @@ TOML_IMPL_NAMESPACE_START
advance_and_return_if_error_or_eof({}); advance_and_return_if_error_or_eof({});
// "SS" // "SS"
if (!consume_digit_sequence(digits, 2_sz)) if (!consume_digit_sequence(digits, 2u))
set_error_and_return_default("expected 2-digit second, saw '"sv, to_sv(cp), "'"sv); set_error_and_return_default("expected 2-digit second, saw '"sv, to_sv(cp), "'"sv);
const auto second = digits[1] + digits[0] * 10u; const auto second = digits[1] + digits[0] * 10u;
if (second > 59u) if (second > 59u)
@ -2211,7 +2211,7 @@ TOML_IMPL_NAMESPACE_START
advance_and_return_if_error_or_eof({}); advance_and_return_if_error_or_eof({});
// "FFFFFFFFF" // "FFFFFFFFF"
auto digit_count = consume_variable_length_digit_sequence(digits, max_digits); size_t digit_count = consume_variable_length_digit_sequence(digits, max_digits);
if (!digit_count) if (!digit_count)
{ {
set_error_and_return_if_eof({}); set_error_and_return_if_eof({});
@ -2228,7 +2228,7 @@ TOML_IMPL_NAMESPACE_START
uint32_t value = 0u; uint32_t value = 0u;
uint32_t place = 1u; uint32_t place = 1u;
for (auto i = digit_count; i-- > 0_sz;) for (auto i = digit_count; i-- > 0u;)
{ {
value += digits[i] * place; value += digits[i] * place;
place *= 10u; place *= 10u;
@ -2280,7 +2280,7 @@ TOML_IMPL_NAMESPACE_START
// "HH" // "HH"
int digits[2]; int digits[2];
if (!consume_digit_sequence(digits, 2_sz)) if (!consume_digit_sequence(digits, 2u))
set_error_and_return_default("expected 2-digit hour, saw '"sv, to_sv(cp), "'"sv); set_error_and_return_default("expected 2-digit hour, saw '"sv, to_sv(cp), "'"sv);
const auto hour = digits[1] + digits[0] * 10; const auto hour = digits[1] + digits[0] * 10;
if (hour > 23) if (hour > 23)
@ -2294,7 +2294,7 @@ TOML_IMPL_NAMESPACE_START
advance_and_return_if_error_or_eof({}); advance_and_return_if_error_or_eof({});
// "MM" // "MM"
if (!consume_digit_sequence(digits, 2_sz)) if (!consume_digit_sequence(digits, 2u))
set_error_and_return_default("expected 2-digit minute, saw '"sv, to_sv(cp), "'"sv); set_error_and_return_default("expected 2-digit minute, saw '"sv, to_sv(cp), "'"sv);
const auto minute = digits[1] + digits[0] * 10; const auto minute = digits[1] + digits[0] * 10;
if (minute > 59) if (minute > 59)
@ -2464,19 +2464,19 @@ TOML_IMPL_NAMESPACE_START
switch (static_cast<char32_t>(c | 32u)) switch (static_cast<char32_t>(c | 32u))
{ {
case U'b': case U'b':
if (char_count == 2_sz && has_any(begins_zero)) if (char_count == 2u && has_any(begins_zero))
add_trait(has_b); add_trait(has_b);
break; break;
case U'e': case U'e':
if (char_count > 1_sz if (char_count > 1u
&& has_none(has_b | has_o | has_p | has_t | has_x | has_z | has_colon) && has_none(has_b | has_o | has_p | has_t | has_x | has_z | has_colon)
&& (has_none(has_plus | has_minus) || has_any(begins_sign))) && (has_none(has_plus | has_minus) || has_any(begins_sign)))
add_trait(has_e); add_trait(has_e);
break; break;
case U'o': case U'o':
if (char_count == 2_sz && has_any(begins_zero)) if (char_count == 2u && has_any(begins_zero))
add_trait(has_o); add_trait(has_o);
break; break;
@ -2486,8 +2486,8 @@ TOML_IMPL_NAMESPACE_START
break; break;
case U'x': case U'x':
if ((char_count == 2_sz && has_any(begins_zero)) if ((char_count == 2u && has_any(begins_zero))
|| (char_count == 3_sz && has_any(begins_sign) && chars[1] == U'0')) || (char_count == 3u && has_any(begins_sign) && chars[1] == U'0'))
add_trait(has_x); add_trait(has_x);
break; break;
@ -2519,7 +2519,7 @@ TOML_IMPL_NAMESPACE_START
return_if_error({}); return_if_error({});
// force further scanning if this could have been a date-time with a space instead of a T // force further scanning if this could have been a date-time with a space instead of a T
if (char_count == 10_sz && traits == (bdigit_msk | has_minus) && chars[4] == U'-' && chars[7] == U'-' if (char_count == 10u && traits == (bdigit_msk | has_minus) && chars[4] == U'-' && chars[7] == U'-'
&& !is_eof() && *cp == U' ') && !is_eof() && *cp == U' ')
{ {
const auto pre_advance_count = advance_count; const auto pre_advance_count = advance_count;
@ -2532,7 +2532,7 @@ TOML_IMPL_NAMESPACE_START
go_back(advance_count - pre_advance_count); go_back(advance_count - pre_advance_count);
advance_count = pre_advance_count; advance_count = pre_advance_count;
traits = pre_scan_traits; traits = pre_scan_traits;
char_count = 10_sz; char_count = 10u;
}; };
advance_and_return_if_error({}); advance_and_return_if_error({});
@ -2550,19 +2550,19 @@ TOML_IMPL_NAMESPACE_START
scan(); scan();
return_if_error({}); return_if_error({});
if (char_count == 12_sz) if (char_count == 12u)
backpedal(); backpedal();
} }
} }
// set the reader back to where we started // set the reader back to where we started
go_back(advance_count); go_back(advance_count);
if (char_count < utf8_buffered_reader::max_history_length - 1_sz) if (char_count < utf8_buffered_reader::max_history_length - 1u)
chars[char_count] = U'\0'; chars[char_count] = U'\0';
// if after scanning ahead we still only have one value character, // if after scanning ahead we still only have one value character,
// the only valid value type is an integer. // the only valid value type is an integer.
if (char_count == 1_sz) if (char_count == 1u)
{ {
if (has_any(begins_zero | begins_digit)) if (has_any(begins_zero | begins_digit))
{ {
@ -2579,7 +2579,7 @@ TOML_IMPL_NAMESPACE_START
// now things that can be identified from two or more characters // now things that can be identified from two or more characters
return_if_error({}); return_if_error({});
assert_or_assume(char_count >= 2_sz); assert_or_assume(char_count >= 2u);
// do some 'fuzzy matching' where there's no ambiguity, since that allows the specific // do some 'fuzzy matching' where there's no ambiguity, since that allows the specific
// typed parse functions to take over and show better diagnostics if there's an issue // typed parse functions to take over and show better diagnostics if there's an issue
@ -2605,7 +2605,7 @@ TOML_IMPL_NAMESPACE_START
else if (has_any(begins_sign)) else if (has_any(begins_sign))
{ {
// single-digit signed integers // single-digit signed integers
if (char_count == 2_sz && has_any(has_digits)) if (char_count == 2u && has_any(has_digits))
{ {
val = new value{ static_cast<int64_t>(chars[1] - U'0') * (chars[0] == U'-' ? -1LL : 1LL) }; val = new value{ static_cast<int64_t>(chars[1] - U'0') * (chars[0] == U'-' ? -1LL : 1LL) };
advance(); // skip the sign advance(); // skip the sign
@ -2911,7 +2911,7 @@ TOML_IMPL_NAMESPACE_START
// get the key // get the key
start_recording(); start_recording();
auto key = parse_key(); auto key = parse_key();
stop_recording(1_sz); stop_recording(1u);
// skip past any whitespace that followed the key // skip past any whitespace that followed the key
consume_leading_whitespace(); consume_leading_whitespace();
@ -2977,7 +2977,7 @@ TOML_IMPL_NAMESPACE_START
// get the actual key // get the actual key
start_recording(); start_recording();
key = parse_key(); key = parse_key();
stop_recording(1_sz); stop_recording(1u);
return_if_error({}); return_if_error({});
// skip past any whitespace that followed the key // skip past any whitespace that followed the key
@ -3006,7 +3006,7 @@ TOML_IMPL_NAMESPACE_START
// check if each parent is a table/table array, or can be created implicitly as a table. // check if each parent is a table/table array, or can be created implicitly as a table.
auto parent = &root; auto parent = &root;
for (size_t i = 0; i < key.segments.size() - 1_sz; i++) for (size_t i = 0; i < key.segments.size() - 1u; i++)
{ {
auto child = parent->get(key.segments[i]); auto child = parent->get(key.segments[i]);
if (!child) if (!child)
@ -3134,13 +3134,13 @@ TOML_IMPL_NAMESPACE_START
auto kvp = parse_key_value_pair(); auto kvp = parse_key_value_pair();
return_if_error(); return_if_error();
TOML_ASSERT(kvp.key.segments.size() >= 1_sz); TOML_ASSERT(kvp.key.segments.size() >= 1u);
// if it's a dotted kvp we need to spawn the sub-tables if necessary, // if it's a dotted kvp we need to spawn the sub-tables if necessary,
// and set the target table to the second-to-last one in the chain // and set the target table to the second-to-last one in the chain
if (kvp.key.segments.size() > 1_sz) if (kvp.key.segments.size() > 1u)
{ {
for (size_t i = 0; i < kvp.key.segments.size() - 1_sz; i++) for (size_t i = 0; i < kvp.key.segments.size() - 1u; i++)
{ {
auto child = tab->get(kvp.key.segments[i]); auto child = tab->get(kvp.key.segments[i]);
if (!child) if (!child)
@ -3525,7 +3525,7 @@ TOML_ANON_NAMESPACE_START
// open file with a custom-sized stack buffer // open file with a custom-sized stack buffer
std::ifstream file; std::ifstream file;
char file_buffer[sizeof(void*) * 1024_sz]; char file_buffer[sizeof(void*) * 1024u];
file.rdbuf()->pubsetbuf(file_buffer, sizeof(file_buffer)); file.rdbuf()->pubsetbuf(file_buffer, sizeof(file_buffer));
file.open(file_path_str, std::ifstream::in | std::ifstream::binary | std::ifstream::ate); file.open(file_path_str, std::ifstream::in | std::ifstream::binary | std::ifstream::ate);
if (!file.is_open()) if (!file.is_open())

View File

@ -531,13 +531,6 @@
#define TOML_UNREACHABLE TOML_ASSERT(false) #define TOML_UNREACHABLE TOML_ASSERT(false)
#endif #endif
#if defined(__cpp_consteval) && __cpp_consteval >= 201811 && !defined(_MSC_VER)
// https://developercommunity.visualstudio.com/t/Erroneous-C7595-error-with-consteval-in/1404234
#define TOML_CONSTEVAL consteval
#else
#define TOML_CONSTEVAL constexpr
#endif
#ifdef __has_cpp_attribute #ifdef __has_cpp_attribute
#define TOML_HAS_ATTR(...) __has_cpp_attribute(__VA_ARGS__) #define TOML_HAS_ATTR(...) __has_cpp_attribute(__VA_ARGS__)
#else #else
@ -758,7 +751,9 @@
#define TOML_EXTERNAL_LINKAGE inline #define TOML_EXTERNAL_LINKAGE inline
#define TOML_INTERNAL_LINKAGE inline #define TOML_INTERNAL_LINKAGE inline
#else #else
#define TOML_ANON_NAMESPACE_START static_assert(TOML_IMPLEMENTATION); using namespace toml; namespace #define TOML_ANON_NAMESPACE_START static_assert(TOML_IMPLEMENTATION); \
using namespace toml; \
namespace
#define TOML_ANON_NAMESPACE_END static_assert(true) #define TOML_ANON_NAMESPACE_END static_assert(true)
#define TOML_ANON_NAMESPACE #define TOML_ANON_NAMESPACE
#define TOML_EXTERNAL_LINKAGE #define TOML_EXTERNAL_LINKAGE

View File

@ -314,26 +314,26 @@ TOML_IMPL_NAMESPACE_START
TOML_EXTERNAL_LINKAGE TOML_EXTERNAL_LINKAGE
void print_to_stream(std::ostream & stream, const toml::date& val) void print_to_stream(std::ostream & stream, const toml::date& val)
{ {
print_integer_leftpad_zeros(stream, val.year, 4_sz); print_integer_leftpad_zeros(stream, val.year, 4u);
stream.put('-'); stream.put('-');
print_integer_leftpad_zeros(stream, val.month, 2_sz); print_integer_leftpad_zeros(stream, val.month, 2u);
stream.put('-'); stream.put('-');
print_integer_leftpad_zeros(stream, val.day, 2_sz); print_integer_leftpad_zeros(stream, val.day, 2u);
} }
TOML_EXTERNAL_LINKAGE TOML_EXTERNAL_LINKAGE
void print_to_stream(std::ostream & stream, const toml::time& val) void print_to_stream(std::ostream & stream, const toml::time& val)
{ {
print_integer_leftpad_zeros(stream, val.hour, 2_sz); print_integer_leftpad_zeros(stream, val.hour, 2u);
stream.put(':'); stream.put(':');
print_integer_leftpad_zeros(stream, val.minute, 2_sz); print_integer_leftpad_zeros(stream, val.minute, 2u);
stream.put(':'); stream.put(':');
print_integer_leftpad_zeros(stream, val.second, 2_sz); print_integer_leftpad_zeros(stream, val.second, 2u);
if (val.nanosecond && val.nanosecond <= 999999999u) if (val.nanosecond && val.nanosecond <= 999999999u)
{ {
stream.put('.'); stream.put('.');
auto ns = val.nanosecond; auto ns = val.nanosecond;
size_t digits = 9_sz; size_t digits = 9u;
while (ns % 10u == 0u) while (ns % 10u == 0u)
{ {
ns /= 10u; ns /= 10u;
@ -363,13 +363,13 @@ TOML_IMPL_NAMESPACE_START
const auto hours = mins / 60; const auto hours = mins / 60;
if (hours) if (hours)
{ {
print_integer_leftpad_zeros(stream, static_cast<unsigned int>(hours), 2_sz); print_integer_leftpad_zeros(stream, static_cast<unsigned int>(hours), 2u);
mins -= hours * 60; mins -= hours * 60;
} }
else else
print_to_stream(stream, "00"sv); print_to_stream(stream, "00"sv);
stream.put(':'); stream.put(':');
print_integer_leftpad_zeros(stream, static_cast<unsigned int>(mins), 2_sz); print_integer_leftpad_zeros(stream, static_cast<unsigned int>(mins), 2u);
} }
TOML_EXTERNAL_LINKAGE TOML_EXTERNAL_LINKAGE

View File

@ -377,12 +377,15 @@ TOML_NAMESPACE_START
} }
TOML_NODISCARD TOML_NODISCARD
TOML_API
bool is_homogeneous(node_type ntype) const noexcept final; bool is_homogeneous(node_type ntype) const noexcept final;
TOML_NODISCARD TOML_NODISCARD
TOML_API
bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept final; bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept final;
TOML_NODISCARD TOML_NODISCARD
TOML_API
bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept final; bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept final;
template <typename ElemType = void> template <typename ElemType = void>

View File

@ -78,7 +78,6 @@ TOML_POP_WARNINGS;
#undef TOML_COMPILER_EXCEPTIONS #undef TOML_COMPILER_EXCEPTIONS
#undef TOML_CONCAT #undef TOML_CONCAT
#undef TOML_CONCAT_1 #undef TOML_CONCAT_1
#undef TOML_CONSTEVAL
#undef TOML_CONSTRAINED_TEMPLATE #undef TOML_CONSTRAINED_TEMPLATE
#undef TOML_CPP #undef TOML_CPP
#undef TOML_DISABLE_ARITHMETIC_WARNINGS #undef TOML_DISABLE_ARITHMETIC_WARNINGS

View File

@ -1,38 +0,0 @@
// This file is a part of toml++ and is subject to the the terms of the MIT license.
// Copyright (c) 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
#pragma once
#include "settings.h"
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Weverything"
#elif defined (__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wall"
#pragma GCC diagnostic ignored "-Wextra"
#pragma GCC diagnostic ignored "-Wpadded"
#pragma GCC diagnostic ignored "-Wfloat-equal"
#elif defined(_MSC_VER)
#pragma warning(push, 0)
#pragma warning(disable : 4365)
#pragma warning(disable : 4868)
#pragma warning(disable : 5105)
#endif
#if __has_include(<Catch2/single_include/catch2/catch.hpp>)
#include <Catch2/single_include/catch2/catch.hpp>
#else
#error Catch2 is missing! You probably need to fetch submodules ("git submodule update --init --depth 1 external/Catch2")
#endif
#ifdef __clang__
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#pragma GCC diagnostic pop
#elif defined(_MSC_VER)
#pragma warning(pop)
#endif

View File

@ -4,6 +4,7 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
//----- //-----
// this file was generated by generate_conformance_tests.py - do not modify it directly // this file was generated by generate_conformance_tests.py - do not modify it directly
// clang-format off
#include "tests.h" #include "tests.h"
using namespace toml::impl; using namespace toml::impl;

View File

@ -4,6 +4,7 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
//----- //-----
// this file was generated by generate_conformance_tests.py - do not modify it directly // this file was generated by generate_conformance_tests.py - do not modify it directly
// clang-format off
#include "tests.h" #include "tests.h"
using namespace toml::impl; using namespace toml::impl;

View File

@ -4,6 +4,7 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
//----- //-----
// this file was generated by generate_conformance_tests.py - do not modify it directly // this file was generated by generate_conformance_tests.py - do not modify it directly
// clang-format off
#include "tests.h" #include "tests.h"
using namespace toml::impl; using namespace toml::impl;

View File

@ -4,6 +4,7 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
//----- //-----
// this file was generated by generate_conformance_tests.py - do not modify it directly // this file was generated by generate_conformance_tests.py - do not modify it directly
// clang-format off
#include "tests.h" #include "tests.h"
using namespace toml::impl; using namespace toml::impl;
@ -1531,4 +1532,3 @@ Location SF.)"sv },
#endif // UNICODE_LITERALS_OK #endif // UNICODE_LITERALS_OK
} }

View File

@ -9,7 +9,7 @@
#endif #endif
#if USE_TARTANLLAMA_OPTIONAL #if USE_TARTANLLAMA_OPTIONAL
#include "tloptional.h" #include "lib_tloptional.h"
#endif #endif
#if USE_SINGLE_HEADER #if USE_SINGLE_HEADER
@ -47,7 +47,6 @@ namespace toml
CHECK_NODE_TYPE_MAPPING(toml::array, node_type::array); CHECK_NODE_TYPE_MAPPING(toml::array, node_type::array);
CHECK_NODE_TYPE_MAPPING(toml::table, node_type::table); CHECK_NODE_TYPE_MAPPING(toml::table, node_type::table);
#define CHECK_CAN_REPRESENT_NATIVE(T, expected) \ #define CHECK_CAN_REPRESENT_NATIVE(T, expected) \
static_assert((impl::value_traits<T>::is_native || impl::value_traits<T>::can_represent_native) == expected) static_assert((impl::value_traits<T>::is_native || impl::value_traits<T>::can_represent_native) == expected)

37
tests/lib_catch2.h Normal file
View File

@ -0,0 +1,37 @@
// This file is a part of toml++ and is subject to the the terms of the MIT license.
// Copyright (c) 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
#pragma once
#include "settings.h"
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Weverything"
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wall"
#pragma GCC diagnostic ignored "-Wextra"
#pragma GCC diagnostic ignored "-Wpadded"
#pragma GCC diagnostic ignored "-Wfloat-equal"
#elif defined(_MSC_VER)
#pragma warning(push, 0)
#pragma warning(disable : 4365)
#pragma warning(disable : 4868)
#pragma warning(disable : 5105)
#endif
#if __has_include(<Catch2/single_include/catch2/catch.hpp>)
#include <Catch2/single_include/catch2/catch.hpp>
#else
#error Catch2 is missing! You probably need to fetch submodules ("git submodule update --init --depth 1 external/Catch2")
#endif
#ifdef __clang__
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#pragma GCC diagnostic pop
#elif defined(_MSC_VER)
#pragma warning(pop)
#endif

View File

@ -2,7 +2,6 @@
// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au> // Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text. // See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
#pragma once #pragma once
#ifdef __clang__ #ifdef __clang__
@ -27,4 +26,3 @@
#elif defined(__GNUC__) #elif defined(__GNUC__)
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif

View File

@ -4,29 +4,59 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
#define CATCH_CONFIG_RUNNER #define CATCH_CONFIG_RUNNER
#include "catch2.h" #include "lib_catch2.h"
#include <clocale> #include <clocale>
#if LEAK_TESTS #if LEAK_TESTS
#include <iostream> #include <iostream>
#include <iomanip> #include <iomanip>
#include <atomic> #include <atomic>
#include "leakproof.h" #include "leakproof.h"
using namespace std::string_view_literals; using namespace std::string_view_literals;
namespace leakproof namespace leakproof
{ {
static std::atomic_llong total_created_ = 0LL; static std::atomic_llong total_created_ = 0LL;
static std::atomic_llong tables_ = 0LL; static std::atomic_llong tables_ = 0LL;
static std::atomic_llong arrays_ = 0LL; static std::atomic_llong arrays_ = 0LL;
static std::atomic_llong values_ = 0LL; static std::atomic_llong values_ = 0LL;
void table_created() noexcept { tables_++; total_created_++; }
void array_created() noexcept { arrays_++; total_created_++; } void table_created() noexcept
void value_created() noexcept { values_++; total_created_++; } {
void table_destroyed() noexcept { tables_--; } tables_++;
void array_destroyed() noexcept { arrays_--; } total_created_++;
void value_destroyed() noexcept { values_--; }
} }
#endif
void array_created() noexcept
{
arrays_++;
total_created_++;
}
void value_created() noexcept
{
values_++;
total_created_++;
}
void table_destroyed() noexcept
{
tables_--;
}
void array_destroyed() noexcept
{
arrays_--;
}
void value_destroyed() noexcept
{
values_--;
}
}
#endif // LEAK_TESTS
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {

View File

@ -64,8 +64,7 @@ TEST_CASE("arrays - moving")
CHECK(!arr2.source().path); CHECK(!arr2.source().path);
CHECK(arr2.size() == 0u); CHECK(arr2.size() == 0u);
}, },
filename filename);
);
} }
TEST_CASE("arrays - copying") TEST_CASE("arrays - copying")
@ -116,8 +115,7 @@ TEST_CASE("arrays - copying")
CHECK(arr3 == *arr1); CHECK(arr3 == *arr1);
CHECK(arr3 == arr2); CHECK(arr3 == arr2);
}, },
filename filename);
);
} }
TEST_CASE("arrays - construction") TEST_CASE("arrays - construction")
@ -395,23 +393,30 @@ TEST_CASE("arrays - flattening")
{ {
{ {
array arr{ array arr{
1, 2, 3, 1,
2,
3,
array{ 4, 5 }, array{ 4, 5 },
6, 6,
array{}, array{},
array{ 7, array{ 8, array{ 9 }, 10, array{}, }, 11 }, array{ 7,
array{
8,
array{ 9 },
10,
array{},
},
11 },
}; };
arr.flatten(); arr.flatten();
REQUIRE(arr == array{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }); REQUIRE(arr == array{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 });
} }
{ {
array arr{ array arr{ array{},
array{},
array{ inserter{ array{} } }, array{ inserter{ array{} } },
array{ array{}, array{ array{}, array{} }, array{} }, array{ array{}, array{ array{}, array{} }, array{} },
array{array{array{array{array{array{ 1 }}}}}} array{ array{ array{ array{ array{ array{ 1 } } } } } } };
};
arr.flatten(); arr.flatten();
REQUIRE(arr == array{ 1 }); REQUIRE(arr == array{ 1 });
} }

View File

@ -52,19 +52,22 @@ TEST_CASE("parse_result - good parse")
size_t tbl_iterations{}; size_t tbl_iterations{};
for (auto&& [k, v] : tbl) for (auto&& [k, v] : tbl)
{ {
(void)k; (void)v; (void)k;
(void)v;
tbl_iterations++; tbl_iterations++;
} }
size_t result_iterations{}; size_t result_iterations{};
for (auto& [k, v] : result) for (auto& [k, v] : result)
{ {
(void)k; (void)v; (void)k;
(void)v;
result_iterations++; result_iterations++;
} }
size_t cresult_iterations{}; size_t cresult_iterations{};
for (auto [k, v] : cresult) for (auto [k, v] : cresult)
{ {
(void)k; (void)v; (void)k;
(void)v;
cresult_iterations++; cresult_iterations++;
} }
CHECK(tbl_iterations == tbl.size()); CHECK(tbl_iterations == tbl.size());
@ -72,7 +75,6 @@ TEST_CASE("parse_result - good parse")
CHECK(tbl_iterations == cresult_iterations); CHECK(tbl_iterations == cresult_iterations);
} }
TEST_CASE("parse_result - bad parse") TEST_CASE("parse_result - bad parse")
{ {
auto result = "key = trUe"_toml; auto result = "key = trUe"_toml;
@ -98,15 +100,16 @@ TEST_CASE("parse_result - bad parse")
for (auto [k, v] : result) for (auto [k, v] : result)
{ {
(void)k; (void)v; (void)k;
(void)v;
FAIL("This code should not run"); FAIL("This code should not run");
} }
for (auto [k, v] : cresult) for (auto [k, v] : cresult)
{ {
(void)k; (void)v; (void)k;
(void)v;
FAIL("This code should not run"); FAIL("This code should not run");
} }
} }
#endif //!TOML_EXCEPTIONS #endif //!TOML_EXCEPTIONS

View File

@ -64,8 +64,7 @@ TEST_CASE("tables - moving")
CHECK(tbl2.size() == 0u); CHECK(tbl2.size() == 0u);
CHECK(!tbl2["test"].as<table>()); CHECK(!tbl2["test"].as<table>());
}, },
filename filename);
);
} }
TEST_CASE("tables - copying") TEST_CASE("tables - copying")
@ -114,8 +113,7 @@ TEST_CASE("tables - copying")
CHECK(tbl3 == tbl2); CHECK(tbl3 == tbl2);
CHECK(tbl3 == tbl); CHECK(tbl3 == tbl);
}, },
filename filename);
);
} }
TEST_CASE("tables - construction") TEST_CASE("tables - construction")
@ -132,9 +130,7 @@ TEST_CASE("tables - construction")
} }
{ {
table tbl{{ table tbl{ { { "foo"sv, 42 } } };
{ "foo"sv, 42 }
}};
CHECK(tbl.size() == 1u); CHECK(tbl.size() == 1u);
CHECK(!tbl.empty()); CHECK(!tbl.empty());
CHECK(tbl.begin() != tbl.end()); CHECK(tbl.begin() != tbl.end());
@ -144,12 +140,7 @@ TEST_CASE("tables - construction")
} }
{ {
table tbl{{ table tbl{ { { "foo"sv, 42 }, { "bar"sv, 10.0 }, { "kek"sv, false }, { "qux"sv, array{ 1 } } } };
{ "foo"sv, 42 },
{ "bar"sv, 10.0 },
{ "kek"sv, false },
{ "qux"sv, array{ 1 } }
}};
CHECK(tbl.size() == 4u); CHECK(tbl.size() == 4u);
CHECK(!tbl.empty()); CHECK(!tbl.empty());
REQUIRE(tbl.get_as<int64_t>("foo"sv)); REQUIRE(tbl.get_as<int64_t>("foo"sv));
@ -164,12 +155,10 @@ TEST_CASE("tables - construction")
#if TOML_WINDOWS_COMPAT #if TOML_WINDOWS_COMPAT
{ {
table tbl{ { table tbl{ { { L"foo", L"test1" },
{ L"foo", L"test1" },
{ L"bar"sv, L"test2"sv }, { L"bar"sv, L"test2"sv },
{ L"kek"s, L"test3"sv }, { L"kek"s, L"test3"sv },
{ L"qux"sv.data(), L"test4"sv.data() } { L"qux"sv.data(), L"test4"sv.data() } } };
} };
CHECK(tbl.size() == 4u); CHECK(tbl.size() == 4u);
CHECK(!tbl.empty()); CHECK(!tbl.empty());
REQUIRE(tbl.get_as<std::string>("foo"sv)); REQUIRE(tbl.get_as<std::string>("foo"sv));
@ -188,39 +177,19 @@ TEST_CASE("tables - equality")
{ {
static constexpr const char* one = "one"; static constexpr const char* one = "one";
table tbl1{{ table tbl1{ { { one, 1 }, { "two", 2 }, { "three", 3 } } };
{ one, 1 },
{ "two", 2 },
{ "three", 3 }
}};
CHECK(tbl1 == tbl1); CHECK(tbl1 == tbl1);
table tbl2{{ table tbl2{ { { "one"sv, 1 }, { "two"sv, 2 }, { "three"sv, 3 } } };
{ "one"sv, 1 },
{ "two"sv, 2 },
{ "three"sv, 3 }
}};
CHECK(tbl1 == tbl2); CHECK(tbl1 == tbl2);
table tbl3{{ table tbl3{ { { "one"sv, 1 }, { "two"sv, 2 } } };
{ "one"sv, 1 },
{ "two"sv, 2 }
}};
CHECK(tbl1 != tbl3); CHECK(tbl1 != tbl3);
table tbl4{{ table tbl4{ { { "one"sv, 1 }, { "two"sv, 2 }, { "three"sv, 3 }, { "four"sv, 4 } } };
{ "one"sv, 1 },
{ "two"sv, 2 },
{ "three"sv, 3 },
{ "four"sv, 4 }
}};
CHECK(tbl1 != tbl4); CHECK(tbl1 != tbl4);
table tbl5{{ table tbl5{ { { "one"sv, 1 }, { "two"sv, 2 }, { "three"sv, 3.0 } } };
{ "one"sv, 1 },
{ "two"sv, 2 },
{ "three"sv, 3.0 }
}};
CHECK(tbl1 != tbl5); CHECK(tbl1 != tbl5);
table tbl6{}; table tbl6{};
@ -328,11 +297,7 @@ TEST_CASE("tables - insertion and erasure")
// void insert(Iter first, Iter last) // void insert(Iter first, Iter last)
{ {
std::vector<std::pair<std::string, std::string>> vals{ std::vector<std::pair<std::string, std::string>> vals{ { "foo", "foo" }, { "bar", "bar" }, { "kek", "kek" } };
{ "foo", "foo" },
{ "bar", "bar" },
{ "kek", "kek" }
};
tbl.insert(vals.begin(), vals.end()); tbl.insert(vals.begin(), vals.end());
CHECK(tbl.size() == 3u); CHECK(tbl.size() == 3u);
REQUIRE(tbl.get_as<std::string>("foo")); REQUIRE(tbl.get_as<std::string>("foo"));
@ -355,11 +320,7 @@ TEST_CASE("tables - insertion and erasure")
// void insert(Iter first, Iter last) (with move iterators) // void insert(Iter first, Iter last) (with move iterators)
{ {
std::vector<std::pair<std::string, std::string>> vals{ std::vector<std::pair<std::string, std::string>> vals{ { "foo", "foo" }, { "bar", "bar" }, { "kek", "kek" } };
{ "foo", "foo" },
{ "bar", "bar" },
{ "kek", "kek" }
};
tbl.insert(std::make_move_iterator(vals.begin()), std::make_move_iterator(vals.end())); tbl.insert(std::make_move_iterator(vals.begin()), std::make_move_iterator(vals.end()));
CHECK(tbl.size() == 3u); CHECK(tbl.size() == 3u);
REQUIRE(tbl.get_as<std::string>("foo")); REQUIRE(tbl.get_as<std::string>("foo"));
@ -380,7 +341,6 @@ TEST_CASE("tables - insertion and erasure")
tbl.clear(); tbl.clear();
} }
#if TOML_WINDOWS_COMPAT #if TOML_WINDOWS_COMPAT
tbl.insert(L"a", L"test1"); tbl.insert(L"a", L"test1");
@ -458,4 +418,3 @@ c = 3)"sv;
CHECK(to_string(some_toml) == some_toml); CHECK(to_string(some_toml) == some_toml);
} }
} }

View File

@ -19,7 +19,8 @@ static constexpr T one = static_cast<T>(1);
TEST_CASE("values - construction") TEST_CASE("values - construction")
{ {
#define CHECK_VALUE_INIT2(initializer, target_type, equiv) \ #define CHECK_VALUE_INIT2(initializer, target_type, equiv) \
do { \ do \
{ \
auto v = value{ initializer }; \ auto v = value{ initializer }; \
static_assert(std::is_same_v<decltype(v), value<target_type>>); \ static_assert(std::is_same_v<decltype(v), value<target_type>>); \
CHECK(v == equiv); \ CHECK(v == equiv); \
@ -29,10 +30,10 @@ TEST_CASE("values - construction")
CHECK(v.is_homogeneous()); \ CHECK(v.is_homogeneous()); \
CHECK(v.is_homogeneous<target_type>()); \ CHECK(v.is_homogeneous<target_type>()); \
CHECK(v.is_homogeneous(impl::node_type_of<target_type>)); \ CHECK(v.is_homogeneous(impl::node_type_of<target_type>)); \
} while (false) } \
while (false)
#define CHECK_VALUE_INIT(initializer, target_type) \ #define CHECK_VALUE_INIT(initializer, target_type) CHECK_VALUE_INIT2(initializer, target_type, initializer)
CHECK_VALUE_INIT2(initializer, target_type, initializer)
CHECK_VALUE_INIT(one<signed char>, int64_t); CHECK_VALUE_INIT(one<signed char>, int64_t);
CHECK_VALUE_INIT(one<signed short>, int64_t); CHECK_VALUE_INIT(one<signed short>, int64_t);
@ -132,10 +133,8 @@ TEST_CASE("values - printing")
TEST_CASE("nodes - value() int/float/bool conversions") TEST_CASE("nodes - value() int/float/bool conversions")
{ {
#define CHECK_VALUE_PASS(type, v) \ #define CHECK_VALUE_PASS(type, v) CHECK(n.value<type>() == static_cast<type>(v))
CHECK(n.value<type>() == static_cast<type>(v)) #define CHECK_VALUE_FAIL(type) CHECK(!n.value<type>())
#define CHECK_VALUE_FAIL(type) \
CHECK(!n.value<type>())
// bools // bools
{ {
@ -328,7 +327,6 @@ TEST_CASE("nodes - value() int/float/bool conversions")
CHECK_VALUE_FAIL(toml::time); CHECK_VALUE_FAIL(toml::time);
CHECK_VALUE_FAIL(toml::date_time); CHECK_VALUE_FAIL(toml::date_time);
*val = 1.0; *val = 1.0;
CHECK_VALUE_FAIL(bool); CHECK_VALUE_FAIL(bool);
CHECK_VALUE_PASS(int8_t, 1); CHECK_VALUE_PASS(int8_t, 1);

View File

@ -7,8 +7,7 @@
TEST_CASE("parsing - arrays") TEST_CASE("parsing - arrays")
{ {
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
integers = [ 1, 2, 3 ] integers = [ 1, 2, 3 ]
integers2 = [ integers2 = [
@ -131,14 +130,12 @@ TEST_CASE("parsing - arrays")
CHECK(tbl["integers"][0] == 1); CHECK(tbl["integers"][0] == 1);
CHECK(tbl["integers"][1] == 2); CHECK(tbl["integers"][1] == 2);
CHECK(tbl["integers"][2] == 3); CHECK(tbl["integers"][2] == 3);
} });
);
// toml/issues/665 (heterogeneous arrays) // toml/issues/665 (heterogeneous arrays)
#if TOML_LANG_AT_LEAST(1, 0, 0) #if TOML_LANG_AT_LEAST(1, 0, 0)
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
# Mixed-type arrays are allowed # Mixed-type arrays are allowed
numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ] numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]
@ -174,8 +171,7 @@ TEST_CASE("parsing - arrays")
CHECK(tbl["contributors"][1]["name"] == "Baz Qux"sv); CHECK(tbl["contributors"][1]["name"] == "Baz Qux"sv);
CHECK(tbl["contributors"][1]["email"] == "bazqux@example.com"sv); CHECK(tbl["contributors"][1]["email"] == "bazqux@example.com"sv);
CHECK(tbl["contributors"][1]["url"] == "https://example.com/bazqux"sv); CHECK(tbl["contributors"][1]["url"] == "https://example.com/bazqux"sv);
} });
);
#else #else

View File

@ -7,8 +7,7 @@
TEST_CASE("parsing - booleans") TEST_CASE("parsing - booleans")
{ {
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
bool1 = true bool1 = true
bool2 = false bool2 = false
@ -17,8 +16,7 @@ TEST_CASE("parsing - booleans")
{ {
CHECK(tbl["bool1"] == true); CHECK(tbl["bool1"] == true);
CHECK(tbl["bool2"] == false); CHECK(tbl["bool2"] == false);
} });
);
// "Always lowercase." // "Always lowercase."
parsing_should_fail(FILE_LINE_ARGS, "bool = True"sv); parsing_should_fail(FILE_LINE_ARGS, "bool = True"sv);

View File

@ -7,9 +7,9 @@
TEST_CASE("parsing - comments") TEST_CASE("parsing - comments")
{ {
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS, R"(
R"(# This is a full-line comment # This is a full-line comment
key = "value" # This is a comment at the end of a line key = "value" # This is a comment at the end of a line
another = "# This is not a comment" another = "# This is not a comment"
)"sv, )"sv,
@ -18,17 +18,11 @@ TEST_CASE("parsing - comments")
CHECK(tbl.size() == 2); CHECK(tbl.size() == 2);
CHECK(tbl["key"] == "value"sv); CHECK(tbl["key"] == "value"sv);
CHECK(tbl["another"] == "# This is not a comment"sv); CHECK(tbl["another"] == "# This is not a comment"sv);
} });
);
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"(# this = "looks like a KVP but is commented out)"sv, R"(# this = "looks like a KVP but is commented out)"sv,
[](table&& tbl) [](table&& tbl) { CHECK(tbl.size() == 0); });
{
CHECK(tbl.size() == 0);
}
);
#if TOML_LANG_AT_LEAST(1, 0, 0) #if TOML_LANG_AT_LEAST(1, 0, 0)
{ {
@ -75,8 +69,8 @@ TEST_CASE("parsing - comments")
} }
#else #else
{ {
parsing_should_succeed(FILE_LINE_ARGS, S( parsing_should_succeed(FILE_LINE_ARGS,
"## 00 - 08" S("## 00 - 08"
"# \u0000 " "# \u0000 "
"# \u0001 " "# \u0001 "
"# \u0002 " "# \u0002 "
@ -110,8 +104,7 @@ TEST_CASE("parsing - comments")
"# \u001E " "# \u001E "
"# \u001F " "# \u001F "
"## 7F " "## 7F "
"# \u007F "sv "# \u007F "sv));
));
} }
#endif #endif
} }

View File

@ -7,8 +7,7 @@
TEST_CASE("parsing - floats") TEST_CASE("parsing - floats")
{ {
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
# fractional # fractional
flt1 = +1.0 flt1 = +1.0
@ -35,8 +34,7 @@ TEST_CASE("parsing - floats")
CHECK(tbl["flt6"] == -2E-2); CHECK(tbl["flt6"] == -2E-2);
CHECK(tbl["flt7"].as<double>()->get() == 6.626e-34_a); CHECK(tbl["flt7"].as<double>()->get() == 6.626e-34_a);
CHECK(tbl["flt8"].as<double>()->get() == 224617.445991228_a); CHECK(tbl["flt8"].as<double>()->get() == 224617.445991228_a);
} });
);
// "Each underscore must be surrounded by at least one digit on each side." // "Each underscore must be surrounded by at least one digit on each side."
parsing_should_fail(FILE_LINE_ARGS, "flt8 = 224_617.445_991_228_"sv); parsing_should_fail(FILE_LINE_ARGS, "flt8 = 224_617.445_991_228_"sv);
@ -44,15 +42,13 @@ TEST_CASE("parsing - floats")
parsing_should_fail(FILE_LINE_ARGS, "flt8 = 224__617.445_991_228"sv); parsing_should_fail(FILE_LINE_ARGS, "flt8 = 224__617.445_991_228"sv);
// "Float values -0.0 and +0.0 are valid and should map according to IEEE 754." // "Float values -0.0 and +0.0 are valid and should map according to IEEE 754."
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"(zeroes = [-0.0, +0.0])"sv, R"(zeroes = [-0.0, +0.0])"sv,
[](table&& tbl) [](table&& tbl)
{ {
CHECK(tbl["zeroes"][0] == -0.0); CHECK(tbl["zeroes"][0] == -0.0);
CHECK(tbl["zeroes"][1] == +0.0); CHECK(tbl["zeroes"][1] == +0.0);
} });
);
// "A float consists of an integer part followed by a fractional part and/or an exponent part" // "A float consists of an integer part followed by a fractional part and/or an exponent part"
// (i.e. omitting the leading digits before the '.' is not legal in TOML) // (i.e. omitting the leading digits before the '.' is not legal in TOML)
@ -183,8 +179,7 @@ TEST_CASE("parsing - floats")
TEST_CASE("parsing - inf and nan") TEST_CASE("parsing - inf and nan")
{ {
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
# infinity # infinity
sf1 = inf # positive infinity sf1 = inf # positive infinity
@ -204,8 +199,7 @@ TEST_CASE("parsing - inf and nan")
CHECK(impl::fpclassify(**tbl["sf4"].as<double>()) == impl::fp_class::nan); CHECK(impl::fpclassify(**tbl["sf4"].as<double>()) == impl::fp_class::nan);
CHECK(impl::fpclassify(**tbl["sf5"].as<double>()) == impl::fp_class::nan); CHECK(impl::fpclassify(**tbl["sf5"].as<double>()) == impl::fp_class::nan);
CHECK(impl::fpclassify(**tbl["sf6"].as<double>()) == impl::fp_class::nan); CHECK(impl::fpclassify(**tbl["sf6"].as<double>()) == impl::fp_class::nan);
} });
);
parsing_should_fail(FILE_LINE_ARGS, " val = NaN "sv); parsing_should_fail(FILE_LINE_ARGS, " val = NaN "sv);
parsing_should_fail(FILE_LINE_ARGS, " val = Nan "sv); parsing_should_fail(FILE_LINE_ARGS, " val = Nan "sv);

View File

@ -7,8 +7,7 @@
TEST_CASE("parsing - integers (decimal)") TEST_CASE("parsing - integers (decimal)")
{ {
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
BOM_PREFIX R"( BOM_PREFIX R"(
int1 = +99 int1 = +99
int2 = 42 int2 = 42
@ -27,8 +26,7 @@ TEST_CASE("parsing - integers (decimal)")
CHECK(tbl["int5"] == 1000); CHECK(tbl["int5"] == 1000);
CHECK(tbl["int6"] == 5349221); CHECK(tbl["int6"] == 5349221);
CHECK(tbl["int7"] == 12345); CHECK(tbl["int7"] == 12345);
} });
);
// "Each underscore must be surrounded by at least one digit on each side." // "Each underscore must be surrounded by at least one digit on each side."
parsing_should_fail(FILE_LINE_ARGS, "int5 = 1__000"sv); parsing_should_fail(FILE_LINE_ARGS, "int5 = 1__000"sv);
@ -45,15 +43,13 @@ TEST_CASE("parsing - integers (decimal)")
parsing_should_fail(FILE_LINE_ARGS, "int7 = 01_2_3_4_5"sv); parsing_should_fail(FILE_LINE_ARGS, "int7 = 01_2_3_4_5"sv);
// "Integer values -0 and +0 are valid and identical to an unprefixed zero." // "Integer values -0 and +0 are valid and identical to an unprefixed zero."
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
"zeroes = [-0, +0]"sv, "zeroes = [-0, +0]"sv,
[](table&& tbl) [](table&& tbl)
{ {
CHECK(tbl["zeroes"][0] == 0); CHECK(tbl["zeroes"][0] == 0);
CHECK(tbl["zeroes"][1] == 0); CHECK(tbl["zeroes"][1] == 0);
} });
);
// "64 bit (signed long) range expected (9,223,372,036,854,775,808 to 9,223,372,036,854,775,807)." // "64 bit (signed long) range expected (9,223,372,036,854,775,808 to 9,223,372,036,854,775,807)."
parse_expected_value(FILE_LINE_ARGS, "9223372036854775807"sv, INT64_MAX); parse_expected_value(FILE_LINE_ARGS, "9223372036854775807"sv, INT64_MAX);
@ -87,8 +83,7 @@ TEST_CASE("parsing - integers (decimal)")
TEST_CASE("parsing - integers (hex, bin, oct)") TEST_CASE("parsing - integers (hex, bin, oct)")
{ {
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
# hexadecimal with prefix `0x` # hexadecimal with prefix `0x`
hex1 = 0xDEADBEEF hex1 = 0xDEADBEEF
@ -110,8 +105,7 @@ TEST_CASE("parsing - integers (hex, bin, oct)")
CHECK(tbl["oct1"] == 01234567); CHECK(tbl["oct1"] == 01234567);
CHECK(tbl["oct2"] == 0755); CHECK(tbl["oct2"] == 0755);
CHECK(tbl["bin1"] == 0b11010110); CHECK(tbl["bin1"] == 0b11010110);
} });
);
// "leading + is not allowed" // "leading + is not allowed"
parsing_should_fail(FILE_LINE_ARGS, "hex1 = +0xDEADBEEF"sv); parsing_should_fail(FILE_LINE_ARGS, "hex1 = +0xDEADBEEF"sv);
@ -123,8 +117,7 @@ TEST_CASE("parsing - integers (hex, bin, oct)")
parsing_should_fail(FILE_LINE_ARGS, "bin1 = +0b11010110"sv); parsing_should_fail(FILE_LINE_ARGS, "bin1 = +0b11010110"sv);
// "leading zeros are allowed (after the prefix)" // "leading zeros are allowed (after the prefix)"
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
hex1 = 0x000DEADBEEF hex1 = 0x000DEADBEEF
hex2 = 0x00000deadbeef hex2 = 0x00000deadbeef
@ -141,8 +134,7 @@ TEST_CASE("parsing - integers (hex, bin, oct)")
CHECK(tbl["oct1"] == 01234567); CHECK(tbl["oct1"] == 01234567);
CHECK(tbl["oct2"] == 0755); CHECK(tbl["oct2"] == 0755);
CHECK(tbl["bin1"] == 0b11010110); CHECK(tbl["bin1"] == 0b11010110);
} });
);
// "***Non-negative*** integer values may also be expressed in hexadecimal, octal, or binary" // "***Non-negative*** integer values may also be expressed in hexadecimal, octal, or binary"
parsing_should_fail(FILE_LINE_ARGS, "val = -0x1"sv); parsing_should_fail(FILE_LINE_ARGS, "val = -0x1"sv);
@ -153,7 +145,9 @@ TEST_CASE("parsing - integers (hex, bin, oct)")
// (ignoring INT64_MIN because toml doesn't allow these forms to represent negative values) // (ignoring INT64_MIN because toml doesn't allow these forms to represent negative values)
parse_expected_value(FILE_LINE_ARGS, "0x7FFFFFFFFFFFFFFF"sv, INT64_MAX); parse_expected_value(FILE_LINE_ARGS, "0x7FFFFFFFFFFFFFFF"sv, INT64_MAX);
parse_expected_value(FILE_LINE_ARGS, "0o777777777777777777777"sv, INT64_MAX); parse_expected_value(FILE_LINE_ARGS, "0o777777777777777777777"sv, INT64_MAX);
parse_expected_value(FILE_LINE_ARGS, "0b111111111111111111111111111111111111111111111111111111111111111"sv, INT64_MAX); parse_expected_value(FILE_LINE_ARGS,
"0b111111111111111111111111111111111111111111111111111111111111111"sv,
INT64_MAX);
parsing_should_fail(FILE_LINE_ARGS, "val = 0x8000000000000000"sv); // INT64_MAX + 1 parsing_should_fail(FILE_LINE_ARGS, "val = 0x8000000000000000"sv); // INT64_MAX + 1
parsing_should_fail(FILE_LINE_ARGS, "val = 0o1000000000000000000000"sv); parsing_should_fail(FILE_LINE_ARGS, "val = 0o1000000000000000000000"sv);
parsing_should_fail(FILE_LINE_ARGS, "val = 0b1000000000000000000000000000000000000000000000000000000000000000"sv); parsing_should_fail(FILE_LINE_ARGS, "val = 0b1000000000000000000000000000000000000000000000000000000000000000"sv);
@ -175,5 +169,4 @@ TEST_CASE("parsing - integers (hex, bin, oct)")
parse_expected_value(FILE_LINE_ARGS, "0b010000"sv, 0b10000); parse_expected_value(FILE_LINE_ARGS, "0b010000"sv, 0b10000);
parse_expected_value(FILE_LINE_ARGS, "0b01_00_00"sv, 0b10000); parse_expected_value(FILE_LINE_ARGS, "0b01_00_00"sv, 0b10000);
parse_expected_value(FILE_LINE_ARGS, "0b111111"sv, 0b111111); parse_expected_value(FILE_LINE_ARGS, "0b111111"sv, 0b111111);
} }

View File

@ -7,8 +7,7 @@
TEST_CASE("parsing - key-value pairs") TEST_CASE("parsing - key-value pairs")
{ {
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
key = "value" key = "value"
bare_key = "value" bare_key = "value"
@ -24,14 +23,12 @@ TEST_CASE("parsing - key-value pairs")
CHECK(tbl["bare-key"] == "value"sv); CHECK(tbl["bare-key"] == "value"sv);
CHECK(tbl["1234"] == "value"sv); CHECK(tbl["1234"] == "value"sv);
CHECK(tbl[""] == "blank"sv); CHECK(tbl[""] == "blank"sv);
} });
);
parsing_should_fail(FILE_LINE_ARGS, R"(key = # INVALID)"sv); parsing_should_fail(FILE_LINE_ARGS, R"(key = # INVALID)"sv);
#if UNICODE_LITERALS_OK #if UNICODE_LITERALS_OK
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
"127.0.0.1" = "value" "127.0.0.1" = "value"
"character encoding" = "value" "character encoding" = "value"
@ -48,8 +45,7 @@ TEST_CASE("parsing - key-value pairs")
CHECK(tbl["key2"] == "value"sv); CHECK(tbl["key2"] == "value"sv);
CHECK(tbl["quoted \"value\""] == "value"sv); CHECK(tbl["quoted \"value\""] == "value"sv);
CHECK(tbl[""] == "blank"sv); CHECK(tbl[""] == "blank"sv);
} });
);
#endif // UNICODE_LITERALS_OK #endif // UNICODE_LITERALS_OK
parsing_should_fail(FILE_LINE_ARGS, R"(= "no key name")"sv); parsing_should_fail(FILE_LINE_ARGS, R"(= "no key name")"sv);
@ -63,8 +59,7 @@ TEST_CASE("parsing - key-value pairs")
TEST_CASE("parsing - key-value pairs (dotted)") TEST_CASE("parsing - key-value pairs (dotted)")
{ {
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
name = "Orange" name = "Orange"
physical.color = "orange" physical.color = "orange"
@ -80,12 +75,9 @@ TEST_CASE("parsing - key-value pairs (dotted)")
CHECK(tbl["physical"]["shape"] == "round"sv); CHECK(tbl["physical"]["shape"] == "round"sv);
CHECK(tbl["site"]["google.com"] == true); CHECK(tbl["site"]["google.com"] == true);
CHECK(tbl["3"]["14159"] == "pi"sv); CHECK(tbl["3"]["14159"] == "pi"sv);
} });
);
parsing_should_succeed(FILE_LINE_ARGS,
parsing_should_succeed(
FILE_LINE_ARGS,
R"( R"(
fruit.apple.smooth = true fruit.apple.smooth = true
fruit.orange = 2 fruit.orange = 2
@ -94,8 +86,7 @@ TEST_CASE("parsing - key-value pairs (dotted)")
{ {
CHECK(tbl["fruit"]["apple"]["smooth"] == true); CHECK(tbl["fruit"]["apple"]["smooth"] == true);
CHECK(tbl["fruit"]["orange"] == 2); CHECK(tbl["fruit"]["orange"] == 2);
} });
);
parsing_should_fail(FILE_LINE_ARGS, R"( parsing_should_fail(FILE_LINE_ARGS, R"(
# THIS IS INVALID # THIS IS INVALID
@ -103,8 +94,7 @@ TEST_CASE("parsing - key-value pairs (dotted)")
fruit.apple.smooth = true fruit.apple.smooth = true
)"sv); )"sv);
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
# VALID BUT DISCOURAGED # VALID BUT DISCOURAGED
@ -125,11 +115,9 @@ TEST_CASE("parsing - key-value pairs (dotted)")
CHECK(tbl["orange"]["type"] == "fruit"sv); CHECK(tbl["orange"]["type"] == "fruit"sv);
CHECK(tbl["orange"]["skin"] == "thick"sv); CHECK(tbl["orange"]["skin"] == "thick"sv);
CHECK(tbl["orange"]["color"] == "orange"sv); CHECK(tbl["orange"]["color"] == "orange"sv);
} });
);
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
# RECOMMENDED # RECOMMENDED
@ -149,14 +137,12 @@ TEST_CASE("parsing - key-value pairs (dotted)")
CHECK(tbl["orange"]["type"] == "fruit"sv); CHECK(tbl["orange"]["type"] == "fruit"sv);
CHECK(tbl["orange"]["skin"] == "thick"sv); CHECK(tbl["orange"]["skin"] == "thick"sv);
CHECK(tbl["orange"]["color"] == "orange"sv); CHECK(tbl["orange"]["color"] == "orange"sv);
} });
);
// toml/issues/644 ('+' in bare keys) & toml/issues/687 (unicode bare keys) // toml/issues/644 ('+' in bare keys) & toml/issues/687 (unicode bare keys)
#if UNICODE_LITERALS_OK #if UNICODE_LITERALS_OK
#if TOML_LANG_UNRELEASED #if TOML_LANG_UNRELEASED
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
key+1 = 0 key+1 = 0
ʎǝʞ2 = 0 ʎǝʞ2 = 0
@ -166,8 +152,7 @@ TEST_CASE("parsing - key-value pairs (dotted)")
CHECK(tbl.size() == 2); CHECK(tbl.size() == 2);
CHECK(tbl["key+1"] == 0); CHECK(tbl["key+1"] == 0);
CHECK(tbl["ʎǝʞ2"] == 0); CHECK(tbl["ʎǝʞ2"] == 0);
} });
);
#else #else
parsing_should_fail(FILE_LINE_ARGS, R"(key+1 = 0)"sv); parsing_should_fail(FILE_LINE_ARGS, R"(key+1 = 0)"sv);
parsing_should_fail(FILE_LINE_ARGS, R"(ʎǝʞ2 = 0)"sv); parsing_should_fail(FILE_LINE_ARGS, R"(ʎǝʞ2 = 0)"sv);
@ -244,10 +229,12 @@ TEST_CASE("parsing - key-value pairs (string keys)")
parsing_should_fail(FILE_LINE_ARGS, R"(a."""b""" = 3)"sv); parsing_should_fail(FILE_LINE_ARGS, R"(a."""b""" = 3)"sv);
// whitespace relevant (success test, values are NOTE equal) // whitespace relevant (success test, values are NOTE equal)
parsing_should_succeed(FILE_LINE_ARGS, R"( parsing_should_succeed(FILE_LINE_ARGS,
R"(
a = " to do " a = " to do "
b = "to do" b = "to do"
)"sv, [](table&& tbl) )"sv,
[](table&& tbl)
{ {
CHECK(tbl["a"] == " to do "sv); CHECK(tbl["a"] == " to do "sv);
CHECK(tbl["b"] == "to do"sv); CHECK(tbl["b"] == "to do"sv);
@ -284,10 +271,12 @@ TEST_CASE("parsing - key-value pairs (string keys)")
)"sv); )"sv);
// inner quotes are not stripped from value, a & b are equal, value surrounded by quotes // inner quotes are not stripped from value, a & b are equal, value surrounded by quotes
parsing_should_succeed(FILE_LINE_ARGS, R"( parsing_should_succeed(FILE_LINE_ARGS,
R"(
a = "\"quoted\"" a = "\"quoted\""
b = """"quoted"""" b = """"quoted""""
)"sv, [](table&& tbl) )"sv,
[](table&& tbl)
{ {
CHECK(tbl["a"] == "\"quoted\""sv); CHECK(tbl["a"] == "\"quoted\""sv);
CHECK(tbl["b"] == "\"quoted\""sv); CHECK(tbl["b"] == "\"quoted\""sv);

View File

@ -7,8 +7,7 @@
TEST_CASE("parsing - strings") TEST_CASE("parsing - strings")
{ {
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF." str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."
@ -23,14 +22,13 @@ Violets are blue"""
)"sv, )"sv,
[](table&& tbl) [](table&& tbl)
{ {
CHECK(tbl["str"] == "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."sv); CHECK(tbl["str"]
== "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."sv);
CHECK(tbl["str1"] == "Roses are red\nViolets are blue"sv); CHECK(tbl["str1"] == "Roses are red\nViolets are blue"sv);
CHECK(tbl["str2"] == "\nRoses are red\nViolets are blue"sv); CHECK(tbl["str2"] == "\nRoses are red\nViolets are blue"sv);
} });
);
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
# The following strings are byte-for-byte equivalent: # The following strings are byte-for-byte equivalent:
str1 = "The quick brown fox jumps over the lazy dog." str1 = "The quick brown fox jumps over the lazy dog."
@ -66,13 +64,11 @@ str7 = """"This," she said, "is just a pointless statement.""""
CHECK(tbl["str5"] == R"(Here are three quotation marks: """.)"sv); CHECK(tbl["str5"] == R"(Here are three quotation marks: """.)"sv);
CHECK(tbl["str6"] == R"(Here are fifteen quotation marks: """"""""""""""".)"sv); CHECK(tbl["str6"] == R"(Here are fifteen quotation marks: """"""""""""""".)"sv);
CHECK(tbl["str7"] == R"("This," she said, "is just a pointless statement.")"sv); CHECK(tbl["str7"] == R"("This," she said, "is just a pointless statement.")"sv);
} });
);
parsing_should_fail(FILE_LINE_ARGS, R"(str5 = """Here are three quotation marks: """.""")"sv); parsing_should_fail(FILE_LINE_ARGS, R"(str5 = """Here are three quotation marks: """.""")"sv);
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
# What you see is what you get. # What you see is what you get.
winpath = 'C:\Users\nodejs\templates' winpath = 'C:\Users\nodejs\templates'
@ -112,11 +108,9 @@ trimmed in raw strings.
All other whitespace All other whitespace
is preserved. is preserved.
)"sv); )"sv);
} });
);
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
quot15 = '''Here are fifteen quotation marks: """""""""""""""''' quot15 = '''Here are fifteen quotation marks: """""""""""""""'''
@ -131,53 +125,39 @@ str = ''''That's still pointless', she said.'''
CHECK(tbl["quot15"] == R"(Here are fifteen quotation marks: """"""""""""""")"sv); CHECK(tbl["quot15"] == R"(Here are fifteen quotation marks: """"""""""""""")"sv);
CHECK(tbl["apos15"] == R"(Here are fifteen apostrophes: ''''''''''''''')"sv); CHECK(tbl["apos15"] == R"(Here are fifteen apostrophes: ''''''''''''''')"sv);
CHECK(tbl["str"] == R"('That's still pointless', she said.)"sv); CHECK(tbl["str"] == R"('That's still pointless', she said.)"sv);
} });
);
parsing_should_fail(FILE_LINE_ARGS, R"(apos15 = '''Here are fifteen apostrophes: '''''''''''''''''' # INVALID)"sv); parsing_should_fail(FILE_LINE_ARGS, R"(apos15 = '''Here are fifteen apostrophes: '''''''''''''''''' # INVALID)"sv);
// value tests // value tests
parse_expected_value( parse_expected_value(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"("The quick brown fox jumps over the lazy dog")"sv, R"("The quick brown fox jumps over the lazy dog")"sv,
"The quick brown fox jumps over the lazy dog"sv); "The quick brown fox jumps over the lazy dog"sv);
parse_expected_value( parse_expected_value(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"('The quick brown fox jumps over the lazy dog')"sv, R"('The quick brown fox jumps over the lazy dog')"sv,
"The quick brown fox jumps over the lazy dog"sv); "The quick brown fox jumps over the lazy dog"sv);
parse_expected_value( parse_expected_value(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"("""The quick brown fox jumps over the lazy dog""")"sv, R"("""The quick brown fox jumps over the lazy dog""")"sv,
"The quick brown fox jumps over the lazy dog"sv); "The quick brown fox jumps over the lazy dog"sv);
parse_expected_value( parse_expected_value(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"('''The quick brown fox jumps over the lazy dog''')"sv, R"('''The quick brown fox jumps over the lazy dog''')"sv,
"The quick brown fox jumps over the lazy dog"sv); "The quick brown fox jumps over the lazy dog"sv);
#if UNICODE_LITERALS_OK #if UNICODE_LITERALS_OK
parse_expected_value( parse_expected_value(FILE_LINE_ARGS, R"("Ýôú' λáƭè è áƒƭèř ƭλïƨ - #")"sv, R"(Ýôú' λáƭè ₥è áƒƭèř ƭλïƨ - #)"sv);
FILE_LINE_ARGS, parse_expected_value(FILE_LINE_ARGS,
R"("Ýôú' λáƭè è áƒƭèř ƭλïƨ - #")"sv,
R"(Ýôú' λáƭè ₥è áƒƭèř ƭλïƨ - #)"sv);
parse_expected_value(
FILE_LINE_ARGS,
R"(" Âñδ ωλèñ \"'ƨ ářè ïñ ƭλè ƨƭřïñϱ, áℓôñϱ ωïƭλ # \"")"sv, R"(" Âñδ ωλèñ \"'ƨ ářè ïñ ƭλè ƨƭřïñϱ, áℓôñϱ ωïƭλ # \"")"sv,
R"( Âñδ ωλèñ "'ƨ ářè ïñ ƭλè ƨƭřïñϱ, áôñϱ ωïƭλ # ")"sv); R"( Âñδ ωλèñ "'ƨ ářè ïñ ƭλè ƨƭřïñϱ, áôñϱ ωïƭλ # ")"sv);
parse_expected_value( parse_expected_value(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"("Ýôú δôñ'ƭ ƭλïñƙ ƨôè úƨèř ωôñ'ƭ δô ƭλáƭ?")"sv, R"("Ýôú δôñ'ƭ ƭλïñƙ ƨôè úƨèř ωôñ'ƭ δô ƭλáƭ?")"sv,
R"(Ýôú δôñ'ƭ ƭλïñƙ ƨô₥è úƨèř ωôñ'ƭ δô ƭλáƭ?)"sv); R"(Ýôú δôñ'ƭ ƭλïñƙ ƨô₥è úƨèř ωôñ'ƭ δô ƭλáƭ?)"sv);
#endif // UNICODE_LITERALS_OK #endif // UNICODE_LITERALS_OK
parse_expected_value( parse_expected_value(FILE_LINE_ARGS, R"("\"\u03B1\u03B2\u03B3\"")"sv, "\"\u03B1\u03B2\u03B3\""sv);
FILE_LINE_ARGS,
R"("\"\u03B1\u03B2\u03B3\"")"sv,
"\"\u03B1\u03B2\u03B3\""sv);
// toml/pull/709 (\xHH unicode scalars) // toml/pull/709 (\xHH unicode scalars)
#if TOML_LANG_UNRELEASED #if TOML_LANG_UNRELEASED
parse_expected_value( parse_expected_value(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"("\x00\x10\x20\x30\x40\x50\x60\x70\x80\x90\x11\xFF\xEE")"sv, R"("\x00\x10\x20\x30\x40\x50\x60\x70\x80\x90\x11\xFF\xEE")"sv,
"\u0000\u0010\u0020\u0030\u0040\u0050\u0060\u0070\u0080\u0090\u0011\u00FF\u00EE"sv); "\u0000\u0010\u0020\u0030\u0040\u0050\u0060\u0070\u0080\u0090\u0011\u00FF\u00EE"sv);
#else #else

View File

@ -10,21 +10,19 @@ TEST_CASE("parsing - tables")
// these are the examples from https://toml.io/en/v1.0.0#table // these are the examples from https://toml.io/en/v1.0.0#table
// "Tables are defined by headers, with square brackets on a line by themselves." // "Tables are defined by headers, with square brackets on a line by themselves."
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS, "[table]"sv, "[table]"sv,
[](table&& tbl) [](table&& tbl)
{ {
REQUIRE(tbl["table"].as_table()); REQUIRE(tbl["table"].as_table());
CHECK(tbl["table"].as_table()->empty()); CHECK(tbl["table"].as_table()->empty());
CHECK(tbl["table"].as_table()->size() == 0u); CHECK(tbl["table"].as_table()->size() == 0u);
} });
);
parsing_should_fail(FILE_LINE_ARGS, "[]"sv); parsing_should_fail(FILE_LINE_ARGS, "[]"sv);
// "Under that, and until the next header or EOF, are the key/values of that table. // "Under that, and until the next header or EOF, are the key/values of that table.
// Key/value pairs within tables are not guaranteed to be in any specific order." // Key/value pairs within tables are not guaranteed to be in any specific order."
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
[table-1] [table-1]
key1 = "some string" key1 = "some string"
@ -45,12 +43,10 @@ TEST_CASE("parsing - tables")
CHECK(tbl["table-2"].as_table()->size() == 2u); CHECK(tbl["table-2"].as_table()->size() == 2u);
CHECK(tbl["table-2"]["key1"] == "another string"sv); CHECK(tbl["table-2"]["key1"] == "another string"sv);
CHECK(tbl["table-2"]["key2"] == 456); CHECK(tbl["table-2"]["key2"] == 456);
} });
);
// "Naming rules for tables are the same as for keys." (i.e. can be quoted) // "Naming rules for tables are the same as for keys." (i.e. can be quoted)
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
[dog."tater.man"] [dog."tater.man"]
type.name = "pug" type.name = "pug"
@ -63,12 +59,10 @@ TEST_CASE("parsing - tables")
REQUIRE(tbl["dog"]["tater.man"].as_table()); REQUIRE(tbl["dog"]["tater.man"].as_table());
CHECK(tbl["dog"]["tater.man"].as_table()->size() == 1u); CHECK(tbl["dog"]["tater.man"].as_table()->size() == 1u);
CHECK(tbl["dog"]["tater.man"]["type"]["name"] == "pug"sv); CHECK(tbl["dog"]["tater.man"]["type"]["name"] == "pug"sv);
} });
);
// "Whitespace around the key is ignored. However, best practice is to not use any extraneous whitespace." // "Whitespace around the key is ignored. However, best practice is to not use any extraneous whitespace."
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
[a.b.c] # this is best practice [a.b.c] # this is best practice
[ d.e.f ] # same as [d.e.f] [ d.e.f ] # same as [d.e.f]
@ -92,12 +86,10 @@ TEST_CASE("parsing - tables")
CHECK(tbl["j"].as_table()); CHECK(tbl["j"].as_table());
CHECK(tbl["j"]["k"].as_table()); CHECK(tbl["j"]["k"].as_table());
CHECK(tbl["j"]["k"]["l"].as_table()); CHECK(tbl["j"]["k"]["l"].as_table());
} });
);
// "You don't need to specify all the super-tables if you don't want to. TOML knows how to do it for you." // "You don't need to specify all the super-tables if you don't want to. TOML knows how to do it for you."
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
# [x] you # [x] you
# [x.y] don't # [x.y] don't
@ -112,8 +104,7 @@ TEST_CASE("parsing - tables")
CHECK(tbl["x"]["y"].as_table()); CHECK(tbl["x"]["y"].as_table());
CHECK(tbl["x"]["y"]["z"].as_table()); CHECK(tbl["x"]["y"]["z"].as_table());
CHECK(tbl["x"]["y"]["z"]["w"].as_table()); CHECK(tbl["x"]["y"]["z"]["w"].as_table());
} });
);
// "Like keys, you cannot define a table more than once. Doing so is invalid." // "Like keys, you cannot define a table more than once. Doing so is invalid."
parsing_should_fail(FILE_LINE_ARGS, R"( parsing_should_fail(FILE_LINE_ARGS, R"(
@ -136,8 +127,7 @@ TEST_CASE("parsing - tables")
)"sv); )"sv);
// "Defining tables out-of-order is discouraged." // "Defining tables out-of-order is discouraged."
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
# VALID BUT DISCOURAGED # VALID BUT DISCOURAGED
[fruit.apple] [fruit.apple]
@ -150,10 +140,8 @@ TEST_CASE("parsing - tables")
CHECK(tbl["fruit"]["apple"].as_table()); CHECK(tbl["fruit"]["apple"].as_table());
CHECK(tbl["animal"].as_table()); CHECK(tbl["animal"].as_table());
CHECK(tbl["fruit"]["orange"].as_table()); CHECK(tbl["fruit"]["orange"].as_table());
} });
); parsing_should_succeed(FILE_LINE_ARGS,
parsing_should_succeed(
FILE_LINE_ARGS,
R"( R"(
# RECOMMENDED # RECOMMENDED
[fruit.apple] [fruit.apple]
@ -166,13 +154,11 @@ TEST_CASE("parsing - tables")
CHECK(tbl["fruit"]["apple"].as_table()); CHECK(tbl["fruit"]["apple"].as_table());
CHECK(tbl["fruit"]["orange"].as_table()); CHECK(tbl["fruit"]["orange"].as_table());
CHECK(tbl["animal"].as_table()); CHECK(tbl["animal"].as_table());
} });
);
// "The top-level table, also called the root table, starts at the beginning of the document // "The top-level table, also called the root table, starts at the beginning of the document
// and ends just before the first table header (or EOF)." // and ends just before the first table header (or EOF)."
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
# Top-level table begins. # Top-level table begins.
name = "Fido" name = "Fido"
@ -195,13 +181,11 @@ TEST_CASE("parsing - tables")
static constexpr auto member_since = toml::date{ 1999, 8, 4 }; static constexpr auto member_since = toml::date{ 1999, 8, 4 };
CHECK(*tbl["owner"]["member_since"].as_date() == member_since); CHECK(*tbl["owner"]["member_since"].as_date() == member_since);
} });
);
// "Dotted keys create and define a table for each key part before the last one, // "Dotted keys create and define a table for each key part before the last one,
// provided that such tables were not previously created." // provided that such tables were not previously created."
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
fruit.apple.color = "red" fruit.apple.color = "red"
# Defines a table named fruit # Defines a table named fruit
@ -221,8 +205,7 @@ TEST_CASE("parsing - tables")
CHECK(tbl["fruit"]["apple"]["taste"].as_table()); CHECK(tbl["fruit"]["apple"]["taste"].as_table());
CHECK(tbl["fruit"]["apple"]["taste"]["sweet"].as_boolean()); CHECK(tbl["fruit"]["apple"]["taste"]["sweet"].as_boolean());
CHECK(*tbl["fruit"]["apple"]["taste"]["sweet"].as_boolean() == true); CHECK(*tbl["fruit"]["apple"]["taste"]["sweet"].as_boolean() == true);
} });
);
// "Since tables cannot be defined more than once, redefining such tables using a [table] header is not allowed." // "Since tables cannot be defined more than once, redefining such tables using a [table] header is not allowed."
parsing_should_fail(FILE_LINE_ARGS, R"( parsing_should_fail(FILE_LINE_ARGS, R"(
@ -257,8 +240,7 @@ TEST_CASE("parsing - tables")
)"sv); )"sv);
// "The [table] form can, however, be used to define sub-tables within tables defined via dotted keys." // "The [table] form can, however, be used to define sub-tables within tables defined via dotted keys."
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
[fruit] [fruit]
apple.color = "red" apple.color = "red"
@ -277,8 +259,7 @@ TEST_CASE("parsing - tables")
CHECK(tbl["fruit"]["apple"]["texture"].as_table()); CHECK(tbl["fruit"]["apple"]["texture"].as_table());
CHECK(tbl["fruit"]["apple"]["texture"]["smooth"].as_boolean()); CHECK(tbl["fruit"]["apple"]["texture"]["smooth"].as_boolean());
CHECK(*tbl["fruit"]["apple"]["texture"]["smooth"].as_boolean() == true); CHECK(*tbl["fruit"]["apple"]["texture"]["smooth"].as_boolean() == true);
} });
);
parsing_should_fail(FILE_LINE_ARGS, R"( parsing_should_fail(FILE_LINE_ARGS, R"(
[fruit] [fruit]
apple.color = "red" apple.color = "red"
@ -293,8 +274,7 @@ TEST_CASE("parsing - tables")
// same as above but the table order is reversed. // same as above but the table order is reversed.
// see: https://github.com/toml-lang/toml/issues/769 // see: https://github.com/toml-lang/toml/issues/769
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
[fruit.apple.texture] [fruit.apple.texture]
smooth = true smooth = true
@ -313,16 +293,14 @@ TEST_CASE("parsing - tables")
CHECK(tbl["fruit"]["apple"]["texture"].as_table()); CHECK(tbl["fruit"]["apple"]["texture"].as_table());
CHECK(tbl["fruit"]["apple"]["texture"]["smooth"].as_boolean()); CHECK(tbl["fruit"]["apple"]["texture"]["smooth"].as_boolean());
CHECK(*tbl["fruit"]["apple"]["texture"]["smooth"].as_boolean() == true); CHECK(*tbl["fruit"]["apple"]["texture"]["smooth"].as_boolean() == true);
} });
);
} }
TEST_CASE("parsing - inline tables") TEST_CASE("parsing - inline tables")
{ {
// these are the examples from https://toml.io/en/v1.0.0#inline-table // these are the examples from https://toml.io/en/v1.0.0#inline-table
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
name = { first = "Tom", last = "Preston-Werner" } name = { first = "Tom", last = "Preston-Werner" }
point = { x = 1, y = 2 } point = { x = 1, y = 2 }
@ -348,8 +326,7 @@ TEST_CASE("parsing - inline tables")
REQUIRE(tbl["animal"]["type"].as_table()); REQUIRE(tbl["animal"]["type"].as_table());
CHECK(tbl["animal"]["type"].as_table()->size() == 1u); CHECK(tbl["animal"]["type"].as_table()->size() == 1u);
CHECK(tbl["animal"]["type"]["name"] == "pug"sv); CHECK(tbl["animal"]["type"]["name"] == "pug"sv);
} });
);
// "Inline tables are fully self-contained and define all keys and sub-tables within them. // "Inline tables are fully self-contained and define all keys and sub-tables within them.
// Keys and sub-tables cannot be added outside the braces." // Keys and sub-tables cannot be added outside the braces."
@ -367,8 +344,7 @@ TEST_CASE("parsing - inline tables")
)"sv); )"sv);
// "newlines are allowed between the curly braces [if] they are valid within a value." // "newlines are allowed between the curly braces [if] they are valid within a value."
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
test = { val1 = "foo", val2 = [ test = { val1 = "foo", val2 = [
1, 2, 1, 2,
@ -386,14 +362,12 @@ test = { val1 = "foo", val2 = [
CHECK(tbl["test"]["val2"][1] == 2); CHECK(tbl["test"]["val2"][1] == 2);
CHECK(tbl["test"]["val2"][2] == 3); CHECK(tbl["test"]["val2"][2] == 3);
CHECK(tbl["test"]["val3"] == "bar"sv); CHECK(tbl["test"]["val3"] == "bar"sv);
} });
);
// toml/issues/516 (newlines/trailing commas in inline tables) // toml/issues/516 (newlines/trailing commas in inline tables)
#if TOML_LANG_UNRELEASED #if TOML_LANG_UNRELEASED
{ {
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
name = { name = {
first = "Tom", first = "Tom",
@ -406,13 +380,12 @@ name = {
CHECK(tbl["name"].as_table()->size() == 2u); CHECK(tbl["name"].as_table()->size() == 2u);
CHECK(tbl["name"]["first"] == "Tom"sv); CHECK(tbl["name"]["first"] == "Tom"sv);
CHECK(tbl["name"]["last"] == "Preston-Werner"sv); CHECK(tbl["name"]["last"] == "Preston-Werner"sv);
} });
);
} }
#else #else
{ {
// "A terminating comma (also called trailing comma) is not permitted after the last key/value pair in an inline table." // "A terminating comma (also called trailing comma) is not permitted after the last key/value pair in an inline
// table."
parsing_should_fail(FILE_LINE_ARGS, R"(name = { first = "Tom", last = "Preston-Werner", })"sv); parsing_should_fail(FILE_LINE_ARGS, R"(name = { first = "Tom", last = "Preston-Werner", })"sv);
// "No newlines are allowed between the curly braces unless they are valid within a value." // "No newlines are allowed between the curly braces unless they are valid within a value."
@ -422,16 +395,13 @@ name = {
last = "Preston-Werner" last = "Preston-Werner"
} }
)"sv); )"sv);
} }
#endif #endif
} }
TEST_CASE("parsing - arrays-of-tables") TEST_CASE("parsing - arrays-of-tables")
{ {
parsing_should_succeed( parsing_should_succeed(FILE_LINE_ARGS,
FILE_LINE_ARGS,
R"( R"(
points = [ { x = 1, y = 2, z = 3 }, points = [ { x = 1, y = 2, z = 3 },
{ x = 7, y = 8, z = 9 }, { x = 7, y = 8, z = 9 },
@ -504,7 +474,6 @@ color = "gray"
CHECK(tbl["products"][2]["sku"] == 284758393); CHECK(tbl["products"][2]["sku"] == 284758393);
CHECK(tbl["products"][2]["color"] == "gray"sv); CHECK(tbl["products"][2]["color"] == "gray"sv);
REQUIRE(tbl["fruit"].as<array>()); REQUIRE(tbl["fruit"].as<array>());
CHECK(tbl["fruit"].as<array>()->size() == 2u); CHECK(tbl["fruit"].as<array>()->size() == 2u);
CHECK(tbl["fruit"].as<array>()->is_homogeneous()); CHECK(tbl["fruit"].as<array>()->is_homogeneous());
@ -535,8 +504,7 @@ color = "gray"
CHECK(tbl["fruit"][1]["variety"].as<array>()->is_homogeneous()); CHECK(tbl["fruit"][1]["variety"].as<array>()->is_homogeneous());
CHECK(tbl["fruit"][1]["variety"].as<array>()->is_array_of_tables()); CHECK(tbl["fruit"][1]["variety"].as<array>()->is_array_of_tables());
CHECK(tbl["fruit"][1]["variety"][0]["name"] == "plantain"sv); CHECK(tbl["fruit"][1]["variety"][0]["name"] == "plantain"sv);
} });
);
parsing_should_fail(FILE_LINE_ARGS, R"( parsing_should_fail(FILE_LINE_ARGS, R"(
# INVALID TOML DOC # INVALID TOML DOC

View File

@ -2,7 +2,6 @@
// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au> // Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text. // See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
#pragma once #pragma once
// toml++ config // toml++ config
@ -42,45 +41,45 @@
#ifdef _WIN32 #ifdef _WIN32
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#define VC_EXTRALEAN #define VC_EXTRALEAN
#define NOATOM // - Atom Manager routines #define NOATOM // Atom Manager routines
#define NOBITMAP #define NOBITMAP //
#define NOCLIPBOARD // - Clipboard routines #define NOCLIPBOARD // Clipboard routines
#define NOCOLOR // - Screen colors #define NOCOLOR // Screen colors
#define NOCOMM // - COMM driver routines #define NOCOMM // COMM driver routines
#define NOCTLMGR // - Control and Dialog routines #define NOCTLMGR // Control and Dialog routines
#define NODEFERWINDOWPOS // - DeferWindowPos routines #define NODEFERWINDOWPOS // DeferWindowPos routines
#define NODRAWTEXT // - DrawText() and DT_* #define NODRAWTEXT // DrawText() and DT_*
#define NOGDI // - All GDI defines and routines #define NOGDI // All GDI defines and routines
#define NOGDICAPMASKS // - CC_*, LC_*, PC_*, CP_*, TC_*, RC_ #define NOGDICAPMASKS // CC_*, LC_*, PC_*, CP_*, TC_*, RC_
#define NOHELP // - Help engine interface. #define NOHELP // Help engine interface.
#define NOICONS // - IDI_* #define NOICONS // IDI_*
#define NOKANJI // - Kanji support stuff. #define NOKANJI // Kanji support stuff.
#define NOKEYSTATES // - MK_* #define NOKEYSTATES // MK_*
#define NOKERNEL // - All KERNEL defines and routines #define NOKERNEL // All KERNEL defines and routines
#define NOMB // - MB_* and MessageBox() #define NOMB // MB_* and MessageBox()
#define NOMCX // - Modem Configuration Extensions #define NOMCX // Modem Configuration Extensions
#define NOMENUS // - MF_* #define NOMENUS // MF_*
#define NOMEMMGR // - GMEM_*, LMEM_*, GHND, LHND, associated routines #define NOMEMMGR // GMEM_*, LMEM_*, GHND, LHND, associated routines
#define NOMETAFILE // - typedef METAFILEPICT #define NOMETAFILE // typedef METAFILEPICT
//#define NOMINMAX // - Macros min(a,b) and max(a,b) #define NOMSG // typedef MSG and associated routines
#define NOMSG // - typedef MSG and associated routines #define NOOPENFILE // OpenFile(), OemToAnsi, AnsiToOem, and OF_*
//#define NONLS // - All NLS defines and routines #define NOPROFILER // Profiler interface.
#define NOOPENFILE // - OpenFile(), OemToAnsi, AnsiToOem, and OF_* #define NORASTEROPS // Binary and Tertiary raster ops
#define NOPROFILER // - Profiler interface. #define NOSCROLL // SB_* and scrolling routines
#define NORASTEROPS // - Binary and Tertiary raster ops #define NOSERVICE // All Service Controller routines, SERVICE_ equates, etc.
#define NOSCROLL // - SB_* and scrolling routines #define NOSHOWWINDOW // SW_*
#define NOSERVICE // - All Service Controller routines, SERVICE_ equates, etc. #define NOSOUND // Sound driver routines
#define NOSHOWWINDOW // - SW_* #define NOSYSCOMMANDS // SC_*
#define NOSOUND // - Sound driver routines #define NOSYSMETRICS // SM_*
#define NOSYSCOMMANDS // - SC_* #define NOTEXTMETRIC // typedef TEXTMETRIC and associated routines
#define NOSYSMETRICS // - SM_* #define NOUSER // All USER defines and routines
#define NOTEXTMETRIC // - typedef TEXTMETRIC and associated routines #define NOVIRTUALKEYCODES // VK_*
#define NOUSER // - All USER defines and routines #define NOWH // SetWindowsHook and WH_*
#define NOVIRTUALKEYCODES // - VK_* #define NOWINOFFSETS // GWL_*, GCL_*, associated routines
#define NOWH // - SetWindowsHook and WH_* #define NOWINMESSAGES // WM_*, EM_*, LB_*, CB_*
#define NOWINOFFSETS // - GWL_*, GCL_*, associated routines #define NOWINSTYLES // WS_*, CS_*, ES_*, LBS_*, SBS_*, CBS_*
#define NOWINMESSAGES // - WM_*, EM_*, LB_*, CB_* //#define NOMINMAX // Macros min(a,b) and max(a,b)
#define NOWINSTYLES // - WS_*, CS_*, ES_*, LBS_*, SBS_*, CBS_* //#define NONLS // All NLS defines and routines
#endif #endif
// test harness stuff // test harness stuff
@ -99,4 +98,3 @@
#ifndef SHOULD_HAVE_EXCEPTIONS #ifndef SHOULD_HAVE_EXCEPTIONS
#define SHOULD_HAVE_EXCEPTIONS 1 #define SHOULD_HAVE_EXCEPTIONS 1
#endif #endif

View File

@ -5,14 +5,14 @@
#include "tests.h" #include "tests.h"
bool parsing_should_succeed( bool parsing_should_succeed(std::string_view test_file,
std::string_view test_file,
uint32_t test_line, uint32_t test_line,
std::string_view toml_str, std::string_view toml_str,
pss_func&& func, pss_func&& func,
std::string_view source_path) std::string_view source_path)
{ {
INFO("["sv << test_file << ", line "sv << test_line << "] "sv << "parsing_should_succeed(\""sv << toml_str << "\")"sv) INFO("["sv << test_file << ", line "sv << test_line << "] "sv
<< "parsing_should_succeed(\""sv << toml_str << "\")"sv)
constexpr auto validate_table = [](table&& tabl, std::string_view path) -> table&& constexpr auto validate_table = [](table&& tabl, std::string_view path) -> table&&
{ {
@ -52,11 +52,8 @@ bool parsing_should_succeed(
} }
catch (const parse_error& err) catch (const parse_error& err)
{ {
FORCE_FAIL( FORCE_FAIL("Parse error on line "sv << err.source().begin.line << ", column "sv << err.source().begin.column
"Parse error on line "sv << err.source().begin.line << ":\n"sv << err.description());
<< ", column "sv << err.source().begin.column
<< ":\n"sv << err.description()
);
return false; return false;
} }
@ -74,11 +71,9 @@ bool parsing_should_succeed(
} }
else else
{ {
FORCE_FAIL( FORCE_FAIL("Parse error on line "sv << result.error().source().begin.line << ", column "sv
"Parse error on line "sv << result.error().source().begin.line << result.error().source().begin.column << ":\n"sv
<< ", column "sv << result.error().source().begin.column << result.error().description());
<< ":\n"sv << result.error().description()
);
} }
} }
@ -96,11 +91,9 @@ bool parsing_should_succeed(
} }
else else
{ {
FORCE_FAIL( FORCE_FAIL("Parse error on line "sv << result.error().source().begin.line << ", column "sv
"Parse error on line "sv << result.error().source().begin.line << result.error().source().begin.column << ":\n"sv
<< ", column "sv << result.error().source().begin.column << result.error().description());
<< ":\n"sv << result.error().description()
);
} }
} }
@ -109,14 +102,14 @@ bool parsing_should_succeed(
return true; return true;
} }
bool parsing_should_fail( bool parsing_should_fail(std::string_view test_file,
std::string_view test_file,
uint32_t test_line, uint32_t test_line,
std::string_view toml_str, std::string_view toml_str,
source_index expected_failure_line, source_index expected_failure_line,
source_index expected_failure_column) source_index expected_failure_column)
{ {
INFO("["sv << test_file << ", line "sv << test_line << "] "sv << "parsing_should_fail(\""sv << toml_str << "\")"sv) INFO("["sv << test_file << ", line "sv << test_line << "] "sv
<< "parsing_should_fail(\""sv << toml_str << "\")"sv)
#if TOML_EXCEPTIONS #if TOML_EXCEPTIONS
@ -130,17 +123,15 @@ bool parsing_should_fail(
{ {
if (ex_line != static_cast<source_index>(-1) && err.source().begin.line != ex_line) if (ex_line != static_cast<source_index>(-1) && err.source().begin.line != ex_line)
{ {
FORCE_FAIL("Expected parse_error at line "sv << ex_line FORCE_FAIL("Expected parse_error at line "sv << ex_line << ", actually occured at line "sv
<< ", actually occured at line "sv << err.source().begin.line << err.source().begin.line);
);
return false; return false;
} }
if (ex_col != static_cast<source_index>(-1) && err.source().begin.column != ex_col) if (ex_col != static_cast<source_index>(-1) && err.source().begin.column != ex_col)
{ {
FORCE_FAIL("Expected parse_error at column "sv << ex_col FORCE_FAIL("Expected parse_error at column "sv << ex_col << ", actually occured at column "sv
<< ", actually occured at column "sv << err.source().begin.column << err.source().begin.column);
);
return false; return false;
} }
@ -162,11 +153,13 @@ bool parsing_should_fail(
return false; return false;
}; };
auto result = run_tests(expected_failure_line, expected_failure_column, [=]() auto result = run_tests(expected_failure_line,
{ expected_failure_column,
[[maybe_unused]] auto res = toml::parse(toml_str); [=]() { [[maybe_unused]] auto res = toml::parse(toml_str); });
}); result = result
result = result && run_tests(expected_failure_line, expected_failure_column, [=]() && run_tests(expected_failure_line,
expected_failure_column,
[=]()
{ {
std::stringstream ss; std::stringstream ss;
ss.write(toml_str.data(), static_cast<std::streamsize>(toml_str.length())); ss.write(toml_str.data(), static_cast<std::streamsize>(toml_str.length()));
@ -182,16 +175,14 @@ bool parsing_should_fail(
{ {
if (ex_line != static_cast<source_index>(-1) && result.error().source().begin.line != ex_line) if (ex_line != static_cast<source_index>(-1) && result.error().source().begin.line != ex_line)
{ {
FORCE_FAIL("Expected parse_error at line "sv << ex_line FORCE_FAIL("Expected parse_error at line "sv << ex_line << ", actually occured at line "sv
<< ", actually occured at line "sv << result.error().source().begin.line << result.error().source().begin.line);
);
} }
if (ex_col != static_cast<source_index>(-1) && result.error().source().begin.column != ex_col) if (ex_col != static_cast<source_index>(-1) && result.error().source().begin.column != ex_col)
{ {
FORCE_FAIL("Expected parse_error at column "sv << ex_col FORCE_FAIL("Expected parse_error at column "sv << ex_col << ", actually occured at column "sv
<< ", actually occured at column "sv << result.error().source().begin.column << result.error().source().begin.column);
);
} }
SUCCEED("parse_error generated OK"sv); SUCCEED("parse_error generated OK"sv);
@ -202,7 +193,9 @@ bool parsing_should_fail(
}; };
return run_tests(expected_failure_line, expected_failure_column, [=]() { return toml::parse(toml_str); }) return run_tests(expected_failure_line, expected_failure_column, [=]() { return toml::parse(toml_str); })
&& run_tests(expected_failure_line, expected_failure_column, [=]() && run_tests(expected_failure_line,
expected_failure_column,
[=]()
{ {
std::stringstream ss; std::stringstream ss;
ss.write(toml_str.data(), static_cast<std::streamsize>(toml_str.length())); ss.write(toml_str.data(), static_cast<std::streamsize>(toml_str.length()));

View File

@ -7,7 +7,7 @@
#include "settings.h" #include "settings.h"
#if USE_TARTANLLAMA_OPTIONAL #if USE_TARTANLLAMA_OPTIONAL
#include "tloptional.h" #include "lib_tloptional.h"
#endif #endif
#if USE_SINGLE_HEADER #if USE_SINGLE_HEADER
@ -50,13 +50,23 @@ TOML_DISABLE_SPAM_WARNINGS;
TOML_DISABLE_ARITHMETIC_WARNINGS; TOML_DISABLE_ARITHMETIC_WARNINGS;
TOML_DISABLE_WARNINGS; TOML_DISABLE_WARNINGS;
#include "catch2.h" #include "lib_catch2.h"
#include <sstream> #include <sstream>
namespace toml {} namespace toml
{
}
using namespace Catch::literals; using namespace Catch::literals;
using namespace toml; using namespace toml;
TOML_ENABLE_WARNINGS; TOML_ENABLE_WARNINGS;
TOML_NODISCARD
TOML_ATTR(const)
TOML_ALWAYS_INLINE
constexpr size_t operator"" _sz(unsigned long long n) noexcept
{
return static_cast<size_t>(n);
}
#define FILE_LINE_ARGS std::string_view{ __FILE__ }, __LINE__ #define FILE_LINE_ARGS std::string_view{ __FILE__ }, __LINE__
#define BOM_PREFIX "\xEF\xBB\xBF" #define BOM_PREFIX "\xEF\xBB\xBF"
@ -99,17 +109,13 @@ class function_view<R(P...)> final
mutable eraser_func_type* eraser = {}; mutable eraser_func_type* eraser = {};
public: public:
function_view() noexcept = default; function_view() noexcept = default;
template <typename T> template <typename T>
function_view(T&& x) noexcept function_view(T&& x) noexcept : ptr_{ reinterpret_cast<void*>(std::addressof(x)) }
: ptr_{ reinterpret_cast<void*>(std::addressof(x)) }
{ {
eraser = [](void* ptr, P&&... xs) -> R eraser = [](void* ptr, P&&... xs) -> R
{ { return (*reinterpret_cast<std::add_pointer_t<std::remove_reference_t<T>>>(ptr))(std::forward<P>(xs)...); };
return (*reinterpret_cast<std::add_pointer_t<std::remove_reference_t<T>>>(ptr))(std::forward<P>(xs)...);
};
} }
decltype(auto) operator()(P&&... xs) const decltype(auto) operator()(P&&... xs) const
@ -117,33 +123,35 @@ class function_view<R(P...)> final
return eraser(ptr_, std::forward<P>(xs)...); return eraser(ptr_, std::forward<P>(xs)...);
} }
[[nodiscard]] operator bool() const noexcept { return !!ptr_; } TOML_NODISCARD
operator bool() const noexcept
{
return !!ptr_;
}
}; };
using pss_func = function_view<void(toml::table&&)>; using pss_func = function_view<void(toml::table&&)>;
bool parsing_should_succeed( bool parsing_should_succeed(std::string_view test_file,
std::string_view test_file,
uint32_t test_line, uint32_t test_line,
std::string_view toml_str, std::string_view toml_str,
pss_func&& func = {}, pss_func&& func = {},
std::string_view source_path = {}); std::string_view source_path = {});
bool parsing_should_fail( bool parsing_should_fail(std::string_view test_file,
std::string_view test_file,
uint32_t test_line, uint32_t test_line,
std::string_view toml_str, std::string_view toml_str,
source_index expected_failure_line = static_cast<source_index>(-1), source_index expected_failure_line = static_cast<source_index>(-1),
source_index expected_failure_column = static_cast<source_index>(-1)); source_index expected_failure_column = static_cast<source_index>(-1));
template <typename T> template <typename T>
inline bool parse_expected_value( inline bool parse_expected_value(std::string_view test_file,
std::string_view test_file,
uint32_t test_line, uint32_t test_line,
std::string_view value_str, std::string_view value_str,
const T& expected) const T& expected)
{ {
INFO("["sv << test_file << ", line "sv << test_line << "] "sv << "parse_expected_value(\""sv << value_str << "\")"sv) INFO("["sv << test_file << ", line "sv << test_line << "] "sv
<< "parse_expected_value(\""sv << value_str << "\")"sv)
std::string val; std::string val;
static constexpr auto key = "val = "sv; static constexpr auto key = "val = "sv;
@ -196,7 +204,8 @@ inline bool parse_expected_value(
using value_type = impl::native_type_of<impl::remove_cvref_t<T>>; using value_type = impl::native_type_of<impl::remove_cvref_t<T>>;
value<value_type> val_parsed; value<value_type> val_parsed;
{ {
INFO("["sv << test_file << ", line "sv << test_line << "] "sv << "parse_expected_value: Checking initial parse"sv) INFO("["sv << test_file << ", line "sv << test_line << "] "sv
<< "parse_expected_value: Checking initial parse"sv)
bool stolen_value = false; // parsing_should_succeed invokes the functor more than once bool stolen_value = false; // parsing_should_succeed invokes the functor more than once
const auto result = parsing_should_succeed( const auto result = parsing_should_succeed(
@ -313,8 +322,7 @@ inline bool parse_expected_value(
val_parsed = std::move(*nv.as<value_type>()); val_parsed = std::move(*nv.as<value_type>());
stolen_value = true; stolen_value = true;
} }
} });
);
if (!result) if (!result)
return false; return false;
@ -322,7 +330,8 @@ inline bool parse_expected_value(
// check round-tripping // check round-tripping
{ {
INFO("["sv << test_file << ", line "sv << test_line << "] "sv << "parse_expected_value: Checking round-trip"sv) INFO("["sv << test_file << ", line "sv << test_line << "] "sv
<< "parse_expected_value: Checking round-trip"sv)
{ {
std::string str; std::string str;
{ {
@ -333,8 +342,8 @@ inline bool parse_expected_value(
} }
bool value_ok = true; bool value_ok = true;
const auto parse_ok = parsing_should_succeed( const auto parse_ok =
test_file, parsing_should_succeed(test_file,
test_line, test_line,
std::string_view{ str }, std::string_view{ str },
[&](table&& tbl) [&](table&& tbl)
@ -350,8 +359,7 @@ inline bool parse_expected_value(
value_ok = false; value_ok = false;
FORCE_FAIL("Value was not the same after round-tripping"sv); FORCE_FAIL("Value was not the same after round-tripping"sv);
} }
} });
);
if (!parse_ok || value_ok) if (!parse_ok || value_ok)
return false; return false;

View File

@ -7,22 +7,14 @@
using namespace toml::impl; using namespace toml::impl;
using func_type = bool(char32_t) noexcept; using func_type = bool(char32_t) noexcept;
inline constexpr func_type* funcs[] = inline constexpr func_type* funcs[] = {
{
// these must be mutually-exclusive // these must be mutually-exclusive
impl::is_ascii_letter, impl::is_ascii_letter, impl::is_ascii_whitespace, impl::is_ascii_line_break<true>,
impl::is_ascii_whitespace, impl::is_decimal_digit, impl::is_string_delimiter, impl::is_non_ascii_whitespace,
impl::is_ascii_line_break<true>, impl::is_non_ascii_line_break, impl::is_unicode_surrogate,
impl::is_decimal_digit,
impl::is_string_delimiter,
impl::is_non_ascii_whitespace,
impl::is_non_ascii_line_break,
impl::is_unicode_surrogate,
#if TOML_LANG_UNRELEASED #if TOML_LANG_UNRELEASED
impl::is_non_ascii_letter, impl::is_non_ascii_letter, impl::is_non_ascii_number, impl::is_combining_mark,
impl::is_non_ascii_number,
impl::is_combining_mark,
#endif #endif
}; };
@ -60,9 +52,7 @@ struct codepoint_range
template <typename T> template <typename T>
TOML_NODISCARD_CTOR TOML_NODISCARD_CTOR
constexpr codepoint_range(T first_) noexcept constexpr codepoint_range(T first_) noexcept : first{ static_cast<char32_t>(first_) }, last{ first }
: first{ static_cast<char32_t>(first_) },
last{ first }
{} {}
}; };

View File

@ -13,15 +13,10 @@ TEST_CASE("user feedback")
{ {
toml::table t1; toml::table t1;
t1.insert_or_assign("bar1", toml::array{ 1, 2, 3 }); t1.insert_or_assign("bar1", toml::array{ 1, 2, 3 });
CHECK(t1 == toml::table{{ CHECK(t1 == toml::table{ { { "bar1"sv, toml::array{ 1, 2, 3 } } } });
{ "bar1"sv, toml::array{ 1, 2, 3 } }
}});
t1.insert_or_assign("foo1", *t1.get("bar1")); t1.insert_or_assign("foo1", *t1.get("bar1"));
CHECK(t1 == toml::table{{ CHECK(t1 == toml::table{ { { "bar1"sv, toml::array{ 1, 2, 3 } }, { "foo1"sv, toml::array{ 1, 2, 3 } } } });
{ "bar1"sv, toml::array{ 1, 2, 3 } },
{ "foo1"sv, toml::array{ 1, 2, 3 } }
}});
// t1["foo1"] = t1["bar1"]; // does nothing, should this fail to compile? // t1["foo1"] = t1["bar1"]; // does nothing, should this fail to compile?
// - yes - // - yes -
@ -31,34 +26,28 @@ TEST_CASE("user feedback")
toml::array* array1 = t1["foo1"].node()->as_array(); toml::array* array1 = t1["foo1"].node()->as_array();
array1->push_back(4); array1->push_back(4);
CHECK(t1 == toml::table{{ CHECK(t1 == toml::table{ { { "bar1"sv, toml::array{ 1, 2, 3 } }, { "foo1"sv, toml::array{ 1, 2, 3, 4 } } } });
{ "bar1"sv, toml::array{ 1, 2, 3 } },
{ "foo1"sv, toml::array{ 1, 2, 3, 4 } }
}});
t1.insert_or_assign("foo3", t1["foo1"]); t1.insert_or_assign("foo3", t1["foo1"]);
CHECK(t1 == toml::table{{ CHECK(t1
{ "bar1"sv, toml::array{ 1, 2, 3 } }, == toml::table{ { { "bar1"sv, toml::array{ 1, 2, 3 } },
{ "foo1"sv, toml::array{ 1, 2, 3, 4 } }, { "foo1"sv, toml::array{ 1, 2, 3, 4 } },
{ "foo3"sv, toml::array{ 1, 2, 3, 4 } } { "foo3"sv, toml::array{ 1, 2, 3, 4 } } } });
}});
t1.insert_or_assign("foo2", *t1["foo1"].node()); t1.insert_or_assign("foo2", *t1["foo1"].node());
CHECK(t1 == toml::table{{ CHECK(t1
{ "bar1"sv, toml::array{ 1, 2, 3 } }, == toml::table{ { { "bar1"sv, toml::array{ 1, 2, 3 } },
{ "foo1"sv, toml::array{ 1, 2, 3, 4 } }, { "foo1"sv, toml::array{ 1, 2, 3, 4 } },
{ "foo2"sv, toml::array{ 1, 2, 3, 4 } }, { "foo2"sv, toml::array{ 1, 2, 3, 4 } },
{ "foo3"sv, toml::array{ 1, 2, 3, 4 } } { "foo3"sv, toml::array{ 1, 2, 3, 4 } } } });
}});
toml::array* array2 = t1["foo2"].node()->as_array(); toml::array* array2 = t1["foo2"].node()->as_array();
array2->push_back("wrench"); array2->push_back("wrench");
CHECK(t1 == toml::table{{ CHECK(t1
{ "bar1"sv, toml::array{ 1, 2, 3 } }, == toml::table{ { { "bar1"sv, toml::array{ 1, 2, 3 } },
{ "foo1"sv, toml::array{ 1, 2, 3, 4 } }, { "foo1"sv, toml::array{ 1, 2, 3, 4 } },
{ "foo2"sv, toml::array{ 1, 2, 3, 4, "wrench" } }, { "foo2"sv, toml::array{ 1, 2, 3, 4, "wrench" } },
{ "foo3"sv, toml::array{ 1, 2, 3, 4 } } { "foo3"sv, toml::array{ 1, 2, 3, 4 } } } });
}});
toml::table t2 = t1; toml::table t2 = t1;
CHECK(t2 == t1); CHECK(t2 == t1);
@ -67,23 +56,21 @@ TEST_CASE("user feedback")
// t2.emplace("bar", toml::array{6, 7}); // fails to compile? not sure what I did wrong // t2.emplace("bar", toml::array{6, 7}); // fails to compile? not sure what I did wrong
// - it should be this: - // - it should be this: -
t2.emplace<toml::array>("bar", 6, 7); t2.emplace<toml::array>("bar", 6, 7);
CHECK(t2 == toml::table{{ CHECK(t2
{ "bar"sv, toml::array{ 6, 7 } }, == toml::table{ { { "bar"sv, toml::array{ 6, 7 } },
{ "bar1"sv, toml::array{ 1, 2, 3 } }, { "bar1"sv, toml::array{ 1, 2, 3 } },
{ "foo1"sv, toml::array{ 1, 2, 3, 4 } }, { "foo1"sv, toml::array{ 1, 2, 3, 4 } },
{ "foo2"sv, toml::array{ 1, 2, 3, 4, "wrench" } }, { "foo2"sv, toml::array{ 1, 2, 3, 4, "wrench" } },
{ "foo3"sv, toml::array{ 1, 2, 3, 4 } } { "foo3"sv, toml::array{ 1, 2, 3, 4 } } } });
}});
t2.insert_or_assign("bar2", toml::array{ 6, 7 }); t2.insert_or_assign("bar2", toml::array{ 6, 7 });
CHECK(t2 == toml::table{{ CHECK(t2
{ "bar"sv, toml::array{ 6, 7 } }, == toml::table{ { { "bar"sv, toml::array{ 6, 7 } },
{ "bar1"sv, toml::array{ 1, 2, 3 } }, { "bar1"sv, toml::array{ 1, 2, 3 } },
{ "bar2"sv, toml::array{ 6, 7 } }, { "bar2"sv, toml::array{ 6, 7 } },
{ "foo1"sv, toml::array{ 1, 2, 3, 4 } }, { "foo1"sv, toml::array{ 1, 2, 3, 4 } },
{ "foo2"sv, toml::array{ 1, 2, 3, 4, "wrench" } }, { "foo2"sv, toml::array{ 1, 2, 3, 4, "wrench" } },
{ "foo3"sv, toml::array{ 1, 2, 3, 4 } } { "foo3"sv, toml::array{ 1, 2, 3, 4 } } } });
}});
} }
SECTION("github/issues/65") // https://github.com/marzer/tomlplusplus/issues/65 SECTION("github/issues/65") // https://github.com/marzer/tomlplusplus/issues/65
@ -98,23 +85,26 @@ TEST_CASE("user feedback")
parsing_should_fail(FILE_LINE_ARGS, "#\xf1\x63"); parsing_should_fail(FILE_LINE_ARGS, "#\xf1\x63");
parsing_should_fail(FILE_LINE_ARGS, "1= 0x6cA#+\xf1"); parsing_should_fail(FILE_LINE_ARGS, "1= 0x6cA#+\xf1");
parsing_should_fail(FILE_LINE_ARGS, "p=06:06:06#\x0b\xff"); parsing_should_fail(FILE_LINE_ARGS, "p=06:06:06#\x0b\xff");
parsing_should_fail(FILE_LINE_ARGS, "''''d' 't' '+o\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c" parsing_should_fail(
FILE_LINE_ARGS,
"''''d' 't' '+o\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
"\x0c\x0c\x0c\x0c\x0c\r\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c" "\x0c\x0c\x0c\x0c\x0c\r\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
"\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c" "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
"\x0c\x0c\x0c\x0c\x0c\x0c\x0cop1\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c" "\x0c\x0c\x0c\x0c\x0c\x0c\x0cop1\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
"\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c" "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
"\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c' 'ml'\n\n%\x87" "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c' 'ml'\n\n%\x87");
); parsing_should_fail(
parsing_should_fail(FILE_LINE_ARGS, FILE_LINE_ARGS,
R"(t =[ 9, 2, 1,"r", 9999999999999999999999999999999999999999999999999999999999999995.0 ])" R"(t =[ 9, 2, 1,"r", 9999999999999999999999999999999999999999999999999999999999999995.0 ])");
);
} }
SECTION("github/issues/67") // https://github.com/marzer/tomlplusplus/issues/67 SECTION("github/issues/67") // https://github.com/marzer/tomlplusplus/issues/67
{ {
const auto data = R"(array=["v1", "v2", "v3"])"sv; const auto data = R"(array=["v1", "v2", "v3"])"sv;
parsing_should_succeed(FILE_LINE_ARGS, data, [](auto&& table) parsing_should_succeed(FILE_LINE_ARGS,
data,
[](auto&& table)
{ {
auto arr = table["array"].as_array(); auto arr = table["array"].as_array();
for (auto it = arr->cbegin(); it != arr->cend();) for (auto it = arr->cbegin(); it != arr->cend();)
@ -129,7 +119,9 @@ TEST_CASE("user feedback")
SECTION("github/issues/68") // https://github.com/marzer/tomlplusplus/issues/68 SECTION("github/issues/68") // https://github.com/marzer/tomlplusplus/issues/68
{ {
const auto data = R"(array=["v1", "v2", "v3"])"sv; const auto data = R"(array=["v1", "v2", "v3"])"sv;
parsing_should_succeed(FILE_LINE_ARGS, data, [](auto&& table) parsing_should_succeed(FILE_LINE_ARGS,
data,
[](auto&& table)
{ {
std::stringstream ss; std::stringstream ss;
ss << table; ss << table;
@ -151,7 +143,9 @@ TEST_CASE("user feedback")
[[c]] # array-of-tables with a single, empty table element [[c]] # array-of-tables with a single, empty table element
)"sv; )"sv;
parsing_should_succeed(FILE_LINE_ARGS, data, [](auto&& table) parsing_should_succeed(FILE_LINE_ARGS,
data,
[](auto&& table)
{ {
std::stringstream ss; std::stringstream ss;
ss << table; ss << table;
@ -178,22 +172,24 @@ b = []
SECTION("github/issues/112") // https://github.com/marzer/tomlplusplus/issues/112 SECTION("github/issues/112") // https://github.com/marzer/tomlplusplus/issues/112
{ {
parsing_should_fail(FILE_LINE_ARGS, R"( parsing_should_fail(FILE_LINE_ARGS,
R"(
[a.b.c.d] [a.b.c.d]
u = 6 u = 6
[a] [a]
b.t = 8 b.t = 8
[a.b] # should cause redefinition error here [a.b] # should cause redefinition error here
u = 0 u = 0
)", 6); )",
6);
parsing_should_fail(FILE_LINE_ARGS, R"( parsing_should_fail(FILE_LINE_ARGS,
R"(
[a] [a]
b.t = 8 b.t = 8
[a.b] # should cause redefinition error here [a.b] # should cause redefinition error here
u = 0 u = 0
)", 4); )",
4);
} }
} }

View File

@ -9,17 +9,19 @@ TEST_CASE("using iterators")
constexpr auto data = R"(array=[1,"Foo",true] constexpr auto data = R"(array=[1,"Foo",true]
string="Bar" string="Bar"
number=5)"sv; number=5)"sv;
parsing_should_succeed(FILE_LINE_ARGS, data, [](auto&& table) parsing_should_succeed(
FILE_LINE_ARGS,
data,
[](auto&& table)
{ {
const auto table_begin = table.begin(); const auto table_begin = table.begin();
const auto table_end = table.end(); const auto table_end = table.end();
auto count_table_lambda = [table_begin, table_end](node_type type) noexcept auto count_table_lambda = [table_begin, table_end](node_type type) noexcept
{ {
return std::count_if(table_begin, table_end, [type](const auto& pair) noexcept return std::count_if(table_begin,
{ table_end,
return pair.second.type() == type; [type](const auto& pair) noexcept { return pair.second.type() == type; });
});
}; };
CHECK(std::distance(table_begin, table_end) == 3); CHECK(std::distance(table_begin, table_end) == 3);
@ -28,22 +30,18 @@ number=5)"sv;
CHECK(count_table_lambda(node_type::string) == 1); CHECK(count_table_lambda(node_type::string) == 1);
CHECK(std::next(table_begin, 3) == table_end); CHECK(std::next(table_begin, 3) == table_end);
const auto array_iter = std::find_if(table_begin, table_end, [](const auto& pair) noexcept const auto array_iter =
{ std::find_if(table_begin, table_end, [](const auto& pair) noexcept { return pair.second.is_array(); });
return pair.second.is_array();
});
REQUIRE(array_iter != table_end); REQUIRE(array_iter != table_end);
const auto& array = array_iter->second.as_array(); const auto& array = array_iter->second.as_array();
const auto array_begin = array->begin(); const auto array_begin = array->begin();
const auto array_end = array->end(); const auto array_end = array->end();
auto count_array_lambda = [array_begin, array_end](node_type type) noexcept auto count_array_lambda = [array_begin, array_end](node_type type) noexcept {
{ return std::count_if(array_begin,
return std::count_if(array_begin, array_end, [type](const auto& node) noexcept array_end,
{ [type](const auto& node) noexcept { return node.type() == type; });
return node.type() == type;
});
}; };
CHECK(std::distance(array_begin, array_end) == 3); CHECK(std::distance(array_begin, array_end) == 3);

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

View File

@ -108,11 +108,11 @@
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />

239
toml.hpp
View File

@ -546,13 +546,6 @@
#define TOML_UNREACHABLE TOML_ASSERT(false) #define TOML_UNREACHABLE TOML_ASSERT(false)
#endif #endif
#if defined(__cpp_consteval) && __cpp_consteval >= 201811 && !defined(_MSC_VER)
// https://developercommunity.visualstudio.com/t/Erroneous-C7595-error-with-consteval-in/1404234
#define TOML_CONSTEVAL consteval
#else
#define TOML_CONSTEVAL constexpr
#endif
#ifdef __has_cpp_attribute #ifdef __has_cpp_attribute
#define TOML_HAS_ATTR(...) __has_cpp_attribute(__VA_ARGS__) #define TOML_HAS_ATTR(...) __has_cpp_attribute(__VA_ARGS__)
#else #else
@ -766,7 +759,9 @@
#define TOML_EXTERNAL_LINKAGE inline #define TOML_EXTERNAL_LINKAGE inline
#define TOML_INTERNAL_LINKAGE inline #define TOML_INTERNAL_LINKAGE inline
#else #else
#define TOML_ANON_NAMESPACE_START static_assert(TOML_IMPLEMENTATION); using namespace toml; namespace #define TOML_ANON_NAMESPACE_START static_assert(TOML_IMPLEMENTATION); \
using namespace toml; \
namespace
#define TOML_ANON_NAMESPACE_END static_assert(true) #define TOML_ANON_NAMESPACE_END static_assert(true)
#define TOML_ANON_NAMESPACE #define TOML_ANON_NAMESPACE
#define TOML_EXTERNAL_LINKAGE #define TOML_EXTERNAL_LINKAGE
@ -1024,15 +1019,6 @@ TOML_NAMESPACE_START
class parse_result; class parse_result;
#endif #endif
TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS
TOML_NODISCARD
TOML_ATTR(const)
TOML_ALWAYS_INLINE
TOML_CONSTEVAL
size_t operator"" _sz(unsigned long long n) noexcept
{
return static_cast<size_t>(n);
}
} }
TOML_NAMESPACE_END; TOML_NAMESPACE_END;
@ -4736,14 +4722,13 @@ TOML_NAMESPACE_START
TOML_API TOML_API
array& operator=(array&& rhs) noexcept; array& operator=(array&& rhs) noexcept;
TOML_CONSTRAINED_TEMPLATE((sizeof...(ElemTypes) > 0_sz TOML_CONSTRAINED_TEMPLATE((sizeof...(ElemTypes) > 0 || !std::is_same_v<impl::remove_cvref_t<ElemType>, array>),
|| !std::is_same_v<impl::remove_cvref_t<ElemType>, array>),
typename ElemType, typename ElemType,
typename... ElemTypes) typename... ElemTypes)
TOML_NODISCARD_CTOR TOML_NODISCARD_CTOR
explicit array(ElemType&& val, ElemTypes&&... vals) explicit array(ElemType&& val, ElemTypes&&... vals)
{ {
elements.reserve(sizeof...(ElemTypes) + 1_sz); elements.reserve(sizeof...(ElemTypes) + 1u);
emplace_back_if_not_empty_view(static_cast<ElemType&&>(val)); emplace_back_if_not_empty_view(static_cast<ElemType&&>(val));
if constexpr (sizeof...(ElemTypes) > 0) if constexpr (sizeof...(ElemTypes) > 0)
{ {
@ -4949,7 +4934,7 @@ TOML_NAMESPACE_START
const auto start_idx = static_cast<size_t>(pos.raw_ - elements.cbegin()); const auto start_idx = static_cast<size_t>(pos.raw_ - elements.cbegin());
preinsertion_resize(start_idx, count); preinsertion_resize(start_idx, count);
size_t i = start_idx; size_t i = start_idx;
for (size_t e = start_idx + count - 1_sz; i < e; i++) for (size_t e = start_idx + count - 1u; i < e; i++)
elements[i].reset(impl::make_node(val)); elements[i].reset(impl::make_node(val));
elements[i].reset(impl::make_node(static_cast<ElemType&&>(val))); elements[i].reset(impl::make_node(static_cast<ElemType&&>(val)));
@ -5119,7 +5104,7 @@ TOML_NAMESPACE_START
if (lhs.size() != rhs.size()) if (lhs.size() != rhs.size())
return false; return false;
if (rhs.size() == 0_sz) if (rhs.size() == 0u)
return true; return true;
size_t i{}; size_t i{};
@ -5501,12 +5486,15 @@ TOML_NAMESPACE_START
} }
TOML_NODISCARD TOML_NODISCARD
TOML_API
bool is_homogeneous(node_type ntype) const noexcept final; bool is_homogeneous(node_type ntype) const noexcept final;
TOML_NODISCARD TOML_NODISCARD
TOML_API
bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept final; bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept final;
TOML_NODISCARD TOML_NODISCARD
TOML_API
bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept final; bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept final;
template <typename ElemType = void> template <typename ElemType = void>
@ -7528,7 +7516,7 @@ TOML_NAMESPACE_START
std::vector<std::string> key_path_; std::vector<std::string> key_path_;
bool pending_table_separator_ = false; bool pending_table_separator_ = false;
static constexpr size_t line_wrap_cols = 120_sz; static constexpr size_t line_wrap_cols = 120;
TOML_NODISCARD TOML_NODISCARD
TOML_API TOML_API
@ -8057,26 +8045,26 @@ TOML_IMPL_NAMESPACE_START
TOML_EXTERNAL_LINKAGE TOML_EXTERNAL_LINKAGE
void print_to_stream(std::ostream & stream, const toml::date& val) void print_to_stream(std::ostream & stream, const toml::date& val)
{ {
print_integer_leftpad_zeros(stream, val.year, 4_sz); print_integer_leftpad_zeros(stream, val.year, 4u);
stream.put('-'); stream.put('-');
print_integer_leftpad_zeros(stream, val.month, 2_sz); print_integer_leftpad_zeros(stream, val.month, 2u);
stream.put('-'); stream.put('-');
print_integer_leftpad_zeros(stream, val.day, 2_sz); print_integer_leftpad_zeros(stream, val.day, 2u);
} }
TOML_EXTERNAL_LINKAGE TOML_EXTERNAL_LINKAGE
void print_to_stream(std::ostream & stream, const toml::time& val) void print_to_stream(std::ostream & stream, const toml::time& val)
{ {
print_integer_leftpad_zeros(stream, val.hour, 2_sz); print_integer_leftpad_zeros(stream, val.hour, 2u);
stream.put(':'); stream.put(':');
print_integer_leftpad_zeros(stream, val.minute, 2_sz); print_integer_leftpad_zeros(stream, val.minute, 2u);
stream.put(':'); stream.put(':');
print_integer_leftpad_zeros(stream, val.second, 2_sz); print_integer_leftpad_zeros(stream, val.second, 2u);
if (val.nanosecond && val.nanosecond <= 999999999u) if (val.nanosecond && val.nanosecond <= 999999999u)
{ {
stream.put('.'); stream.put('.');
auto ns = val.nanosecond; auto ns = val.nanosecond;
size_t digits = 9_sz; size_t digits = 9u;
while (ns % 10u == 0u) while (ns % 10u == 0u)
{ {
ns /= 10u; ns /= 10u;
@ -8106,13 +8094,13 @@ TOML_IMPL_NAMESPACE_START
const auto hours = mins / 60; const auto hours = mins / 60;
if (hours) if (hours)
{ {
print_integer_leftpad_zeros(stream, static_cast<unsigned int>(hours), 2_sz); print_integer_leftpad_zeros(stream, static_cast<unsigned int>(hours), 2u);
mins -= hours * 60; mins -= hours * 60;
} }
else else
print_to_stream(stream, "00"sv); print_to_stream(stream, "00"sv);
stream.put(':'); stream.put(':');
print_integer_leftpad_zeros(stream, static_cast<unsigned int>(mins), 2_sz); print_integer_leftpad_zeros(stream, static_cast<unsigned int>(mins), 2u);
} }
TOML_EXTERNAL_LINKAGE TOML_EXTERNAL_LINKAGE
@ -8476,14 +8464,14 @@ TOML_NAMESPACE_START
void array::preinsertion_resize(size_t idx, size_t count) noexcept void array::preinsertion_resize(size_t idx, size_t count) noexcept
{ {
TOML_ASSERT(idx <= elements.size()); TOML_ASSERT(idx <= elements.size());
TOML_ASSERT(count >= 1_sz); TOML_ASSERT(count >= 1u);
const auto old_size = elements.size(); const auto old_size = elements.size();
const auto new_size = old_size + count; const auto new_size = old_size + count;
const auto inserting_at_end = idx == old_size; const auto inserting_at_end = idx == old_size;
elements.resize(new_size); elements.resize(new_size);
if (!inserting_at_end) if (!inserting_at_end)
{ {
for (size_t left = old_size, right = new_size - 1_sz; left-- > idx; right--) for (size_t left = old_size, right = new_size - 1u; left-- > idx; right--)
elements[right] = std::move(elements[left]); elements[right] = std::move(elements[left]);
} }
} }
@ -8547,7 +8535,7 @@ TOML_NAMESPACE_START
for (size_t i = 0, e = elements.size(); i < e; i++) for (size_t i = 0, e = elements.size(); i < e; i++)
{ {
auto arr = elements[i]->as_array(); auto arr = elements[i]->as_array();
leaves += arr ? arr->total_leaf_count() : 1_sz; leaves += arr ? arr->total_leaf_count() : size_t{ 1 };
} }
return leaves; return leaves;
} }
@ -8577,14 +8565,14 @@ TOML_NAMESPACE_START
bool requires_flattening = false; bool requires_flattening = false;
size_t size_after_flattening = elements.size(); size_t size_after_flattening = elements.size();
for (size_t i = elements.size(); i-- > 0_sz;) for (size_t i = elements.size(); i-- > 0u;)
{ {
auto arr = elements[i]->as_array(); auto arr = elements[i]->as_array();
if (!arr) if (!arr)
continue; continue;
size_after_flattening--; // discount the array itself size_after_flattening--; // discount the array itself
const auto leaf_count = arr->total_leaf_count(); const auto leaf_count = arr->total_leaf_count();
if (leaf_count > 0_sz) if (leaf_count > 0u)
{ {
requires_flattening = true; requires_flattening = true;
size_after_flattening += leaf_count; size_after_flattening += leaf_count;
@ -8610,8 +8598,8 @@ TOML_NAMESPACE_START
std::unique_ptr<node> arr_storage = std::move(elements[i]); std::unique_ptr<node> arr_storage = std::move(elements[i]);
const auto leaf_count = arr->total_leaf_count(); const auto leaf_count = arr->total_leaf_count();
if (leaf_count > 1_sz) if (leaf_count > 1u)
preinsertion_resize(i + 1_sz, leaf_count - 1_sz); preinsertion_resize(i + 1u, leaf_count - 1u);
flatten_child(std::move(*arr), i); // increments i flatten_child(std::move(*arr), i); // increments i
} }
@ -8814,7 +8802,7 @@ TOML_ANON_NAMESPACE_START
template <typename Char> template <typename Char>
class utf8_byte_stream<std::basic_string_view<Char>> class utf8_byte_stream<std::basic_string_view<Char>>
{ {
static_assert(sizeof(Char) == 1_sz); static_assert(sizeof(Char) == 1);
private: private:
std::basic_string_view<Char> source_; std::basic_string_view<Char> source_;
@ -8828,20 +8816,20 @@ TOML_ANON_NAMESPACE_START
// trim trailing nulls // trim trailing nulls
const size_t initial_len = source_.length(); const size_t initial_len = source_.length();
size_t actual_len = initial_len; size_t actual_len = initial_len;
for (size_t i = actual_len; i-- > 0_sz;) for (size_t i = actual_len; i-- > 0u;)
{ {
if (source_[i] != Char{}) // not '\0' if (source_[i] != Char{}) // not '\0'
{ {
actual_len = i + 1_sz; actual_len = i + 1u;
break; break;
} }
} }
if (initial_len != actual_len) if (initial_len != actual_len)
source_ = source_.substr(0_sz, actual_len); source_ = source_.substr(0u, actual_len);
// skip bom // skip bom
if (actual_len >= 3_sz && memcmp(utf8_byte_order_mark.data(), source_.data(), 3_sz) == 0) if (actual_len >= 3u && memcmp(utf8_byte_order_mark.data(), source_.data(), 3u) == 0)
position_ += 3_sz; position_ += 3u;
} }
TOML_NODISCARD TOML_NODISCARD
@ -8877,7 +8865,7 @@ TOML_ANON_NAMESPACE_START
template <typename Char> template <typename Char>
class utf8_byte_stream<std::basic_istream<Char>> class utf8_byte_stream<std::basic_istream<Char>>
{ {
static_assert(sizeof(Char) == 1_sz); static_assert(sizeof(Char) == 1);
private: private:
std::basic_istream<Char>* source_; std::basic_istream<Char>* source_;
@ -8893,7 +8881,7 @@ TOML_ANON_NAMESPACE_START
const auto initial_pos = source_->tellg(); const auto initial_pos = source_->tellg();
Char bom[3]; Char bom[3];
source_->read(bom, 3); source_->read(bom, 3);
if (source_->bad() || (source_->gcount() == 3 && memcmp(utf8_byte_order_mark.data(), bom, 3_sz) == 0)) if (source_->bad() || (source_->gcount() == 3 && memcmp(utf8_byte_order_mark.data(), bom, 3u) == 0))
return; return;
source_->clear(); source_->clear();
@ -8941,7 +8929,7 @@ TOML_ANON_NAMESPACE_START
TOML_NODISCARD TOML_NODISCARD
std::string_view as_view() const noexcept std::string_view as_view() const noexcept
{ {
return bytes[3] ? std::string_view{ bytes, 4_sz } : std::string_view{ bytes }; return bytes[3] ? std::string_view{ bytes, 4u } : std::string_view{ bytes };
} }
TOML_NODISCARD TOML_NODISCARD
@ -9032,7 +9020,7 @@ TOML_ANON_NAMESPACE_START
{ {
TOML_ERROR_CHECK; TOML_ERROR_CHECK;
auto& prev = codepoints_[(cp_idx_ - 1_sz) % 2_sz]; auto& prev = codepoints_[(cp_idx_ - 1u) % 2u];
if (stream_.eof()) if (stream_.eof())
return nullptr; return nullptr;
@ -9096,7 +9084,7 @@ TOML_ANON_NAMESPACE_START
TOML_ERROR_CHECK; TOML_ERROR_CHECK;
auto& current = codepoints_[cp_idx_ % 2_sz]; auto& current = codepoints_[cp_idx_ % 2u];
current.bytes[current_byte_count_++] = static_cast<char>(next_byte); current.bytes[current_byte_count_++] = static_cast<char>(next_byte);
if (decoder_.has_code_point()) if (decoder_.has_code_point())
{ {
@ -9725,7 +9713,7 @@ TOML_IMPL_NAMESPACE_START
TOML_NEVER_INLINE TOML_NEVER_INLINE
void set_error_at(source_position pos, const T&... reason) const TOML_MAY_THROW void set_error_at(source_position pos, const T&... reason) const TOML_MAY_THROW
{ {
static_assert(sizeof...(T) > 0_sz); static_assert(sizeof...(T) > 0);
#if !TOML_EXCEPTIONS #if !TOML_EXCEPTIONS
if (err) if (err)
return; return;
@ -9750,7 +9738,7 @@ TOML_IMPL_NAMESPACE_START
set_error_at(current_position(1), reason...); set_error_at(current_position(1), reason...);
} }
void go_back(size_t count = 1_sz) noexcept void go_back(size_t count = 1) noexcept
{ {
return_if_error(); return_if_error();
assert_or_assume(count); assert_or_assume(count);
@ -9793,7 +9781,7 @@ TOML_IMPL_NAMESPACE_START
recording_buffer.append(cp->as_view()); recording_buffer.append(cp->as_view());
} }
void stop_recording(size_t pop_bytes = 0_sz) noexcept void stop_recording(size_t pop_bytes = 0) noexcept
{ {
return_if_error(); return_if_error();
@ -9802,7 +9790,7 @@ TOML_IMPL_NAMESPACE_START
{ {
if (pop_bytes >= recording_buffer.length()) if (pop_bytes >= recording_buffer.length())
recording_buffer.clear(); recording_buffer.clear();
else if (pop_bytes == 1_sz) else if (pop_bytes == 1u)
recording_buffer.pop_back(); recording_buffer.pop_back();
else else
recording_buffer.erase(recording_buffer.begin() recording_buffer.erase(recording_buffer.begin()
@ -10081,7 +10069,7 @@ TOML_IMPL_NAMESPACE_START
if (multi_line) if (multi_line)
{ {
size_t lookaheads = {}; size_t lookaheads = {};
size_t consecutive_delimiters = 1_sz; size_t consecutive_delimiters = 1;
do do
{ {
advance_and_return_if_error({}); advance_and_return_if_error({});
@ -10091,30 +10079,30 @@ TOML_IMPL_NAMESPACE_START
else else
break; break;
} }
while (lookaheads < 4_sz); while (lookaheads < 4u);
switch (consecutive_delimiters) switch (consecutive_delimiters)
{ {
// """ " (one quote somewhere in a ML string) // """ " (one quote somewhere in a ML string)
case 1_sz: case 1:
str += '"'; str += '"';
skipping_whitespace = false; skipping_whitespace = false;
continue; continue;
// """ "" (two quotes somewhere in a ML string) // """ "" (two quotes somewhere in a ML string)
case 2_sz: case 2:
str.append("\"\""sv); str.append("\"\""sv);
skipping_whitespace = false; skipping_whitespace = false;
continue; continue;
// """ """ (the end of the string) // """ """ (the end of the string)
case 3_sz: return str; case 3: return str;
// """ """" (one at the end of the string) // """ """" (one at the end of the string)
case 4_sz: str += '"'; return str; case 4: str += '"'; return str;
// """ """"" (two quotes at the end of the string) // """ """"" (two quotes at the end of the string)
case 5_sz: case 5:
str.append("\"\""sv); str.append("\"\""sv);
advance_and_return_if_error({}); // skip the last '"' advance_and_return_if_error({}); // skip the last '"'
return str; return str;
@ -10210,7 +10198,7 @@ TOML_IMPL_NAMESPACE_START
if (multi_line) if (multi_line)
{ {
size_t lookaheads = {}; size_t lookaheads = {};
size_t consecutive_delimiters = 1_sz; size_t consecutive_delimiters = 1;
do do
{ {
advance_and_return_if_error({}); advance_and_return_if_error({});
@ -10220,24 +10208,24 @@ TOML_IMPL_NAMESPACE_START
else else
break; break;
} }
while (lookaheads < 4_sz); while (lookaheads < 4u);
switch (consecutive_delimiters) switch (consecutive_delimiters)
{ {
// ''' ' (one quote somewhere in a ML string) // ''' ' (one quote somewhere in a ML string)
case 1_sz: str += '\''; continue; case 1: str += '\''; continue;
// ''' '' (two quotes somewhere in a ML string) // ''' '' (two quotes somewhere in a ML string)
case 2_sz: str.append("''"sv); continue; case 2: str.append("''"sv); continue;
// ''' ''' (the end of the string) // ''' ''' (the end of the string)
case 3_sz: return str; case 3: return str;
// ''' '''' (one at the end of the string) // ''' '''' (one at the end of the string)
case 4_sz: str += '\''; return str; case 4: str += '\''; return str;
// ''' ''''' (two quotes at the end of the string) // ''' ''''' (two quotes at the end of the string)
case 5_sz: case 5:
str.append("''"sv); str.append("''"sv);
advance_and_return_if_error({}); // skip the last ' advance_and_return_if_error({}); // skip the last '
return str; return str;
@ -10320,7 +10308,7 @@ TOML_IMPL_NAMESPACE_START
{ {
// step back two characters so that the current // step back two characters so that the current
// character is the string delimiter // character is the string delimiter
go_back(2_sz); go_back(2u);
return { first == U'\'' ? parse_literal_string(false) : parse_basic_string(false), false }; return { first == U'\'' ? parse_literal_string(false) : parse_basic_string(false), false };
} }
@ -10630,7 +10618,7 @@ TOML_IMPL_NAMESPACE_START
set_error_and_return_default("expected exponent digit or sign, saw '"sv, to_sv(*cp), "'"sv); set_error_and_return_default("expected exponent digit or sign, saw '"sv, to_sv(*cp), "'"sv);
// 0x.p-0 (mantissa is just '.') // 0x.p-0 (mantissa is just '.')
else if (fragments[0].length == 0_sz && fragments[1].length == 0_sz) else if (fragments[0].length == 0u && fragments[1].length == 0u)
set_error_and_return_default("expected hexadecimal digit, saw '"sv, to_sv(*cp), "'"sv); set_error_and_return_default("expected hexadecimal digit, saw '"sv, to_sv(*cp), "'"sv);
else else
@ -10665,7 +10653,7 @@ TOML_IMPL_NAMESPACE_START
} }
// sanity-check ending state // sanity-check ending state
if (current_fragment != fragments + 2 || current_fragment->length == 0_sz) if (current_fragment != fragments + 2 || current_fragment->length == 0u)
{ {
set_error_and_return_if_eof({}); set_error_and_return_if_eof({});
set_error_and_return_default("missing exponent"sv); set_error_and_return_default("missing exponent"sv);
@ -10696,7 +10684,7 @@ TOML_IMPL_NAMESPACE_START
// calculate value // calculate value
auto place = 1u; auto place = 1u;
for (size_t i = 0; i < f.length - 1_sz; i++) for (size_t i = 0; i < f.length - 1u; i++)
place *= base; place *= base;
uint32_t val{}; uint32_t val{};
while (place) while (place)
@ -10810,7 +10798,7 @@ TOML_IMPL_NAMESPACE_START
} }
// single digits can be converted trivially // single digits can be converted trivially
if (length == 1_sz) if (length == 1u)
{ {
if constexpr (base == 16) if constexpr (base == 16)
return static_cast<int64_t>(hex_to_dec(chars[0])); return static_cast<int64_t>(hex_to_dec(chars[0]));
@ -10860,7 +10848,7 @@ TOML_IMPL_NAMESPACE_START
// "YYYY" // "YYYY"
uint32_t digits[4]; uint32_t digits[4];
if (!consume_digit_sequence(digits, 4_sz)) if (!consume_digit_sequence(digits, 4u))
set_error_and_return_default("expected 4-digit year, saw '"sv, to_sv(cp), "'"sv); set_error_and_return_default("expected 4-digit year, saw '"sv, to_sv(cp), "'"sv);
const auto year = digits[3] + digits[2] * 10u + digits[1] * 100u + digits[0] * 1000u; const auto year = digits[3] + digits[2] * 10u + digits[1] * 100u + digits[0] * 1000u;
const auto is_leap_year = (year % 4u == 0u) && ((year % 100u != 0u) || (year % 400u == 0u)); const auto is_leap_year = (year % 4u == 0u) && ((year % 100u != 0u) || (year % 400u == 0u));
@ -10872,7 +10860,7 @@ TOML_IMPL_NAMESPACE_START
advance_and_return_if_error_or_eof({}); advance_and_return_if_error_or_eof({});
// "MM" // "MM"
if (!consume_digit_sequence(digits, 2_sz)) if (!consume_digit_sequence(digits, 2u))
set_error_and_return_default("expected 2-digit month, saw '"sv, to_sv(cp), "'"sv); set_error_and_return_default("expected 2-digit month, saw '"sv, to_sv(cp), "'"sv);
const auto month = digits[1] + digits[0] * 10u; const auto month = digits[1] + digits[0] * 10u;
if (month == 0u || month > 12u) if (month == 0u || month > 12u)
@ -10889,7 +10877,7 @@ TOML_IMPL_NAMESPACE_START
advance_and_return_if_error_or_eof({}); advance_and_return_if_error_or_eof({});
// "DD" // "DD"
if (!consume_digit_sequence(digits, 2_sz)) if (!consume_digit_sequence(digits, 2u))
set_error_and_return_default("expected 2-digit day, saw '"sv, to_sv(cp), "'"sv); set_error_and_return_default("expected 2-digit day, saw '"sv, to_sv(cp), "'"sv);
const auto day = digits[1] + digits[0] * 10u; const auto day = digits[1] + digits[0] * 10u;
if (day == 0u || day > max_days_in_month) if (day == 0u || day > max_days_in_month)
@ -10912,11 +10900,11 @@ TOML_IMPL_NAMESPACE_START
assert_or_assume(is_decimal_digit(*cp)); assert_or_assume(is_decimal_digit(*cp));
push_parse_scope("time"sv); push_parse_scope("time"sv);
static constexpr auto max_digits = 9_sz; static constexpr size_t max_digits = 9;
uint32_t digits[max_digits]; uint32_t digits[max_digits];
// "HH" // "HH"
if (!consume_digit_sequence(digits, 2_sz)) if (!consume_digit_sequence(digits, 2u))
set_error_and_return_default("expected 2-digit hour, saw '"sv, to_sv(cp), "'"sv); set_error_and_return_default("expected 2-digit hour, saw '"sv, to_sv(cp), "'"sv);
const auto hour = digits[1] + digits[0] * 10u; const auto hour = digits[1] + digits[0] * 10u;
if (hour > 23u) if (hour > 23u)
@ -10930,7 +10918,7 @@ TOML_IMPL_NAMESPACE_START
advance_and_return_if_error_or_eof({}); advance_and_return_if_error_or_eof({});
// "MM" // "MM"
if (!consume_digit_sequence(digits, 2_sz)) if (!consume_digit_sequence(digits, 2u))
set_error_and_return_default("expected 2-digit minute, saw '"sv, to_sv(cp), "'"sv); set_error_and_return_default("expected 2-digit minute, saw '"sv, to_sv(cp), "'"sv);
const auto minute = digits[1] + digits[0] * 10u; const auto minute = digits[1] + digits[0] * 10u;
if (minute > 59u) if (minute > 59u)
@ -10954,7 +10942,7 @@ TOML_IMPL_NAMESPACE_START
advance_and_return_if_error_or_eof({}); advance_and_return_if_error_or_eof({});
// "SS" // "SS"
if (!consume_digit_sequence(digits, 2_sz)) if (!consume_digit_sequence(digits, 2u))
set_error_and_return_default("expected 2-digit second, saw '"sv, to_sv(cp), "'"sv); set_error_and_return_default("expected 2-digit second, saw '"sv, to_sv(cp), "'"sv);
const auto second = digits[1] + digits[0] * 10u; const auto second = digits[1] + digits[0] * 10u;
if (second > 59u) if (second > 59u)
@ -10970,7 +10958,7 @@ TOML_IMPL_NAMESPACE_START
advance_and_return_if_error_or_eof({}); advance_and_return_if_error_or_eof({});
// "FFFFFFFFF" // "FFFFFFFFF"
auto digit_count = consume_variable_length_digit_sequence(digits, max_digits); size_t digit_count = consume_variable_length_digit_sequence(digits, max_digits);
if (!digit_count) if (!digit_count)
{ {
set_error_and_return_if_eof({}); set_error_and_return_if_eof({});
@ -10987,7 +10975,7 @@ TOML_IMPL_NAMESPACE_START
uint32_t value = 0u; uint32_t value = 0u;
uint32_t place = 1u; uint32_t place = 1u;
for (auto i = digit_count; i-- > 0_sz;) for (auto i = digit_count; i-- > 0u;)
{ {
value += digits[i] * place; value += digits[i] * place;
place *= 10u; place *= 10u;
@ -11039,7 +11027,7 @@ TOML_IMPL_NAMESPACE_START
// "HH" // "HH"
int digits[2]; int digits[2];
if (!consume_digit_sequence(digits, 2_sz)) if (!consume_digit_sequence(digits, 2u))
set_error_and_return_default("expected 2-digit hour, saw '"sv, to_sv(cp), "'"sv); set_error_and_return_default("expected 2-digit hour, saw '"sv, to_sv(cp), "'"sv);
const auto hour = digits[1] + digits[0] * 10; const auto hour = digits[1] + digits[0] * 10;
if (hour > 23) if (hour > 23)
@ -11053,7 +11041,7 @@ TOML_IMPL_NAMESPACE_START
advance_and_return_if_error_or_eof({}); advance_and_return_if_error_or_eof({});
// "MM" // "MM"
if (!consume_digit_sequence(digits, 2_sz)) if (!consume_digit_sequence(digits, 2u))
set_error_and_return_default("expected 2-digit minute, saw '"sv, to_sv(cp), "'"sv); set_error_and_return_default("expected 2-digit minute, saw '"sv, to_sv(cp), "'"sv);
const auto minute = digits[1] + digits[0] * 10; const auto minute = digits[1] + digits[0] * 10;
if (minute > 59) if (minute > 59)
@ -11223,19 +11211,19 @@ TOML_IMPL_NAMESPACE_START
switch (static_cast<char32_t>(c | 32u)) switch (static_cast<char32_t>(c | 32u))
{ {
case U'b': case U'b':
if (char_count == 2_sz && has_any(begins_zero)) if (char_count == 2u && has_any(begins_zero))
add_trait(has_b); add_trait(has_b);
break; break;
case U'e': case U'e':
if (char_count > 1_sz if (char_count > 1u
&& has_none(has_b | has_o | has_p | has_t | has_x | has_z | has_colon) && has_none(has_b | has_o | has_p | has_t | has_x | has_z | has_colon)
&& (has_none(has_plus | has_minus) || has_any(begins_sign))) && (has_none(has_plus | has_minus) || has_any(begins_sign)))
add_trait(has_e); add_trait(has_e);
break; break;
case U'o': case U'o':
if (char_count == 2_sz && has_any(begins_zero)) if (char_count == 2u && has_any(begins_zero))
add_trait(has_o); add_trait(has_o);
break; break;
@ -11245,8 +11233,8 @@ TOML_IMPL_NAMESPACE_START
break; break;
case U'x': case U'x':
if ((char_count == 2_sz && has_any(begins_zero)) if ((char_count == 2u && has_any(begins_zero))
|| (char_count == 3_sz && has_any(begins_sign) && chars[1] == U'0')) || (char_count == 3u && has_any(begins_sign) && chars[1] == U'0'))
add_trait(has_x); add_trait(has_x);
break; break;
@ -11278,7 +11266,7 @@ TOML_IMPL_NAMESPACE_START
return_if_error({}); return_if_error({});
// force further scanning if this could have been a date-time with a space instead of a T // force further scanning if this could have been a date-time with a space instead of a T
if (char_count == 10_sz && traits == (bdigit_msk | has_minus) && chars[4] == U'-' && chars[7] == U'-' if (char_count == 10u && traits == (bdigit_msk | has_minus) && chars[4] == U'-' && chars[7] == U'-'
&& !is_eof() && *cp == U' ') && !is_eof() && *cp == U' ')
{ {
const auto pre_advance_count = advance_count; const auto pre_advance_count = advance_count;
@ -11291,7 +11279,7 @@ TOML_IMPL_NAMESPACE_START
go_back(advance_count - pre_advance_count); go_back(advance_count - pre_advance_count);
advance_count = pre_advance_count; advance_count = pre_advance_count;
traits = pre_scan_traits; traits = pre_scan_traits;
char_count = 10_sz; char_count = 10u;
}; };
advance_and_return_if_error({}); advance_and_return_if_error({});
@ -11309,19 +11297,19 @@ TOML_IMPL_NAMESPACE_START
scan(); scan();
return_if_error({}); return_if_error({});
if (char_count == 12_sz) if (char_count == 12u)
backpedal(); backpedal();
} }
} }
// set the reader back to where we started // set the reader back to where we started
go_back(advance_count); go_back(advance_count);
if (char_count < utf8_buffered_reader::max_history_length - 1_sz) if (char_count < utf8_buffered_reader::max_history_length - 1u)
chars[char_count] = U'\0'; chars[char_count] = U'\0';
// if after scanning ahead we still only have one value character, // if after scanning ahead we still only have one value character,
// the only valid value type is an integer. // the only valid value type is an integer.
if (char_count == 1_sz) if (char_count == 1u)
{ {
if (has_any(begins_zero | begins_digit)) if (has_any(begins_zero | begins_digit))
{ {
@ -11338,7 +11326,7 @@ TOML_IMPL_NAMESPACE_START
// now things that can be identified from two or more characters // now things that can be identified from two or more characters
return_if_error({}); return_if_error({});
assert_or_assume(char_count >= 2_sz); assert_or_assume(char_count >= 2u);
// do some 'fuzzy matching' where there's no ambiguity, since that allows the specific // do some 'fuzzy matching' where there's no ambiguity, since that allows the specific
// typed parse functions to take over and show better diagnostics if there's an issue // typed parse functions to take over and show better diagnostics if there's an issue
@ -11364,7 +11352,7 @@ TOML_IMPL_NAMESPACE_START
else if (has_any(begins_sign)) else if (has_any(begins_sign))
{ {
// single-digit signed integers // single-digit signed integers
if (char_count == 2_sz && has_any(has_digits)) if (char_count == 2u && has_any(has_digits))
{ {
val = new value{ static_cast<int64_t>(chars[1] - U'0') * (chars[0] == U'-' ? -1LL : 1LL) }; val = new value{ static_cast<int64_t>(chars[1] - U'0') * (chars[0] == U'-' ? -1LL : 1LL) };
advance(); // skip the sign advance(); // skip the sign
@ -11670,7 +11658,7 @@ TOML_IMPL_NAMESPACE_START
// get the key // get the key
start_recording(); start_recording();
auto key = parse_key(); auto key = parse_key();
stop_recording(1_sz); stop_recording(1u);
// skip past any whitespace that followed the key // skip past any whitespace that followed the key
consume_leading_whitespace(); consume_leading_whitespace();
@ -11736,7 +11724,7 @@ TOML_IMPL_NAMESPACE_START
// get the actual key // get the actual key
start_recording(); start_recording();
key = parse_key(); key = parse_key();
stop_recording(1_sz); stop_recording(1u);
return_if_error({}); return_if_error({});
// skip past any whitespace that followed the key // skip past any whitespace that followed the key
@ -11765,7 +11753,7 @@ TOML_IMPL_NAMESPACE_START
// check if each parent is a table/table array, or can be created implicitly as a table. // check if each parent is a table/table array, or can be created implicitly as a table.
auto parent = &root; auto parent = &root;
for (size_t i = 0; i < key.segments.size() - 1_sz; i++) for (size_t i = 0; i < key.segments.size() - 1u; i++)
{ {
auto child = parent->get(key.segments[i]); auto child = parent->get(key.segments[i]);
if (!child) if (!child)
@ -11893,13 +11881,13 @@ TOML_IMPL_NAMESPACE_START
auto kvp = parse_key_value_pair(); auto kvp = parse_key_value_pair();
return_if_error(); return_if_error();
TOML_ASSERT(kvp.key.segments.size() >= 1_sz); TOML_ASSERT(kvp.key.segments.size() >= 1u);
// if it's a dotted kvp we need to spawn the sub-tables if necessary, // if it's a dotted kvp we need to spawn the sub-tables if necessary,
// and set the target table to the second-to-last one in the chain // and set the target table to the second-to-last one in the chain
if (kvp.key.segments.size() > 1_sz) if (kvp.key.segments.size() > 1u)
{ {
for (size_t i = 0; i < kvp.key.segments.size() - 1_sz; i++) for (size_t i = 0; i < kvp.key.segments.size() - 1u; i++)
{ {
auto child = tab->get(kvp.key.segments[i]); auto child = tab->get(kvp.key.segments[i]);
if (!child) if (!child)
@ -12279,7 +12267,7 @@ TOML_ANON_NAMESPACE_START
// open file with a custom-sized stack buffer // open file with a custom-sized stack buffer
std::ifstream file; std::ifstream file;
char file_buffer[sizeof(void*) * 1024_sz]; char file_buffer[sizeof(void*) * 1024u];
file.rdbuf()->pubsetbuf(file_buffer, sizeof(file_buffer)); file.rdbuf()->pubsetbuf(file_buffer, sizeof(file_buffer));
file.open(file_path_str, std::ifstream::in | std::ifstream::binary | std::ifstream::ate); file.open(file_path_str, std::ifstream::in | std::ifstream::binary | std::ifstream::ate);
if (!file.is_open()) if (!file.is_open())
@ -12657,7 +12645,7 @@ TOML_NAMESPACE_START
if (requires_quotes) if (requires_quotes)
{ {
std::string s; std::string s;
s.reserve(str.length() + 2_sz); s.reserve(str.length() + 2u);
s += '"'; s += '"';
for (auto c : str) for (auto c : str)
{ {
@ -12687,11 +12675,11 @@ TOML_NAMESPACE_START
{ {
auto& n = *reinterpret_cast<const table*>(&node); auto& n = *reinterpret_cast<const table*>(&node);
if (n.empty()) if (n.empty())
return 2_sz; // "{}" return 2u; // "{}"
size_t weight = 3_sz; // "{ }" size_t weight = 3u; // "{ }"
for (auto&& [k, v] : n) for (auto&& [k, v] : n)
{ {
weight += k.length() + count_inline_columns(v) + 2_sz; // + ", " weight += k.length() + count_inline_columns(v) + 2u; // + ", "
if (weight >= line_wrap_cols) if (weight >= line_wrap_cols)
break; break;
} }
@ -12702,11 +12690,11 @@ TOML_NAMESPACE_START
{ {
auto& n = *reinterpret_cast<const array*>(&node); auto& n = *reinterpret_cast<const array*>(&node);
if (n.empty()) if (n.empty())
return 2_sz; // "[]" return 2u; // "[]"
size_t weight = 3_sz; // "[ ]" size_t weight = 3u; // "[ ]"
for (auto& elem : n) for (auto& elem : n)
{ {
weight += count_inline_columns(elem) + 2_sz; // + ", " weight += count_inline_columns(elem) + 2u; // + ", "
if (weight >= line_wrap_cols) if (weight >= line_wrap_cols)
break; break;
} }
@ -12716,7 +12704,7 @@ TOML_NAMESPACE_START
case node_type::string: case node_type::string:
{ {
auto& n = *reinterpret_cast<const value<std::string>*>(&node); auto& n = *reinterpret_cast<const value<std::string>*>(&node);
return n.get().length() + 2_sz; // + "" return n.get().length() + 2u; // + ""
} }
case node_type::integer: case node_type::integer:
@ -12724,14 +12712,14 @@ TOML_NAMESPACE_START
auto& n = *reinterpret_cast<const value<int64_t>*>(&node); auto& n = *reinterpret_cast<const value<int64_t>*>(&node);
auto v = n.get(); auto v = n.get();
if (!v) if (!v)
return 1_sz; return 1u;
size_t weight = {}; size_t weight = {};
if (v < 0) if (v < 0)
{ {
weight += 1; weight += 1u;
v *= -1; v *= -1;
} }
return weight + static_cast<size_t>(log10(static_cast<double>(v))) + 1_sz; return weight + static_cast<size_t>(log10(static_cast<double>(v))) + 1u;
} }
case node_type::floating_point: case node_type::floating_point:
@ -12739,21 +12727,21 @@ TOML_NAMESPACE_START
auto& n = *reinterpret_cast<const value<double>*>(&node); auto& n = *reinterpret_cast<const value<double>*>(&node);
auto v = n.get(); auto v = n.get();
if (v == 0.0) if (v == 0.0)
return 3_sz; // "0.0" return 3u; // "0.0"
size_t weight = 2_sz; // ".0" size_t weight = 2u; // ".0"
if (v < 0.0) if (v < 0.0)
{ {
weight += 1; weight += 1u;
v *= -1.0; v *= -1.0;
} }
return weight + static_cast<size_t>(log10(v)) + 1_sz; return weight + static_cast<size_t>(log10(v)) + 1u;
break; break;
} }
case node_type::boolean: return 5_sz; case node_type::boolean: return 5u;
case node_type::date: [[fallthrough]]; case node_type::date: [[fallthrough]];
case node_type::time: return 10_sz; case node_type::time: return 10u;
case node_type::date_time: return 30_sz; case node_type::date_time: return 30u;
case node_type::none: TOML_UNREACHABLE; case node_type::none: TOML_UNREACHABLE;
default: TOML_UNREACHABLE; default: TOML_UNREACHABLE;
} }
@ -12879,7 +12867,7 @@ TOML_NAMESPACE_START
for (size_t i = 0; i < arr.size(); i++) for (size_t i = 0; i < arr.size(); i++)
{ {
if (i > 0_sz) if (i > 0u)
{ {
impl::print_to_stream(base::stream(), ','); impl::print_to_stream(base::stream(), ',');
if (!multiline) if (!multiline)
@ -12921,7 +12909,7 @@ TOML_NAMESPACE_START
static constexpr auto is_non_inline_array_of_tables = [](auto&& nde) noexcept static constexpr auto is_non_inline_array_of_tables = [](auto&& nde) noexcept
{ {
auto arr = nde.as_array(); auto arr = nde.as_array();
return arr && arr->is_array_of_tables() && !arr->template get_as<table>(0_sz)->is_inline(); return arr && arr->is_array_of_tables() && !arr->template get_as<table>(0u)->is_inline();
}; };
// values, arrays, and inline tables/table arrays // values, arrays, and inline tables/table arrays
@ -12984,7 +12972,7 @@ TOML_NAMESPACE_START
} }
} }
bool skip_self = false; bool skip_self = false;
if (child_value_count == 0_sz && (child_table_count > 0_sz || child_table_array_count > 0_sz)) if (child_value_count == 0u && (child_table_count > 0u || child_table_array_count > 0u))
skip_self = true; skip_self = true;
key_path_.push_back(make_key_segment(k)); key_path_.push_back(make_key_segment(k));
@ -13121,7 +13109,7 @@ TOML_NAMESPACE_START
base::increase_indent(); base::increase_indent();
for (size_t i = 0; i < arr.size(); i++) for (size_t i = 0; i < arr.size(); i++)
{ {
if (i > 0_sz) if (i > 0u)
impl::print_to_stream(base::stream(), ','); impl::print_to_stream(base::stream(), ',');
base::print_newline(true); base::print_newline(true);
base::print_indent(); base::print_indent();
@ -13186,7 +13174,6 @@ TOML_POP_WARNINGS;
#undef TOML_COMPILER_EXCEPTIONS #undef TOML_COMPILER_EXCEPTIONS
#undef TOML_CONCAT #undef TOML_CONCAT
#undef TOML_CONCAT_1 #undef TOML_CONCAT_1
#undef TOML_CONSTEVAL
#undef TOML_CONSTRAINED_TEMPLATE #undef TOML_CONSTRAINED_TEMPLATE
#undef TOML_CPP #undef TOML_CPP
#undef TOML_DISABLE_ARITHMETIC_WARNINGS #undef TOML_DISABLE_ARITHMETIC_WARNINGS

View File

@ -10,6 +10,7 @@ REM ----------------------------------------------------------------------------
CALL :RunClangFormatOnDirectories ^ CALL :RunClangFormatOnDirectories ^
include\toml++ ^ include\toml++ ^
include\toml++\impl ^ include\toml++\impl ^
tests ^
examples examples
GOTO FINISH GOTO FINISH

View File

@ -412,16 +412,17 @@ def write_test_file(name, all_tests):
write = lambda txt,end='\n': print(txt, file=test_file, end=end) write = lambda txt,end='\n': print(txt, file=test_file, end=end)
# preamble # preamble
write('// This file is a part of toml++ and is subject to the the terms of the MIT license.') write(r'// This file is a part of toml++ and is subject to the the terms of the MIT license.')
write('// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>') write(r'// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>')
write('// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.') write(r'// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.')
write('// SPDX-License-Identifier: MIT') write(r'// SPDX-License-Identifier: MIT')
write('//-----') write(r'//-----')
write('// this file was generated by generate_conformance_tests.py - do not modify it directly') write(r'// this file was generated by generate_conformance_tests.py - do not modify it directly')
write('') write(r'// clang-format off')
write('#include "tests.h"') write(r'')
write('using namespace toml::impl;') write(r'#include "tests.h"')
write('') write(r'using namespace toml::impl;')
write(r'')
# test data # test data
write('TOML_DISABLE_WARNINGS; // unused variable spam') write('TOML_DISABLE_WARNINGS; // unused variable spam')

View File

@ -151,11 +151,11 @@ def main():
<Natvis Include="..\..\toml++.natvis" /> <Natvis Include="..\..\toml++.natvis" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\catch2.h" />
<ClInclude Include="..\leakproof.h" /> <ClInclude Include="..\leakproof.h" />
<ClInclude Include="..\lib_catch2.h" />
<ClInclude Include="..\lib_tloptional.h" />
<ClInclude Include="..\settings.h" /> <ClInclude Include="..\settings.h" />
<ClInclude Include="..\tests.h" /> <ClInclude Include="..\tests.h" />
<ClInclude Include="..\tloptional.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\cpp.hint" /> <None Include="..\cpp.hint" />