Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Examples

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 
00061 
00062 #define DEF_OPS(name)                                           \
00063 public:                                                         \
00064     const YCP##name##Rep *operator ->() const {                 \
00065         return static_cast<const YCP##name##Rep *>(element); }  \
00066     YCP##name##Rep *operator ->() {                             \
00067         return const_cast<YCP##name##Rep *>(                    \
00068                static_cast<const YCP##name##Rep *>(element)); } \
00069 private:                                                        \
00070     int operator !() const;                                     \
00071     int operator ==(const YCPElement &) const;
00072 
00073 #define DEF_COMMON(name, base)                                  \
00074     DEF_OPS(name)                                               \
00075     friend class YCP##base##Rep;                                \
00076 public:                                                         \
00077     virtual size_t mem_size () const { return sizeof (YCP##name); } \
00078     YCP##name(const YCPNull &n) : YCP##base(n) {}               \
00079 protected:                                                      \
00080     YCP##name (const YCP##name##Rep *x) : YCP##base(x) {}
00081 
00082 
00083 #define DEF_COW_OPS(name)                                       \
00084 public:                                                         \
00085     const YCP##name *operator ->() const {                      \
00086         return static_cast<const YCP##name *>(this); }          \
00087     YCP##name *operator ->() {                                  \
00088         return const_cast<YCP##name *>(                         \
00089                static_cast<const YCP##name *>(this)); }         \
00090 private:                                                        \
00091     int operator !() const;                                     \
00092     int operator ==(const YCPElement &) const;
00093 
00094 #define DEF_COW_COMMON(name, base)                              \
00095     friend class YCP##base##Rep;                                \
00096     DEF_COW_OPS(name)                                           \
00097 public:                                                         \
00098     YCP##name(const YCPNull &n) : YCP##base(n) {}               \
00099 protected:                                                      \
00100     YCP##name (const YCP##name##Rep *x) : YCP##base(x) {}       \
00101 public:                                                         \
00102     YCPOrder compare(const YCP##name x) const {                 \
00103         return (static_cast<const YCP##name##Rep*>(element))->compare(x);                               \
00104     }                                                           \
00105     string toString () const { return element->toString (); }   \
00106     std::ostream & toStream (std::ostream & str ) const {       \
00107         return element->toStream (str);                         \
00108     }                                                           \
00109     YCPValueType valuetype () const { return (static_cast<const YCP##name##Rep*>(element))->valuetype (); }
00110 
00111 
00112 class YCPNull {};
00113 
00114 /***
00115  * <h2>The YCP Datastructures</h2>
00116  *
00117  * <p>YCP is both a scripting language and a communication protocol.
00118  * A YCP value is a data structure. It has currently two possible
00119  * representations. One ist an ASCII representation, the other is
00120  * a representation a network of C++ objects. The class framework
00121  * for this object representation is laid in this library. Furthermore
00122  * It contains the @ref Parser, that transforms an ASCII representation
00123  * of YCP values into the object-representation.
00124  *
00125  * <h2>YCP Data management</h2>
00126  *
00127  * <p>YCP data are managed via "smart pointers". This means that an application
00128  * instantiates an object from a class in a conventional way but does not get
00129  * the object itself. The result is a wrapper object that "points" to the real
00130  * object which is automatically created on instantiation. This real object
00131  * (the representation of the actual data) holds a reference counter and
00132  * therefore "knows" who is using it. After all references to this object have
00133  * diminished (e.g. auto variables get out of scope) the real object is
00134  * automatically destroyed. This way it is neither necessary nor allowed
00135  * to "new" or "delete" YCP data objects. Furthermore all members of the
00136  * object must be accessed using pointer notation.
00137  *
00138  * <p>So all YCP data objects do exist in two flavours:
00139  * <ul>
00140  * <li>Class name without "Rep" is the usable object, e.g. @ref YCPInteger.</li>
00141  * <li>Class name with "Rep" is the real Object, e.g. @ref YCPIntegerRep.</li>
00142  * </ul>
00143  *
00144  * <p>Important: Applications <i>never</i> use "Rep" classes directly!
00145  *
00146  * <p>Example:
00147  * <pre>
00148  * {
00149  *    YCPInteger a (18);         // here a YCPIntegerRep is created automatically
00150  *    YCPInteger b = a;          // b points to the same YCPIntegerRep as a
00151  *
00152  *    cout << b->toString ();    // use pointer notation to access members
00153  *    cout << b->value () - 18;  // a and b out of scope, last reference lost, YCPIntegerRep is destroyed automatically
00154  * }
00155  * </pre>
00156  */
00157 
00209 class YCPElementRep
00210 #ifdef D_MEMUSAGE
00211  : public MemUsage
00212 #endif
00213 {
00218     YCPElementRep& operator=(const YCPElementRep&);
00219 
00224     YCPElementRep(const YCPElementRep&);
00225 
00232     mutable int reference_counter;
00233 
00234 protected:
00235 
00236     friend class YCPElement;
00237 
00241     YCPElementRep();
00242 
00248     virtual ~YCPElementRep();
00249 
00250 public:
00254     YCPValue asValue() const;
00255 
00262     virtual string toString() const = 0;
00263 
00267     virtual std::ostream & toStream (std::ostream & str) const = 0;
00268     
00273     virtual const YCPElementRep* shallowCopy() const { return this; }
00274 
00275 private:
00286     void destroy() const;
00287 
00294     const YCPElementRep *clone() const;
00295 };
00296 
00303 class YCPElement
00304 #ifdef D_MEMUSAGE
00305  : public MemUsage
00306 #endif
00307 {
00308     DEF_OPS(Element);
00309 protected:
00310     const YCPElementRep *element;
00311     
00316     const YCPElementRep *writeCopy() { 
00317         if (element->reference_counter == 1 ) return element;
00318         
00319         const YCPElementRep* old = element;
00320         element = element->shallowCopy ();
00321         element->clone ();
00322         old->destroy ();
00323         return element;
00324     }
00325 
00326 public:
00327     YCPElement();
00328     YCPElement(const YCPNull&);
00329     YCPElement(const YCPElementRep *e);
00330     YCPElement(const YCPElement &e);
00331     virtual ~YCPElement();
00332     const YCPElement& operator=(const YCPElement& e);
00333     bool isNull() const { return element == 0; }
00334     bool refersToSameElementAs(const YCPElement& e) const { return element == e.element; }    
00335 };
00336 
00337 #endif   // YCPElement_h

Generated on Fri Nov 9 18:15:22 2007 for yast2-core by doxygen 1.3.6