YCPElement.h

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                                                                      |
00003 |                      __   __    ____ _____ ____                      |
00004 |                      \ \ / /_ _/ ___|_   _|___ \                     |
00005 |                       \ V / _` \___ \ | |   __) |                    |
00006 |                        | | (_| |___) || |  / __/                     |
00007 |                        |_|\__,_|____/ |_| |_____|                    |
00008 |                                                                      |
00009 |                               core system                            |
00010 |                                                        (C) SuSE GmbH |
00011 \----------------------------------------------------------------------/
00012 
00013    File:       YCPElement.h
00014 
00015    Author:     Mathias Kettner <kettner@suse.de>
00016    Maintainer: Klaus Kaempf <kkaempf@suse.de>
00017 
00018 /-*/
00019 // -*- c++ -*-
00020 
00021 #ifndef YCPElement_h
00022 #define YCPElement_h
00023 
00024 // MemUsage.h defines/undefines D_MEMUSAGE
00025 #include <y2util/MemUsage.h>
00026 
00027 // include only forward declarations of iostream
00028 #include <iosfwd>
00029 #include <string>
00030 #include <vector>
00031 #include <map>
00032 
00033 using std::string;
00034 using std::vector;
00035 using std::map;
00036 using std::pair;
00037 
00038 #include "toString.h"
00039 
00040 // forward declarations
00041 
00042 class YCPElement;
00043 class YCPValue;
00044 class YCPVoid;
00045 class YCPBoolean;
00046 class YCPInteger;
00047 class YCPFloat;
00048 class YCPString;
00049 class YCPByteblock;
00050 class YCPPath;
00051 class YCPSymbol;
00052 class YCPLocale;
00053 class YCPList;
00054 class YCPTerm;
00055 class YCPMap;
00056 class YCPBuiltin;
00057 class YCPCode;
00058 class YCPEntry;
00059 class YCPReference;
00060 class YCPExternal;
00061 
00062 
00063 #define DEF_OPS(name)                                           \
00064 public:                                                         \
00065     const YCP##name##Rep *operator ->() const {                 \
00066         return static_cast<const YCP##name##Rep *>(element); }  \
00067     YCP##name##Rep *operator ->() {                             \
00068         return const_cast<YCP##name##Rep *>(                    \
00069                static_cast<const YCP##name##Rep *>(element)); } \
00070 private:                                                        \
00071     int operator !() const;                                     \
00072     int operator ==(const YCPElement &) const;
00073 
00074 
00075 #ifdef D_MEMUSAGE
00076 #define DEF_MEMSIZE(name)                                       \
00077     virtual size_t mem_size () const { return sizeof (YCP##name); }
00078 #else
00079 #define DEF_MEMSIZE(name)
00080 #endif
00081 
00082 #define DEF_COMMON(name, base)                                  \
00083     DEF_OPS(name)                                               \
00084     friend class YCP##base##Rep;                                \
00085 public:                                                         \
00086     DEF_MEMSIZE(name)                                           \
00087     YCP##name(const YCPNull &n) : YCP##base(n) {}               \
00088 protected:                                                      \
00089     YCP##name (const YCP##name##Rep *x) : YCP##base(x) {}
00090 
00091 
00092 #define DEF_COW_OPS(name)                                       \
00093 public:                                                         \
00094     const YCP##name *operator ->() const {                      \
00095         return static_cast<const YCP##name *>(this); }          \
00096     YCP##name *operator ->() {                                  \
00097         return const_cast<YCP##name *>(                         \
00098                static_cast<const YCP##name *>(this)); }         \
00099 private:                                                        \
00100     int operator !() const;                                     \
00101     int operator ==(const YCPElement &) const;
00102 
00103 #define DEF_COW_COMMON(name, base)                              \
00104     friend class YCP##base##Rep;                                \
00105     DEF_COW_OPS(name)                                           \
00106 public:                                                         \
00107     YCP##name(const YCPNull &n) : YCP##base(n) {}               \
00108 protected:                                                      \
00109     YCP##name (const YCP##name##Rep *x) : YCP##base(x) {}       \
00110 public:                                                         \
00111     YCPOrder compare(const YCP##name x) const {                 \
00112         return (static_cast<const YCP##name##Rep*>(element))->compare(x);                               \
00113     }                                                           \
00114     string toString () const { return element->toString (); }   \
00115     std::ostream & toStream (std::ostream & str ) const {       \
00116         return element->toStream (str);                         \
00117     }                                                           \
00118     std::ostream & toXml (std::ostream & str, int indent ) const {      \
00119         return element->toXml( str, indent );                           \
00120     }                                                           \
00121     YCPValueType valuetype () const { return (static_cast<const YCP##name##Rep*>(element))->valuetype (); }
00122 
00123 
00124 class YCPNull {};
00125 
00126 /***
00127  * <h2>The YCP Datastructures</h2>
00128  *
00129  * <p>YCP is both a scripting language and a communication protocol.
00130  * A YCP value is a data structure. It has currently two possible
00131  * representations. One ist an ASCII representation, the other is
00132  * a representation a network of C++ objects. The class framework
00133  * for this object representation is laid in this library. Furthermore
00134  * It contains the @ref Parser, that transforms an ASCII representation
00135  * of YCP values into the object-representation.
00136  *
00137  * <h2>YCP Data management</h2>
00138  *
00139  * <p>YCP data are managed via "smart pointers". This means that an application
00140  * instantiates an object from a class in a conventional way but does not get
00141  * the object itself. The result is a wrapper object that "points" to the real
00142  * object which is automatically created on instantiation. This real object
00143  * (the representation of the actual data) holds a reference counter and
00144  * therefore "knows" who is using it. After all references to this object have
00145  * diminished (e.g. auto variables get out of scope) the real object is
00146  * automatically destroyed. This way it is neither necessary nor allowed
00147  * to "new" or "delete" YCP data objects. Furthermore all members of the
00148  * object must be accessed using pointer notation.
00149  *
00150  * <p>So all YCP data objects do exist in two flavours:
00151  * <ul>
00152  * <li>Class name without "Rep" is the usable object, e.g. @ref YCPInteger.</li>
00153  * <li>Class name with "Rep" is the real Object, e.g. @ref YCPIntegerRep.</li>
00154  * </ul>
00155  *
00156  * <p>Important: Applications <i>never</i> use "Rep" classes directly!
00157  *
00158  * <p>Example:
00159  * <pre>
00160  * {
00161  *    YCPInteger a (18);         // here a YCPIntegerRep is created automatically
00162  *    YCPInteger b = a;          // b points to the same YCPIntegerRep as a
00163  *
00164  *    cout << b->toString ();    // use pointer notation to access members
00165  *    cout << b->value () - 18;  // a and b out of scope, last reference lost, YCPIntegerRep is destroyed automatically
00166  * }
00167  * </pre>
00168  */
00169 
00221 class YCPElementRep
00222 #ifdef D_MEMUSAGE
00223  : public MemUsage
00224 #endif
00225 {
00230     YCPElementRep& operator=(const YCPElementRep&);
00231 
00236     YCPElementRep(const YCPElementRep&);
00237 
00244     mutable int reference_counter;
00245 
00246 protected:
00247 
00248     friend class YCPElement;
00249 
00253     YCPElementRep();
00254 
00260     virtual ~YCPElementRep();
00261 
00262 public:
00266     YCPValue asValue() const;
00267 
00274     virtual string toString() const = 0;
00275 
00279     virtual std::ostream & toStream (std::ostream & str) const = 0;
00280     virtual std::ostream & toXml (std::ostream & str, int indent ) const = 0;
00281     
00286     virtual const YCPElementRep* shallowCopy() const { return this; }
00287 
00288 private:
00299     void destroy() const;
00300 
00307     const YCPElementRep *clone() const;
00308 };
00309 
00316 class YCPElement
00317 #ifdef D_MEMUSAGE
00318  : public MemUsage
00319 #endif
00320 {
00321     DEF_OPS(Element);
00322 protected:
00323     const YCPElementRep *element;
00324     
00329     const YCPElementRep *writeCopy() { 
00330         if (element->reference_counter == 1 ) return element;
00331         
00332         const YCPElementRep* old = element;
00333         element = element->shallowCopy ();
00334         element->clone ();
00335         old->destroy ();
00336         return element;
00337     }
00338 
00339 public:
00340     YCPElement();
00341     YCPElement(const YCPNull&);
00342     YCPElement(const YCPElementRep *e);
00343     YCPElement(const YCPElement &e);
00344     ~YCPElement();
00345     const YCPElement& operator=(const YCPElement& e);
00346     bool isNull() const { return element == 0; }
00347     bool refersToSameElementAs(const YCPElement& e) const { return element == e.element; }    
00348 };
00349 
00350 #endif   // YCPElement_h

Generated on Tue Nov 6 01:27:46 2007 for yast2-core by  doxygen 1.5.3