diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/Node.hpp | 2 | ||||
| -rw-r--r-- | src/core/managed/Managed.hpp | 2 | ||||
| -rw-r--r-- | src/core/managed/ManagedContainer.cpp | 24 | ||||
| -rw-r--r-- | src/core/managed/ManagedContainer.hpp | 520 | ||||
| -rw-r--r-- | src/core/managed/Manager.cpp | 62 | ||||
| -rw-r--r-- | src/core/managed/Manager.hpp | 25 | 
6 files changed, 353 insertions, 282 deletions
diff --git a/src/core/Node.hpp b/src/core/Node.hpp index e0d14a8..b7d050d 100644 --- a/src/core/Node.hpp +++ b/src/core/Node.hpp @@ -30,8 +30,6 @@  namespace ousia { -// TODO: Let Manager handle associated data -  /* Forward declarations */  class Node;  class Event; diff --git a/src/core/managed/Managed.hpp b/src/core/managed/Managed.hpp index eec2fc5..8b0bb17 100644 --- a/src/core/managed/Managed.hpp +++ b/src/core/managed/Managed.hpp @@ -64,7 +64,7 @@ public:  	/**  	 * Virtual destuctor which may be overwritten by child classes.  	 */ -	virtual ~Managed(){ mgr.unmanage(this); }; +	virtual ~Managed(){};  	/**  	 * Returns a reference ot the manager instance which owns this managed diff --git a/src/core/managed/ManagedContainer.cpp b/src/core/managed/ManagedContainer.cpp deleted file mode 100644 index e7f30fa..0000000 --- a/src/core/managed/ManagedContainer.cpp +++ /dev/null @@ -1,24 +0,0 @@ -/* -    Ousía -    Copyright (C) 2014, 2015  Benjamin Paaßen, Andreas Stöckel - -    This program is free software: you can redistribute it and/or modify -    it under the terms of the GNU General Public License as published by -    the Free Software Foundation, either version 3 of the License, or -    (at your option) any later version. - -    This program is distributed in the hope that it will be useful, -    but WITHOUT ANY WARRANTY; without even the implied warranty of -    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -    GNU General Public License for more details. - -    You should have received a copy of the GNU General Public License -    along with this program.  If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "ManagedContainer.hpp" - -namespace ousia { - -} - diff --git a/src/core/managed/ManagedContainer.hpp b/src/core/managed/ManagedContainer.hpp index 7b18bcd..1454608 100644 --- a/src/core/managed/ManagedContainer.hpp +++ b/src/core/managed/ManagedContainer.hpp @@ -16,6 +16,14 @@      along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ +/** + * @file ManagedContainer.hpp + * + * Container classes for conviniently storing managed instances. + * + * @author Andreas Stöckel (astoecke@techfak.uni-bielefeld.de) + */ +  #ifndef _OUSIA_MANAGED_CONTAINER_H_  #define _OUSIA_MANAGED_CONTAINER_H_ @@ -31,48 +39,140 @@  namespace ousia {  /** + * Default accessor class for accessing the managed element within a list value + * type. + * + * @tparam ValueType is the list value type that should be accessed. + */ +template <class ValueType> +struct ListAccessor { +	Managed *getManaged(const ValueType &val) const { return val.get(); } +}; + +/** + * Default accessor class for accessing the managed element within a map value + * type. + * + * @tparam ValueType is the map value type that should be accessed. + */ +template <class ValueType> +struct MapAccessor { +	Managed *getManaged(const ValueType &val) const { return val.second.get(); } +}; + +/** + * Default implementation of a Listener class. With empty functions. + */ +template <class ValueType> +struct DefaultListener { +	void addElement(const ValueType &val, Managed *owner) {} +	void deleteElement(const ValueType &val, Managed *owner) {} +}; + +/**   * Template class which can be used to collect refrences to a certain type of   * managed objects. Do not use this class directly, use ManagedMap or   * ManagedVector instead. This class only provides functionality which is common   * to list and map containers (iterators and state).   * - * @param T is the type of the Managed object that should be managed. - * @param Collection should be a STL container of Owned<T> + * @tparam T is the type of the Managed object that should be managed. + * @tparam Collection is the underlying STL collection and should contain + * pointers of type T as value. + * @tparam Accessor is a type that allows to resolve the STL value type to the + * actual, underlying pointer to T -- this is important to generically support + * maps, where the value type is a pair of key type and the actual value. + * @tparam Listener is an optional type that allows to execute arbitrary code + * whenever data is read or written to the collection.   */ -template <class T, class Collection> -class ManagedContainer : Managed { +template <class T, class Collection, class Accessor, class Listener> +class ManagedContainer {  public: -	using collection_type = Collection; -	using value_type = typename collection_type::value_type; -	using reference = typename collection_type::reference; -	using const_reference = typename collection_type::const_reference; -	using iterator = typename collection_type::iterator; -	using const_iterator = typename collection_type::const_iterator; -	using size_type = typename collection_type::size_type; +	using own_type = ManagedContainer<T, Collection, Accessor, Listener>; +	using value_type = typename Collection::value_type; +	using reference = typename Collection::reference; +	using const_reference = typename Collection::const_reference; +	using iterator = typename Collection::iterator; +	using const_iterator = typename Collection::const_iterator; +	using size_type = typename Collection::size_type; -protected: +private:  	/**  	 * Handle containing a reference to the owner of the collection.  	 */ -	Handle<Managed> owner; +	Managed *owner;  	/** -	 * Underlying STL collection. +	 * Accessor used to access the managed instance inside a "reference type". +	 */ +	Accessor accessor; + +	/** +	 * Listener which is notified whenever an element is added to or removed +	 * from the list. +	 */ +	Listener listener; + +	/** +	 * Calls the "addElement" function of each element and thus initializes +	 * the references from the owner to the elements. +	 */ +	void initialize() +	{ +		for (const auto &elem : *this) { +			addElement(elem); +		} +	} + +	/** +	 * Calls the "deleteElement" function of each element and thus finalizes +	 * the references from the owner to the elements.  	 */ -	collection_type c; +	void finalize() +	{ +		if (owner) { +			for (const auto &elem : *this) { +				deleteElement(elem); +			} +		} +	}  protected:  	/** -	 * Function which can be overridden by child classes to execute special code -	 * whenever a new element is added to the collection. +	 * Underlying STL collection. +	 */ +	Collection c; + +	/** +	 * Function to be called whenever an element is added to the collection. +	 * This function makes sure that the association from the owner to the added +	 * element is established. +	 * +	 * @param managed is the managed instance that is being added to the +	 * container. +	 * @param elem is a reference to the actual element that is being added to +	 * the underlying container.  	 */ -	virtual void addElement(value_type h) {} +	void addElement(const value_type &elem) +	{ +		getManager().addRef(accessor.getManaged(elem), owner); +		listener.addElement(elem, owner); +	}  	/** -	 * Function which can be overriden by child classes to execute special code -	 * whenever an element is removed from the collection. +	 * Function to be called whenever an element is removed from the collection. +	 * This function makes sure that the association from the owner to the added +	 * element is removed. +	 * +	 * @param managed is the managed instance that is being deleted from the +	 * container. +	 * @param elem is a reference to the actual element that is being removed +	 * from the underlying container.  	 */ -	virtual void deleteElement(value_type h) {} +	void deleteElement(const value_type &elem) +	{ +		getManager().deleteRef(accessor.getManaged(elem), owner); +		listener.deleteElement(elem, owner); +	}  public:  	/** @@ -81,15 +181,162 @@ public:  	 * @param owner is the managed object which owns the collection and all  	 * handles to other managed objects stored within.  	 */ -	ManagedContainer(Handle<Managed> owner) : Managed(owner->getManager), owner(owner){}; +	ManagedContainer(Handle<Managed> owner) : owner(owner.get()){}; + +	/** +	 * Copy constructor. Creates a copy of the given container with the same +	 * owner as the given container. +	 * +	 * @param other is the other coontainer that should be copied. +	 */ +	ManagedContainer(const own_type &other) : owner(other.owner), c(other.c) +	{ +		initialize(); +	} + +	/** +	 * Copy constructor. Creates a copy of the given container with another +	 * owner. +	 * +	 * @param other is the other container that should be copied. +	 */ +	ManagedContainer(Handle<Managed> owner, const own_type &other) +	    : owner(owner.get()), c(other.c) +	{ +		initialize(); +	} + +	/** +	 * Copy constructor. Creates a copy of the given container and takes over +	 * ownership. +	 */ +	ManagedContainer(Handle<Managed> owner, const Collection &collection) +	    : owner(owner), c(collection) +	{ +		initialize(); +	} + +	/** +	 * Move constructor. Moves the other instance to this instance. +	 * +	 * @param other is the other container that should be moved. +	 */ +	ManagedContainer(own_type &&other) +	    : owner(other.owner), c(std::move(other.c)) +	{ +		other.owner = nullptr; +	} + +	/** +	 * Copy constructor. Creates a copy of the given container with another +	 * owner. +	 * +	 * @param other is the other container that should be moved. +	 */ +	ManagedContainer(Handle<Managed> owner, own_type &&other) +	    : owner(owner.get()), c(std::move(other.c)) +	{ +		other.finalize(); +		other.owner = nullptr; +		initialize(); +	} + +	/** +	 * Copy constructor. Initialize with an iterator from another collection. +	 * +	 * @param owner is the managed object which owns the collection and all +	 * handles to other managed objects stored within. +	 * @param first is an iterator pointing at the first element to be copied +	 * from some other collection. +	 * @param last is an iterator pointing at the last element to be copied +	 * from some other collection. +	 */ +	template <class InputIterator> +	ManagedContainer(Handle<Managed> owner, InputIterator first, +	                 InputIterator last) +	    : owner(owner.get()) +	{ +		auto it = end(); +		for (auto it2 = first; it2 != last; it2++) { +			it = insert(it, *it2); +			it++; +		} +	} + +	/** +	 * Destructor of the ManagedContainer class. Calls the "deleteElement" +	 * function for each element in the container. +	 */ +	~ManagedContainer() { finalize(); }; + +	/** +	 * Copy assignment operator. +	 * +	 * @param other is the collection instance that should be copied. +	 * @return this instance. +	 */ +	own_type &operator=(const own_type &other) +	{ +		finalize(); +		owner = other.owner; +		c = other.c; +		initialize(); +		return *this; +	} + +	/** +	 * Move assignment operator. +	 * +	 * @param other is the collection instance that should be moved; +	 * @return this instance. +	 */ +	own_type &operator=(own_type &&other) +	{ +		finalize(); +		owner = other.owner; +		c = std::move(other.c); +		other.owner = nullptr; +		return *this; +	} + +	/** +	 * Equality operator. +	 */ +	bool operator==(const own_type &other) { +		return (owner == other.owner) && (c == other.c); +	} + +	/** +	 * Inequality operator. +	 */ +	bool operator!=(const own_type &other) { +		return (owner != other.owner) || (c != other.c); +	}  	/** -	 * Destructor of the ManagedContainer class. +	 * Returns the owner of the ManagedContainer instance.  	 */ -	virtual ~ManagedContainer() {}; +	Managed *getOwner() { return owner; } + +	/** +	 * Returns the manager instance associated with the owner. +	 */ +	Manager &getManager() { return owner->getManager(); }  	/* State functions */ + +	/** +	 * Returns the size of the container. +	 * +	 * @return the number of elements in the container. +	 */  	size_type size() const noexcept { return c.size(); } + +	/** +	 * Returns whether the container is empty. +	 * +	 * @return true if the container is empty, false otherwise. +	 */  	bool empty() const noexcept { return c.empty(); }  	/* Iterators */ @@ -111,7 +358,9 @@ public:  	const_iterator crbegin() const { return c.crbegin(); }  	const_iterator crend() const { return c.crend(); } -	/* Clear function */ +	/** +	 * Removes all elements from the container. +	 */  	void clear() noexcept  	{  		for (const_iterator it = cbegin(); it != cend(); it++) { @@ -119,6 +368,41 @@ public:  		}  		c.clear();  	} + +	/** +	 * Generic insert operation. +	 */ +	iterator insert(const_iterator position, value_type val) +	{ +		addElement(val); +		return c.insert(position, val); +	} + +	/** +	 * Erases the element at the given position. +	 * +	 * @param position is the position at which the element should be removed. +	 * @return an iterator to the element after the deleted element. +	 */ +	iterator erase(iterator position) +	{ +		deleteElement(*position); +		return c.erase(position); +	} + +	/** +	 * Erases a range of elements from the collection. +	 * +	 * @param position is the position at which the element should be removed. +	 * @return an iterator to the element after the deleted element. +	 */ +	iterator erase(iterator first, iterator last) +	{ +		for (const_iterator it = first; it != last; it++) { +			this->deleteElement(*it); +		} +		return c.erase(first, last); +	}  };  /** @@ -128,16 +412,15 @@ public:   * owner of this collection whenever a new element is added.   *   * @param T is the type of the Managed object that should be managed. - * @param Collection should be a STL list container of Owned<T> + * @param Collection should be a STL list container of T*   */ -template <class T, class Collection> -class ManagedGenericList : public ManagedContainer<T, Collection> { +template <class T, class Collection, class Accessor, class Listener> +class ManagedGenericList +    : public ManagedContainer<T, Collection, Accessor, Listener> {  private: -	using Base = ManagedContainer<T, Collection>; +	using Base = ManagedContainer<T, Collection, Accessor, Listener>;  public: -	using Base::ManagedContainer; -	using collection_type = typename Base::collection_type;  	using value_type = typename Base::value_type;  	using reference = typename Base::reference;  	using const_reference = typename Base::const_reference; @@ -145,40 +428,8 @@ public:  	using const_iterator = typename Base::const_iterator;  	using size_type = typename Base::size_type; -	/** -	 * Initialize with an iterator from another collection. -	 * -	 * @param owner is the managed object which owns the collection and all -	 * handles to other managed objects stored within. -	 * @param first is an iterator pointing at the first element to be copied -	 * from some other collection. -	 * @param last is an iterator pointing at the last element to be copied -	 * from some other collection. -	 */ -	template <class InputIterator> -	ManagedGenericList(Handle<Managed> owner, InputIterator first, -	                   InputIterator last) -	    : ManagedContainer<T, Collection>(owner) -	{ -		insert(Base::c.begin(), first, last); -	} - -	/** -	 * Initialize with another collection. -	 * -	 * @param owner is the managed object which owns the collection and all -	 * handles to other managed objects stored within. -	 * @param in is a reference at some other collection with content that -	 * should be copied. -	 */ -	template <class InputCollection> -	ManagedGenericList(Handle<Managed> owner, const InputCollection &in) -	    : ManagedContainer<T, Collection>(owner) -	{ -		for (const auto &e : in) { -			push_back(e); -		} -	} +	using Base::ManagedContainer; +	using Base::insert;  	/* Front and back */  	reference front() { return Base::c.front(); } @@ -188,13 +439,6 @@ public:  	/* Insert and delete operations */ -	iterator insert(const_iterator position, Handle<T> h) -	{ -		value_type v = Base::owner->acquire(h); -		addElement(v); -		return Base::c.insert(position, v); -	} -  	template <class InputIterator>  	iterator insert(const_iterator position, InputIterator first,  	                InputIterator last) @@ -212,20 +456,20 @@ public:  		return pos;  	} -	iterator find(const Handle<T> h) +	iterator find(const value_type &val)  	{  		for (iterator it = Base::begin(); it != Base::end(); it++) { -			if (*it == h) { +			if (*it == val) {  				return it;  			}  		}  		return Base::end();  	} -	const_iterator find(const Handle<T> h) const +	const_iterator find(const value_type &val) const  	{  		for (const_iterator it = Base::cbegin(); it != Base::cend(); it++) { -			if (*it == h) { +			if (*it == val) {  				return it;  			}  		} @@ -234,9 +478,8 @@ public:  	void push_back(Handle<T> h)  	{ -		value_type v = Base::owner->acquire(h); -		this->addElement(v); -		Base::c.push_back(v); +		this->addElement(h.get()); +		Base::c.push_back(h.get());  	}  	void pop_back() @@ -246,33 +489,18 @@ public:  		}  		Base::c.pop_back();  	} - -	iterator erase(iterator position) -	{ -		this->deleteElement(*position); -		return Base::c.erase(position); -	} - -	iterator erase(iterator first, iterator last) -	{ -		for (const_iterator it = first; it != last; it++) { -			this->deleteElement(*it); -		} -		return Base::c.erase(first, last); -	}  };  /**   * Special type of ManagedContainer based on an STL map.   */ -template <class K, class T, class Collection> -class ManagedGenericMap : public ManagedContainer<T, Collection> { +template <class K, class T, class Collection, class Accessor, class Listener> +class ManagedGenericMap +    : public ManagedContainer<T, Collection, Accessor, Listener> {  private: -	using Base = ManagedContainer<T, Collection>; +	using Base = ManagedContainer<T, Collection, Accessor, Listener>;  public: -	using Base::ManagedContainer; -	using collection_type = typename Base::collection_type;  	using value_type = typename Base::value_type;  	using key_type = typename Collection::key_type;  	using reference = typename Base::reference; @@ -281,76 +509,30 @@ public:  	using const_iterator = typename Base::const_iterator;  	using size_type = typename Base::size_type; -private: -	value_type acquirePair(std::pair<K, Handle<T>> val) -	{ -		return value_type{val.first, Base::owner->acquire(val.second)}; -	} - -public: -	/** -	 * Initialize with an iterator from another collection. -	 * -	 * @param owner is the managed object which owns the collection and all -	 * handles to other managed objects stored within. -	 * @param first is an iterator pointing at the first element to be copied -	 * from some other collection. -	 * @param last is an iterator pointing at the last element to be copied -	 * from some other collection. -	 */ -	template <class InputIterator> -	ManagedGenericMap(Handle<Managed> owner, InputIterator first, -	                  InputIterator last) -	    : ManagedContainer<T, Collection>(owner) -	{ -		insert(first, last); -	} - -	/** -	 * Initialize with another collection. -	 * -	 * @param owner is the managed object which owns the collection and all -	 * handles to other managed objects stored within. -	 * @param in is a reference at some other collection with content that -	 * should be copied. -	 */ -	template <class InputCollection> -	ManagedGenericMap(Handle<Managed> owner, const InputCollection &in) -	    : ManagedContainer<T, Collection>(owner) -	{ -		for (const auto &e : in) { -			insert(*in); -		} -	} +	using Base::ManagedContainer; +	using Base::erase; +	using Base::insert; -	std::pair<iterator, bool> insert(std::pair<K, Handle<T>> val) +	std::pair<iterator, bool> insert(value_type val)  	{ -		value_type v = acquirePair(val); -		this->addElement(v); -		return Base::c.insert(v); +		this->addElement(val); +		return Base::c.insert(val);  	} -	iterator insert(const_iterator position, std::pair<K, Handle<T>> val) +	iterator insert(const_iterator position, value_type val)  	{ -		value_type v = acquirePair(val); -		this->addElement(v); -		return Base::c.insert(position, v); +		this->addElement(val); +		return Base::c.insert(position, val);  	}  	template <class InputIterator>  	void insert(InputIterator first, InputIterator last)  	{  		for (auto it = first; it != last; it++) { -			insert(acquirePair); +			insert(*it);  		}  	} -	iterator erase(const_iterator position) -	{ -		this->deleteElement(*position); -		return Base::c.erase(position); -	} -  	size_t erase(const key_type &k)  	{  		iterator pos = find(k); @@ -361,14 +543,6 @@ public:  		return 0;  	} -	iterator erase(const_iterator first, const_iterator last) -	{ -		for (const_iterator it = first; it != last; it++) { -			this->deleteElement(*it); -		} -		return Base::c.erase(first, last); -	} -  	iterator find(const key_type &k) { return Base::c.find(k); }  	const_iterator find(const key_type &k) const { return Base::c.find(k); }  }; @@ -376,19 +550,29 @@ public:  /**   * Special type of ManagedGenericList based on an STL vector.   */ -template <class T> -class ManagedVector : public ManagedGenericList<T, std::vector<Owned<T>>> { +template <class T, class Listener = DefaultListener<Handle<T>>> +class ManagedVector +    : public ManagedGenericList<T, std::vector<Handle<T>>, +                                ListAccessor<Handle<T>>, Listener> {  public: -	using ManagedGenericList<T, std::vector<Owned<T>>>::ManagedGenericList; +	using Base = ManagedGenericList<T, std::vector<Handle<T>>, +	                                ListAccessor<Handle<T>>, Listener>; +	using Base::ManagedGenericList;  };  /**   * Special type of ManagedGenericMap based on an STL map.   */ -template <class K, class T> -class ManagedMap : public ManagedGenericMap<K, T, std::map<K, Owned<T>>> { +template <class K, class T, +          class Listener = DefaultListener<std::pair<K, Handle<T>>>> +class ManagedMap +    : public ManagedGenericMap<K, T, std::map<K, Handle<T>>, +                               MapAccessor<std::pair<K, Handle<T>>>, Listener> {  public: -	using ManagedGenericMap<K, T, std::map<K, Owned<T>>>::ManagedGenericMap; +	using Base = +	    ManagedGenericMap<K, T, std::map<K, Handle<T>>, +	                      MapAccessor<std::pair<K, Handle<T>>>, Listener>; +	using Base::ManagedGenericMap;  };  } diff --git a/src/core/managed/Manager.cpp b/src/core/managed/Manager.cpp index 411c675..b81d89f 100644 --- a/src/core/managed/Manager.cpp +++ b/src/core/managed/Manager.cpp @@ -174,11 +174,6 @@ void Manager::addRef(Managed *tar, Managed *src)  void Manager::deleteRef(Managed *tar, Managed *src, bool all)  { -	// Make sure the source and target manager are the same -	if (src) { -		assert(&tar->getManager() == &src->getManager()); -	} -  	// Fetch the Managed descriptors for the two objects  	ObjectDescriptor *dTar = getDescriptor(tar);  	ObjectDescriptor *dSrc = getDescriptor(src); @@ -419,62 +414,5 @@ bool Manager::deleteData(Managed *ref, const std::string &key)  	return false;  } -/* Class Manager: Tagged Memory */ - -void Manager::tagMemoryRegion(void *tag, void *pStart, void *pEnd) -{ -	// Convert start and end to integers -	uintptr_t s1 = reinterpret_cast<uintptr_t>(pStart); -	uintptr_t e1 = reinterpret_cast<uintptr_t>(pEnd); - -#ifndef NDEBUG -	// Make sure the same memory region is not tagged multiple times -	const auto itStart = tags.lower_bound(s1); -	const auto itEnd = tags.upper_bound(e1); -	for (auto it = itStart; it != itEnd; it++) { -		uintptr_t s2 = it->first; -		uintptr_t e2 = it->second.first; -		assert(!((s2 >= s1 && s2 < e1) || (e2 >= s1 && e2 < e1))); -	} -#endif - -	// Insert the new region -	tags.emplace(s1, std::make_pair(e1, tag)); -} - -void Manager::untagMemoryRegion(void *pStart, void *pEnd) -{ -	// Convert start and end to integers -	uintptr_t s1 = reinterpret_cast<uintptr_t>(pStart); -	uintptr_t e1 = reinterpret_cast<uintptr_t>(pEnd); - -	auto itStart = tags.lower_bound(s1); -	auto itEnd = tags.upper_bound(e1); -	for (auto it = itStart; it != itEnd;) { -		// Copy the data of the element -		uintptr_t s2 = it->first; -		uintptr_t e2 = it->second.first; -		void* tag = it->second.second; - -		// Remove the element from the map as we need to modify it -		it = tags.erase(it); -		if (s1 <= s2 && e1 >= e2) { -			// Remove completely covered elements -			continue; -		} -		if (s1 > s2) { -			// Insert s1-s2 section -			it = tags.emplace(s2, std::make_pair(s1, tag)).first; -		} -		if (e1 < e2) { -			// Insert e1-e2 section -			it = tags.emplace(e1, std::make_pair(e2, tag)).first; -		} - -		// Go to the next element -		it++; -	} -} -  } diff --git a/src/core/managed/Manager.hpp b/src/core/managed/Manager.hpp index 5b08cf4..ae0d130 100644 --- a/src/core/managed/Manager.hpp +++ b/src/core/managed/Manager.hpp @@ -299,31 +299,6 @@ public:  	 * @return true if data for this key was deleted, false otherwise.  	 */  	bool deleteData(Managed *ref, const std::string &key); - -	/** -	 * Stores a tag for the given memory region. May not overlap with another -	 * memory region. -	 * -	 * @param tag is user defined data that should be stored. -	 * @param pStart marks the beginning of the memory region (inclusive), -	 * @param pEnd is the end of the memory region (not inclusive). -	 */ -	void tagMemoryRegion(void *tag, void *pStart, void *pEnd); - -	/** -	 * Removes the tag from the given memory region. May be a part of a -	 * previously tagged region. -	 */ -	void untagMemoryRegion(void *pStart, void *pEnd); - -	/** -	 * Returns the tag for the given pointer or nullptr if no tag is set. -	 * -	 * @param p is the pointer for which the tag should be queried. -	 * @return the associated tag or nullptr if p points at a memory region for -	 * which no tag is set. -	 */ -	void* memoryRegionTag(void *p);  };  }  | 
