libs/EDoc/IndexedDictionary.h

Go to the documentation of this file.
00001 /*******************************************************************************
00002 
00003    Copyright (C) 2007 by Brendon Costa
00004 
00005    This library is free software; you can redistribute it and/or modify 
00006    it under the terms of the "LGPL Like" License defined in the file COPYING 
00007    that should have been distributed along with this source.
00008 
00009    This library is distributed in the hope that it will be useful, 
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of 
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013    You should have received a copy of the "LGPL Like" License 
00014    along with this library; see the file COPYING. if not, it can be 
00015    obtained from the EDoc++ website: 
00016    http://edoc.sourceforge.net/license.html
00017 
00018 *******************************************************************************/
00019 #ifndef EDOC_INDEXEDDICTIONARY_H
00020 #define EDOC_INDEXEDDICTIONARY_H
00021 
00022 #include "EDoc/stdint.h"
00023 #include "EDoc/Dictionary.h"
00024 #include "EDoc/utils.h"
00025 #include "EDoc/exceptions.h"
00026 #include "EDoc/StringIdentifiedObject.h"
00027 #include <vector>
00028 
00029 // @@@Brendon Not sure why i need to include these here to compile on GCC 4
00030 // Works fine without them on GCC 3
00031 #include "EDoc/Function.h"
00032 #include "EDoc/FunctionType.h"
00033 #include "EDoc/Type.h"
00034 
00035 namespace EDoc
00036 {
00037    class Type;
00038    class Function;
00039    class Dictionary;
00040    class File;
00041 
00042    //===========================================================================
00043    /** \brief Stores a map of StringIdentifiedObject's that are indexed by an
00044     * integer value.
00045     *
00046     * This is designed to be used for the process of loading EDoc++ data items
00047     * from a file. In the EDoc++ data format all items are identified by a 
00048     * integer instead of a string to reduce the size of the resulting data file.
00049     */
00050    class IndexedObject
00051    {
00052    public:
00053    
00054       //------------------------------------------------------------------------
00055       /** \brief Create an instance to manage loading for the given dictionary.
00056        */
00057       IndexedObject(Dictionary& dict_in) :
00058          dict(dict_in)
00059       {
00060       }
00061 
00062       //------------------------------------------------------------------------
00063       /** \brief Destructor.
00064        */
00065       virtual ~IndexedObject() {}
00066 
00067       //------------------------------------------------------------------------
00068       /** \brief Obtain the instance for the given index or return NULL if one 
00069        * does not exist.
00070        */
00071       StringIdentifiedObject* CGet(uint32_t index)
00072       {
00073          if (index < items.size())
00074          {
00075             return items[index];
00076          }
00077          else
00078          {
00079             return NULL;
00080          }
00081       }
00082 
00083       //------------------------------------------------------------------------
00084       /** \brief Adds an existing StringIdentifiedObject instance to this map.
00085        *
00086        * Should not be called ore than once for a single index.
00087        */
00088       void CAdd(uint32_t index, StringIdentifiedObject* item)
00089       {
00090          // Make the vector larger if it is too small.
00091          if (index >= items.size())
00092          {
00093             items.resize(index + 1, NULL);
00094          }
00095 
00096          if (items[index] != NULL)
00097          {
00098             EDOC_THROW_EXCEPTION(FileIOException, "Multiple records with same index."
00099                "The index: " << index << ", was previously taken.",
00100                "");
00101          }
00102          items[index] = item;
00103          item->index = index;
00104       }
00105 
00106       //------------------------------------------------------------------------
00107       /** \brief Obtain the instance for the given index or create one if one 
00108        * does not exist.
00109        */
00110       StringIdentifiedObject* CAlwaysGet(uint32_t index)
00111       {
00112          StringIdentifiedObject* item = CGet(index);
00113          if (!item)
00114          {
00115             item = New(dict, index);
00116             CAdd(index, item);
00117          }
00118 
00119          return item;
00120       }
00121 
00122       //------------------------------------------------------------------------
00123       /** \brief Implemented in child to create instance of specific 
00124        * derivation from StringIdentifiedObject.
00125        */
00126       virtual StringIdentifiedObject* New(Dictionary& dict, uint32_t index) = 0;
00127 
00128       //------------------------------------------------------------------------
00129       /** \brief Reference to the dictionary object that all instances belong.
00130        */
00131       Dictionary& dict;
00132 
00133       //------------------------------------------------------------------------
00134       /** \brief List of items that currently exist.
00135        */
00136       // @@@Brendon Probably create a map for this.
00137       std::vector<StringIdentifiedObject*> items;
00138    };
00139    
00140    //===========================================================================
00141    /** \brief Specific varient of IndexedObject for a particular 
00142     * StringIdentifiedObject derivation type like, File, Function etc.
00143     */
00144    template<typename T>
00145    class SpecificIndexedObject : public IndexedObject
00146    {
00147    public:
00148       
00149       //------------------------------------------------------------------------
00150       /** \brief Create an instance for a specific dictionary.
00151        */
00152       SpecificIndexedObject(Dictionary& dict_in) :
00153          IndexedObject(dict_in)
00154       {
00155       }
00156       
00157       //------------------------------------------------------------------------
00158       /** \brief Create a new instance of the type with the given index as an
00159        * identifier.
00160        */
00161       virtual StringIdentifiedObject* New(Dictionary& dict, uint32_t index)
00162       {
00163          T* item = NULL;
00164          AllocNew(item, dict, index);
00165          return static_cast<StringIdentifiedObject*>(item);
00166       }
00167 
00168       //------------------------------------------------------------------------
00169       /** \brief Type specific implementation of IndexedObject::CGet()
00170        */
00171       T* Get(uint32_t index)
00172       {
00173          return dynamic_cast<T*>(CGet(index));
00174       }
00175 
00176       //------------------------------------------------------------------------
00177       /** \brief Type specific implementation of IndexedObject::AlwaysGet()
00178        */
00179       T* AlwaysGet(uint32_t index)
00180       {
00181          return dynamic_cast<T*>(CAlwaysGet(index));
00182       }
00183       
00184       //------------------------------------------------------------------------
00185 
00186    };
00187    //===========================================================================
00188 
00189 
00190 
00191    //===========================================================================
00192    /** \brief Manages all File, Type, FunctionType, and Function instances as 
00193     * they are being loaded from a EDoc++ data file. 
00194     *
00195     * This stores all items indexed by an integer value.
00196     */
00197    class IndexedDictionary
00198    {
00199       friend class Dictionary;
00200    public:
00201 
00202       //------------------------------------------------------------------------
00203       /** \brief Create an instance for loading data for the given dictionary.
00204        */
00205       IndexedDictionary(Dictionary& dict_in) :
00206          files(dict_in),
00207          types(dict_in),
00208          function_types(dict_in),
00209          functions(dict_in),
00210          dict(&dict_in)
00211       {}
00212 
00213       //------------------------------------------------------------------------
00214       /** \brief Returns a vector with all managed types.
00215        *
00216        * This is a helper to simplify the code a little.
00217        */
00218       std::vector<IndexedObject*> GetManagedObjects()
00219       {
00220          // NOTE: The order is important here.
00221          std::vector<IndexedObject*> ret;
00222          ret.push_back(&files);
00223          ret.push_back(&types);
00224          ret.push_back(&function_types);
00225          ret.push_back(&functions);
00226          
00227          return ret;
00228       }
00229 
00230       //------------------------------------------------------------------------
00231       /** \brief Map of all File instances.
00232        */
00233       SpecificIndexedObject<File> files;
00234 
00235       //------------------------------------------------------------------------
00236       /** \brief Map of all Type instances.
00237        */
00238       SpecificIndexedObject<Type> types;
00239 
00240       //------------------------------------------------------------------------
00241       /** \brief Map of all FunctionType instances.
00242        */
00243       SpecificIndexedObject<FunctionType> function_types;
00244 
00245       //------------------------------------------------------------------------
00246       /** \brief Map of all Function instances.
00247        */
00248       SpecificIndexedObject<Function> functions;
00249 
00250       //------------------------------------------------------------------------
00251       /** \brief A reference to the dictionary all these instances belong to.
00252        */
00253       Dictionary* dict;
00254       
00255       //------------------------------------------------------------------------
00256    };
00257 }
00258 
00259 #endif // EDOC_INDEXEDDICTIONARY_H

Generated on Tue Jan 20 18:26:07 2009 for EDoc-0.2.1 by  doxygen 1.5.1