From 6766f35338fafca445faf3c8a271ef558d6ec963 Mon Sep 17 00:00:00 2001 From: halex2005 Date: Tue, 14 Apr 2015 00:56:23 +0500 Subject: add align each attribute on new line support with format_indent_attribute --- src/pugixml.cpp | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'src/pugixml.cpp') diff --git a/src/pugixml.cpp b/src/pugixml.cpp index 7c463cc..bf5835f 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -3480,13 +3480,26 @@ PUGI__NS_BEGIN } } - PUGI__FN void node_output_attributes(xml_buffered_writer& writer, xml_node_struct* node, unsigned int flags) + PUGI__FN void node_output_attributes(xml_buffered_writer &writer, xml_node_struct *node, const char_t *indent, size_t indent_length, unsigned int flags, unsigned int depth) { const char_t* default_name = PUGIXML_TEXT(":anonymous"); + bool eachAttributeOnNewLine = PUGI__NODETYPE(node) != node_declaration + && (flags & format_indent) + && (flags & format_each_attribute_on_new_line) + && (flags & format_raw) == 0; + for (xml_attribute_struct* a = node->first_attribute; a; a = a->next_attribute) { - writer.write(' '); + if (eachAttributeOnNewLine) + { + writer.write('\n'); + text_output_indent(writer, indent, indent_length, depth + 1); + } + else + { + writer.write(' '); + } writer.write_string(a->name ? a->name : default_name); writer.write('=', '"'); @@ -3497,7 +3510,7 @@ PUGI__NS_BEGIN } } - PUGI__FN bool node_output_start(xml_buffered_writer& writer, xml_node_struct* node, unsigned int flags) + PUGI__FN bool node_output_start(xml_buffered_writer &writer, xml_node_struct *node, const char_t *indent, size_t indent_length, unsigned int flags, unsigned int depth) { const char_t* default_name = PUGIXML_TEXT(":anonymous"); const char_t* name = node->name ? node->name : default_name; @@ -3506,18 +3519,16 @@ PUGI__NS_BEGIN writer.write_string(name); if (node->first_attribute) - node_output_attributes(writer, node, flags); + node_output_attributes(writer, node, indent, indent_length, flags, depth); if (!node->first_child) { writer.write(' ', '/', '>'); - return false; } else { writer.write('>'); - return true; } } @@ -3532,7 +3543,7 @@ PUGI__NS_BEGIN writer.write('>'); } - PUGI__FN void node_output_simple(xml_buffered_writer& writer, xml_node_struct* node, unsigned int flags) + PUGI__FN void node_output_simple(xml_buffered_writer &writer, xml_node_struct *node, const char_t *indent, size_t indent_length, unsigned int flags, unsigned int depth) { const char_t* default_name = PUGIXML_TEXT(":anonymous"); @@ -3566,7 +3577,7 @@ PUGI__NS_BEGIN case node_declaration: writer.write('<', '?'); writer.write_string(node->name ? node->name : default_name); - node_output_attributes(writer, node, flags); + node_output_attributes(writer, node, indent, indent_length, flags, depth); writer.write('?', '>'); break; @@ -3608,7 +3619,7 @@ PUGI__NS_BEGIN // begin writing current node if (PUGI__NODETYPE(node) == node_pcdata || PUGI__NODETYPE(node) == node_cdata) { - node_output_simple(writer, node, flags); + node_output_simple(writer, node, indent, indent_length, flags, depth); indent_flags = 0; } @@ -3624,7 +3635,7 @@ PUGI__NS_BEGIN { indent_flags = indent_newline | indent_indent; - if (node_output_start(writer, node, flags)) + if (node_output_start(writer, node, indent, indent_length, flags, depth)) { node = node->first_child; depth++; @@ -3643,7 +3654,7 @@ PUGI__NS_BEGIN } else { - node_output_simple(writer, node, flags); + node_output_simple(writer, node, indent, indent_length, flags, depth); indent_flags = indent_newline | indent_indent; } -- cgit v1.2.3 From 2a3435274f0d7d0e3ccb4417e143e5957e820332 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 13 Apr 2015 21:21:26 -0700 Subject: Refactor format_indent_attributes implementation Fix code style and revert redundant parameters/whitespace changes. Also remove format_each_attribute_on_new_line - we're only introducing one extra formatting flag. The flag implies format_indent but does not include its bitmask. Also add a few more tests. Fixes #14. --- src/pugixml.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'src/pugixml.cpp') diff --git a/src/pugixml.cpp b/src/pugixml.cpp index bf5835f..590d07f 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -3480,26 +3480,23 @@ PUGI__NS_BEGIN } } - PUGI__FN void node_output_attributes(xml_buffered_writer &writer, xml_node_struct *node, const char_t *indent, size_t indent_length, unsigned int flags, unsigned int depth) + PUGI__FN void node_output_attributes(xml_buffered_writer& writer, xml_node_struct* node, const char_t* indent, size_t indent_length, unsigned int flags, unsigned int depth) { const char_t* default_name = PUGIXML_TEXT(":anonymous"); - bool eachAttributeOnNewLine = PUGI__NODETYPE(node) != node_declaration - && (flags & format_indent) - && (flags & format_each_attribute_on_new_line) - && (flags & format_raw) == 0; - for (xml_attribute_struct* a = node->first_attribute; a; a = a->next_attribute) { - if (eachAttributeOnNewLine) + if ((flags & (format_indent_attributes | format_raw)) == format_indent_attributes) { writer.write('\n'); + text_output_indent(writer, indent, indent_length, depth + 1); } else { writer.write(' '); } + writer.write_string(a->name ? a->name : default_name); writer.write('=', '"'); @@ -3510,7 +3507,7 @@ PUGI__NS_BEGIN } } - PUGI__FN bool node_output_start(xml_buffered_writer &writer, xml_node_struct *node, const char_t *indent, size_t indent_length, unsigned int flags, unsigned int depth) + PUGI__FN bool node_output_start(xml_buffered_writer& writer, xml_node_struct* node, const char_t* indent, size_t indent_length, unsigned int flags, unsigned int depth) { const char_t* default_name = PUGIXML_TEXT(":anonymous"); const char_t* name = node->name ? node->name : default_name; @@ -3524,11 +3521,13 @@ PUGI__NS_BEGIN if (!node->first_child) { writer.write(' ', '/', '>'); + return false; } else { writer.write('>'); + return true; } } @@ -3543,7 +3542,7 @@ PUGI__NS_BEGIN writer.write('>'); } - PUGI__FN void node_output_simple(xml_buffered_writer &writer, xml_node_struct *node, const char_t *indent, size_t indent_length, unsigned int flags, unsigned int depth) + PUGI__FN void node_output_simple(xml_buffered_writer& writer, xml_node_struct* node, unsigned int flags) { const char_t* default_name = PUGIXML_TEXT(":anonymous"); @@ -3577,7 +3576,7 @@ PUGI__NS_BEGIN case node_declaration: writer.write('<', '?'); writer.write_string(node->name ? node->name : default_name); - node_output_attributes(writer, node, indent, indent_length, flags, depth); + node_output_attributes(writer, node, PUGIXML_TEXT(""), 0, flags | format_raw, 0); writer.write('?', '>'); break; @@ -3607,7 +3606,7 @@ PUGI__NS_BEGIN PUGI__FN void node_output(xml_buffered_writer& writer, xml_node_struct* root, const char_t* indent, unsigned int flags, unsigned int depth) { - size_t indent_length = ((flags & (format_indent | format_raw)) == format_indent) ? strlength(indent) : 0; + size_t indent_length = ((flags & (format_indent | format_indent_attributes)) && (flags & format_raw) == 0) ? strlength(indent) : 0; unsigned int indent_flags = indent_indent; xml_node_struct* node = root; @@ -3619,7 +3618,7 @@ PUGI__NS_BEGIN // begin writing current node if (PUGI__NODETYPE(node) == node_pcdata || PUGI__NODETYPE(node) == node_cdata) { - node_output_simple(writer, node, indent, indent_length, flags, depth); + node_output_simple(writer, node, flags); indent_flags = 0; } @@ -3654,7 +3653,7 @@ PUGI__NS_BEGIN } else { - node_output_simple(writer, node, indent, indent_length, flags, depth); + node_output_simple(writer, node, flags); indent_flags = indent_newline | indent_indent; } -- cgit v1.2.3 From 2badcbb6743ff803c9cd82db77a1d8a50802058f Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 14 Apr 2015 19:11:26 -0700 Subject: Explicitly call xml_buffered_writer::flush() If xml_writer::write throws an exception while being called from flush(), the exception is thrown from destructor. Clang in C++11 mode calls std::terminate in this case. --- src/pugixml.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/pugixml.cpp') diff --git a/src/pugixml.cpp b/src/pugixml.cpp index 590d07f..1c1b539 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -3115,11 +3115,6 @@ PUGI__NS_BEGIN PUGI__STATIC_ASSERT(bufcapacity >= 8); } - ~xml_buffered_writer() - { - flush(); - } - size_t flush() { flush(buffer, bufsize); @@ -5496,6 +5491,8 @@ namespace pugi impl::xml_buffered_writer buffered_writer(writer, encoding); impl::node_output(buffered_writer, _root, indent, flags, depth); + + buffered_writer.flush(); } #ifndef PUGIXML_NO_STL @@ -6205,6 +6202,8 @@ namespace pugi } impl::node_output(buffered_writer, _root, indent, flags, 0); + + buffered_writer.flush(); } #ifndef PUGIXML_NO_STL -- cgit v1.2.3 From 5158ee903be463c189a80715f92235ceb04871a7 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 14 Apr 2015 19:19:13 -0700 Subject: Fix xpath_node_set assignment to provide strong exception guarantee Since the type of the set was updated before assignment, assigning in out-of-memory condition could change the type to not match the content. --- src/pugixml.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src/pugixml.cpp') diff --git a/src/pugixml.cpp b/src/pugixml.cpp index 1c1b539..fbe13f6 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -11025,7 +11025,7 @@ namespace pugi } #endif - PUGI__FN void xpath_node_set::_assign(const_iterator begin_, const_iterator end_) + PUGI__FN void xpath_node_set::_assign(const_iterator begin_, const_iterator end_, type_t type_) { assert(begin_ <= end_); @@ -11041,6 +11041,7 @@ namespace pugi _begin = &_storage; _end = &_storage + size_; + _type = type_; } else { @@ -11064,6 +11065,7 @@ namespace pugi // finalize _begin = storage; _end = storage + size_; + _type = type_; } } @@ -11071,9 +11073,9 @@ namespace pugi { } - PUGI__FN xpath_node_set::xpath_node_set(const_iterator begin_, const_iterator end_, type_t type_): _type(type_), _begin(&_storage), _end(&_storage) + PUGI__FN xpath_node_set::xpath_node_set(const_iterator begin_, const_iterator end_, type_t type_): _type(type_unsorted), _begin(&_storage), _end(&_storage) { - _assign(begin_, end_); + _assign(begin_, end_, type_); } PUGI__FN xpath_node_set::~xpath_node_set() @@ -11081,17 +11083,16 @@ namespace pugi if (_begin != &_storage) impl::xml_memory::deallocate(_begin); } - PUGI__FN xpath_node_set::xpath_node_set(const xpath_node_set& ns): _type(ns._type), _begin(&_storage), _end(&_storage) + PUGI__FN xpath_node_set::xpath_node_set(const xpath_node_set& ns): _type(type_unsorted), _begin(&_storage), _end(&_storage) { - _assign(ns._begin, ns._end); + _assign(ns._begin, ns._end, ns._type); } PUGI__FN xpath_node_set& xpath_node_set::operator=(const xpath_node_set& ns) { if (this == &ns) return *this; - - _type = ns._type; - _assign(ns._begin, ns._end); + + _assign(ns._begin, ns._end, ns._type); return *this; } -- cgit v1.2.3 From 8c8940430ac0d0f82add6fb028ffe9712c9669e8 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 15 Apr 2015 08:32:22 -0700 Subject: Minor xpath_variable refactoring The type of the variable is now initialized correctly in the ctor, so that there is no interim invalid state. --- src/pugixml.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'src/pugixml.cpp') diff --git a/src/pugixml.cpp b/src/pugixml.cpp index fbe13f6..078a39c 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -7626,7 +7626,7 @@ PUGI__NS_BEGIN struct xpath_variable_boolean: xpath_variable { - xpath_variable_boolean(): value(false) + xpath_variable_boolean(): xpath_variable(xpath_type_boolean), value(false) { } @@ -7636,7 +7636,7 @@ PUGI__NS_BEGIN struct xpath_variable_number: xpath_variable { - xpath_variable_number(): value(0) + xpath_variable_number(): xpath_variable(xpath_type_number), value(0) { } @@ -7646,7 +7646,7 @@ PUGI__NS_BEGIN struct xpath_variable_string: xpath_variable { - xpath_variable_string(): value(0) + xpath_variable_string(): xpath_variable(xpath_type_string), value(0) { } @@ -7661,6 +7661,10 @@ PUGI__NS_BEGIN struct xpath_variable_node_set: xpath_variable { + xpath_variable_node_set(): xpath_variable(xpath_type_node_set) + { + } + xpath_node_set value; char_t name[1]; }; @@ -11080,7 +11084,8 @@ namespace pugi PUGI__FN xpath_node_set::~xpath_node_set() { - if (_begin != &_storage) impl::xml_memory::deallocate(_begin); + if (_begin != &_storage) + impl::xml_memory::deallocate(_begin); } PUGI__FN xpath_node_set::xpath_node_set(const xpath_node_set& ns): _type(type_unsorted), _begin(&_storage), _end(&_storage) @@ -11152,7 +11157,7 @@ namespace pugi return error ? error : "No error"; } - PUGI__FN xpath_variable::xpath_variable(): _type(xpath_type_none), _next(0) + PUGI__FN xpath_variable::xpath_variable(xpath_value_type type_): _type(type_), _next(0) { } @@ -11251,7 +11256,8 @@ namespace pugi PUGI__FN xpath_variable_set::xpath_variable_set() { - for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) _data[i] = 0; + for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) + _data[i] = 0; } PUGI__FN xpath_variable_set::~xpath_variable_set() @@ -11299,7 +11305,6 @@ namespace pugi if (result) { - result->_type = type; result->_next = _data[hash]; _data[hash] = result; -- cgit v1.2.3 From cbf3807ad4e93441d4a4324d1c21099ca644fac7 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 15 Apr 2015 23:22:31 -0700 Subject: Implement copy ctor/assignment for xpath_variable_set xpath_variable_set is essentially an associative container; it's about time it became copyable. Implementation is slightly tricky due to out of memory handling. Both copy ctor and assignment operator have strong exception guarantee (even if exceptions are disabled! which translates to "roll back on allocation errors"). --- src/pugixml.cpp | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 3 deletions(-) (limited to 'src/pugixml.cpp') diff --git a/src/pugixml.cpp b/src/pugixml.cpp index 078a39c..ce47fce 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -7758,6 +7758,28 @@ PUGI__NS_BEGIN } } + PUGI__FN bool copy_xpath_variable(xpath_variable* lhs, const xpath_variable* rhs) + { + switch (rhs->type()) + { + case xpath_type_node_set: + return lhs->set(static_cast(rhs)->value); + + case xpath_type_number: + return lhs->set(static_cast(rhs)->value); + + case xpath_type_string: + return lhs->set(static_cast(rhs)->value); + + case xpath_type_boolean: + return lhs->set(static_cast(rhs)->value); + + default: + assert(!"Invalid variable type"); + return false; + } + } + PUGI__FN bool get_variable_scratch(char_t (&buffer)[32], xpath_variable_set* set, const char_t* begin, const char_t* end, xpath_variable** out_result) { size_t length = static_cast(end - begin); @@ -11277,7 +11299,46 @@ namespace pugi } } - PUGI__FN xpath_variable* xpath_variable_set::find(const char_t* name) const + PUGI__FN xpath_variable_set::xpath_variable_set(const xpath_variable_set& rhs) + { + for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) + _data[i] = 0; + + _assign(rhs); + } + + PUGI__FN xpath_variable_set& xpath_variable_set::operator=(const xpath_variable_set& rhs) + { + if (this == &rhs) return *this; + + _assign(rhs); + + return *this; + } + + PUGI__FN void xpath_variable_set::_assign(const xpath_variable_set& rhs) + { + xpath_variable_set temp; + + for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) + if (rhs._data[i] && !_clone(rhs._data[i], &temp._data[i])) + return; + + _swap(temp); + } + + PUGI__FN void xpath_variable_set::_swap(xpath_variable_set& rhs) + { + for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) + { + xpath_variable* chain = _data[i]; + + _data[i] = rhs._data[i]; + rhs._data[i] = chain; + } + } + + PUGI__FN xpath_variable* xpath_variable_set::_find(const char_t* name) const { const size_t hash_size = sizeof(_data) / sizeof(_data[0]); size_t hash = impl::hash_string(name) % hash_size; @@ -11290,6 +11351,33 @@ namespace pugi return 0; } + PUGI__FN bool xpath_variable_set::_clone(xpath_variable* var, xpath_variable** out_result) + { + xpath_variable* last = 0; + + while (var) + { + // allocate storage for new variable + xpath_variable* nvar = impl::new_xpath_variable(var->_type, var->name()); + if (!nvar) return false; + + // link the variable to the result immediately to handle failures gracefully + if (last) + last->_next = nvar; + else + *out_result = nvar; + + last = nvar; + + // copy the value; this can fail due to out-of-memory conditions + if (!impl::copy_xpath_variable(nvar, var)) return false; + + var = var->_next; + } + + return true; + } + PUGI__FN xpath_variable* xpath_variable_set::add(const char_t* name, xpath_value_type type) { const size_t hash_size = sizeof(_data) / sizeof(_data[0]); @@ -11339,12 +11427,12 @@ namespace pugi PUGI__FN xpath_variable* xpath_variable_set::get(const char_t* name) { - return find(name); + return _find(name); } PUGI__FN const xpath_variable* xpath_variable_set::get(const char_t* name) const { - return find(name); + return _find(name); } PUGI__FN xpath_query::xpath_query(const char_t* query, xpath_variable_set* variables): _impl(0) -- cgit v1.2.3 From a414c5c52d50714d5e88f743760a5d83cd37c1a1 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 21 Apr 2015 10:02:26 -0700 Subject: Fix compilation warning in some configurations --- src/pugixml.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/pugixml.cpp') diff --git a/src/pugixml.cpp b/src/pugixml.cpp index ce47fce..d98df3e 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -1691,6 +1691,7 @@ PUGI__NS_BEGIN assert(begin + size == end); (void)!end; + (void)!size; } #ifndef PUGIXML_NO_STL -- cgit v1.2.3 From 83b894b8f17e8c09eb21675983be0656301d2d99 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 21 Apr 2015 19:42:31 -0700 Subject: XPath: Implement move semantics support xpath_query, xpath_node_set and xpath_variable_set are now moveable. This is a nice performance optimization for variable/node sets, and enables storing xpath_query in containers without using pointers (it's only possible now since the query is not copyable). --- src/pugixml.cpp | 107 +++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 95 insertions(+), 12 deletions(-) (limited to 'src/pugixml.cpp') diff --git a/src/pugixml.cpp b/src/pugixml.cpp index d98df3e..37c61bb 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -11096,6 +11096,20 @@ namespace pugi } } +#if __cplusplus >= 201103 + PUGI__FN void xpath_node_set::_move(xpath_node_set& rhs) + { + _type = rhs._type; + _storage = rhs._storage; + _begin = (rhs._begin == &rhs._storage) ? &_storage : rhs._begin; + _end = _begin + (rhs._end - rhs._begin); + + rhs._type = type_unsorted; + rhs._begin = &rhs._storage; + rhs._end = rhs._begin; + } +#endif + PUGI__FN xpath_node_set::xpath_node_set(): _type(type_unsorted), _begin(&_storage), _end(&_storage) { } @@ -11125,6 +11139,25 @@ namespace pugi return *this; } +#if __cplusplus >= 201103 + PUGI__FN xpath_node_set::xpath_node_set(xpath_node_set&& rhs): _type(type_unsorted), _begin(&_storage), _end(&_storage) + { + _move(rhs); + } + + PUGI__FN xpath_node_set& xpath_node_set::operator=(xpath_node_set&& rhs) + { + if (this == &rhs) return *this; + + if (_begin != &_storage) + impl::xml_memory::deallocate(_begin); + + _move(rhs); + + return *this; + } +#endif + PUGI__FN xpath_node_set::type_t xpath_node_set::type() const { return _type; @@ -11286,18 +11319,7 @@ namespace pugi PUGI__FN xpath_variable_set::~xpath_variable_set() { for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) - { - xpath_variable* var = _data[i]; - - while (var) - { - xpath_variable* next = var->_next; - - impl::delete_xpath_variable(var->_type, var); - - var = next; - } - } + _destroy(_data[i]); } PUGI__FN xpath_variable_set::xpath_variable_set(const xpath_variable_set& rhs) @@ -11317,6 +11339,30 @@ namespace pugi return *this; } +#if __cplusplus >= 201103 + PUGI__FN xpath_variable_set::xpath_variable_set(xpath_variable_set&& rhs) + { + for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) + { + _data[i] = rhs._data[i]; + rhs._data[i] = 0; + } + } + + PUGI__FN xpath_variable_set& xpath_variable_set::operator=(xpath_variable_set&& rhs) + { + for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) + { + _destroy(_data[i]); + + _data[i] = rhs._data[i]; + rhs._data[i] = 0; + } + + return *this; + } +#endif + PUGI__FN void xpath_variable_set::_assign(const xpath_variable_set& rhs) { xpath_variable_set temp; @@ -11379,6 +11425,18 @@ namespace pugi return true; } + PUGI__FN void xpath_variable_set::_destroy(xpath_variable* var) + { + while (var) + { + xpath_variable* next = var->_next; + + impl::delete_xpath_variable(var->_type, var); + + var = next; + } + } + PUGI__FN xpath_variable* xpath_variable_set::add(const char_t* name, xpath_value_type type) { const size_t hash_size = sizeof(_data) / sizeof(_data[0]); @@ -11464,12 +11522,37 @@ namespace pugi } } + PUGI__FN xpath_query::xpath_query(): _impl(0) + { + } + PUGI__FN xpath_query::~xpath_query() { if (_impl) impl::xpath_query_impl::destroy(static_cast(_impl)); } +#if __cplusplus >= 201103 + PUGI__FN xpath_query::xpath_query(xpath_query&& rhs) + { + _impl = rhs._impl; + rhs._impl = 0; + } + + xpath_query& xpath_query::operator=(xpath_query&& rhs) + { + if (this == &rhs) return *this; + + if (_impl) + impl::xpath_query_impl::destroy(static_cast(_impl)); + + _impl = rhs._impl; + rhs._impl = 0; + + return *this; + } +#endif + PUGI__FN xpath_value_type xpath_query::return_type() const { if (!_impl) return xpath_type_none; -- cgit v1.2.3