home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / SLAX 6.0.8 / slax-6.0.8.iso / slax / base / 006-devel.lzm / usr / include / arts / reference.h < prev    next >
Encoding:
C/C++ Source or Header  |  2005-09-10  |  9.4 KB  |  350 lines

  1. /*
  2.     Copyright (C) 2000 Nicolas Brodu, nicolas.brodu@free.fr
  3.                        Stefan Westerfeld, stefan@space.twc.de
  4.  
  5.     This library is free software; you can redistribute it and/or
  6.     modify it under the terms of the GNU Library General Public
  7.     License as published by the Free Software Foundation; either
  8.     version 2 of the License, or (at your option) any later version.
  9.   
  10.     This library is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.     Library General Public License for more details.
  14.    
  15.     You should have received a copy of the GNU Library General Public License
  16.     along with this library; see the file COPYING.LIB.  If not, write to
  17.     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  18.     Boston, MA 02111-1307, USA.
  19. */
  20.  
  21. /*
  22.  * BC - Status (2002-03-08): Reference, SubClass, Object, DynamicCast.
  23.  *
  24.  * Part of the public API. Must be kept binary compatible by NOT TOUCHING
  25.  * AT ALL. Interaction with generated and written code.
  26.  */
  27.  
  28.  
  29. #ifndef MCOP_REFERENCE_H
  30. #define MCOP_REFERENCE_H
  31.  
  32. #include "common.h"
  33. #include <string>
  34. #include <vector>
  35.  
  36. #include "arts_export.h"
  37.  
  38. namespace Arts {
  39.  
  40. // Acts as a string or ObjectReference, but enables a different constructor
  41. class ARTS_EXPORT Reference {
  42. private:
  43.     ObjectReference myref;
  44.     std::string mys;
  45.     bool strMode;
  46. public:
  47.     
  48.     inline explicit Reference(const ObjectReference& ref) {
  49.         myref=ref;
  50.         strMode=false;
  51.     }
  52.  
  53.     inline explicit Reference(const std::string& s) {
  54.         mys=s;
  55.         strMode=true;
  56.     }
  57.     
  58.     inline explicit Reference(const char* c) {
  59.         mys=c;
  60.         strMode=true;
  61.     }
  62.     inline Reference& operator=(const std::string& s) {
  63.         mys=s;
  64.         strMode=true;
  65.         return *this;
  66.     }
  67.     inline Reference& operator=(const char*c) {
  68.         mys=c;
  69.         strMode=true;
  70.         return *this;
  71.     }
  72.     inline bool isString() const {return strMode;}
  73. //    inline operator const std::string() const {return mys;}
  74.     inline const std::string& string() const {return mys;}
  75. //    inline operator const ObjectReference() const {return myref;}
  76.     inline const ObjectReference& reference() const {return myref;}
  77. };
  78.  
  79. // Acts as a string, but enables a different constructor
  80. class ARTS_EXPORT SubClass {
  81. private:
  82.     std::string mys;
  83. public:
  84.  
  85.     inline explicit SubClass(const std::string& s) : mys(s) {}
  86.     inline explicit SubClass(const char* c) : mys(c) {}
  87.     inline SubClass& operator=(const std::string& s) {mys=s; return *this;}
  88.     inline SubClass& operator=(const char*c) {mys=c; return *this;}
  89. //    inline operator const std::string() const {return mys;}
  90.     inline const std::string& string() const {return mys;}
  91. };
  92.  
  93.  
  94. class ScheduleNode;
  95. class FlowSystem;
  96.  
  97. // Object has _no_ virtual, and must not have. That way, all the
  98. // wrappers can be passed as argument or return type, and there is also
  99. // no virtual table bloat.
  100. // Moreover, the virtual mechanism still works correctly thanks to the
  101. // _pool->base redirection.
  102. class ARTS_EXPORT Object {
  103. protected:
  104.     // Pool of common variables for a bunch a wrappers
  105.     class Pool {
  106.         friend class Object;
  107.         Object_base* (*creator)();
  108.         bool created;
  109.         int count;
  110.     public:
  111.         Object_base* base;
  112.         inline Pool(Object_base* b)
  113.             : creator(0), created(true), count(1), base(b) {}
  114.         inline Pool(Object_base* (*cor)())
  115.             : creator(cor), created(false), count(1), base(0) {}
  116.         inline void Inc() {count++;}
  117.         inline void Dec() {
  118.             if (--count==0) {
  119.                 if(base) base->_release();
  120.                 delete this;
  121.             }
  122.         }
  123.         inline void checkcreate() {
  124.             if (!created) {base = creator(); created=true;}
  125.         }
  126.     } *_pool;
  127.  
  128.     inline Object(Object_base* (*cor)()) {
  129.         _pool = new Pool(cor);
  130.     }
  131.     inline Object(Pool* p) : _pool(p) {
  132.         _pool->Inc();
  133.     }
  134.     inline Object(Pool& p) : _pool(&p) {
  135.         _pool->Inc();
  136.     }
  137.     inline Object(Object_base* b) {
  138.         _pool = new Pool(b);
  139.     }
  140. public:
  141.     typedef Object_base _base_class;
  142.  
  143.     // Dynamic cast constructor of inherited classes needs to access the _pool
  144.     // of a generic object if casting successful. But it could not without this
  145.     inline Pool* _get_pool() const {return _pool;}
  146.     
  147.     inline ~Object() {
  148.         _pool->Dec();
  149.     }
  150.     
  151.     // Those constructors are public, since we don't need an actual creator.
  152.     // They enable generic object creation (like from a subclass defined at
  153.     // run-time!)
  154.     inline Object(const SubClass& s) {
  155.         _pool = new Pool(Object_base::_create(s.string()));
  156.     }
  157.     inline Object(const Reference &r) {
  158.         _pool = new Pool(r.isString()?(Object_base::_fromString(r.string())):(Object_base::_fromReference(r.reference(),true)));
  159.     }
  160.     inline Object(const Object& target) : _pool(target._pool) {
  161.         _pool->Inc();
  162.     }
  163.     inline Object() { // creates a null object
  164.         _pool = new Pool((Object_base*)0);
  165.     }
  166.     inline Object& operator=(const Object& target) {
  167.         if (_pool == target._pool) return *this;
  168.         _pool->Dec();
  169.         _pool = target._pool;
  170.         _pool->Inc();
  171.         return *this;
  172.     }
  173.     // No problem for the creator, this class has protected constructors.
  174.     // So creator should give back an actual implementation
  175.     inline Object_base* _base() const {
  176.         _pool->checkcreate();
  177.         return _pool->base;
  178.     }
  179.  
  180.     // null, error?
  181.     inline bool isNull() const {
  182.         _pool->checkcreate();
  183.         return !(_pool->base);
  184.     }
  185.     inline bool error() const {
  186.         _pool->checkcreate();
  187.         return _pool->base && _pool->base->_error();
  188.     }
  189.     
  190.     // Comparision
  191.     inline bool _isEqual(const Object& other) const {
  192.         if(isNull() != other.isNull()) return false;
  193.  
  194.         // we can assume that things are created here, as we've
  195.         // called isNull of both wrappers once
  196.         if(!isNull())
  197.             return _pool->base->_isEqual(other._pool->base);
  198.  
  199.         // both null references
  200.         return true;
  201.     }
  202.  
  203.  
  204. // Object_base wrappers
  205.  
  206.     // Custom messaging - see Object_base for comments
  207.     inline Buffer *_allocCustomMessage(long handlerID) const {
  208.         _pool->checkcreate();
  209.         assert(_pool->base);
  210.         return _pool->base->_allocCustomMessage(handlerID);
  211.     }
  212.  
  213.     inline void _sendCustomMessage(Buffer *data) const {
  214.         _pool->checkcreate();
  215.         assert(_pool->base);
  216.         _pool->base->_sendCustomMessage(data);
  217.     }
  218.     
  219.     // generic capabilities, which allow find out what you can do with an
  220.     // object even if you don't know it's interface
  221.     inline long _lookupMethod(const MethodDef& methodDef) const {
  222.         _pool->checkcreate();
  223.         assert(_pool->base);
  224.         return _pool->base->_lookupMethod(methodDef);
  225.     }
  226.     inline std::string _interfaceName() const {
  227.         _pool->checkcreate();
  228.         assert(_pool->base);
  229.         return _pool->base->_interfaceName();
  230.     }
  231.     inline InterfaceDef _queryInterface(const std::string& name) const {
  232.         _pool->checkcreate();
  233.         assert(_pool->base);
  234.         return _pool->base->_queryInterface(name);
  235.     }
  236.     inline TypeDef _queryType(const std::string& name) const {
  237.         _pool->checkcreate();
  238.         assert(_pool->base);
  239.         return _pool->base->_queryType(name);
  240.     }
  241.     inline EnumDef _queryEnum(const std::string& name) const {
  242.         _pool->checkcreate();
  243.         assert(_pool->base);
  244.         return _pool->base->_queryEnum(name);
  245.     }
  246.     // Stringification
  247.     inline std::string _toString() const {
  248.         _pool->checkcreate();
  249.         assert(_pool->base);
  250.         return _pool->base->_toString();
  251.     }
  252.     inline std::string toString() const {return _toString();}
  253.  
  254.     // stuff for streaming (put in a seperate interface?)
  255.     inline void calculateBlock(unsigned long cycles) const {
  256.         _pool->checkcreate();
  257.         assert(_pool->base);
  258.         _pool->base->calculateBlock(cycles);
  259.     }
  260.     // Node info
  261.     inline ScheduleNode *_node() const {
  262.         _pool->checkcreate();
  263.         assert(_pool->base);
  264.         return _pool->base->_node();
  265.     }
  266.     
  267.     // Ah! Flowsystem is not defined yet, so cannot be returned inline.
  268.     FlowSystem _flowSystem() const;
  269.     
  270.     inline void _copyRemote() const {
  271.         _pool->checkcreate();
  272.         assert(_pool->base);
  273.         _pool->base->_copyRemote();
  274.     }
  275.     inline void _useRemote() const {
  276.         _pool->checkcreate();
  277.         assert(_pool->base);
  278.         _pool->base->_useRemote();
  279.     }
  280.     inline void _releaseRemote() const {
  281.         _pool->checkcreate();
  282.         assert(_pool->base);
  283.         _pool->base->_releaseRemote();
  284.     }
  285.     
  286.     // Default I/O info
  287.     inline std::vector<std::string> _defaultPortsIn() const {
  288.         _pool->checkcreate();
  289.         assert(_pool->base);
  290.         return _pool->base->_defaultPortsIn();
  291.     }
  292.     inline std::vector<std::string> _defaultPortsOut() const {
  293.         _pool->checkcreate();
  294.         assert(_pool->base);
  295.         return _pool->base->_defaultPortsOut();
  296.     }
  297.     
  298.     // aggregation
  299.     inline std::string _addChild(Arts::Object child, const std::string& name) const {
  300.         _pool->checkcreate();
  301.         assert(_pool->base);
  302.         return _pool->base->_addChild(child, name);
  303.     }
  304.     inline bool _removeChild(const std::string& name) const {
  305.         _pool->checkcreate();
  306.         assert(_pool->base);
  307.         return _pool->base->_removeChild(name);
  308.     }
  309.     inline Arts::Object _getChild(const std::string& name) const {
  310.         _pool->checkcreate();
  311.         assert(_pool->base);
  312.         return _pool->base->_getChild(name);
  313.     }
  314.     inline std::vector<std::string> * _queryChildren() const {
  315.         _pool->checkcreate();
  316.         assert(_pool->base);
  317.         return _pool->base->_queryChildren();
  318.     }
  319.     // Do we really need those in the Wrapper?
  320.     // And would it really be sensible to make _cast wrappers?
  321. /*    inline void _release() const {
  322.         _pool->checkcreate();
  323.         assert(_pool->base);
  324.         return _pool->base->_release();
  325.     }
  326.     inline Object_base *_copy() const {
  327.         _poo->checkcreate();
  328.         assert(_pool->base);
  329.         return _pool->base->_copy();
  330.     }
  331. */
  332.  
  333.     // Object::null() returns a null object (and not just a reference to one)
  334.     inline static Object null() {return Object((Object_base*)0);}
  335.     inline static Object _from_base(Object_base* b) {return Object(b);}
  336. };
  337.  
  338. // Enables a different constructor, that should do the cast
  339. class ARTS_EXPORT DynamicCast {
  340. private:
  341.     Object obj;
  342. public:
  343.     inline explicit DynamicCast(const Object& o) : obj(o) {}
  344.     inline const Object& object() const {return obj;}
  345. };
  346.  
  347. }
  348.  
  349. #endif
  350.