mirror of
https://github.com/marzer/tomlplusplus.git
synced 2026-01-19 04:52:09 +00:00
added prune() to table and array
This commit is contained in:
@@ -37,6 +37,7 @@ code changes at callsites or in build systems are indicated with ⚠️.
|
||||
- added `operator->` to `toml::value` for class types
|
||||
- added `parse_benchmark` example
|
||||
- added `toml::array::at()` (same semantics as `std::vector::at()`)
|
||||
- added `toml::array::prune()`
|
||||
- added `toml::array::replace()` (#109) (@LebJe)
|
||||
- added `toml::array::resize()` param `default_init_flags`
|
||||
- added `toml::format_flags::allow_binary_integers`
|
||||
@@ -50,6 +51,7 @@ code changes at callsites or in build systems are indicated with ⚠️.
|
||||
- added `toml::table::at()` (same semantics as `std::map::at()`)
|
||||
- added `toml::table::emplace_hint()` (same semantics as `std::map::emplace_hint()`)
|
||||
- added `toml::table::lower_bound()` (same semantics as `std::map::lower_bound()`)
|
||||
- added `toml::table::prune()`
|
||||
- added `toml::yaml_formatter`
|
||||
- added `TOML_ENABLE_FORMATTERS` option
|
||||
- added clang's enum annotation attributes to all enums
|
||||
|
||||
@@ -1339,12 +1339,43 @@ TOML_NAMESPACE_START
|
||||
/// \brief Flattens this array, recursively hoisting the contents of child arrays up into itself (rvalue overload).
|
||||
///
|
||||
/// \returns An rvalue reference to the array.
|
||||
TOML_API
|
||||
array&& flatten() &&
|
||||
{
|
||||
return static_cast<toml::array&&>(this->flatten());
|
||||
}
|
||||
|
||||
/// \brief Removes empty child arrays and tables.
|
||||
///
|
||||
/// \detail \cpp
|
||||
///
|
||||
/// auto arr = toml::array{ 1, 2, toml::array{ }, toml::array{ 3, toml::array{ } }, 4 };
|
||||
/// std::cout << arr << "\n";
|
||||
///
|
||||
/// arr.prune();
|
||||
/// std::cout << arr << "\n";
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// [ 1, 2, [], [ 3, [] ], 4 ]
|
||||
/// [ 1, 2, [ 3 ], 4 ]
|
||||
/// \eout
|
||||
///
|
||||
/// \param recursive Should child arrays and tables themselves be pruned?
|
||||
///
|
||||
/// \returns A reference to the array.
|
||||
TOML_API
|
||||
array& prune(bool recursive = true) & noexcept;
|
||||
|
||||
/// \brief Removes empty child arrays and tables (rvalue overload).
|
||||
///
|
||||
/// \param recursive Should child arrays and tables themselves be pruned?
|
||||
///
|
||||
/// \returns An rvalue reference to the array.
|
||||
array&& prune(bool recursive = true) && noexcept
|
||||
{
|
||||
return static_cast<toml::array&&>(this->prune(recursive));
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
private:
|
||||
|
||||
@@ -243,6 +243,33 @@ TOML_NAMESPACE_START
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
array& array::prune(bool recursive)& noexcept
|
||||
{
|
||||
if (elems_.empty())
|
||||
return *this;
|
||||
|
||||
for (size_t i = elems_.size(); i-- > 0u;)
|
||||
{
|
||||
if (auto arr = elems_[i]->as_array())
|
||||
{
|
||||
if (recursive)
|
||||
arr->prune(true);
|
||||
if (arr->empty())
|
||||
elems_.erase(elems_.cbegin() + static_cast<ptrdiff_t>(i));
|
||||
}
|
||||
else if (auto tbl = elems_[i]->as_table())
|
||||
{
|
||||
if (recursive)
|
||||
tbl->prune(true);
|
||||
if (tbl->empty())
|
||||
elems_.erase(elems_.cbegin() + static_cast<ptrdiff_t>(i));
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
|
||||
@@ -98,7 +98,6 @@ TOML_NAMESPACE_START
|
||||
class toml_formatter;
|
||||
class json_formatter;
|
||||
class yaml_formatter;
|
||||
class xml_formatter;
|
||||
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex);
|
||||
#if TOML_EXCEPTIONS
|
||||
|
||||
@@ -1555,6 +1555,38 @@ TOML_NAMESPACE_START
|
||||
|
||||
#endif // TOML_ENABLE_WINDOWS_COMPAT
|
||||
|
||||
/// \brief Removes empty child arrays and tables.
|
||||
///
|
||||
/// \detail \cpp
|
||||
///
|
||||
/// auto tbl = toml::table{ { "a", 1 }, { "b", toml::array{ } }, { "c", toml::array{ toml::table{}, toml::array{} } } };
|
||||
/// std::cout << arr << "\n";
|
||||
///
|
||||
/// arr.prune();
|
||||
/// std::cout << arr << "\n";
|
||||
/// \ecpp
|
||||
///
|
||||
/// \out
|
||||
/// { a = 1, b = [], c = [ {}, [] ] }
|
||||
/// { a = 1 }
|
||||
/// \eout
|
||||
///
|
||||
/// \param recursive Should child arrays and tables themselves be pruned?
|
||||
///
|
||||
/// \returns A reference to the table.
|
||||
TOML_API
|
||||
table& prune(bool recursive = true) & noexcept;
|
||||
|
||||
/// \brief Removes empty child arrays and tables (rvalue overload).
|
||||
///
|
||||
/// \param recursive Should child arrays and tables themselves be pruned?
|
||||
///
|
||||
/// \returns An rvalue reference to the table.
|
||||
table&& prune(bool recursive = true) && noexcept
|
||||
{
|
||||
return static_cast<toml::table&&>(this->prune(recursive));
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
private:
|
||||
|
||||
@@ -204,6 +204,42 @@ TOML_NAMESPACE_START
|
||||
{
|
||||
return const_iterator{ map_.lower_bound(key) };
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table& table::prune(bool recursive)& noexcept
|
||||
{
|
||||
if (map_.empty())
|
||||
return *this;
|
||||
|
||||
for (auto it = map_.begin(); it != map_.end();)
|
||||
{
|
||||
if (auto arr = it->second->as_array())
|
||||
{
|
||||
if (recursive)
|
||||
arr->prune(true);
|
||||
|
||||
if (arr->empty())
|
||||
{
|
||||
it = map_.erase(it);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (auto tbl = it->second->as_table())
|
||||
{
|
||||
if (recursive)
|
||||
tbl->prune(true);
|
||||
|
||||
if (tbl->empty())
|
||||
{
|
||||
it = map_.erase(it);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
it++;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ TOML_DISABLE_SUGGEST_ATTR_WARNINGS;
|
||||
#include "impl/value.h"
|
||||
#include "impl/make_node.h"
|
||||
#include "impl/array.h"
|
||||
#include "impl/key.h"
|
||||
#include "impl/table.h"
|
||||
#include "impl/utf8.h"
|
||||
#include "impl/parse_error.h"
|
||||
|
||||
@@ -441,16 +441,16 @@ TEST_CASE("arrays - insertion and erasure")
|
||||
|
||||
arr.clear();
|
||||
it = arr.insert(arr.cbegin(), L"test");
|
||||
REQUIRE(*arr.get_as<std::string>(0u) == "test"sv);
|
||||
CHECK(*arr.get_as<std::string>(0u) == "test"sv);
|
||||
|
||||
it = arr.emplace<std::string>(arr.cbegin(), L"test2"sv);
|
||||
REQUIRE(*arr.get_as<std::string>(0u) == "test2"sv);
|
||||
CHECK(*arr.get_as<std::string>(0u) == "test2"sv);
|
||||
|
||||
arr.push_back(L"test3"s);
|
||||
REQUIRE(*arr.back().as_string() == "test3"sv);
|
||||
CHECK(*arr.back().as_string() == "test3"sv);
|
||||
|
||||
arr.emplace_back<std::string>(L"test4");
|
||||
REQUIRE(*arr.back().as_string() == "test4"sv);
|
||||
CHECK(*arr.back().as_string() == "test4"sv);
|
||||
|
||||
#endif // TOML_ENABLE_WINDOWS_COMPAT
|
||||
}
|
||||
@@ -475,7 +475,7 @@ TEST_CASE("arrays - flattening")
|
||||
11 },
|
||||
};
|
||||
arr.flatten();
|
||||
REQUIRE(arr == array{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 });
|
||||
CHECK(arr == array{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 });
|
||||
}
|
||||
|
||||
{
|
||||
@@ -484,37 +484,53 @@ TEST_CASE("arrays - flattening")
|
||||
array{ array{}, array{ array{}, array{} }, array{} },
|
||||
array{ array{ array{ array{ array{ array{ 1 } } } } } } };
|
||||
arr.flatten();
|
||||
REQUIRE(arr == array{ 1 });
|
||||
CHECK(arr == array{ 1 });
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("arrays - pruning")
|
||||
{
|
||||
// [ 1, [ 2, [], 3 ], { 4 = 5, 6 = 7 }, [], 8, [{}], 9, 10 ]
|
||||
const auto arr =
|
||||
array{ 1, array{ 2, array{}, 3 }, table{ { "4", 5 }, { "6", array{} } }, array{}, 8, array{ table{} }, 9, 10 };
|
||||
|
||||
// [ 1, [ 2, 3 ], { 4 = 5, 6 = 7 }, 8, 9, 10 ]
|
||||
const auto pruned_recursive = array{ 1, array{ 2, 3 }, table{ { "4", 5 } }, 8, 9, 10 };
|
||||
CHECK(array{ arr }.prune(true) == pruned_recursive);
|
||||
|
||||
// [ 1, [ 2, [], 3 ], { 4 = 5, 6 = 7 }, [], 8, [{}], 9, 10 ]
|
||||
const auto pruned_flat =
|
||||
array{ 1, array{ 2, array{}, 3 }, table{ { "4", 5 }, { "6", array{} } }, 8, array{ table{} }, 9, 10 };
|
||||
CHECK(array{ arr }.prune(false) == pruned_flat);
|
||||
}
|
||||
|
||||
TEST_CASE("arrays - resizing and truncation")
|
||||
{
|
||||
array arr{ 1, 2, 3, 4, 5 };
|
||||
REQUIRE(arr.size() == 5u);
|
||||
CHECK(arr.size() == 5u);
|
||||
|
||||
// truncate with no change
|
||||
arr.truncate(5u);
|
||||
REQUIRE(arr.size() == 5u);
|
||||
REQUIRE(arr == array{ 1, 2, 3, 4, 5 });
|
||||
CHECK(arr.size() == 5u);
|
||||
CHECK(arr == array{ 1, 2, 3, 4, 5 });
|
||||
|
||||
// truncate down to three elements
|
||||
arr.truncate(3u);
|
||||
REQUIRE(arr.size() == 3u);
|
||||
REQUIRE(arr == array{ 1, 2, 3 });
|
||||
CHECK(arr.size() == 3u);
|
||||
CHECK(arr == array{ 1, 2, 3 });
|
||||
|
||||
// resize down to two elements
|
||||
arr.resize(2u, 42);
|
||||
REQUIRE(arr.size() == 2u);
|
||||
REQUIRE(arr == array{ 1, 2 });
|
||||
CHECK(arr.size() == 2u);
|
||||
CHECK(arr == array{ 1, 2 });
|
||||
|
||||
// resize with no change
|
||||
arr.resize(2u, 42);
|
||||
REQUIRE(arr.size() == 2u);
|
||||
REQUIRE(arr == array{ 1, 2 });
|
||||
CHECK(arr.size() == 2u);
|
||||
CHECK(arr == array{ 1, 2 });
|
||||
|
||||
// resize up to six elements
|
||||
arr.resize(6u, 42);
|
||||
REQUIRE(arr.size() == 6u);
|
||||
REQUIRE(arr == array{ 1, 2, 42, 42, 42, 42 });
|
||||
CHECK(arr.size() == 6u);
|
||||
CHECK(arr == array{ 1, 2, 42, 42, 42, 42 });
|
||||
}
|
||||
|
||||
94
toml.hpp
94
toml.hpp
@@ -1112,7 +1112,6 @@ TOML_NAMESPACE_START
|
||||
class toml_formatter;
|
||||
class json_formatter;
|
||||
class yaml_formatter;
|
||||
class xml_formatter;
|
||||
|
||||
TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex);
|
||||
#if TOML_EXCEPTIONS
|
||||
@@ -5540,12 +5539,19 @@ TOML_NAMESPACE_START
|
||||
TOML_API
|
||||
array& flatten() &;
|
||||
|
||||
TOML_API
|
||||
array&& flatten() &&
|
||||
{
|
||||
return static_cast<toml::array&&>(this->flatten());
|
||||
}
|
||||
|
||||
TOML_API
|
||||
array& prune(bool recursive = true) & noexcept;
|
||||
|
||||
array&& prune(bool recursive = true) && noexcept
|
||||
{
|
||||
return static_cast<toml::array&&>(this->prune(recursive));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
TOML_NODISCARD
|
||||
@@ -5625,12 +5631,8 @@ TOML_NAMESPACE_END;
|
||||
#endif
|
||||
TOML_POP_WARNINGS;
|
||||
|
||||
//******** impl/table.h **********************************************************************************************
|
||||
//******** impl/key.h ************************************************************************************************
|
||||
|
||||
TOML_DISABLE_WARNINGS;
|
||||
#include <map>
|
||||
#include <iterator>
|
||||
TOML_ENABLE_WARNINGS;
|
||||
TOML_PUSH_WARNINGS;
|
||||
#ifdef _MSC_VER
|
||||
#pragma push_macro("min")
|
||||
@@ -5863,6 +5865,13 @@ TOML_IMPL_NAMESPACE_END;
|
||||
#pragma pop_macro("max")
|
||||
#endif
|
||||
TOML_POP_WARNINGS;
|
||||
|
||||
//******** impl/table.h **********************************************************************************************
|
||||
|
||||
TOML_DISABLE_WARNINGS;
|
||||
#include <map>
|
||||
#include <iterator>
|
||||
TOML_ENABLE_WARNINGS;
|
||||
TOML_PUSH_WARNINGS;
|
||||
#ifdef _MSC_VER
|
||||
#pragma push_macro("min")
|
||||
@@ -6779,6 +6788,14 @@ TOML_NAMESPACE_START
|
||||
|
||||
#endif // TOML_ENABLE_WINDOWS_COMPAT
|
||||
|
||||
TOML_API
|
||||
table& prune(bool recursive = true) & noexcept;
|
||||
|
||||
table&& prune(bool recursive = true) && noexcept
|
||||
{
|
||||
return static_cast<toml::table&&>(this->prune(recursive));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
TOML_NODISCARD
|
||||
@@ -9770,6 +9787,33 @@ TOML_NAMESPACE_START
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
array& array::prune(bool recursive)& noexcept
|
||||
{
|
||||
if (elems_.empty())
|
||||
return *this;
|
||||
|
||||
for (size_t i = elems_.size(); i-- > 0u;)
|
||||
{
|
||||
if (auto arr = elems_[i]->as_array())
|
||||
{
|
||||
if (recursive)
|
||||
arr->prune(true);
|
||||
if (arr->empty())
|
||||
elems_.erase(elems_.cbegin() + static_cast<ptrdiff_t>(i));
|
||||
}
|
||||
else if (auto tbl = elems_[i]->as_table())
|
||||
{
|
||||
if (recursive)
|
||||
tbl->prune(true);
|
||||
if (tbl->empty())
|
||||
elems_.erase(elems_.cbegin() + static_cast<ptrdiff_t>(i));
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
@@ -9978,6 +10022,42 @@ TOML_NAMESPACE_START
|
||||
{
|
||||
return const_iterator{ map_.lower_bound(key) };
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
table& table::prune(bool recursive)& noexcept
|
||||
{
|
||||
if (map_.empty())
|
||||
return *this;
|
||||
|
||||
for (auto it = map_.begin(); it != map_.end();)
|
||||
{
|
||||
if (auto arr = it->second->as_array())
|
||||
{
|
||||
if (recursive)
|
||||
arr->prune(true);
|
||||
|
||||
if (arr->empty())
|
||||
{
|
||||
it = map_.erase(it);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (auto tbl = it->second->as_table())
|
||||
{
|
||||
if (recursive)
|
||||
tbl->prune(true);
|
||||
|
||||
if (tbl->empty())
|
||||
{
|
||||
it = map_.erase(it);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
it++;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user