Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add remaining std::string_view overloads #2

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
257 changes: 257 additions & 0 deletions src/pugixml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,24 @@ PUGI_IMPL_NS_BEGIN
#endif
}

#ifdef PUGIXML_HAS_STRING_VIEW
// Check if the null-terminated dst string is equal to the entire contents of srcview
PUGI_IMPL_FN bool stringview_equal(string_view_t srcview, const char_t* dst)
{
// std::basic_string_view::compare(const char*) has the right behavior, but it performs an
// extra traversal of dst to compute its length.
assert(dst);
const char_t* src = srcview.data();
size_t srclen = srcview.size();

while (srclen && *dst && *src == *dst)
{
--srclen; ++dst; ++src;
}
return srclen == 0 && *dst == 0;
}
#endif

// Compare lhs with [rhs_begin, rhs_end)
PUGI_IMPL_FN bool strequalrange(const char_t* lhs, const char_t* rhs, size_t count)
{
Expand Down Expand Up @@ -5413,6 +5431,14 @@ namespace pugi
return *this;
}

#ifdef PUGIXML_HAS_STRING_VIEW
PUGI_IMPL_FN xml_attribute& xml_attribute::operator=(string_view_t rhs)
{
set_value(rhs);
return *this;
}
#endif

#ifdef PUGIXML_HAS_LONG_LONG
PUGI_IMPL_FN xml_attribute& xml_attribute::operator=(long long rhs)
{
Expand Down Expand Up @@ -5736,6 +5762,64 @@ namespace pugi
return xml_node();
}

#ifdef PUGIXML_HAS_STRING_VIEW
PUGI_IMPL_FN xml_node xml_node::child(string_view_t name_) const
{
if (!_root) return xml_node();

for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling)
{
const char_t* iname = i->name;
if (iname && impl::stringview_equal(name_, iname))
return xml_node(i);
}

return xml_node();
}

PUGI_IMPL_FN xml_attribute xml_node::attribute(string_view_t name_) const
{
if (!_root) return xml_attribute();

for (xml_attribute_struct* i = _root->first_attribute; i; i = i->next_attribute)
{
const char_t* iname = i->name;
if (iname && impl::stringview_equal(name_, iname))
return xml_attribute(i);
}

return xml_attribute();
}

PUGI_IMPL_FN xml_node xml_node::next_sibling(string_view_t name_) const
{
if (!_root) return xml_node();

for (xml_node_struct* i = _root->next_sibling; i; i = i->next_sibling)
{
const char_t* iname = i->name;
if (iname && impl::stringview_equal(name_, iname))
return xml_node(i);
}

return xml_node();
}

PUGI_IMPL_FN xml_node xml_node::previous_sibling(string_view_t name_) const
{
if (!_root) return xml_node();

for (xml_node_struct* i = _root->prev_sibling_c; i->next_sibling; i = i->prev_sibling_c)
{
const char_t* iname = i->name;
if (iname && impl::stringview_equal(name_, iname))
return xml_node(i);
}

return xml_node();
}
#endif

PUGI_IMPL_FN xml_attribute xml_node::attribute(const char_t* name_, xml_attribute& hint_) const
{
xml_attribute_struct* hint = hint_._attr;
Expand Down Expand Up @@ -5775,6 +5859,47 @@ namespace pugi
return xml_attribute();
}

#ifdef PUGIXML_HAS_STRING_VIEW
PUGI_IMPL_FN xml_attribute xml_node::attribute(string_view_t name_, xml_attribute& hint_) const
{
xml_attribute_struct* hint = hint_._attr;

// if hint is not an attribute of node, behavior is not defined
assert(!hint || (_root && impl::is_attribute_of(hint, _root)));

if (!_root) return xml_attribute();

// optimistically search from hint up until the end
for (xml_attribute_struct* i = hint; i; i = i->next_attribute)
{
const char_t* iname = i->name;
if (iname && impl::stringview_equal(name_, iname))
{
// update hint to maximize efficiency of searching for consecutive attributes
hint_._attr = i->next_attribute;

return xml_attribute(i);
}
}

// wrap around and search from the first attribute until the hint
// 'j' null pointer check is technically redundant, but it prevents a crash in case the assertion above fails
for (xml_attribute_struct* j = _root->first_attribute; j && j != hint; j = j->next_attribute)
{
const char_t* jname = j->name;
if (jname && impl::stringview_equal(name_, jname))
{
// update hint to maximize efficiency of searching for consecutive attributes
hint_._attr = j->next_attribute;

return xml_attribute(j);
}
}

return xml_attribute();
}
#endif

PUGI_IMPL_FN xml_node xml_node::previous_sibling() const
{
if (!_root) return xml_node();
Expand Down Expand Up @@ -5980,6 +6105,78 @@ namespace pugi
return a;
}

#ifdef PUGIXML_HAS_STRING_VIEW
PUGI_IMPL_FN xml_attribute xml_node::append_attribute(string_view_t name_)
{
if (!impl::allow_insert_attribute(type())) return xml_attribute();

impl::xml_allocator& alloc = impl::get_allocator(_root);
if (!alloc.reserve()) return xml_attribute();

xml_attribute a(impl::allocate_attribute(alloc));
if (!a) return xml_attribute();

impl::append_attribute(a._attr, _root);

a.set_name(name_);

return a;
}

PUGI_IMPL_FN xml_attribute xml_node::prepend_attribute(string_view_t name_)
{
if (!impl::allow_insert_attribute(type())) return xml_attribute();

impl::xml_allocator& alloc = impl::get_allocator(_root);
if (!alloc.reserve()) return xml_attribute();

xml_attribute a(impl::allocate_attribute(alloc));
if (!a) return xml_attribute();

impl::prepend_attribute(a._attr, _root);

a.set_name(name_);

return a;
}

PUGI_IMPL_FN xml_attribute xml_node::insert_attribute_after(string_view_t name_, const xml_attribute& attr)
{
if (!impl::allow_insert_attribute(type())) return xml_attribute();
if (!attr || !impl::is_attribute_of(attr._attr, _root)) return xml_attribute();

impl::xml_allocator& alloc = impl::get_allocator(_root);
if (!alloc.reserve()) return xml_attribute();

xml_attribute a(impl::allocate_attribute(alloc));
if (!a) return xml_attribute();

impl::insert_attribute_after(a._attr, attr._attr, _root);

a.set_name(name_);

return a;
}

PUGI_IMPL_FN xml_attribute xml_node::insert_attribute_before(string_view_t name_, const xml_attribute& attr)
{
if (!impl::allow_insert_attribute(type())) return xml_attribute();
if (!attr || !impl::is_attribute_of(attr._attr, _root)) return xml_attribute();

impl::xml_allocator& alloc = impl::get_allocator(_root);
if (!alloc.reserve()) return xml_attribute();

xml_attribute a(impl::allocate_attribute(alloc));
if (!a) return xml_attribute();

impl::insert_attribute_before(a._attr, attr._attr, _root);

a.set_name(name_);

return a;
}
#endif

PUGI_IMPL_FN xml_attribute xml_node::append_copy(const xml_attribute& proto)
{
if (!proto) return xml_attribute();
Expand Down Expand Up @@ -6156,6 +6353,44 @@ namespace pugi
return result;
}

#ifdef PUGIXML_HAS_STRING_VIEW
PUGI_IMPL_FN xml_node xml_node::append_child(string_view_t name_)
{
xml_node result = append_child(node_element);

result.set_name(name_);

return result;
}

PUGI_IMPL_FN xml_node xml_node::prepend_child(string_view_t name_)
{
xml_node result = prepend_child(node_element);

result.set_name(name_);

return result;
}

PUGI_IMPL_FN xml_node xml_node::insert_child_after(string_view_t name_, const xml_node& node)
{
xml_node result = insert_child_after(node_element, node);

result.set_name(name_);

return result;
}

PUGI_IMPL_FN xml_node xml_node::insert_child_before(string_view_t name_, const xml_node& node)
{
xml_node result = insert_child_before(node_element, node);

result.set_name(name_);

return result;
}
#endif

PUGI_IMPL_FN xml_node xml_node::append_copy(const xml_node& proto)
{
xml_node_type type_ = proto.type();
Expand Down Expand Up @@ -6299,6 +6534,13 @@ namespace pugi
return remove_attribute(attribute(name_));
}

#ifdef PUGIXML_HAS_STRING_VIEW
PUGI_IMPL_FN bool xml_node::remove_attribute(string_view_t name_)
{
return remove_attribute(attribute(name_));
}
#endif

PUGI_IMPL_FN bool xml_node::remove_attribute(const xml_attribute& a)
{
if (!_root || !a._attr) return false;
Expand Down Expand Up @@ -6339,6 +6581,13 @@ namespace pugi
return remove_child(child(name_));
}

#ifdef PUGIXML_HAS_STRING_VIEW
PUGI_IMPL_FN bool xml_node::remove_child(string_view_t name_)
{
return remove_child(child(name_));
}
#endif

PUGI_IMPL_FN bool xml_node::remove_child(const xml_node& n)
{
if (!_root || !n._root || n._root->parent != _root) return false;
Expand Down Expand Up @@ -6935,6 +7184,14 @@ namespace pugi
return *this;
}

#ifdef PUGIXML_HAS_STRING_VIEW
PUGI_IMPL_FN xml_text& xml_text::operator=(string_view_t rhs)
{
set(rhs);
return *this;
}
#endif

#ifdef PUGIXML_HAS_LONG_LONG
PUGI_IMPL_FN xml_text& xml_text::operator=(long long rhs)
{
Expand Down
Loading