// Copyright (C) 1999-2005 Open Source Telecom Corporation. // // 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 2 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, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // As a special exception, you may use this file as part of a free software // library without restriction. Specifically, if other files instantiate // templates or use macros or inline functions from this file, or you compile // this file and link it with other files to produce an executable, this // file does not by itself cause the resulting executable to be covered by // the GNU General Public License. This exception does not however // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. // // This exception applies only to the code released under the name GNU // Common C++. If you copy code from other releases into a copy of GNU // Common C++, as the General Public License permits, the exception does // not apply to the code that you add in this way. To avoid misleading // anyone as to the status of such modified files, you must delete // this exception notice from them. // // If you write modifications of your own for GNU Common C++, it is your choice // whether to permit this exception to apply to your modifications. // If you do not wish that, delete this exception notice. // /** * @file object.h * @short Some object manipulation classes for smart pointers, linked lists, * etc. **/ #ifndef CCXX_OBJECT_H_ #define CCXX_OBJECT_H_ #ifndef CCXX_MISSING_H_ #include #endif #ifdef CCXX_NAMESPACES namespace ost { #endif class __EXPORT MapObject; /** * A reference countable object. This is used in association with smart * pointers (RefPointer). * * @author David Sugar * @short Object managed by smart pointer reference count. */ class __EXPORT RefObject { protected: friend class RefPointer; unsigned refCount; /** * The constructor simply initializes the count. */ inline RefObject() {refCount = 0;}; /** * The destructor is called when the reference count returns * to zero. This is done through a virtual destructor. */ virtual ~RefObject(); public: /** * The actual object being managed can be returned by this * method as a void and then recast to the actual type. This * removes the need to dynamic cast from RefObject and the * dependence on rtti this implies. * * @return underlying object being referenced. */ virtual void *getObject(void) = 0; }; /** * Pointer to reference counted objects. This is a non-template form * of a reference count smart pointer, and so uses common code. This * can be subclassed to return explicit object types. * * @author David Sugar * @short Pointer to reference count managed objects. */ class __EXPORT RefPointer { protected: RefObject *ref; /** * Detach current object, for example, when changing pointer. */ void detach(void); /** * Patch point for mutex in derived class. This may often * be a single static mutex shared by a managed type. */ virtual void enterLock(void); /** * Patch point for a mutex in derived class. This may often * be a single static mutex shared by a managed type. */ virtual void leaveLock(void); public: /** * Create an unattached pointer. */ inline RefPointer() {ref = NULL;}; /** * Create a pointer attached to a reference counted object. * * Object being referenced. */ RefPointer(RefObject *obj); /** * A copy constructor. * * Pointer being copied. */ RefPointer(const RefPointer &ptr); virtual ~RefPointer(); RefPointer& operator=(const RefObject &ref); inline void *operator*() const {return getObject();}; inline void *operator->() const {return getObject();}; void *getObject(void) const; bool operator!() const; }; /** * Self managed single linked list object chain. This is used for * accumulating lists by using as a base class for a derived subclass. * * @author David Sugar * @short Accumulating single linked list. */ class __EXPORT LinkedSingle { protected: LinkedSingle *nextObject; inline LinkedSingle() {nextObject = NULL;}; virtual ~LinkedSingle(); public: /** * Get first linked object in list. This may be dynamically * recast, and may refer to a master static bookmark pointer * in a derived class. Otherwise it simply returns the current * object. In a "free" list, this may not only return the first * object, but also set the first to next. * * @return pointer to first object in list. */ virtual LinkedSingle *getFirst(void); /** * Gets the last object in the list. This normally follows the * links to the end. This is a virtual because derived class * may include a static member bookmark for the current end. * * @return pointer to last object in list. */ virtual LinkedSingle *getLast(void); /** * Get next object, for convenience. Derived class may use * this with a dynamic cast. * * @return next object in list. */ inline LinkedSingle *getNext(void) {return nextObject;}; /** * Insert object into chain. This is a virtual because * derived class may choose instead to perform an insert * at head or tail, may manage bookmarks, and may add mutex lock. * * @param object being inserted. */ virtual void insert(LinkedSingle& obj); LinkedSingle &operator+=(LinkedSingle &obj); }; /** * Self managed double linked list object chain. This is used for * accumulating lists by using as a base class for a derived subclass. * * @author David Sugar * @short Accumulating double linked list. */ class __EXPORT LinkedDouble { protected: LinkedDouble *nextObject, *prevObject; inline LinkedDouble() {nextObject = prevObject = NULL;}; virtual ~LinkedDouble(); virtual void enterLock(void); virtual void leaveLock(void); public: /** * Requested in overloaded insert() method to indicate how to insert * data into list */ enum InsertMode { modeAtFirst, /**< insert at first position in list pointed by current object */ modeAtLast, /**< insert at last position in list pointed by current object */ modeBefore, /**< insert in list before current object */ modeAfter /**< insert in list after current object */ }; /** * Get first linked object in list. This may be dynamically * recast, and may refer to a master static bookmark pointer * in a derived class. Otherwise it follows list to front. * * @return pointer to first object in list. */ virtual LinkedDouble *getFirst(void); /** * Gets the last object in the list. This normally follows the * links to the end. This is a virtual because derived class * may include a static member bookmark for the current end. * * @return pointer to last object in list. */ virtual LinkedDouble *getLast(void); /** * Virtual to get the insert point to use when adding new members. This * may be current, or always head or always tail. As a virtual, this allows * derived class to establish "policy". * * @return pointer to insertion point in list. */ virtual LinkedDouble *getInsert(void); /** * Get next object, for convenience. Derived class may use * this with a dynamic cast. * * @return next object in list. */ inline LinkedDouble *getNext(void) {return nextObject;}; /** * Get prev object in the list. * * @return pointer to previous object. */ inline LinkedDouble *getPrev(void) {return prevObject;}; /** * Insert object into chain. * * @param object being inserted. */ virtual void insert(LinkedDouble& obj); /** * Insert object into chain at given position, as indicated by \ref InsertMode * * @param position where object is inserted. * @param object being inserted. */ virtual void insert(InsertMode position, LinkedDouble& obj); /** * Remove object from chain. */ virtual void detach(void); LinkedDouble &operator+=(LinkedDouble &obj); LinkedDouble &operator--(); }; /** * A map table allows for entities to be mapped (hash index) onto it. * Unlike with Assoc, This form of map table also allows objects to be * removed from the table. This table also includes a mutex lock for * thread safety. A free list is also optionally maintained for reusable * maps. * * @author David Sugar * @short Table to hold hash indexed objects. */ class __EXPORT MapTable : public Mutex { protected: friend class MapObject; unsigned range; MapObject **map; void cleanup(void); public: /** * Create a map table with a specified number of slots. * * @param number of slots. */ MapTable(unsigned size); /** * Destroy the table, calls cleanup. */ virtual ~MapTable(); /** * Get index value from id string. This function can be changed * as needed to provide better collision avoidence for specific * tables. * * @param id string * @return index slot in table. */ virtual unsigned getIndex(const char *id); /** * Return range of this table. * * @return table range. */ inline unsigned getRange(void) {return range;}; /** * Lookup an object by id key. It is returned as void * for * easy re-cast. * * @param key to find. * @return pointer to found object or NULL. */ void *getObject(const char *id); /** * Map an object to our table. If it is in another table * already, it is removed there first. * * @param object to map. */ void addObject(MapObject &obj); /** * Get next object from managed free list. This returns as a * void so it can be recast into the actual type being used in * derived MapObject's. A derived version of MapTable may well * offer an explicit type version of this. Some derived * MapObject's may override new to use managed list. * * @return next object on free list. */ void *getFree(void); /** * Add an object to the managed free list. Some MapObject's * may override delete operator to detach and do this. * * @param object to add. */ void addFree(MapObject *obj); /** * An operator to map an object to the table. * * @return table being used. * @param object being mapped. */ MapTable &operator+=(MapObject &obj); /** * This operator is virtual in case it must also add the object to a * managed free list. * * @return current table. * @param object entity to remove. */ virtual MapTable &operator-=(MapObject &obj); }; /** * The MapObject is a base class which can be used to make a derived * class operate on a MapTable. Derived classes may override new and * delete operators to use managed free list from a MapTable. * * @author David Sugar * @short Mappable object. */ class __EXPORT MapObject { protected: friend class MapTable; MapObject *nextObject; const char *idObject; MapTable *table; /** * Remove the object from it's current table. */ void detach(void); /** * Save id, mark as not using any table. * * @param id string for this object. */ MapObject(const char *id); }; #ifdef CCXX_NAMESPACES } #endif #endif /** EMACS ** * Local variables: * mode: c++ * c-basic-offset: 8 * End: */