summaryrefslogtreecommitdiff
path: root/src/pugixml.cpp
diff options
context:
space:
mode:
authorArseny Kapoulkine <arseny.kapoulkine@gmail.com>2015-04-21 19:42:31 -0700
committerArseny Kapoulkine <arseny.kapoulkine@gmail.com>2015-04-21 19:42:31 -0700
commit83b894b8f17e8c09eb21675983be0656301d2d99 (patch)
tree02b64ea789a270efef4911294affca945d6dca0d /src/pugixml.cpp
parenta414c5c52d50714d5e88f743760a5d83cd37c1a1 (diff)
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).
Diffstat (limited to 'src/pugixml.cpp')
-rw-r--r--src/pugixml.cpp107
1 files changed, 95 insertions, 12 deletions
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::xpath_query_impl*>(_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::xpath_query_impl*>(_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;