NVIDIA IndeX: Base API nvidia_logo_transpbg.gif 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 2020 NVIDIA Corporation. All rights reserved.
3  **************************************************************************************************/
6 
7 #ifndef MI_BASE_HANDLE_H
8 #define MI_BASE_HANDLE_H
9 
10 #include <mi/base/assert.h>
11 #include <mi/base/config.h> // for MI_CXX_FEATURE_RVALUE_REFERENCES
12 #include <mi/base/iinterface.h>
13 
14 namespace mi {
15 namespace base {
16 
21 // Helper type to define Dup_interface
22 struct Dup_interface_helper {};
23 
27 typedef const Dup_interface_helper* Dup_interface;
28 
32 static const Dup_interface DUP_INTERFACE = 0;
33 
106 template <class Interface>
107 class Handle
108 {
109 public:
112 
114  typedef Interface Interface_type;
115 
116  // STL iterator inspired typedef names
117 
119  typedef Interface value_type;
120 
123 
125  typedef Interface* pointer;
126 
128  typedef Interface& reference;
129 
130 private:
131  // Pointer to underlying interface, can be \c NULL
132  Interface* m_iptr;
133 
134 public:
136  Handle() : m_iptr( 0) { }
137 
143  explicit Handle( Interface* ptr) : m_iptr( ptr) { }
144 
152  Handle( Interface* ptr, Dup_interface)
153  : m_iptr( ptr)
154  {
155  if( m_iptr)
156  m_iptr->retain();
157  }
158 
160  Handle( const Self& other)
161  : m_iptr( other.m_iptr)
162  {
163  if( m_iptr)
164  m_iptr->retain();
165  }
166 
173  template <class Interface2>
174  Handle( const Handle<Interface2>& other)
175  : m_iptr( other.get())
176  {
177  if( m_iptr)
178  m_iptr->retain();
179  }
180 
181 #ifdef MI_CXX_FEATURE_RVALUE_REFERENCES
182  Handle( Self&& other)
184  : m_iptr( other.m_iptr)
185  {
186  other.m_iptr = 0;
187  }
188 #endif
189 
191  void swap( Self& other)
192  {
193  Interface* tmp_iptr = m_iptr;
194  m_iptr = other.m_iptr;
195  other.m_iptr = tmp_iptr;
196  }
197 
200  Self& operator=( const Self& other)
201  {
202  Self( other).swap( *this);
203  return *this;
204  }
205 
213  template <class Interface2>
215  {
216  Self( other).swap( *this);
217  return *this;
218  }
219 
220 #ifdef MI_CXX_FEATURE_RVALUE_REFERENCES
221  Self& operator=( Self&& other)
223  {
224  if( this != &other) {
225  if( m_iptr)
226  m_iptr->release();
227  m_iptr = other.m_iptr;
228  other.m_iptr = 0;
229  }
230  return *this;
231  }
232 #endif
233 
239  Self& operator=( Interface* ptr)
240  {
241  Self( ptr).swap( *this);
242  return *this;
243  }
244 
246  void reset()
247  {
248  if( m_iptr) {
249  m_iptr->release();
250  m_iptr = 0;
251  }
252  }
253 
258  {
259  if( m_iptr)
260  m_iptr->release();
261  }
262 
264  bool is_valid_interface() const { return m_iptr != 0; }
265 
267  Interface* get() const { return m_iptr; }
268 
272  Interface& operator*() const
273  {
274  mi_base_assert_msg( is_valid_interface(), "precondition");
275  return *m_iptr;
276  }
277 
281  Interface* operator->() const
282  {
283  mi_base_assert_msg( is_valid_interface(), "precondition");
284  return m_iptr;
285  }
286 
292  template <class New_interface>
294  {
295  if( !is_valid_interface())
296  return Handle<New_interface>( 0);
297  return Handle<New_interface>( static_cast< New_interface*>(
298  m_iptr->get_interface( typename New_interface::IID())));
299  }
300 
305  typedef bool (Handle::*bool_conversion_support)() const;
306 
319  operator bool_conversion_support() const
320  {
322  }
323 
325  friend bool operator==( const Handle<Interface>& lhs, const Interface* rhs)
326  {
327  return lhs.get() == rhs;
328  }
329 
331  friend bool operator==( const Interface* lhs, const Handle<Interface>& rhs)
332  {
333  return lhs == rhs.get();
334  }
335 
337  friend bool operator!=( const Handle<Interface>& lhs, const Interface* rhs)
338  {
339  return !( lhs == rhs);
340  }
341 
343  friend bool operator!=( const Interface* lhs, const Handle<Interface>& rhs) {
344  return !( lhs == rhs);
345  }
346 };
347 
349 template <class Interface1, class Interface2>
350 inline bool operator==( const Handle<Interface1>& lhs, const Handle<Interface2>& rhs)
351 {
352  return lhs.get() == rhs.get();
353 }
354 
356 template <class Interface1, class Interface2>
357 inline bool operator!=( const Handle<Interface1>& lhs, const Handle<Interface2>& rhs)
358 {
359  return !( lhs == rhs);
360 }
361 
367 template <class Interface>
368 inline Handle<Interface> make_handle( Interface* iptr)
369 {
370  return Handle<Interface>( iptr);
371 }
372 
378 template <class Interface>
379 inline Handle<Interface> make_handle_dup( Interface* iptr)
380 {
381  return Handle<Interface>( iptr, DUP_INTERFACE);
382 }
383  // end group mi_base_iinterface
385 
386 } // namespace base
387 } // namespace mi
388 
389 #endif // MI_BASE_HANDLE_H