Salome HOME
Add const classifier to getters to be able to use in const methods.
[modules/kernel.git] / src / GenericObj / SALOME_GenericObj_wrap.hxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 // File      : SALOME_GenericObj_wrap.hxx
23 // Created   : Fri Dec  7 11:32:45 2012
24 // Author    : Edward AGAPOV (eap)
25
26
27 #ifndef __SALOME_GenericObj_wrap_HXX__
28 #define __SALOME_GenericObj_wrap_HXX__
29
30 namespace SALOME
31 {
32   // call UnRegister on each element in a sequence of SALOME::GenericObj's
33   template< class SEQ_OF_GENOBJ >
34   void UnRegister( SEQ_OF_GENOBJ& seq )
35   {
36     for ( size_t i = 0; i < seq->length(); ++i )
37       if ( !CORBA::is_nil( seq[i] ))
38         seq[i]->UnRegister();
39   }
40
41   // This class is intended to free the user of objects, iherited from SALOME::GenericObj,
42   // from a need to call UnRegister() after having finished using the object.
43   // The behavior of this class is similar to that of var CORBA class and thus it
44   // can replace var types of wrapped CORBA classes in some code like follows:
45   //
46   // namespace SALOMEDS
47   // {
48   //   typedef SALOME::GenericObj_wrap< SObject >       SObject_wrap;
49   //   typedef SALOME::GenericObj_wrap< ChildIterator > ChildIterator_wrap;
50   // }
51   // ...
52   // SALOMEDS::ChildIterator_wrap anIter = aStudy->NewChildIterator( mainSO );
53   // for ( ; anIter->More(); anIter->Next() ) {
54   //   SALOMEDS::SObject_wrap so = anIter->Value();
55   // ...
56   //
57   // Note that the need to call UnRegister(), and thus to use GenericObj_wrap, depends on
58   // implementation of a method returning a GenericObj servant. If the method creates a
59   // servant, than UnRegister() must be called. If the method retrieves a servant from
60   // some storage, then it's wrong to call UnRegister().
61   //
62   // A pleasant additional feature privided by this class is that one can assign
63   // GenericObj_wrap< BASE_CLASS > to GenericObj_wrap< CHILD_CLASS > without
64   // calling CHILD_CLASS::_narrow().
65   //
66   template< class GENOBJ >
67   class GenericObj_wrap
68   {
69   public:
70     typedef typename GENOBJ::_ptr_type TPtr;
71     typedef typename GENOBJ::_var_type TVar;
72
73     // CONSTRUCTION
74     GenericObj_wrap()
75     {
76       _isOwn = false;
77     }
78     GenericObj_wrap( const TPtr& obj )
79       : _obj( obj ), _isOwn( true )
80     {}
81     GenericObj_wrap( const TVar& obj )
82       : _obj( obj ), _isOwn( true )
83     {}
84     GenericObj_wrap( const GenericObj_wrap& wrap )
85       : _obj( wrap._obj ), _isOwn( wrap._getIsOwn() )
86     {
87       _register();
88     }
89     template< class BASE_GENOBJ >
90     GenericObj_wrap( const GenericObj_wrap<BASE_GENOBJ>& wrap )
91       : _obj( GENOBJ::_narrow( wrap.in() )), _isOwn( wrap._getIsOwn() )
92     {
93       _register();
94     }
95     // DESTRUCTION
96     ~GenericObj_wrap()
97     {
98       _release();
99     }
100     // COPYING
101     GenericObj_wrap& operator=( const TPtr& obj )
102     {
103       _release();
104       _obj   = obj;
105       _isOwn = true;
106       return *this;
107     }
108     GenericObj_wrap& operator=( const TVar& obj )
109     {
110       _release();
111       _obj   = obj;
112       _isOwn = true;
113       return *this;
114     }
115     GenericObj_wrap& operator=( const GenericObj_wrap& wrap )
116     {
117       _release();
118       _obj   = wrap._obj;//wrap.in();
119       _isOwn = wrap._getIsOwn();
120       _register();
121       return *this;
122     }
123     template< class BASE_GENOBJ >
124     GenericObj_wrap& operator=( const GenericObj_wrap<BASE_GENOBJ>& wrap )
125     {
126       _release();
127       _obj   = GENOBJ::_narrow( wrap.in() );
128       _isOwn = wrap._getIsOwn();
129       _register();
130       return *this;
131     }
132     // ACCESS
133     operator TPtr() const
134     {
135       return _obj.in();
136     }
137     operator TVar() const
138     {
139       return _obj;
140     }
141     TVar operator->() const
142     {
143       return _obj;
144     }
145     TPtr in() const
146     {
147       return _obj;
148     }
149     TPtr& inout()
150     {
151       _release(); // returned reference to _obj will be initialized with another object
152       _isOwn = true;
153       return _obj.inout();
154     }
155     TPtr _retn()
156     {
157       _isOwn = false;
158       return _obj._retn();
159     }
160
161     bool _getIsOwn() const { return  _isOwn; }
162
163   private:
164     void _register()
165     {
166       if ( _isOwn && !CORBA::is_nil( _obj ))
167         _obj->Register();
168     }
169     void _release()
170     {
171       if ( _isOwn && !CORBA::is_nil( _obj ))
172         _obj->UnRegister();
173       _isOwn = false;
174     }
175     TVar _obj;
176     bool _isOwn;
177   };
178 } // namespace SALOME
179
180 #endif