// -*- c++ -*- /* * MICO --- an Open Source CORBA implementation * Copyright (c) 1997-2004 by The Mico Team * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * For more information, visit the MICO Home Page at * http://www.mico.org/ */ #ifndef __mico_template_h__ #define __mico_template_h__ /* * Template to generate _var types for object references */ template class ObjOut; template class ObjVar { friend class ObjOut; private: T* _ptr; static T* nil() { return 0; } public: static T* duplicate (T *); static void release (T *); private: void free(); void reset( T* ptr ) { free(); _ptr = ptr; } public: ObjVar() { _ptr = nil(); } ObjVar( T* ptr ) { _ptr = ptr; } ObjVar( const ObjVar& var ) { _ptr = duplicate (var._ptr); } ~ObjVar() { free(); } ObjVar& operator=( const ObjVar &var ) { if (this != &var) { free(); _ptr = duplicate( var._ptr ); } return *this; } ObjVar& operator=( T* ptr ) { reset( ptr ); return *this; } // g++ const overload problem #ifdef HAVE_CONST_OVERLOAD operator T*() const { return _ptr; } #endif operator T* () { return _ptr; } T* operator->() const { assert (_ptr); return _ptr; } T* in() const { return _ptr; } T*& inout() { return _ptr; } T*& out() { free(); return _ptr; } T*& _for_demarshal() { return out(); } T* _retn() { T *_p = _ptr; _ptr = nil(); return _p; } }; template inline void ObjVar::free() { release( _ptr ); _ptr = nil(); } /* * Template to generate _out types for object references */ template class ObjOut { private: T*& _ptr; public: ObjOut (T*& p); ObjOut (ObjVar& p); ObjOut (const ObjOut& p) : _ptr (p._ptr) { } ObjOut& operator= (const ObjOut& p) { _ptr = p._ptr; return *this; } ObjOut& operator= (const ObjVar& p); ObjOut& operator= (T* p) { _ptr = p; return *this; } operator T& () { return *_ptr; } operator T*& () { return _ptr; } T* operator-> () { assert (_ptr); return _ptr; } T*& ptr () { return _ptr; } }; /* * Template to generate _var types for value types */ template class ValueOut; template class ValueVar { friend class ValueOut; private: T* _ptr; static T* nil() { return 0; } static T* duplicate (T *); static void release (T *); void free(); void reset( T* ptr ) { free(); _ptr = ptr; } public: ValueVar() { _ptr = nil(); } ValueVar( T* ptr ) { _ptr = ptr; } ValueVar( const ValueVar& var ) { _ptr = duplicate (var._ptr); } ~ValueVar() { free(); } ValueVar& operator=( const ValueVar &var ) { if (this != &var) { free(); _ptr = duplicate( var._ptr ); } return *this; } ValueVar& operator=( T* ptr ) { if (_ptr != ptr) reset( ptr ); return *this; } // g++ const overload problem #ifdef HAVE_CONST_OVERLOAD operator T*() const { return _ptr; } #endif operator T* () { return _ptr; } T* operator->() const { assert (_ptr); return _ptr; } T* in() const { return _ptr; } T*& inout() { return _ptr; } T*& out() { free(); return _ptr; } T*& _for_demarshal() { return out(); } T* _retn() { T *_p = _ptr; _ptr = nil(); return _p; } }; template inline void ValueVar::free() { release( _ptr ); _ptr = nil(); } /* * Template to generate _out types for value types. */ template class ValueOut { private: T*& _ptr; static T* nil() { return 0; } public: ValueOut (T*& p) : _ptr (p) { _ptr = nil(); } ValueOut (ValueVar& p) : _ptr (p._ptr) { release (_ptr); _ptr = nil(); } ValueOut (const ValueOut& p) : _ptr (p._ptr) { } ValueOut& operator= (const ValueOut& p) { _ptr = p._ptr; return *this; } ValueOut& operator= (T* p) { _ptr = p; return *this; } operator T* () { return _ptr; } T* operator-> () { assert (_ptr); return _ptr; } T*& ptr () { return _ptr; } private: void operator= (const ValueVar& p); }; /* * Template to generate _var types for fixed length data types. * We don't need a class TFixOut for generating _out types of fixed * length data types. The _out types will be a simple refence to the * original type. */ template class TFixVar { private: T* _ptr; void free(); void reset( T* ptr ) { free(); _ptr = ptr; } public: TFixVar() { _ptr = NULL; } TFixVar( T* ptr ) { _ptr = ptr; } TFixVar( const TFixVar& var ) { if( !var._ptr ) _ptr = NULL; else _ptr = new T (*var._ptr); } TFixVar( const T& t) : _ptr(new T(t)) { } ~TFixVar() { free(); } TFixVar& operator=( T* ptr ) { if( _ptr != ptr ) reset( ptr ); return *this; } TFixVar& operator=( const TFixVar& var ) { if( this != &var ) { free(); if( !var._ptr ) _ptr = NULL; else _ptr = new T (*var._ptr); } return *this; } TFixVar& operator=(const T& t) { reset ( new T(t) ); return *this; } #ifdef HAVE_CONST_OVERLOAD operator const T&() const { assert( _ptr ); return *_ptr; } operator T&() { assert (_ptr); return *_ptr; } #else operator T&() const { assert (_ptr); return *_ptr; } #endif operator T* () { return _ptr; } T* operator->() const { assert( _ptr ); return _ptr; } T& operator*() const { assert (_ptr); return *_ptr; } const T& in() const { assert (_ptr); return *_ptr; } T& inout() { assert (_ptr); return *_ptr; } T& out() { if (!_ptr) { _ptr = new T(); } return *_ptr; } T& _for_demarshal() { return out(); } T* _retn() { T *_p = _ptr; _ptr = NULL; return _p; } }; template inline void TFixVar::free() { if( _ptr ) delete _ptr; _ptr = NULL; } /* * Template to generate _var types for variable length data types. */ template class TVarOut; template class TVarVar { friend class TVarOut; private: T* _ptr; void free(); void reset( T* ptr ) { free(); _ptr = ptr; } public: TVarVar() { _ptr = NULL; } TVarVar( T* ptr ) { _ptr = ptr; } TVarVar( const TVarVar& var ) { if( !var._ptr ) _ptr = NULL; else _ptr = new T (*var._ptr); } ~TVarVar() { free(); } TVarVar& operator=( T* ptr ) { if( _ptr != ptr ) reset( ptr ); return *this; } TVarVar& operator=( const TVarVar& var ) { if( this != &var ) { free(); if( !var._ptr ) _ptr = NULL; else _ptr = new T (*var._ptr); } return *this; } #ifdef HAVE_CONST_OVERLOAD operator const T&() const { assert (_ptr); return *_ptr; } operator T&() { assert (_ptr); return *_ptr; } #else operator T&() const { assert (_ptr); return *_ptr; } #endif operator T* () { return _ptr; } T* operator->() const { assert( _ptr ); return _ptr; } T& operator*() const { assert (_ptr); return *_ptr; } const T& in() const { return *_ptr; } T& inout() { return *_ptr; } T*& out() { free(); return _ptr; } T& _for_demarshal() { free(); return *_ptr; } T* _retn() { T *_p = _ptr; _ptr = NULL; return _p; } }; template inline void TVarVar::free() { if( _ptr ) delete _ptr; _ptr = NULL; } /* * Template to generate _out types for variable length data types. */ template class TVarOut { private: T*& _ptr; public: TVarOut (T*& p) : _ptr (p) { _ptr = NULL; } TVarOut (TVarVar& p) : _ptr (p._ptr) { delete _ptr; _ptr = NULL; } TVarOut (const TVarOut& p) : _ptr (p._ptr) { } TVarOut& operator= (const TVarOut& p) { _ptr = p._ptr; return *this; } TVarOut& operator= (T* p) { _ptr = p; return *this; } operator T& () { return *_ptr; } operator T*& () { return _ptr; } T*& ptr () { return _ptr; } T* operator-> () { assert (_ptr); return _ptr; } private: void operator= (const TVarVar&); }; /* * Template to generate _var types for sequences. The difference * to the TVarVar template is, that operator[] is overloaded as well. */ template class TSeqOut; template class TSeqVar { friend class TSeqOut; private: T* _ptr; void free(); void reset( T* ptr ) { free(); _ptr = ptr; } public: TSeqVar() { _ptr = NULL; } TSeqVar( T* ptr ) { _ptr = ptr; } TSeqVar( const TSeqVar& var ) { if (!var._ptr) _ptr = NULL; else _ptr = new T (*var._ptr); } ~TSeqVar() { free(); } TSeqVar& operator=( T* ptr ) { if (_ptr != ptr) reset( ptr ); return *this; } TSeqVar& operator=( const TSeqVar& var ) { if (this != &var) { free(); if (!var._ptr) _ptr = NULL; else _ptr = new T (*var._ptr); } return *this; } #ifdef HAVE_CONST_OVERLOAD operator const T&() const { assert (_ptr); return *_ptr; } operator T&() { assert (_ptr); return *_ptr; } #else operator T&() const { assert (_ptr); return *_ptr; } #endif operator T*() { return _ptr; } T* operator->() const { assert (_ptr); return _ptr; } T& operator*() const { assert (_ptr); return *_ptr; } typename T::ElementType operator[] (MICO_ULong idx) { assert (_ptr); return (*_ptr)[ idx ]; } const T& in() const { return *_ptr; } T& inout() { return *_ptr; } T*& out() { free(); return _ptr; } T& _for_demarshal() { free(); return *_ptr; } T* _retn() { T *_p = _ptr; _ptr = NULL; return _p; } }; template inline void TSeqVar::free() { if( _ptr ) delete _ptr; _ptr = NULL; } /* * Template to generate _out types for sequences. */ template class TSeqOut { private: T*& _ptr; public: TSeqOut (T*& p) : _ptr (p) { _ptr = NULL; } TSeqOut (TSeqVar& p) : _ptr (p._ptr) { delete _ptr; _ptr = NULL; } TSeqOut (const TSeqOut& p) : _ptr (p._ptr) { } typename T::ElementType operator[] (MICO_ULong idx) { assert (_ptr); return (*_ptr)[ idx ]; } TSeqOut& operator= (const TSeqOut& p) { _ptr = p._ptr; return *this; } TSeqOut& operator= (T* p) { _ptr = p; return *this; } operator T& () { return *_ptr; } operator T*& () { return _ptr; } T* operator-> () { assert (_ptr); return _ptr; } T*& ptr () { return _ptr; } private: void operator= (const TSeqVar&); }; #ifndef HAVE_STD_EH /* * Template to generate _var types for exceptions. Difference to * TVarVar is that _clone() is used instead of the copy constructor. * We can use the TVarOut template to generate the _out type for * exceptions. */ template class ExceptVar { private: T* _ptr; void free(); void reset( T* ptr ) { free(); _ptr = ptr; } public: ExceptVar() { _ptr = NULL; } ExceptVar( T* ptr ) { _ptr = ptr; } ExceptVar( const ExceptVar& var ) { if (!var._ptr) _ptr = NULL; else _ptr = (T *)var._ptr->_clone(); } ~ExceptVar() { free(); } ExceptVar& operator=( T* ptr ) { if (_ptr != ptr) reset( ptr ); return *this; } ExceptVar& operator=( const ExceptVar& var ) { if (this != &var) { free(); if (!var._ptr) _ptr = NULL; else _ptr = (T *)var._ptr->_clone(); } return *this; } T* operator->() const { assert (_ptr); return _ptr; } T& operator*() const { assert (_ptr); return *_ptr; } T* _retn() { T *_p = _ptr; _ptr = NULL; return _p; } }; template inline void ExceptVar::free() { if( _ptr ) delete _ptr; _ptr = NULL; } #endif // ! HAVE_STD_EH #endif