NVIDIA Iray: Math API Home  Up
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
handle.h
Go to the documentation of this file.
1 //*****************************************************************************
2 // Copyright 1986, 2016 NVIDIA Corporation. All rights reserved.
3 //*****************************************************************************
7 //*****************************************************************************
8 
9 #ifndef MI_BASE_HANDLE_H
10 #define MI_BASE_HANDLE_H
11 
12 #include <mi/base/assert.h>
13 #include <mi/base/iinterface.h>
14 
15 namespace mi {
16 namespace base {
17 
22 // Helper type to define Dup_interface
23 struct Dup_interface_helper {};
24 
28 typedef const Dup_interface_helper* Dup_interface;
29 
33 static const Dup_interface DUP_INTERFACE = 0;
34 
104 template < class Interface>
105 class Handle
106 {
107 public:
110 
112  typedef Interface Interface_type;
113 
114  // STL iterator inspired typedef names
115 
117  typedef Interface value_type;
118 
121 
123  typedef Interface* pointer;
124 
126  typedef Interface& reference;
127 
128 private:
129  Interface* m_iptr; // pointer to underlying interface, can be 0
130 
131 public:
133  Handle() : m_iptr(0) {}
134 
140  explicit Handle( Interface* ptr) : m_iptr(ptr) {}
141 
150  Handle( Interface* ptr, Dup_interface) : m_iptr(ptr) {
151  if ( m_iptr)
152  m_iptr->retain();
153  }
154 
156  Handle( const Self& other) : m_iptr( other.m_iptr) {
157  if ( m_iptr)
158  m_iptr->retain();
159  }
160 
168  template <class Interface2>
169  Handle( const Handle<Interface2>& other) : m_iptr( other.get()) {
170  if ( m_iptr)
171  m_iptr->retain();
172  }
173 
175  void swap( Self& other) {
176  Interface* tmp_iptr = m_iptr;
177  m_iptr = other.m_iptr;
178  other.m_iptr = tmp_iptr;
179  }
180 
183  Self& operator=( const Self& other) {
184  Self(other).swap(*this);
185  return *this;
186  }
187 
195  template <class Interface2>
197  Self(other).swap(*this);
198  return *this;
199  }
200 
205  Self& operator=( Interface* ptr) {
206  Self(ptr).swap(*this);
207  return *this;
208  }
209 
211  void reset() {
212  if(m_iptr != NULL)
213  {
214  m_iptr->release();
215  m_iptr = NULL;
216  }
217  }
218 
223  if ( m_iptr)
224  m_iptr->release();
225  }
226 
228  bool is_valid_interface() const { return m_iptr != 0; }
229 
231  Interface* get() const { return m_iptr; }
232 
235  Interface& operator*() const {
236  mi_base_assert_msg( is_valid_interface(), "precondition");
237  return * m_iptr;
238  }
239 
242  Interface* operator->() const {
243  mi_base_assert_msg( is_valid_interface(), "precondition");
244  return m_iptr;
245  }
246 
253  template <class New_interface>
255  if ( ! is_valid_interface())
256  return Handle<New_interface>(0);
257  return Handle<New_interface>( static_cast< New_interface*>(
258  m_iptr->get_interface( typename New_interface::IID())));
259  }
260 
264  typedef bool (Handle::*bool_conversion_support)() const;
265 
277  operator bool_conversion_support() const {
279  }
280 
282  friend bool operator==( const Handle<Interface>& lhs, const Interface* rhs) {
283  return lhs.get() == rhs;
284  }
285 
287  friend bool operator==( const Interface* lhs, const Handle<Interface>& rhs) {
288  return lhs == rhs.get();
289  }
290 
292  friend bool operator!=( const Handle<Interface>& lhs, const Interface* rhs) {
293  return ! ( lhs == rhs);
294  }
295 
297  friend bool operator!=( const Interface* lhs, const Handle<Interface>& rhs) {
298  return ! ( lhs == rhs);
299  }
300 };
301 
303 template <class Interface1, class Interface2>
304 inline bool operator==( const Handle<Interface1>& lhs, const Handle<Interface2>& rhs) {
305  return lhs.get() == rhs.get();
306 }
307 
309 template <class Interface1, class Interface2>
310 inline bool operator!=( const Handle<Interface1>& lhs, const Handle<Interface2>& rhs) {
311  return ! ( lhs == rhs);
312 }
313 
315 
319 template <class Interface>
320 inline Handle<Interface> make_handle( Interface* iptr) {
321  return Handle<Interface>(iptr);
322 }
323 
325 
329 template <class Interface>
330 inline Handle<Interface> make_handle_dup( Interface* iptr) {
331  return Handle<Interface>(iptr, DUP_INTERFACE);
332 }
333  // end group mi_base_iinterface
335 
336 } // namespace base
337 } // namespace mi
338 
339 #endif // MI_BASE_HANDLE_H