Merge pull request #557 from biojppm/fix/556_python_tree

Improve behaviour of tree creation and Tree::root_id().
This commit is contained in:
jpmag
2025-12-03 08:52:49 +00:00
committed by GitHub
12 changed files with 105 additions and 54 deletions

View File

@@ -0,0 +1,13 @@
import ryml
def test_create_empty_tree():
tree = ryml.Tree(0)
assert tree.empty()
def test_create_tree():
tree = ryml.Tree()
assert not tree.empty()
root = tree.root_id()
tree.to_seq(root)

View File

@@ -597,10 +597,11 @@ using id_type = RYML_ID_TYPE;
struct Tree
{
Tree();
Tree(id_type node_type, size_t arena_capacity=RYML_DEFAULT_TREE_ARENA_CAPACITY);
~Tree();
void reserve(id_type node_capacity);
void reserve_arena(size_t arena_capacity);
void reserve(id_type node_capacity=RYML_DEFAULT_TREE_CAPACITY);
void reserve_arena(size_t arena_capacity=RYML_DEFAULT_TREE_ARENA_CAPACITY);
void clear();
void clear_arena();

View File

@@ -6,3 +6,17 @@
---
more data here
```
- [PR#557](https://github.com/biojppm/rapidyaml/pull/557) - `Tree` is now non-empty by default, and `Tree::root_id()` will no longer modify the tree when it is empty. To create an empty tree now it is necessary to use the capacity constructor with a capacity of zero:
```c++
// default-constructed tree is now non-empty
Tree tree;
assert(!tree.empty()); // MODIFIED! was empty on previous version
id_type root = tree.root_id(); // OK. default-constructed tree is now non-empty
// to create an empty tree:
Tree tree(0); // pass capacity of zero
assert(tree.empty()); // as expected
// but watchout, this is no longer possible:
//id_type root = tree.root_id(); // ERROR: cannot get root of empty tree.
```
This changeset also enables the python library to call `root_id()` on a default-constructed tree (fixes [#556](https://github.com/biojppm/rapidyaml/issues/556)).

View File

@@ -3911,7 +3911,7 @@ void sample_float_precision()
// have to build the container.
//
// First a function to check the result:
auto check_precision = [&](ryml::Tree serialized){
auto check_precision = [&](ryml::Tree const& serialized){
std::cout << serialized;
// now it works!
CHECK((ryml::emitrs_yaml<std::string>(serialized) == R"(- 1.23234412342131239

View File

@@ -22,6 +22,16 @@
//-----------------------------------------------------------------------------
#ifndef RYML_DEFAULT_TREE_CAPACITY
/// default capacity for the tree when not set explicitly
#define RYML_DEFAULT_TREE_CAPACITY (16)
#endif
#ifndef RYML_DEFAULT_TREE_ARENA_CAPACITY
/// default capacity for the tree's arena when not set explicitly
#define RYML_DEFAULT_TREE_ARENA_CAPACITY (0)
#endif
#ifndef RYML_ERRMSG_SIZE
/// size for the error message buffer
#define RYML_ERRMSG_SIZE (1024)

View File

@@ -49,8 +49,8 @@ void parse_json_in_place(Parser *parser, csubstr filename, substr json, Tree *t,
// this is vertically aligned to highlight the parameter differences.
void parse_in_place(Parser *parser, substr yaml, Tree *t, id_type node_id) { parse_in_place(parser, {}, yaml, t, node_id); }
void parse_in_place(Parser *parser, csubstr filename, substr yaml, Tree *t ) { RYML_CHECK(t); parse_in_place(parser, filename, yaml, t, t->root_id()); }
void parse_in_place(Parser *parser, substr yaml, Tree *t ) { RYML_CHECK(t); parse_in_place(parser, {} , yaml, t, t->root_id()); }
void parse_in_place(Parser *parser, csubstr filename, substr yaml, Tree *t ) { RYML_CHECK(t); if(t->empty()) { t->reserve(); } parse_in_place(parser, filename, yaml, t, t->root_id()); }
void parse_in_place(Parser *parser, substr yaml, Tree *t ) { RYML_CHECK(t); if(t->empty()) { t->reserve(); } parse_in_place(parser, {} , yaml, t, t->root_id()); }
void parse_in_place(Parser *parser, csubstr filename, substr yaml, NodeRef node ) { RYML_CHECK(!node.invalid()); parse_in_place(parser, filename, yaml, node.tree(), node.id()); }
void parse_in_place(Parser *parser, substr yaml, NodeRef node ) { RYML_CHECK(!node.invalid()); parse_in_place(parser, {} , yaml, node.tree(), node.id()); }
Tree parse_in_place(Parser *parser, csubstr filename, substr yaml ) { RYML_CHECK(parser); RYML_CHECK(parser->m_evt_handler); Tree tree(parser->callbacks()); parse_in_place(parser, filename, yaml, &tree, tree.root_id()); return tree; }
@@ -59,8 +59,8 @@ Tree parse_in_place(Parser *parser, substr yaml
// this is vertically aligned to highlight the parameter differences.
void parse_in_place(csubstr filename, substr yaml, Tree *t, id_type node_id) { RYML_CHECK(t); Parser::handler_type event_handler(t->callbacks()); Parser parser(&event_handler); parse_in_place(&parser, filename, yaml, t, node_id); }
void parse_in_place( substr yaml, Tree *t, id_type node_id) { RYML_CHECK(t); Parser::handler_type event_handler(t->callbacks()); Parser parser(&event_handler); parse_in_place(&parser, {} , yaml, t, node_id); }
void parse_in_place(csubstr filename, substr yaml, Tree *t ) { RYML_CHECK(t); Parser::handler_type event_handler(t->callbacks()); Parser parser(&event_handler); parse_in_place(&parser, filename, yaml, t, t->root_id()); }
void parse_in_place( substr yaml, Tree *t ) { RYML_CHECK(t); Parser::handler_type event_handler(t->callbacks()); Parser parser(&event_handler); parse_in_place(&parser, {} , yaml, t, t->root_id()); }
void parse_in_place(csubstr filename, substr yaml, Tree *t ) { RYML_CHECK(t); Parser::handler_type event_handler(t->callbacks()); Parser parser(&event_handler); if(t->empty()) { t->reserve(); } parse_in_place(&parser, filename, yaml, t, t->root_id()); }
void parse_in_place( substr yaml, Tree *t ) { RYML_CHECK(t); Parser::handler_type event_handler(t->callbacks()); Parser parser(&event_handler); if(t->empty()) { t->reserve(); } parse_in_place(&parser, {} , yaml, t, t->root_id()); }
void parse_in_place(csubstr filename, substr yaml, NodeRef node ) { RYML_CHECK(!node.invalid()); Parser::handler_type event_handler(node.tree()->callbacks()); Parser parser(&event_handler); parse_in_place(&parser, filename, yaml, node.tree(), node.id()); }
void parse_in_place( substr yaml, NodeRef node ) { RYML_CHECK(!node.invalid()); Parser::handler_type event_handler(node.tree()->callbacks()); Parser parser(&event_handler); parse_in_place(&parser, {} , yaml, node.tree(), node.id()); }
Tree parse_in_place(csubstr filename, substr yaml ) { Parser::handler_type event_handler; Parser parser(&event_handler); Tree tree(parser.callbacks()); parse_in_place(&parser, filename, yaml, &tree, tree.root_id()); return tree; }
@@ -69,8 +69,8 @@ Tree parse_in_place( substr yaml ) { P
// this is vertically aligned to highlight the parameter differences.
void parse_json_in_place(Parser *parser, substr json, Tree *t, id_type node_id) { parse_json_in_place(parser, {}, json, t, node_id); }
void parse_json_in_place(Parser *parser, csubstr filename, substr json, Tree *t ) { RYML_CHECK(t); parse_json_in_place(parser, filename, json, t, t->root_id()); }
void parse_json_in_place(Parser *parser, substr json, Tree *t ) { RYML_CHECK(t); parse_json_in_place(parser, {} , json, t, t->root_id()); }
void parse_json_in_place(Parser *parser, csubstr filename, substr json, Tree *t ) { RYML_CHECK(t); if(t->empty()) { t->reserve(); } parse_json_in_place(parser, filename, json, t, t->root_id()); }
void parse_json_in_place(Parser *parser, substr json, Tree *t ) { RYML_CHECK(t); if(t->empty()) { t->reserve(); } parse_json_in_place(parser, {} , json, t, t->root_id()); }
void parse_json_in_place(Parser *parser, csubstr filename, substr json, NodeRef node ) { RYML_CHECK(!node.invalid()); parse_json_in_place(parser, filename, json, node.tree(), node.id()); }
void parse_json_in_place(Parser *parser, substr json, NodeRef node ) { RYML_CHECK(!node.invalid()); parse_json_in_place(parser, {} , json, node.tree(), node.id()); }
Tree parse_json_in_place(Parser *parser, csubstr filename, substr json ) { RYML_CHECK(parser); RYML_CHECK(parser->m_evt_handler); Tree tree(parser->callbacks()); parse_json_in_place(parser, filename, json, &tree, tree.root_id()); return tree; }
@@ -79,8 +79,8 @@ Tree parse_json_in_place(Parser *parser, substr json
// this is vertically aligned to highlight the parameter differences.
void parse_json_in_place(csubstr filename, substr json, Tree *t, id_type node_id) { RYML_CHECK(t); Parser::handler_type event_handler(t->callbacks()); Parser parser(&event_handler); parse_json_in_place(&parser, filename, json, t, node_id); }
void parse_json_in_place( substr json, Tree *t, id_type node_id) { RYML_CHECK(t); Parser::handler_type event_handler(t->callbacks()); Parser parser(&event_handler); parse_json_in_place(&parser, {} , json, t, node_id); }
void parse_json_in_place(csubstr filename, substr json, Tree *t ) { RYML_CHECK(t); Parser::handler_type event_handler(t->callbacks()); Parser parser(&event_handler); parse_json_in_place(&parser, filename, json, t, t->root_id()); }
void parse_json_in_place( substr json, Tree *t ) { RYML_CHECK(t); Parser::handler_type event_handler(t->callbacks()); Parser parser(&event_handler); parse_json_in_place(&parser, {} , json, t, t->root_id()); }
void parse_json_in_place(csubstr filename, substr json, Tree *t ) { RYML_CHECK(t); Parser::handler_type event_handler(t->callbacks()); Parser parser(&event_handler); if(t->empty()) { t->reserve(); } parse_json_in_place(&parser, filename, json, t, t->root_id()); }
void parse_json_in_place( substr json, Tree *t ) { RYML_CHECK(t); Parser::handler_type event_handler(t->callbacks()); Parser parser(&event_handler); if(t->empty()) { t->reserve(); } parse_json_in_place(&parser, {} , json, t, t->root_id()); }
void parse_json_in_place(csubstr filename, substr json, NodeRef node ) { RYML_CHECK(!node.invalid()); Parser::handler_type event_handler(node.tree()->callbacks()); Parser parser(&event_handler); parse_json_in_place(&parser, filename, json, node.tree(), node.id()); }
void parse_json_in_place( substr json, NodeRef node ) { RYML_CHECK(!node.invalid()); Parser::handler_type event_handler(node.tree()->callbacks()); Parser parser(&event_handler); parse_json_in_place(&parser, {} , json, node.tree(), node.id()); }
Tree parse_json_in_place(csubstr filename, substr json ) { Parser::handler_type event_handler; Parser parser(&event_handler); Tree tree(parser.callbacks()); parse_json_in_place(&parser, filename, json, &tree, tree.root_id()); return tree; }
@@ -90,8 +90,8 @@ Tree parse_json_in_place( substr json
// this is vertically aligned to highlight the parameter differences.
void parse_in_arena(Parser *parser, csubstr filename, csubstr yaml, Tree *t, id_type node_id) { RYML_CHECK(t); substr src = t->copy_to_arena(yaml); parse_in_place(parser, filename, src, t, node_id); }
void parse_in_arena(Parser *parser, csubstr yaml, Tree *t, id_type node_id) { RYML_CHECK(t); substr src = t->copy_to_arena(yaml); parse_in_place(parser, {} , src, t, node_id); }
void parse_in_arena(Parser *parser, csubstr filename, csubstr yaml, Tree *t ) { RYML_CHECK(t); substr src = t->copy_to_arena(yaml); parse_in_place(parser, filename, src, t, t->root_id()); }
void parse_in_arena(Parser *parser, csubstr yaml, Tree *t ) { RYML_CHECK(t); substr src = t->copy_to_arena(yaml); parse_in_place(parser, {} , src, t, t->root_id()); }
void parse_in_arena(Parser *parser, csubstr filename, csubstr yaml, Tree *t ) { RYML_CHECK(t); substr src = t->copy_to_arena(yaml); if(t->empty()) { t->reserve(); } parse_in_place(parser, filename, src, t, t->root_id()); }
void parse_in_arena(Parser *parser, csubstr yaml, Tree *t ) { RYML_CHECK(t); substr src = t->copy_to_arena(yaml); if(t->empty()) { t->reserve(); } parse_in_place(parser, {} , src, t, t->root_id()); }
void parse_in_arena(Parser *parser, csubstr filename, csubstr yaml, NodeRef node ) { RYML_CHECK(!node.invalid()); substr src = node.tree()->copy_to_arena(yaml); parse_in_place(parser, filename, src, node.tree(), node.id()); }
void parse_in_arena(Parser *parser, csubstr yaml, NodeRef node ) { RYML_CHECK(!node.invalid()); substr src = node.tree()->copy_to_arena(yaml); parse_in_place(parser, {} , src, node.tree(), node.id()); }
Tree parse_in_arena(Parser *parser, csubstr filename, csubstr yaml ) { RYML_CHECK(parser); RYML_CHECK(parser->m_evt_handler); Tree tree(parser->callbacks()); substr src = tree.copy_to_arena(yaml); parse_in_place(parser, filename, src, &tree, tree.root_id()); return tree; }
@@ -100,8 +100,8 @@ Tree parse_in_arena(Parser *parser, csubstr yaml
// this is vertically aligned to highlight the parameter differences.
void parse_in_arena(csubstr filename, csubstr yaml, Tree *t, id_type node_id) { RYML_CHECK(t); Parser::handler_type event_handler(t->callbacks()); Parser parser(&event_handler); substr src = t->copy_to_arena(yaml); parse_in_place(&parser, filename, src, t, node_id); }
void parse_in_arena( csubstr yaml, Tree *t, id_type node_id) { RYML_CHECK(t); Parser::handler_type event_handler(t->callbacks()); Parser parser(&event_handler); substr src = t->copy_to_arena(yaml); parse_in_place(&parser, {} , src, t, node_id); }
void parse_in_arena(csubstr filename, csubstr yaml, Tree *t ) { RYML_CHECK(t); Parser::handler_type event_handler(t->callbacks()); Parser parser(&event_handler); substr src = t->copy_to_arena(yaml); parse_in_place(&parser, filename, src, t, t->root_id()); }
void parse_in_arena( csubstr yaml, Tree *t ) { RYML_CHECK(t); Parser::handler_type event_handler(t->callbacks()); Parser parser(&event_handler); substr src = t->copy_to_arena(yaml); parse_in_place(&parser, {} , src, t, t->root_id()); }
void parse_in_arena(csubstr filename, csubstr yaml, Tree *t ) { RYML_CHECK(t); Parser::handler_type event_handler(t->callbacks()); Parser parser(&event_handler); substr src = t->copy_to_arena(yaml); if(t->empty()) { t->reserve(); } parse_in_place(&parser, filename, src, t, t->root_id()); }
void parse_in_arena( csubstr yaml, Tree *t ) { RYML_CHECK(t); Parser::handler_type event_handler(t->callbacks()); Parser parser(&event_handler); substr src = t->copy_to_arena(yaml); if(t->empty()) { t->reserve(); } parse_in_place(&parser, {} , src, t, t->root_id()); }
void parse_in_arena(csubstr filename, csubstr yaml, NodeRef node ) { RYML_CHECK(!node.invalid()); Parser::handler_type event_handler(node.tree()->callbacks()); Parser parser(&event_handler); substr src = node.tree()->copy_to_arena(yaml); parse_in_place(&parser, filename, src, node.tree(), node.id()); }
void parse_in_arena( csubstr yaml, NodeRef node ) { RYML_CHECK(!node.invalid()); Parser::handler_type event_handler(node.tree()->callbacks()); Parser parser(&event_handler); substr src = node.tree()->copy_to_arena(yaml); parse_in_place(&parser, {} , src, node.tree(), node.id()); }
Tree parse_in_arena(csubstr filename, csubstr yaml ) { Parser::handler_type event_handler; Parser parser(&event_handler); Tree tree(parser.callbacks()); substr src = tree.copy_to_arena(yaml); parse_in_place(&parser, filename, src, &tree, tree.root_id()); return tree; }
@@ -111,8 +111,8 @@ Tree parse_in_arena( csubstr yaml ) {
// this is vertically aligned to highlight the parameter differences.
void parse_json_in_arena(Parser *parser, csubstr filename, csubstr json, Tree *t, id_type node_id) { RYML_CHECK(t); substr src = t->copy_to_arena(json); parse_json_in_place(parser, filename, src, t, node_id); }
void parse_json_in_arena(Parser *parser, csubstr json, Tree *t, id_type node_id) { RYML_CHECK(t); substr src = t->copy_to_arena(json); parse_json_in_place(parser, {} , src, t, node_id); }
void parse_json_in_arena(Parser *parser, csubstr filename, csubstr json, Tree *t ) { RYML_CHECK(t); substr src = t->copy_to_arena(json); parse_json_in_place(parser, filename, src, t, t->root_id()); }
void parse_json_in_arena(Parser *parser, csubstr json, Tree *t ) { RYML_CHECK(t); substr src = t->copy_to_arena(json); parse_json_in_place(parser, {} , src, t, t->root_id()); }
void parse_json_in_arena(Parser *parser, csubstr filename, csubstr json, Tree *t ) { RYML_CHECK(t); substr src = t->copy_to_arena(json); if(t->empty()) { t->reserve(); } parse_json_in_place(parser, filename, src, t, t->root_id()); }
void parse_json_in_arena(Parser *parser, csubstr json, Tree *t ) { RYML_CHECK(t); substr src = t->copy_to_arena(json); if(t->empty()) { t->reserve(); } parse_json_in_place(parser, {} , src, t, t->root_id()); }
void parse_json_in_arena(Parser *parser, csubstr filename, csubstr json, NodeRef node ) { RYML_CHECK(!node.invalid()); substr src = node.tree()->copy_to_arena(json); parse_json_in_place(parser, filename, src, node.tree(), node.id()); }
void parse_json_in_arena(Parser *parser, csubstr json, NodeRef node ) { RYML_CHECK(!node.invalid()); substr src = node.tree()->copy_to_arena(json); parse_json_in_place(parser, {} , src, node.tree(), node.id()); }
Tree parse_json_in_arena(Parser *parser, csubstr filename, csubstr json ) { RYML_CHECK(parser); RYML_CHECK(parser->m_evt_handler); Tree tree(parser->callbacks()); substr src = tree.copy_to_arena(json); parse_json_in_place(parser, filename, src, &tree, tree.root_id()); return tree; }
@@ -121,8 +121,8 @@ Tree parse_json_in_arena(Parser *parser, csubstr json
// this is vertically aligned to highlight the parameter differences.
void parse_json_in_arena(csubstr filename, csubstr json, Tree *t, id_type node_id) { RYML_CHECK(t); Parser::handler_type event_handler(t->callbacks()); Parser parser(&event_handler); substr src = t->copy_to_arena(json); parse_json_in_place(&parser, filename, src, t, node_id); }
void parse_json_in_arena( csubstr json, Tree *t, id_type node_id) { RYML_CHECK(t); Parser::handler_type event_handler(t->callbacks()); Parser parser(&event_handler); substr src = t->copy_to_arena(json); parse_json_in_place(&parser, {} , src, t, node_id); }
void parse_json_in_arena(csubstr filename, csubstr json, Tree *t ) { RYML_CHECK(t); Parser::handler_type event_handler(t->callbacks()); Parser parser(&event_handler); substr src = t->copy_to_arena(json); parse_json_in_place(&parser, filename, src, t, t->root_id()); }
void parse_json_in_arena( csubstr json, Tree *t ) { RYML_CHECK(t); Parser::handler_type event_handler(t->callbacks()); Parser parser(&event_handler); substr src = t->copy_to_arena(json); parse_json_in_place(&parser, {} , src, t, t->root_id()); }
void parse_json_in_arena(csubstr filename, csubstr json, Tree *t ) { RYML_CHECK(t); Parser::handler_type event_handler(t->callbacks()); Parser parser(&event_handler); substr src = t->copy_to_arena(json); if(t->empty()) { t->reserve(); } parse_json_in_place(&parser, filename, src, t, t->root_id()); }
void parse_json_in_arena( csubstr json, Tree *t ) { RYML_CHECK(t); Parser::handler_type event_handler(t->callbacks()); Parser parser(&event_handler); substr src = t->copy_to_arena(json); if(t->empty()) { t->reserve(); } parse_json_in_place(&parser, {} , src, t, t->root_id()); }
void parse_json_in_arena(csubstr filename, csubstr json, NodeRef node ) { RYML_CHECK(!node.invalid()); Parser::handler_type event_handler(node.tree()->callbacks()); Parser parser(&event_handler); substr src = node.tree()->copy_to_arena(json); parse_json_in_place(&parser, filename, src, node.tree(), node.id()); }
void parse_json_in_arena( csubstr json, NodeRef node ) { RYML_CHECK(!node.invalid()); Parser::handler_type event_handler(node.tree()->callbacks()); Parser parser(&event_handler); substr src = node.tree()->copy_to_arena(json); parse_json_in_place(&parser, {} , src, node.tree(), node.id()); }
Tree parse_json_in_arena(csubstr filename, csubstr json ) { Parser::handler_type event_handler; Parser parser(&event_handler); Tree tree(parser.callbacks()); substr src = tree.copy_to_arena(json); parse_json_in_place(&parser, filename, src, &tree, tree.root_id()); return tree; }

View File

@@ -10,6 +10,7 @@ C4_SUPPRESS_WARNING_GCC_CLANG_WITH_PUSH("-Wold-style-cast")
C4_SUPPRESS_WARNING_GCC("-Wtype-limits")
C4_SUPPRESS_WARNING_GCC("-Wuseless-cast")
namespace c4 {
namespace yml {
@@ -82,6 +83,11 @@ ConstNodeRef Tree::cdocref(id_type i) const
//-----------------------------------------------------------------------------
Tree::Tree(Callbacks const& cb)
: Tree(RYML_DEFAULT_TREE_CAPACITY, RYML_DEFAULT_TREE_ARENA_CAPACITY, cb)
{
}
Tree::Tree(id_type node_capacity, size_t arena_capacity, Callbacks const& cb)
: m_buf(nullptr)
, m_cap(0)
, m_size(0)
@@ -92,13 +98,10 @@ Tree::Tree(Callbacks const& cb)
, m_callbacks(cb)
, m_tag_directives()
{
}
Tree::Tree(id_type node_capacity, size_t arena_capacity, Callbacks const& cb)
: Tree(cb)
{
reserve(node_capacity);
reserve_arena(arena_capacity);
if(node_capacity)
reserve(node_capacity);
if(arena_capacity)
reserve_arena(arena_capacity);
}
Tree::~Tree()
@@ -107,11 +110,18 @@ Tree::~Tree()
}
Tree::Tree(Tree const& that) : Tree(that.m_callbacks)
Tree::Tree(Tree const& that) : m_callbacks(that.m_callbacks)
{
_clear();
_copy(that);
}
Tree::Tree(Tree && that) noexcept : m_callbacks(that.m_callbacks)
{
_clear();
_move(that);
}
Tree& Tree::operator= (Tree const& that)
{
if(&that != this)
@@ -123,11 +133,6 @@ Tree& Tree::operator= (Tree const& that)
return *this;
}
Tree::Tree(Tree && that) noexcept : Tree(that.m_callbacks)
{
_move(that);
}
Tree& Tree::operator= (Tree && that) noexcept
{
if(&that != this)

View File

@@ -33,7 +33,6 @@ C4_SUPPRESS_WARNING_GCC_CLANG("-Wold-style-cast")
C4_SUPPRESS_WARNING_GCC("-Wuseless-cast")
C4_SUPPRESS_WARNING_GCC("-Wtype-limits")
namespace c4 {
namespace yml {
@@ -206,7 +205,7 @@ public:
Tree() : Tree(get_callbacks()) {}
Tree(Callbacks const& cb);
Tree(id_type node_capacity, size_t arena_capacity=0) : Tree(node_capacity, arena_capacity, get_callbacks()) {}
Tree(id_type node_capacity, size_t arena_capacity=RYML_DEFAULT_TREE_ARENA_CAPACITY) : Tree(node_capacity, arena_capacity, get_callbacks()) {}
Tree(id_type node_capacity, size_t arena_capacity, Callbacks const& cb);
~Tree();
@@ -224,7 +223,7 @@ public:
/** @name memory and sizing */
/** @{ */
void reserve(id_type node_capacity);
void reserve(id_type node_capacity=RYML_DEFAULT_TREE_CAPACITY);
/** clear the tree and zero every node
* @note does NOT clear the arena
@@ -284,10 +283,8 @@ public:
//! This function is implementation only; use at your own risk.
NodeData const * _p(id_type node) const { _RYML_CB_ASSERT(m_callbacks, node != NONE && node >= 0 && node < m_cap); return m_buf + node; }
//! Get the id of the root node
id_type root_id() { if(m_cap == 0) { reserve(16); } _RYML_CB_ASSERT(m_callbacks, m_cap > 0 && m_size > 0); return 0; }
//! Get the id of the root node
id_type root_id() const { _RYML_CB_ASSERT(m_callbacks, m_cap > 0 && m_size > 0); return 0; }
//! Get the id of the root node. The tree must not be empty.
id_type root_id() const { _RYML_CB_ASSERT(m_callbacks, m_cap > 0 && m_size > 0); return 0; }
//! Get a NodeRef of a node by id
NodeRef ref(id_type node);
@@ -313,17 +310,17 @@ public:
//! @note @p i is NOT the node id, but the doc position within the stream
ConstNodeRef cdocref(id_type i) const;
//! find a root child by name, return it as a NodeRef
//! find a root child (ie child of root) by name, return it as a NodeRef
//! @note requires the root to be a map.
NodeRef operator[] (csubstr key);
//! find a root child by name, return it as a NodeRef
//! find a root child (ie child of root) by name, return it as a NodeRef
//! @note requires the root to be a map.
ConstNodeRef operator[] (csubstr key) const;
//! find a root child by index: return the root node's @p i-th child as a NodeRef
//! find a root child (ie child of root) by index: return the root node's @p i-th child as a NodeRef
//! @note @p i is NOT the node id, but the child's position
NodeRef operator[] (id_type i);
//! find a root child by index: return the root node's @p i-th child as a NodeRef
//! find a root child (ie child of root) by index: return the root node's @p i-th child as a NodeRef
//! @note @p i is NOT the node id, but the child's position
ConstNodeRef operator[] (id_type i) const;
@@ -971,7 +968,7 @@ public:
* @warning This operation may be expensive, with a potential complexity of O(numNodes)+O(arenasize).
* @warning Growing the arena may cause relocation of the entire
* existing arena, and thus change the contents of individual nodes. */
void reserve_arena(size_t arena_cap)
void reserve_arena(size_t arena_cap=RYML_DEFAULT_TREE_ARENA_CAPACITY)
{
if(arena_cap > m_arena.len)
{

View File

@@ -492,7 +492,7 @@ TEST(CaseNode, anchors)
TEST(simple_anchor, resolve_works_on_an_empty_tree)
{
Tree t;
Tree t(0);
t.resolve();
EXPECT_TRUE(t.empty());
}

View File

@@ -310,7 +310,7 @@ struct CaseDataLineEndings
std::vector<char> src_buf;
substr src;
Tree parsed_tree;
Tree parsed_tree{0};
size_t numbytes_stdout;
size_t numbytes_stdout_json;
@@ -327,10 +327,10 @@ struct CaseDataLineEndings
std::string parse_buf_json;
substr parsed_json;
Tree emitted_tree;
Tree emitted_tree_json;
Tree emitted_tree{0};
Tree emitted_tree_json{0};
Tree recreated;
Tree recreated{0};
std::string parse_buf_ints;
std::vector<int> parsed_ints;

View File

@@ -547,7 +547,7 @@ TEST(tag_directives, resolve_tags)
TEST(tag_directives, safe_with_empty_tree)
{
Tree t;
Tree t(0);
t.resolve_tags();
EXPECT_TRUE(t.empty());
}

View File

@@ -592,17 +592,28 @@ TEST(Tree, empty_ctor)
{
Tree tree;
EXPECT_EQ(tree.callbacks(), get_callbacks());
EXPECT_EQ(tree.empty(), true);
EXPECT_EQ(tree.capacity(), 0u);
EXPECT_EQ(tree.empty(), RYML_DEFAULT_TREE_CAPACITY == 0);
EXPECT_EQ(tree.capacity(), RYML_DEFAULT_TREE_CAPACITY);
EXPECT_EQ(tree.size(), RYML_DEFAULT_TREE_CAPACITY != 0); // the root
EXPECT_EQ(tree.slack(), RYML_DEFAULT_TREE_CAPACITY ? RYML_DEFAULT_TREE_CAPACITY - 1u : 0);
EXPECT_EQ(tree.arena_capacity(), 0u);
EXPECT_EQ(tree.arena_slack(), 0u);
EXPECT_EQ(tree.size(), 0u);
EXPECT_EQ(tree.slack(), 0u);
EXPECT_EQ(tree.arena().empty(), true);
}
TEST(Tree, node_cap_ctor)
{
{
Tree tree(0u);
EXPECT_EQ(tree.callbacks(), get_callbacks());
EXPECT_EQ(tree.empty(), true);
EXPECT_EQ(tree.capacity(), 0u);
EXPECT_EQ(tree.arena_capacity(), 0u);
EXPECT_EQ(tree.arena_slack(), 0u);
EXPECT_EQ(tree.size(), 0u);
EXPECT_EQ(tree.slack(), 0u);
EXPECT_EQ(tree.arena().empty(), true);
}
{
Tree tree(10u);
EXPECT_EQ(tree.callbacks(), get_callbacks());