mirror of
https://github.com/zeux/pugixml.git
synced 2024-12-31 00:13:01 +08:00
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).
This commit is contained in:
parent
a414c5c52d
commit
83b894b8f1
107
src/pugixml.cpp
107
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;
|
||||
|
@ -65,7 +65,7 @@
|
||||
|
||||
// If the platform is known to have long long support, enable long long functions
|
||||
#ifndef PUGIXML_HAS_LONG_LONG
|
||||
# if defined(__cplusplus) && __cplusplus >= 201103
|
||||
# if __cplusplus >= 201103
|
||||
# define PUGIXML_HAS_LONG_LONG
|
||||
# elif defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
# define PUGIXML_HAS_LONG_LONG
|
||||
@ -1081,6 +1081,7 @@ namespace pugi
|
||||
xpath_variable* _find(const char_t* name) const;
|
||||
|
||||
static bool _clone(xpath_variable* var, xpath_variable** out_result);
|
||||
static void _destroy(xpath_variable* var);
|
||||
|
||||
public:
|
||||
// Default constructor/destructor
|
||||
@ -1091,6 +1092,12 @@ namespace pugi
|
||||
xpath_variable_set(const xpath_variable_set& rhs);
|
||||
xpath_variable_set& operator=(const xpath_variable_set& rhs);
|
||||
|
||||
#if __cplusplus >= 201103
|
||||
// Move semantics support
|
||||
xpath_variable_set(xpath_variable_set&& rhs);
|
||||
xpath_variable_set& operator=(xpath_variable_set&& rhs);
|
||||
#endif
|
||||
|
||||
// Add a new variable or get the existing one, if the types match
|
||||
xpath_variable* add(const char_t* name, xpath_value_type type);
|
||||
|
||||
@ -1123,9 +1130,18 @@ namespace pugi
|
||||
// If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on compilation errors.
|
||||
explicit xpath_query(const char_t* query, xpath_variable_set* variables = 0);
|
||||
|
||||
// Constructor
|
||||
xpath_query();
|
||||
|
||||
// Destructor
|
||||
~xpath_query();
|
||||
|
||||
#if __cplusplus >= 201103
|
||||
// Move semantics support
|
||||
xpath_query(xpath_query&& rhs);
|
||||
xpath_query& operator=(xpath_query&& rhs);
|
||||
#endif
|
||||
|
||||
// Get query expression return type
|
||||
xpath_value_type return_type() const;
|
||||
|
||||
@ -1261,6 +1277,12 @@ namespace pugi
|
||||
xpath_node_set(const xpath_node_set& ns);
|
||||
xpath_node_set& operator=(const xpath_node_set& ns);
|
||||
|
||||
#if __cplusplus >= 201103
|
||||
// Move semantics support
|
||||
xpath_node_set(xpath_node_set&& rhs);
|
||||
xpath_node_set& operator=(xpath_node_set&& rhs);
|
||||
#endif
|
||||
|
||||
// Get collection type
|
||||
type_t type() const;
|
||||
|
||||
@ -1292,6 +1314,7 @@ namespace pugi
|
||||
xpath_node* _end;
|
||||
|
||||
void _assign(const_iterator begin, const_iterator end, type_t type);
|
||||
void _move(xpath_node_set& rhs);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user