diff options
author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2014-12-16 02:10:53 +0100 |
---|---|---|
committer | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2014-12-16 02:10:53 +0100 |
commit | abbfae912b8d54106dbcbb7260c10e3a204c9f93 (patch) | |
tree | 8081a182e815484543e43e1133dc0596edc5228f /src | |
parent | 84cbdcaba520f89eb3ddbdaf1fe2ab3db412501a (diff) |
added possibility to register a ManagedType for a class derived from Managed, improved Managed readData function
Diffstat (limited to 'src')
-rw-r--r-- | src/core/managed/Managed.cpp | 28 | ||||
-rw-r--r-- | src/core/managed/Managed.hpp | 65 | ||||
-rw-r--r-- | src/core/managed/ManagedContainer.hpp | 55 | ||||
-rw-r--r-- | src/core/managed/ManagedType.cpp | 52 | ||||
-rw-r--r-- | src/core/managed/ManagedType.hpp | 119 |
5 files changed, 259 insertions, 60 deletions
diff --git a/src/core/managed/Managed.cpp b/src/core/managed/Managed.cpp index 991f941..f55cca5 100644 --- a/src/core/managed/Managed.cpp +++ b/src/core/managed/Managed.cpp @@ -20,8 +20,36 @@ #include <queue> #include "Managed.hpp" +#include "ManagedContainer.hpp" namespace ousia { +/* Class Managed */ + +void Managed::storeData(const std::string &key, Handle<Managed> h) { + mgr.storeData(this, key, h.get()); +} + +bool Managed::hasDataKey(const std::string &key) +{ + return mgr.readData(this, key) != nullptr; +} + +Rooted<Managed> Managed::readData(const std::string &key) { + return mgr.readData(this, key); +} + +std::map<std::string, Rooted<Managed>> Managed::readData() { + auto map = mgr.readData(this); + std::map<std::string, Rooted<Managed>> res; + for (auto e : map) { + res.emplace(e.first, e.second); + } + return res; +} + +bool Managed::deleteData(const std::string &key) { + return mgr.deleteData(this, key); +} } diff --git a/src/core/managed/Managed.hpp b/src/core/managed/Managed.hpp index 8b0bb17..4818c3d 100644 --- a/src/core/managed/Managed.hpp +++ b/src/core/managed/Managed.hpp @@ -19,6 +19,7 @@ #ifndef _OUSIA_MANAGED_HPP_ #define _OUSIA_MANAGED_HPP_ +#include "ManagedType.hpp" #include "Manager.hpp" namespace ousia { @@ -32,6 +33,9 @@ class Rooted; template <class T> class Owned; +template <class T> +class DefaultListener; + // TODO: Implement clone, getReferenced and getReferencing /** @@ -93,33 +97,36 @@ public: return Owned<T>{t, this}; } - template <class T> - std::vector<Owned<T>> acquire(const std::vector<Handle<T>> &vec) - { - std::vector<Owned<T>> res; - for (auto &e : vec) { - res.push_back(acquire(e)); - } - return res; - } - - template <class T> - std::vector<Owned<T>> acquire(const std::vector<T *> &vec) - { - std::vector<Owned<T>> res; - for (auto &e : vec) { - res.push_back(acquire(e)); - } - return res; - } - void storeData(const std::string &key, Handle<Managed> h); bool hasDataKey(const std::string &key); Rooted<Managed> readData(const std::string &key); + std::map<std::string, Rooted<Managed>> readData(); + bool deleteData(const std::string &key); + + /** + * Returns the ManagedType instance registered for instances of the type + * of this Managed instance. + * + * @return a reference to the registered ManagedType for this particular + * Managed class. + */ + const ManagedType& type() const { + return ManagedType::typeOf(typeid(*this)); + } + + /** + * Returns true if this Managed instance is of the given ManagedType. + * + * @param true if the ManagedType registered for this particular Managed + * class is + */ + bool isa(const ManagedType &t) const { + return type().isa(t); + } }; /** @@ -506,24 +513,6 @@ public: Managed *getOwner() const { return owner; } }; - -inline void Managed::storeData(const std::string &key, Handle<Managed> h) { - mgr.storeData(this, key, h.get()); -} - -inline bool Managed::hasDataKey(const std::string &key) -{ - return mgr.readData(this, key) != nullptr; -} - -inline Rooted<Managed> Managed::readData(const std::string &key) { - return mgr.readData(this, key); -} - -inline bool Managed::deleteData(const std::string &key) { - return mgr.deleteData(this, key); -} - } #endif /* _OUSIA_MANAGED_HPP_ */ diff --git a/src/core/managed/ManagedContainer.hpp b/src/core/managed/ManagedContainer.hpp index 1454608..071db2c 100644 --- a/src/core/managed/ManagedContainer.hpp +++ b/src/core/managed/ManagedContainer.hpp @@ -30,14 +30,17 @@ #include <unordered_map> #include <unordered_set> #include <vector> -#include <iostream> #include <map> #include <type_traits> +#include "Manager.hpp" #include "Managed.hpp" namespace ousia { +template <class T> +class Handle; + /** * Default accessor class for accessing the managed element within a list value * type. @@ -57,7 +60,10 @@ struct ListAccessor { */ template <class ValueType> struct MapAccessor { - Managed *getManaged(const ValueType &val) const { return val.second.get(); } + Managed *getManaged(const ValueType &val) const + { + return val.second.get(); + } }; /** @@ -118,8 +124,9 @@ private: */ void initialize() { + Manager &manager = this->getManager(); for (const auto &elem : *this) { - addElement(elem); + addElement(manager, elem); } } @@ -130,8 +137,9 @@ private: void finalize() { if (owner) { + Manager &manager = this->getManager(); for (const auto &elem : *this) { - deleteElement(elem); + deleteElement(manager, elem); } } } @@ -152,9 +160,9 @@ protected: * @param elem is a reference to the actual element that is being added to * the underlying container. */ - void addElement(const value_type &elem) + void addElement(Manager &manager, const value_type &elem) { - getManager().addRef(accessor.getManaged(elem), owner); + manager.addRef(accessor.getManaged(elem), owner); listener.addElement(elem, owner); } @@ -168,20 +176,21 @@ protected: * @param elem is a reference to the actual element that is being removed * from the underlying container. */ - void deleteElement(const value_type &elem) + void deleteElement(Manager &manager, const value_type &elem) { - getManager().deleteRef(accessor.getManaged(elem), owner); + manager.deleteRef(accessor.getManaged(elem), owner); listener.deleteElement(elem, owner); } public: + /** * Constructor of the ManagedContainer class. * * @param owner is the managed object which owns the collection and all * handles to other managed objects stored within. */ - ManagedContainer(Handle<Managed> owner) : owner(owner.get()){}; + ManagedContainer(Handle<Managed> owner) : owner(owner.get()) {}; /** * Copy constructor. Creates a copy of the given container with the same @@ -211,7 +220,7 @@ public: * ownership. */ ManagedContainer(Handle<Managed> owner, const Collection &collection) - : owner(owner), c(collection) + : owner(owner.get()), c(collection) { initialize(); } @@ -302,26 +311,28 @@ public: /** * Equality operator. */ - bool operator==(const own_type &other) { + bool operator==(const own_type &other) + { return (owner == other.owner) && (c == other.c); } /** * Inequality operator. */ - bool operator!=(const own_type &other) { + bool operator!=(const own_type &other) + { return (owner != other.owner) || (c != other.c); } /** * Returns the owner of the ManagedContainer instance. */ - Managed *getOwner() { return owner; } + Managed *getOwner() const { return owner; } /** * Returns the manager instance associated with the owner. */ - Manager &getManager() { return owner->getManager(); } + Manager &getManager() const { return owner->getManager(); } /* State functions */ @@ -364,7 +375,7 @@ public: void clear() noexcept { for (const_iterator it = cbegin(); it != cend(); it++) { - deleteElement(*it); + deleteElement(this->getManager(), *it); } c.clear(); } @@ -374,7 +385,7 @@ public: */ iterator insert(const_iterator position, value_type val) { - addElement(val); + addElement(this->getManager(), val); return c.insert(position, val); } @@ -386,7 +397,7 @@ public: */ iterator erase(iterator position) { - deleteElement(*position); + deleteElement(this->getManager(), *position); return c.erase(position); } @@ -399,7 +410,7 @@ public: iterator erase(iterator first, iterator last) { for (const_iterator it = first; it != last; it++) { - this->deleteElement(*it); + this->deleteElement(this->getManager(), *it); } return c.erase(first, last); } @@ -478,14 +489,14 @@ public: void push_back(Handle<T> h) { - this->addElement(h.get()); + this->addElement(this->getManager(), h.get()); Base::c.push_back(h.get()); } void pop_back() { if (!Base::empty()) { - this->deleteElement(back()); + this->deleteElement(this->getManager(), back()); } Base::c.pop_back(); } @@ -515,13 +526,13 @@ public: std::pair<iterator, bool> insert(value_type val) { - this->addElement(val); + this->addElement(this->getManager(), val); return Base::c.insert(val); } iterator insert(const_iterator position, value_type val) { - this->addElement(val); + this->addElement(this->getManager(), val); return Base::c.insert(position, val); } diff --git a/src/core/managed/ManagedType.cpp b/src/core/managed/ManagedType.cpp new file mode 100644 index 0000000..ed4c7da --- /dev/null +++ b/src/core/managed/ManagedType.cpp @@ -0,0 +1,52 @@ +/* + 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 "ManagedType.hpp" + +namespace ousia { + +/* Instantiation of static variables */ + +const ManagedType ManagedType::None; + +/* Class ManagedType */ + +const ManagedType &ManagedType::typeOf(const std::type_info &nativeType) +{ + auto it = table().find(std::type_index{nativeType}); + if (it == table().end()) { + return None; + } else { + return *(it->second); + } +} + +bool ManagedType::isa(const ManagedType &other) const +{ + if (&other == this) { + return true; + } + for (auto t : parents) { + if (t->isa(other)) { + return true; + } + } + return false; +} +} + diff --git a/src/core/managed/ManagedType.hpp b/src/core/managed/ManagedType.hpp new file mode 100644 index 0000000..f3ed5fd --- /dev/null +++ b/src/core/managed/ManagedType.hpp @@ -0,0 +1,119 @@ +/* + 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/>. +*/ + +#ifndef _OUSIA_MANAGED_TYPE_HPP_ +#define _OUSIA_MANAGED_TYPE_HPP_ + +#include <typeinfo> +#include <typeindex> +#include <unordered_map> +#include <unordered_set> + +namespace ousia { + +/** + * The ManagedType is used to register type information that can be retrieved + * using the "type" method of the Managed class. + */ +class ManagedType { +private: + /** + * Used internally to store all registered native types and their + * corresponding type information. + */ + static std::unordered_map<std::type_index, ManagedType *>& table() { + static std::unordered_map<std::type_index, ManagedType *> table; + return table; + } + + /** + * Name of the type -- for messages and debug output. + */ + const std::string name; + + /** + * Set containing references to the parent types. + */ + const std::unordered_set<ManagedType *> parents; + +public: + /** + * ManagedType of no particular type. + */ + static const ManagedType None; + + /** + * Returns the ManagedType for the given type_info structure. + */ + static const ManagedType &typeOf(const std::type_info &nativeType); + + /** + * Default constructor. Creates a ManagedType instance with name "unknown" + * and no parents. + */ + ManagedType() : name("unknown") {} + + /** + * Creates a new ManagedType instance and registers it in the global type + * table. + * + * @param name is the name of the type. + * @param nativeType is the underlying C++ class the type should be attached + * to. + */ + ManagedType(std::string name, const std::type_info &nativeType) + : name(std::move(name)) + { + table().emplace(std::make_pair(std::type_index{nativeType}, this)); + } + + /** + * Creates a new ManagedType instance and registers it in the global type + * table. + * + * @param name is the name of the type. + * @param nativeType is the underlying C++ class the type should be attached + * to. + * @param parents is a list of parent types. + */ + ManagedType(std::string name, const std::type_info &nativeType, + std::unordered_set<ManagedType *> parents) + : name(std::move(name)), parents(parents) + { + table().emplace(std::make_pair(std::type_index{nativeType}, this)); + } + + /** + * Returns the name of this type. + */ + std::string getName() const { return name; } + + /** + * Returns true if this ManagedType instance is the given type or has the + *given + * type as one of its parents. + * + * @param other is the other type for which the relation to this type + * should be checked. + */ + bool isa(const ManagedType &other) const; +}; +} + +#endif /* _OUSIA_MANAGED_TYPE_HPP_ */ + |