summaryrefslogtreecommitdiff
path: root/include/extensible.h
diff options
context:
space:
mode:
authorAdam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864>2009-12-20 18:39:52 +0000
committerAdam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864>2009-12-20 18:39:52 +0000
commit7a7f1f8390f68f84350de63ff330184999264fcc (patch)
tree3990cde97ba0cd53db38114de9e4412b24930dd6 /include/extensible.h
parent861fe9e7b32c8e1e523cc774547e460c9ed67289 (diff)
Rewrote part of extensible, it will now automatically unallocate memory for us so we don't have to manually delete it everywhere anymore
git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@2711 5417fbe8-f217-4b02-8779-1006273d7864
Diffstat (limited to 'include/extensible.h')
-rw-r--r--include/extensible.h233
1 files changed, 233 insertions, 0 deletions
diff --git a/include/extensible.h b/include/extensible.h
new file mode 100644
index 000000000..beee04bd8
--- /dev/null
+++ b/include/extensible.h
@@ -0,0 +1,233 @@
+/*
+ *
+ * Copyright (C) 2008-2009 Anope Team <team@anope.org>
+ *
+ * Please read COPYING and README for further details.
+ *
+ *
+ * $Id$
+ *
+ */
+
+/** Dummy base class we use to cast everything to/from
+ */
+class ExtensibleItemBase
+{
+ public:
+ ExtensibleItemBase() { }
+ virtual ~ExtensibleItemBase() { }
+};
+
+/** Class used to represent an extensible item that doesn't hold a pointer
+ */
+template<typename T> class ExtensibleItemRegular : public ExtensibleItemBase
+{
+ protected:
+ T Item;
+
+ public:
+ ExtensibleItemRegular(T item) : Item(item) { }
+ virtual ~ExtensibleItemRegular() { }
+ T GetItem() const { return Item; }
+};
+
+/** Class used to represent an extensible item that holds a pointer
+ */
+template<typename T> class ExtensibleItemPointer : public ExtensibleItemBase
+{
+ protected:
+ T *Item;
+
+ public:
+ ExtensibleItemPointer(T *item) : Item(item) { }
+ virtual ~ExtensibleItemPointer() { delete Item; }
+ T *GetItem() const { return Item; }
+};
+
+/** Class used to represent an extensible item that holds a pointer to an arrray
+ */
+template<typename T> class ExtensibleItemPointerArray : public ExtensibleItemBase
+{
+ protected:
+ T *Item;
+
+ public:
+ ExtensibleItemPointerArray(T *item) : Item(item) { }
+ virtual ~ExtensibleItemPointerArray() { delete [] Item; }
+ T *GetItem() const { return Item; }
+};
+
+class CoreExport Extensible
+{
+ private:
+ std::map<std::string, ExtensibleItemBase *> Extension_Items;
+
+ public:
+ /** Default constructor, does nothing
+ */
+ Extensible() { }
+
+ /** Default destructor, deletes all of the extensible items in this object
+ * then clears the map
+ */
+ virtual ~Extensible()
+ {
+ for (std::map<std::string, ExtensibleItemBase *>::iterator it = Extension_Items.begin(); it != Extension_Items.end(); ++it)
+ {
+ delete it->second;
+ }
+ Extension_Items.clear();
+ }
+
+ /** Extend an Extensible class.
+ *
+ * @param key The key parameter is an arbitary string which identifies the extension data
+ * @param p This parameter is a pointer to an ExtensibleItem or ExtensibleItemBase derived class
+ *
+ * You must provide a key to store the data as via the parameter 'key'.
+ * The data will be inserted into the map. If the data already exists, you may not insert it
+ * twice, Extensible::Extend will return false in this case.
+ *
+ * @return Returns true on success, false if otherwise
+ */
+ bool Extend(const std::string &key, ExtensibleItemBase *p)
+ {
+ bool Ret = this->Extension_Items.insert(std::make_pair(key, p)).second;
+ if (!Ret)
+ delete p;
+ return Ret;
+ }
+
+ /** Extend an Extensible class.
+ *
+ * @param key The key parameter is an arbitary string which identifies the extension data
+ *
+ * You must provide a key to store the data as via the parameter 'key', this single-parameter
+ * version takes no 'data' parameter, this is used purely for boolean values.
+ * The key will be inserted into the map with a NULL 'data' pointer. If the key already exists
+ * then you may not insert it twice, Extensible::Extend will return false in this case.
+ *
+ * @return Returns true on success, false if otherwise
+ */
+ bool Extend(const std::string &key)
+ {
+ /* This will only add an item if it doesnt already exist,
+ * the return value is a std::pair of an iterator to the
+ * element, and a bool saying if it was actually inserted.
+ */
+ return this->Extend(key, new ExtensibleItemRegular<char *>(NULL));
+ }
+
+ /** Shrink an Extensible class.
+ *
+ * @param key The key parameter is an arbitary string which identifies the extension data
+ *
+ * You must provide a key name. The given key name will be removed from the classes data. If
+ * you provide a nonexistent key (case is important) then the function will return false.
+ * @return Returns true on success.
+ */
+ bool Shrink(const std::string &key)
+ {
+ std::map<std::string, ExtensibleItemBase *>::iterator it = this->Extension_Items.find(key);
+ if (it != this->Extension_Items.end())
+ {
+ delete it->second;
+ /* map::size_type map::erase( const key_type& key );
+ * returns the number of elements removed, std::map
+ * is single-associative so this should only be 0 or 1
+ */
+ return this->Extension_Items.erase(key);
+ }
+
+ return false;
+ }
+
+ /** Get an extension item that is not a pointer.
+ *
+ * @param key The key parameter is an arbitary string which identifies the extension data
+ * @param p If you provide a non-existent key, this value will be 0. Otherwise a copy to the item you requested will be placed in this templated parameter.
+ * @return Returns true if the item was found and false if it was nor, regardless of wether 'p' is NULL. This allows you to store NULL values in Extensible.
+ */
+ template<typename T> bool GetExtRegular(const std::string &key, T &p)
+ {
+ std::map<std::string, ExtensibleItemBase *>::iterator it = this->Extension_Items.find(key);
+
+ if (it != this->Extension_Items.end())
+ {
+ p = dynamic_cast<ExtensibleItemRegular<T> *>(it->second)->GetItem();
+ return true;
+ }
+
+ p = 0;
+ return false;
+ }
+
+ /** Get an extension item that is a pointer.
+ *
+ * @param key The key parameter is an arbitary string which identifies the extension data
+ * * @param p If you provide a non-existent key, this value will be NULL. Otherwise a pointer to the item you requested will be placed in this templated parameter.
+ * @return Returns true if the item was found and false if it was nor, regardless of wether 'p' is NULL. This allows you to store NULL values in Extensible.
+ */
+ template<typename T> bool GetExtPointer(const std::string &key, T *&p)
+ {
+ std::map<std::string, ExtensibleItemBase *>::iterator it = this->Extension_Items.find(key);
+
+ if (it != this->Extension_Items.end())
+ {
+ p = dynamic_cast<ExtensibleItemPointer<T> *>(it->second)->GetItem();
+ return true;
+ }
+
+ p = NULL;
+ return false;
+ }
+
+ /** Get an extension item that is a pointer to an array
+ *
+ * @param key The key parameter is an arbitary string which identifies the extension data
+ * @param p If you provide a non-existent key, this value will be NULL. Otherwise a pointer to the item you requested will be placed in this templated parameter.
+ * @return Returns true if the item was found and false if it was nor, regardless of wether 'p' is NULL. This allows you to store NULL values in Extensible.
+ */
+ template<typename T> bool GetExtArray(const std::string &key, T *&p)
+ {
+ std::map<std::string, ExtensibleItemBase *>::iterator it = this->Extension_Items.find(key);
+
+ if (it != this->Extension_Items.end())
+ {
+ p = dynamic_cast<ExtensibleItemPointerArray<T> *>(it->second)->GetItem();
+ return true;
+ }
+
+ p = NULL;
+ return false;
+ }
+
+ /** Get an extension item.
+ *
+ * @param key The key parameter is an arbitary string which identifies the extension data
+ * @return Returns true if the item was found and false if it was not.
+ *
+ * This single-parameter version only checks if the key exists, it does nothing with
+ * the 'data' field and is probably only useful in conjunction with the single-parameter
+ * version of Extend().
+ */
+ bool GetExt(const std::string &key)
+ {
+ return (this->Extension_Items.find(key) != this->Extension_Items.end());
+ }
+
+ /** Get a list of all extension items names.
+ * @param list A deque of strings to receive the list
+ * @return This function writes a list of all extension items stored
+ * in this object by name into the given deque and returns void.
+ */
+ void GetExtList(std::deque<std::string> &list)
+ {
+ for (std::map<std::string, ExtensibleItemBase *>::iterator i = Extension_Items.begin(); i != Extension_Items.end(); ++i)
+ {
+ list.push_back(i->first);
+ }
+ }
+
+};
+