home *** CD-ROM | disk | FTP | other *** search
/ Power GUI Programming with VisualAge C++ / powergui.iso / trialva / ibmcppw / include / imetaimp.hpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-22  |  17.2 KB  |  376 lines

  1. #ifndef _IMETAIMP_
  2. #define _IMETAIMP_
  3. /*******************************************************************************
  4. * FILE NAME: imetaimp.hpp                                                      *
  5. *                                                                              *
  6. * DESCRIPTION:                                                                 *
  7. *   Macros and template definitions for the classes:                           *
  8. *     IMetaTypeInfo                                                            * 
  9. *                                                                              *
  10. * COPYRIGHT:                                                                   *
  11. *   IBM Open Class Library                                                     *
  12. *   (C) Copyright International Business Machines Corporation 1992, 1996       *
  13. *   Licensed Material - Program-Property of IBM - All Rights Reserved.         *
  14. *   US Government Users Restricted Rights - Use, duplication, or disclosure    *
  15. *   restricted by GSA ADP Schedule Contract with IBM Corp.                     *
  16. *                                                                              *
  17. *   Portions or this component are based on work originating from Taligent.    *
  18. *   (C) Copyright Taligent, Inc. 1996 - All rights reserved.                   *
  19. *                                                                              *
  20. *******************************************************************************/
  21. #ifdef IC_LIBRARYUSEONLY
  22. //
  23. // Added to reduce last minute changes...
  24. //
  25. typedef IMetaTypeInfo typeinfo;
  26. #define typeid(x) dynamicTypeInfo(x)
  27. #define static_type_info(x) staticTypeInfo(x)
  28.  
  29. #endif
  30.  
  31. #define staticTypeInfo(AType) (*AType::TGB((ITypeHelper*)0))
  32.  
  33. template <class AType>
  34. inline const IMetaTypeInfo& dynamicTypeInfo(const AType& obj)
  35. {
  36.     const IMetaTypeInfo* info = 0;
  37. #ifdef IC_LIBRARYUSEONLY
  38.     info = obj.TGV();
  39. #endif
  40.     return *info;
  41. }
  42.  
  43. inline int IMetaTypeInfo::operator==(const IMetaTypeInfo& other) const
  44. {
  45.     return (this == &other);
  46. }
  47.  
  48. inline int IMetaTypeInfo::operator!=(const IMetaTypeInfo& other) const
  49. {
  50.     return (this != &other);
  51. }
  52.  
  53. inline const char* IMetaTypeInfo::name() const
  54. {
  55.     return theName;
  56. }
  57.  
  58. #ifdef IC_LIBRARYUSEONLY
  59.  
  60. #include <iostream.h>
  61. #define TypeExtensionDeclarationsMacro(aname)\
  62.     static const IMetaTypeInfo* gTypeInfo;\
  63.     virtual const IMetaTypeInfo* TGV() const;\
  64.     static const IMetaTypeInfo* TGB(ITypeHelper* helper);\
  65.     static void*                TGD(const void* obj);\
  66.     virtual void*               TGC(IBoolean returnThis) const;\
  67.     static IString              TGCls();\
  68.     static ITypeInstaller       gInstaller;
  69. #define TypeExtensionMacro(aname)\
  70.     const IMetaTypeInfo*        aname::gTypeInfo = 0;\
  71.     const IMetaTypeInfo*        aname::TGV() const {\
  72.         return TGB((ITypeHelper*)0); };\
  73.     const IMetaTypeInfo*        aname::TGB(ITypeHelper* helper) {\
  74.         if (helper == 0) {\
  75.             if (gTypeInfo == 0)\                
  76.                 gTypeInfo = ITypeHelper::StaticCreate(TGCls(), &TGB, &TGD);\
  77.             return gTypeInfo; }\
  78.         else {\
  79.             try { helper->ThrowObject(); } catch (aname* obj) { helper->CaughtObject(obj); }; return 0; } };\
  80.     void*                       aname::TGD(const void* obj) {\
  81.         if (obj == 0) {\
  82.             return new aname(); }\
  83.         else {\
  84.             throw (aname*) obj; } };\
  85.     void*                       aname::TGC(IBoolean returnThis) const {\
  86.         if (returnThis) {\
  87.             return (void*)this;\
  88.         } else {\
  89.             throw new aname(*this); } };\
  90.     IString                     aname::TGCls() { return #aname; };\
  91.     ITypeInstaller              aname::gInstaller(TGCls(), &TGB);
  92. #define TypeExtensionDeclarationsMacro_Abstract(aname)\
  93.     static const IMetaTypeInfo* gTypeInfo;\
  94.     virtual const IMetaTypeInfo* TGV() const;\
  95.     static const IMetaTypeInfo* TGB(ITypeHelper* helper);\
  96.     static void*                TGD(const void* obj);\
  97.     virtual void*               TGC(IBoolean returnThis) const;\
  98.     static IString              TGCls();\
  99.     static ITypeInstaller       gInstaller;
  100. #define TypeExtensionMacro_Abstract(aname)\
  101.     const IMetaTypeInfo*        aname::gTypeInfo = 0;\
  102.     const IMetaTypeInfo*        aname::TGV() const {\
  103.         return TGB((ITypeHelper*)0); };\
  104.     const IMetaTypeInfo*        aname::TGB(ITypeHelper* helper) {\
  105.         if (helper == 0) {\
  106.             if (gTypeInfo == 0)\                
  107.                 gTypeInfo =     ITypeHelper::StaticCreate(TGCls(), &TGB, &TGD);\
  108.             return gTypeInfo; }\
  109.         else {\
  110.             try { helper->ThrowObject(); } catch (aname* obj) { helper->CaughtObject(obj); }; return 0; } };\
  111.     void*                       aname::TGD(const void* obj) {\
  112.         if (obj == 0) {\
  113.             return ITypeHelper::CantConstructAbstractClass(); }\
  114.         else {\
  115.             throw (aname*) obj; } };\
  116.     void*                       aname::TGC(IBoolean returnThis) const {\
  117.         if (returnThis) {\
  118.             return (void*)this;\
  119.         } else {\
  120.             return (void*)ITypeHelper::CantConstructAbstractClass(); } };\
  121.     IString                     aname::TGCls() { return #aname; };\
  122.     ITypeInstaller              aname::gInstaller(TGCls(), &TGB);
  123. #define TypeExtensionTemplateDeclarationsMacro(_tclass,_ptype)\
  124.     static const IMetaTypeInfo* gTypeInfo;\
  125.     virtual const IMetaTypeInfo* TGV() const;\
  126.     static const IMetaTypeInfo* TGB(ITypeHelper* helper);\
  127.     static void*                TGD(const void* obj);\
  128.     virtual void*               TGC(IBoolean returnThis) const;\
  129.     static IString              TGCls();\
  130.     static ITypeInstaller       gInstaller;
  131. #define TypeExtensionTemplateMacro(_tclass,_ptype)\
  132.     template <class _ptype > const IMetaTypeInfo* _tclass<_ptype >::gTypeInfo = 0;\
  133.     template <class _ptype > const IMetaTypeInfo* _tclass<_ptype >::TGV() const {\
  134.         return TGB((ITypeHelper*)0); };\
  135.     template <class _ptype > const IMetaTypeInfo* _tclass<_ptype >::TGB(ITypeHelper* helper) {\
  136.         if (helper == 0) {\
  137.             if (gTypeInfo == 0)\                
  138.                 gTypeInfo = ITypeHelper::StaticCreate(TGCls(), &TGB, &TGD);\
  139.             return gTypeInfo; }\
  140.         else {\
  141.             try { helper->ThrowObject(); } catch (_tclass<_ptype >* obj) { helper->CaughtObject(obj); }; return 0; } };\
  142.     template <class _ptype > void* _tclass<_ptype >::TGD(const void* obj) {\
  143.         if (obj == 0) {\
  144.             return new _tclass<_ptype >(); }\
  145.         else {\
  146.             throw (_tclass<_ptype >*) obj; } };\
  147.     template <class _ptype > void* _tclass<_ptype >::TGC(IBoolean returnThis) const {\
  148.         if (returnThis) {\
  149.             return (void*)this;\
  150.         } else {\
  151.             throw new _tclass<_ptype >(*this); } };\
  152.     template <class _ptype > IString _tclass<_ptype >::TGCls() { return ITypeHelper::MakeClassName(#_tclass, _ptype::TGCls(), 0); };\
  153.     template <class _ptype > ITypeInstaller _tclass<_ptype >::gInstaller(TGCls(), &TGB);
  154. #define TypeExtensionTemplateDeclarationsMacro_Abstract(_tclass,_ptype)\
  155.     static const IMetaTypeInfo* gTypeInfo;\
  156.     virtual const IMetaTypeInfo* TGV() const;\
  157.     static const IMetaTypeInfo* TGB(ITypeHelper* helper);\
  158.     static void*                TGD(const void* obj);\
  159.     virtual void*               TGC(IBoolean returnThis) const;\
  160.     static IString              TGCls();\
  161.     static ITypeInstaller       gInstaller;
  162. #define TypeExtensionTemplateMacro_Abstract(_tclass,_ptype)\
  163.     template <class _ptype > const IMetaTypeInfo* _tclass<_ptype >::gTypeInfo = 0;\
  164.     template <class _ptype > const IMetaTypeInfo* _tclass<_ptype >::TGV() const {\
  165.         return TGB((ITypeHelper*)0); };\
  166.     template <class _ptype > const IMetaTypeInfo* _tclass<_ptype >::TGB(ITypeHelper* helper) {\
  167.         if (helper == 0) {\
  168.             if (gTypeInfo == 0)\                
  169.                 gTypeInfo = ITypeHelper::StaticCreate(TGCls(), &TGB, &TGD);\
  170.             return gTypeInfo; }\
  171.         else {\
  172.             try { helper->ThrowObject(); } catch (_tclass<_ptype >* obj) { helper->CaughtObject(obj); }; return 0; } };\
  173.     template <class _ptype > void* _tclass<_ptype >::TGD(const void* obj) {\
  174.         if (obj == 0) {\
  175.             return ITypeHelper::CantConstructAbstractClass(); }\
  176.         else {\
  177.             throw (_tclass<_ptype >*) obj; } };\
  178.     template <class _ptype > void* _tclass<_ptype >::TGC(IBoolean returnThis) const {\
  179.         if (returnThis) {\
  180.             return (void*)this;\
  181.         } else {\
  182.             return (void*)ITypeHelper::CantConstructAbstractClass(); } };\
  183.     template <class _ptype > IString _tclass<_ptype >::TGCls() { return ITypeHelper::MakeClassName(#_tclass, _ptype::TGCls(), 0); };\
  184.     template <class _ptype > ITypeInstaller _tclass<_ptype >::gInstaller(TGCls(), &TGB);
  185. #define TypeExtensionTemplatePairDeclarationsMacro(_tclass,_ptypeK,_ptypeV)\
  186.     static const IMetaTypeInfo* gTypeInfo;\
  187.     virtual const IMetaTypeInfo* TGV() const;\
  188.     static const IMetaTypeInfo* TGB(ITypeHelper* helper);\
  189.     static void*                TGD(const void* obj);\
  190.     virtual void*               TGC(IBoolean returnThis) const;\
  191.     static IString              TGCls();\
  192.     static ITypeInstaller       gInstaller;
  193. #define TypeExtensionTemplatePairMacro(_tclass,_ptypeK,_ptypeV)\
  194.     template <class _ptypeK, class _ptypeV > const IMetaTypeInfo* _tclass<_ptypeK,_ptypeV >::gTypeInfo = 0;\
  195.     template <class _ptypeK, class _ptypeV > const IMetaTypeInfo* _tclass<_ptypeK,_ptypeV >::TGV() const {\
  196.         return TGB((ITypeHelper*)0); };\
  197.     template <class _ptypeK, class _ptypeV > const IMetaTypeInfo* _tclass<_ptypeK,_ptypeV >::TGB(ITypeHelper* helper) {\
  198.         if (helper == 0) {\
  199.             if (gTypeInfo == 0)\                
  200.                 gTypeInfo = ITypeHelper::StaticCreate(TGCls(), &TGB, &TGD);\
  201.             return gTypeInfo; }\
  202.         else {\
  203.             try { helper->ThrowObject(); } catch (_tclass<_ptypeK,_ptypeV >* obj) { helper->CaughtObject(obj); }; return 0; } };\
  204.     template <class _ptypeK, class _ptypeV > void* _tclass<_ptypeK,_ptypeV >::TGD(const void* obj) {\
  205.         if (obj == 0) {\
  206.             return new _tclass<_ptypeK,_ptypeV >(); }\
  207.         else {\
  208.             throw (_tclass<_ptypeK,_ptypeV >*) obj; } };\
  209.     template <class _ptypeK, class _ptypeV > void* _tclass<_ptypeK,_ptypeV >::TGC(IBoolean returnThis) const {\
  210.         if (returnThis) {\
  211.             return (void*)this;\
  212.         } else {\
  213.             throw new _tclass<_ptypeK,_ptypeV >(*this); } };\
  214.     template <class _ptypeK, class _ptypeV > IString _tclass<_ptypeK,_ptypeV >::TGCls() { return ITypeHelper::MakeClassName(#_tclass, _ptypeK::TGCls(), _ptypeV::TGCls()); };\
  215.     template <class _ptypeK, class _ptypeV > ITypeInstaller _tclass<_ptypeK,_ptypeV >::gInstaller(TGCls(), &TGB);
  216. #define TypeExtensionTemplatePairDeclarationsMacro_Abstract(_tclass,_ptypeK,_ptypeV)\
  217.     static const IMetaTypeInfo* gTypeInfo;\
  218.     virtual const IMetaTypeInfo* TGV() const;\
  219.     static const IMetaTypeInfo* TGB(ITypeHelper* helper);\
  220.     static void*                TGD(const void* obj);\
  221.     virtual void*               TGC(IBoolean returnThis) const;\
  222.     static IString              TGCls();\
  223.     static ITypeInstaller       gInstaller;
  224. #define TypeExtensionTemplatePairMacro_Abstract(_tclass,_ptypeK,_ptypeV)\
  225.     template <class _ptypeK, class _ptypeV > const IMetaTypeInfo* _tclass<_ptypeK,_ptypeV >::gTypeInfo = 0;\
  226.     template <class _ptypeK, class _ptypeV > const IMetaTypeInfo* _tclass<_ptypeK,_ptypeV >::TGV() const {\
  227.         return TGB((ITypeHelper*)0); };\
  228.     template <class _ptypeK, class _ptypeV > const IMetaTypeInfo* _tclass<_ptypeK,_ptypeV >::TGB(ITypeHelper* helper) {\
  229.         if (helper == 0) {\
  230.             if (gTypeInfo == 0)\                
  231.                 gTypeInfo = ITypeHelper::StaticCreate(TGCls(), &TGB, &TGD);\
  232.             return gTypeInfo; }\
  233.         else {\
  234.             try { helper->ThrowObject(); } catch (_tclass<_ptypeK,_ptypeV >* obj) { helper->CaughtObject(obj); }; return 0; } };\
  235.     template <class _ptypeK, class _ptypeV > void* _tclass<_ptypeK,_ptypeV >::TGD(const void* obj) {\
  236.         if (obj == 0) {\
  237.             return ITypeHelper::CantConstructAbstractClass(); }\
  238.         else {\
  239.             throw (_tclass<_ptypeK,_ptypeV >*) obj; } };\
  240.     template <class _ptypeK, class _ptypeV > void* _tclass<_ptypeK,_ptypeV >::TGC(IBoolean returnThis) const {\
  241.         if (returnThis) {\
  242.             return (void*)this;\
  243.         } else {\
  244.             return (void*)ITypeHelper::CantConstructAbstractClass(); } };\
  245.     template <class _ptypeK, class _ptypeV > IString _tclass<_ptypeK,_ptypeV >::TGCls() { return ITypeHelper::MakeClassName(#_tclass, _ptypeK::TGCls(), _ptypeV::TGCls()); };\
  246.     template <class _ptypeK, class _ptypeV > ITypeInstaller _tclass<_ptypeK,_ptypeV >::gInstaller(TGCls(), &TGB);
  247.  
  248. class ITypeHelper {
  249. public:
  250.                             ITypeHelper(IBaseStream& aStream);
  251.                             ITypeHelper();
  252.                             ~ITypeHelper();
  253.  
  254.     // support for Flatten
  255.     //
  256.     IBoolean                MustStreamOutObject(const IMetaTypeInfo& baseTypeInfo, const IMetaTypeInfo* typeInfo, const void* obj);
  257.  
  258.     // support for Resurrect
  259.     //
  260.     const void*             ConstructObject(const IMetaTypeInfo& baseTypeInfo, IBoolean& mustStreamInObject);
  261.  
  262.     // support for DynamicCast
  263.     //
  264.     static const void*      DynamicCastImplementation(const IMetaTypeInfo& derivedTypeInfo, const IMetaTypeInfo& castToTypeInfo, const void* obj);
  265.  
  266.     // support for CreateNewObject
  267.     //
  268.     static const void*      ConstructObject(const IMetaTypeInfo& baseTypeInfo,
  269.                                             const IMetaType& theType);
  270.  
  271.     void                    PrepareContext();
  272.     unsigned long           UpdateContext(const void* newObj, IBoolean& update) const;
  273.     const void*             LookupContext(unsigned long refNum) const;   
  274.     void                    SetObject(const void* obj, const ITypeInternal* t);
  275.     const void*             GetObject() const;
  276.  
  277.     void                    ThrowObject() const;
  278.     void                    CaughtObject(const void* obj);
  279.  
  280. private:
  281.     const void*             fObject;
  282.     const ITypeInternal*    fObjectType;
  283.     const ITypeInternal*    fBaseType;
  284.     IBaseStream*            fStream;
  285.     IBoolean                fCreatedContext;
  286.     IBoolean                fMustStreamInObject;
  287.  
  288. public:
  289.     enum EPreType           { kNil, kObject, kReference };
  290.     static void*            CantConstructAbstractClass();
  291.     static const IMetaTypeInfo* StaticCreate( const IString& className,
  292.                                                const IMetaTypeInfo* (*tgbFunction)(ITypeHelper* helper),
  293.                                                void* (*tgdFunction)(const void* obj));
  294.     static IString          MakeClassName(const char* tName, const char* ptype1, const char* ptype2);
  295. };
  296.  
  297. IBaseStream &operator <<=(ITypeHelper::EPreType& theValue, IBaseStream& fromwhere);
  298. IBaseStream &operator >>=(ITypeHelper::EPreType theValue, IBaseStream& towhere);
  299.  
  300. #endif // IC_LIBRARYUSEONLY 
  301.  
  302.  
  303. // ==================== T E M P L A T E   D E F I N I T I O N S ====================
  304. //
  305.  
  306. template <class AType> AType* copy(const AType& source)
  307. {
  308.     AType* retVal = 0;
  309.     try {
  310.         // Use TGC to create a new instance of the original object
  311.         // using the copy constructor
  312.         source.TGC(false);
  313.     } catch (AType* obj) {
  314.         retVal = obj;
  315.     }
  316.     return retVal;
  317. }
  318.  
  319. template <class AType> AType* copyPointer(const AType* sourcePtr)
  320. {
  321.     if (sourcePtr == 0)
  322.         return 0;
  323.     return ::copy(*sourcePtr);
  324. }
  325.  
  326. template <class AType>
  327. void flatten(const AType* userObjectToFlatten, IBaseStream& theStream)
  328. {
  329. #ifdef IC_LIBRARYUSEONLY
  330.     ITypeHelper helper(theStream);
  331.     const IMetaTypeInfo* dynamicType = 0;
  332.     void* mostDerived = 0;
  333.     if (userObjectToFlatten) {
  334.         dynamicType = &dynamicTypeInfo(*userObjectToFlatten);
  335.         mostDerived = userObjectToFlatten->TGC(true);
  336.     }
  337.     if (helper.MustStreamOutObject(staticTypeInfo(AType), dynamicType, mostDerived))
  338.         *userObjectToFlatten >>= theStream;
  339. #endif  // IC_LIBRARYUSEONLY 
  340. }
  341.  
  342. template <class AType>
  343. void resurrect(AType*& theResult, IBaseStream& theStream)
  344. {
  345. #ifdef IC_LIBRARYUSEONLY
  346.     ITypeHelper helper(theStream);
  347.     IBoolean mustStreamInObject;
  348.     theResult = (AType*) helper.ConstructObject(staticTypeInfo(AType), mustStreamInObject);
  349.     if (mustStreamInObject) *theResult <<= theStream;
  350. #endif  // IC_LIBRARYUSEONLY 
  351. }
  352.  
  353. template <class AType>
  354. void createNewObject(AType*& theResult, const IMetaType& theType)
  355. {
  356. #ifdef IC_LIBRARYUSEONLY
  357.     theResult = (AType*) ITypeHelper::ConstructObject(staticTypeInfo(AType), theType);
  358. #endif  // IC_LIBRARYUSEONLY
  359. }
  360.  
  361. template <class AType, class BType>
  362. void
  363. dynamicCastTo(AType*& target, BType* object)
  364. {
  365. #ifdef IC_LIBRARYUSEONLY
  366.     if (object == 0) {
  367.         target = 0;
  368.     } else {
  369.         target = (AType *) ITypeHelper::DynamicCastImplementation(dynamicTypeInfo(*object), staticTypeInfo(AType), object->TGC(true));
  370.     }
  371. #endif  // IC_LIBRARYUSEONLY
  372. }
  373.  
  374.  
  375. #endif // _IMETAIMP_
  376.