diff options
| author | Arseny Kapoulkine <arseny.kapoulkine@gmail.com> | 2015-04-21 19:42:31 -0700 | 
|---|---|---|
| committer | Arseny Kapoulkine <arseny.kapoulkine@gmail.com> | 2015-04-21 19:42:31 -0700 | 
| commit | 83b894b8f17e8c09eb21675983be0656301d2d99 (patch) | |
| tree | 02b64ea789a270efef4911294affca945d6dca0d /src | |
| parent | a414c5c52d50714d5e88f743760a5d83cd37c1a1 (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')
| -rw-r--r-- | src/pugixml.cpp | 107 | ||||
| -rw-r--r-- | src/pugixml.hpp | 25 | 
2 files changed, 119 insertions, 13 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; diff --git a/src/pugixml.hpp b/src/pugixml.hpp index b8b8946..0f79fb7 100644 --- a/src/pugixml.hpp +++ b/src/pugixml.hpp @@ -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 | 
