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     YCPValueType valuetype () const { return (static_cast<const YCP##name##Rep*>(element))->valuetype (); }
00119 
00120 
00121 class YCPNull {};
00122 
00123 /***
00124  * <h2>The YCP Datastructures</h2>
00125  *
00126  * <p>YCP is both a scripting language and a communication protocol.
00127  * A YCP value is a data structure. It has currently two possible
00128  * representations. One ist an ASCII representation, the other is
00129  * a representation a network of C++ objects. The class framework
00130  * for this object representation is laid in this library. Furthermore
00131  * It contains the @ref Parser, that transforms an ASCII representation
00132  * of YCP values into the object-representation.
00133  *
00134  * <h2>YCP Data management</h2>
00135  *
00136  * <p>YCP data are managed via "smart pointers". This means that an application
00137  * instantiates an object from a class in a conventional way but does not get
00138  * the object itself. The result is a wrapper object that "points" to the real
00139  * object which is automatically created on instantiation. This real object
00140  * (the representation of the actual data) holds a reference counter and
00141  * therefore "knows" who is using it. After all references to this object have
00142  * diminished (e.g. auto variables get out of scope) the real object is
00143  * automatically destroyed. This way it is neither necessary nor allowed
00144  * to "new" or "delete" YCP data objects. Furthermore all members of the
00145  * object must be accessed using pointer notation.
00146  *
00147  * <p>So all YCP data objects do exist in two flavours:
00148  * <ul>
00149  * <li>Class name without "Rep" is the usable object, e.g. @ref YCPInteger.</li>
00150  * <li>Class name with "Rep" is the real Object, e.g. @ref YCPIntegerRep.</li>
00151  * </ul>
00152  *
00153  * <p>Important: Applications <i>never</i> use "Rep" classes directly!
00154  *
00155  * <p>Example:
00156  * <pre>
00157  * {
00158  *    YCPInteger a (18);         // here a YCPIntegerRep is created automatically
00159  *    YCPInteger b = a;          // b points to the same YCPIntegerRep as a
00160  *
00161  *    cout << b->toString ();    // use pointer notation to access members
00162  *    cout << b->value () - 18;  // a and b out of scope, last reference lost, YCPIntegerRep is destroyed automatically
00163  * }
00164  * </pre>
00165  */
00166 
00218 class YCPElementRep
00219 #ifdef D_MEMUSAGE
00220  : public MemUsage
00221 #endif
00222 {
00227     YCPElementRep& operator=(const YCPElementRep&);
00228 
00233     YCPElementRep(const YCPElementRep&);
00234 
00241     mutable int reference_counter;
00242 
00243 protected:
00244 
00245     friend class YCPElement;
00246 
00250     YCPElementRep();
00251 
00257     virtual ~YCPElementRep();
00258 
00259 public:
00263     YCPValue asValue() const;
00264 
00271     virtual string toString() const = 0;
00272 
00276     virtual std::ostream & toStream (std::ostream & str) const = 0;
00277     
00282     virtual const YCPElementRep* shallowCopy() const { return this; }
00283 
00284 private:
00295     void destroy() const;
00296 
00303     const YCPElementRep *clone() const;
00304 };
00305 
00312 class YCPElement
00313 #ifdef D_MEMUSAGE
00314  : public MemUsage
00315 #endif
00316 {
00317     DEF_OPS(Element);
00318 protected:
00319     const YCPElementRep *element;
00320     
00325     const YCPElementRep *writeCopy() { 
00326         if (element->reference_counter == 1 ) return element;
00327         
00328         const YCPElementRep* old = element;
00329         element = element->shallowCopy ();
00330         element->clone ();
00331         old->destroy ();
00332         return element;
00333     }
00334 
00335 public:
00336     YCPElement();
00337     YCPElement(const YCPNull&);
00338     YCPElement(const YCPElementRep *e);
00339     YCPElement(const YCPElement &e);
00340     ~YCPElement();
00341     const YCPElement& operator=(const YCPElement& e);
00342     bool isNull() const { return element == 0; }
00343     bool refersToSameElementAs(const YCPElement& e) const { return element == e.element; }    
00344 };
00345 
00346 #endif   // YCPElement_h

Generated on Tue Nov 6 01:20:21 2007 for yast2-core by  doxygen 1.5.0