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

Generated on Fri Jun 16 18:07:45 2006 for yast2-core by  doxygen 1.4.6