include/EDoc/DictionarySpecific.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_DICTIONARYSPECIFIC_H
00020 #define EDOC_DICTIONARYSPECIFIC_H
00021 
00022 #include "EDoc/stdint.h"
00023 #include <string>
00024 #include <iostream>
00025 
00026 
00027 namespace EDoc
00028 {
00029    class Dictionary;
00030    class PStack;
00031    class ManagedObject;
00032    
00033    
00034    //===========================================================================
00035    /** \brief Encapsulates functionality common to all dictionary specific
00036     * types.
00037     *
00038     * A dictionary specific type is a type/class which "belongs" to a particular
00039     * instance of the Dictionary class. Objects that belong to one dictionary
00040     * can NOT be referenced by object from another dictionary. They need to be
00041     * specially copied/merged. For this reason there is special processing that
00042     * occurs for assignment and copies of dictionary specific objects to ensure
00043     * that these rules are not violated.
00044     *
00045     *
00046     * HISTORY
00047     *
00048     * This was done because the other option was to use identifiers and lookups
00049     * or copies of all the data. Initially this was attempted but processing
00050     * time and memory usage were enormous, so the method was changed in order to
00051     * store pointers directly to members. However objects can only store
00052     * pointers to other members that belong to the same Dictionary instance.
00053     * This means that when a dictionary object is destroyed along with all
00054     * objects that "belong" to it, no other objects are invalidated.
00055     *
00056     * As a result this class was created in order to simplify management of
00057     * these objects.
00058     *
00059     * All DictionarySpecific objects have functionality to replace pointer
00060     * references and to validate themselves. 
00061     *
00062     * \see See Dictionary.
00063     */
00064    class DictionarySpecific
00065    {
00066       friend class ManagedObject;
00067    public:
00068 
00069       //------------------------------------------------------------------------
00070       /** \brief Create this dictionary specific object belonging to the given
00071        * dictionary.
00072        *
00073        * \param dict_in The dictionary that this object will belong to
00074        * if NULL then will use the dictionary that can be obtained by:
00075        * GetCurrentDictionaryAssert()
00076        */
00077       DictionarySpecific(Dictionary* dict_in);
00078    
00079       //------------------------------------------------------------------------
00080       /** \brief Destructor.
00081        */
00082       virtual ~DictionarySpecific() {}
00083 
00084       //------------------------------------------------------------------------
00085       /** \brief Replaces all references of pointers referencing remove with
00086        * pointers to replace.
00087        *
00088        * The replacement is used because when after Read()'ing it is possible to
00089        * have two instances of an object indexed by the same key. The contents
00090        * of them must be merged and all references to one object be changed to
00091        * reference the other. Then the now unreferenced object would be deleted.
00092        * This is a part of the loading phase and is a result of the fact that
00093        * GCC can generate multiple tree nodes for a single type. Thus when
00094        * loading we often get the same type multiple times. 
00095        *
00096        * \todo As an option in the future we may choose to allow replace to be a
00097        * NULL pointer. In which case it will completely erase references to a
00098        * particular object instead of having to replace them with something
00099        * else. This works for containers, but for non-optional fixed pointers it
00100        * may cause some problems. Maybe in these cases, we should throw an
00101        * exception that indicates to the user that they cant just erase that
00102        * reference, they must at least replace it in some places with something
00103        * or first erase other nodes that reference it first. This exception
00104        * would need to include as its data a reference to the object that cant
00105        * release its reference to "remove".
00106        */
00107       virtual size_t ReplaceReferences(PStack& stack, 
00108          void* remove, void* replace) = 0;
00109 
00110       //------------------------------------------------------------------------
00111       /** \brief Print the current object to the given stream in a user readable
00112        * manner.
00113        *
00114        * \param out The stream to print to.
00115        *
00116        * \param prefix A string prefix to display at the start of every line. As
00117        * an example this can be used in order to indent the print by passing
00118        * "\t" as the string.
00119        */
00120       virtual std::ostream& Print(std::ostream& out, 
00121          std::string prefix="") const = 0;
00122 
00123       //------------------------------------------------------------------------
00124       /** \brief Returns a string representing the current object in a user
00125        * readable manner.
00126        *
00127        * This will return as a string exactly what Print() would display. This
00128        * is primarily here for use from within python and for debugging.
00129        */
00130       std::string ToString(std::string prefix="") const;
00131 
00132       //------------------------------------------------------------------------
00133       /** \brief Performs internal valtidation on the current object and will
00134        * throw a BugException if the validation fails.
00135        *
00136        * This is primarily used to ensure that all DictionarySpecific objects
00137        * are internally consistent, not referencing dictionaries that they
00138        * actually do not belong to. It is also used for a few other validations
00139        * too that if they fail would indicate a bug in the code somewhere.
00140        */
00141       virtual void Validate(PStack& stack, const Dictionary& dict_in) const = 0;
00142 
00143       //------------------------------------------------------------------------
00144 
00145    protected:
00146    
00147       //------------------------------------------------------------------------
00148       /** \brief A reference to the dictionary this object belongs to.
00149        */
00150       Dictionary& dict;
00151       
00152       //------------------------------------------------------------------------
00153    
00154    private:
00155    
00156       //------------------------------------------------------------------------
00157       /** \brief COPY DISALLOWED.
00158        */
00159       DictionarySpecific(const DictionarySpecific& right);
00160    
00161       //------------------------------------------------------------------------
00162       /** \brief ASSIGNMENT DISALLOWED.
00163        */
00164       DictionarySpecific& operator=(const DictionarySpecific& right);
00165 
00166       //------------------------------------------------------------------------
00167    };
00168    //===========================================================================
00169 }
00170 
00171 namespace std
00172 {
00173    //===========================================================================
00174    /** \brief See DictionarySpecific::Print()
00175     */
00176    static inline std::ostream& operator<<(std::ostream& out, 
00177       const EDoc::DictionarySpecific& value)
00178    {
00179       return value.Print(out);
00180    }
00181    //===========================================================================
00182 }
00183 
00184 #endif // EDOC_DICTIONARYSPECIFIC_H

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