MDL SDK API nvidia_logo_transpbg.gif Up
handle.h
Go to the documentation of this file.
1/***************************************************************************************************
2 * Copyright 2025 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/iinterface.h>
12
13#ifdef __cpp_variadic_templates
14#include <utility>
15#endif
16
17
18namespace mi {
19namespace base {
20
25// Helper type to define Dup_interface
26struct Dup_interface_helper {};
27
31using Dup_interface = const Dup_interface_helper *;
32
36static const Dup_interface DUP_INTERFACE = nullptr;
37
110template <class Interface>
112{
113public:
116
118 using Interface_type = Interface;
119
120 // STL iterator inspired typedef names
121
123 using value_type = Interface;
124
127
129 using pointer = Interface*;
130
132 using reference = Interface&;
133
134private:
135 template <typename I2> friend class Handle;
136
137 // Pointer to underlying interface, can be \c nullptr
138 Interface* m_iptr;
139
140public:
142 Handle() : m_iptr( nullptr) { }
143
149 explicit Handle( Interface* ptr) : m_iptr( ptr) { }
150
158 Handle( Interface* ptr, Dup_interface)
159 : m_iptr( ptr)
160 {
161 if( m_iptr)
162 m_iptr->retain();
163 }
164
166 Handle( const Self& other)
167 : m_iptr( other.m_iptr)
168 {
169 if( m_iptr)
170 m_iptr->retain();
171 }
172
179 template <class Interface2>
181 : m_iptr( other.get())
182 {
183 if( m_iptr)
184 m_iptr->retain();
185 }
186
188 Handle( Self&& other) noexcept
189 : m_iptr( other.m_iptr)
190 {
191 other.m_iptr = nullptr;
192 }
193
195 template <class Interface2>
196 Handle( Handle<Interface2>&& other) noexcept
197 : m_iptr( other.m_iptr)
198 {
199 other.m_iptr = 0;
200 }
201
203 void swap( Self& other)
204 {
205 Interface* tmp_iptr = m_iptr;
206 m_iptr = other.m_iptr;
207 other.m_iptr = tmp_iptr;
208 }
209
212 Self& operator=( const Self& other)
213 {
214 Self( other).swap( *this);
215 return *this;
216 }
217
225 template <class Interface2>
227 {
228 Self( other).swap( *this);
229 return *this;
230 }
231
233 Self& operator=( Self&& other) noexcept
234 {
235 if( this != &other) {
236 if( m_iptr)
237 m_iptr->release();
238 m_iptr = other.m_iptr;
239 other.m_iptr = nullptr;
240 }
241 return *this;
242 }
243
245 template <class Interface2>
247 {
248 if( m_iptr)
249 m_iptr->release();
250 m_iptr = other.m_iptr;
251 other.m_iptr = 0;
252
253 return *this;
254 }
255
261 Self& operator=( Interface* ptr)
262 {
263 Self( ptr).swap( *this);
264 return *this;
265 }
266
268 void reset()
269 {
270 if( m_iptr) {
271 m_iptr->release();
272 m_iptr = 0;
273 }
274 }
275
280 {
281 if( m_iptr)
282 m_iptr->release();
283 }
284
286 bool is_valid_interface() const { return m_iptr != nullptr; }
287
289 Interface* get() const { return m_iptr; }
290
294 Interface* extract()
295 {
296 Interface* ptr = m_iptr;
297 m_iptr = 0;
298 return ptr;
299 }
300
301#ifdef __cpp_variadic_templates
303 template <typename... T>
304 Self& emplace(T&&... args)
305 {
306 return emplace<Interface>(std::forward<T>(args)...);
307 }
308
314 template <typename Impl, typename... T>
315 Self& emplace(T&&... args)
316 {
317 reset();
318 m_iptr = new Impl(std::forward<T>(args)...);
319 return *this;
320 }
321#endif
322
326 Interface& operator*() const
327 {
328 mi_base_assert_msg( is_valid_interface(), "precondition");
329 return *m_iptr;
330 }
331
335 Interface* operator->() const
336 {
337 mi_base_assert_msg( is_valid_interface(), "precondition");
338 return m_iptr;
339 }
340
347 template <class New_interface>
349 {
350 if( !is_valid_interface())
351 return Handle<New_interface>( 0);
352 return Handle<New_interface>( static_cast< New_interface*>(
353 m_iptr->get_interface( typename New_interface::IID())));
354 }
355
360 using bool_conversion_support = bool (Handle::*)() const;
361
374 operator bool_conversion_support() const
375 {
377 }
378
380 friend bool operator==( const Handle<Interface>& lhs, const Interface* rhs)
381 {
382 return lhs.get() == rhs;
383 }
384
386 friend bool operator==( const Interface* lhs, const Handle<Interface>& rhs)
387 {
388 return lhs == rhs.get();
389 }
390
392 friend bool operator!=( const Handle<Interface>& lhs, const Interface* rhs)
393 {
394 return !( lhs == rhs);
395 }
396
398 friend bool operator!=( const Interface* lhs, const Handle<Interface>& rhs) {
399 return !( lhs == rhs);
400 }
401};
402
404template <class Interface1, class Interface2>
405inline bool operator==( const Handle<Interface1>& lhs, const Handle<Interface2>& rhs)
406{
407 return lhs.get() == rhs.get();
408}
409
411template <class Interface1, class Interface2>
412inline bool operator!=( const Handle<Interface1>& lhs, const Handle<Interface2>& rhs)
413{
414 return !( lhs == rhs);
415}
416
422template <class Interface>
423inline Handle<Interface> make_handle( Interface* iptr)
424{
425 return Handle<Interface>( iptr);
426}
427
433template <class Interface>
434inline Handle<Interface> make_handle_dup( Interface* iptr)
435{
436 return Handle<Interface>( iptr, DUP_INTERFACE);
437}
438
439#ifdef __cpp_variadic_templates
444template <typename Impl, typename... T>
445inline Handle<Impl> construct_handle(T&&... args)
446{
447 return Handle<Impl>{new Impl(std::forward<T>(args)...)};
448}
449
450#endif
451
452 // end group mi_base_iinterface
454
455} // namespace base
456} // namespace mi
457
458#endif // MI_BASE_HANDLE_H
Assertions and compile-time assertions.
Handle class template for interfaces, automatizing the lifetime control via reference counting.
Definition: handle.h:112
#define mi_base_assert_msg(expr, msg)
Base API assertion macro (with message).
Definition: assert.h:103
Handle()
Default constructor, initializes handle to hold an invalid interface.
Definition: handle.h:142
Interface * operator->() const
The arrow operator accesses the interface.
Definition: handle.h:335
Interface & operator*() const
The dereference operator accesses the interface.
Definition: handle.h:326
Handle(const Handle<Interface2> &other)
Copy constructor template which allows the construction from assignment compatible interface pointers...
Definition: handle.h:180
Difference difference_type
Difference type (signed integral type to hold pointer differences).
Definition: handle.h:126
Handle(const Self &other)
Copy constructor, increments reference count if interface is valid.
Definition: handle.h:166
friend bool operator==(const Interface *lhs, const Handle<Interface> &rhs)
Returns true if lhs is equal to the underlying interface pointer of rhs.
Definition: handle.h:386
~Handle()
Destructor, releases the interface if it is valid, which decrements the reference count,...
Definition: handle.h:279
friend bool operator==(const Handle<Interface> &lhs, const Interface *rhs)
Returns true if the underlying interface pointer of lhs is equal to rhs.
Definition: handle.h:380
Handle<Interface> make_handle_dup(Interface *iptr)
Converts passed-in interface pointer to a handle, without taking interface over.
Definition: handle.h:434
void swap(Self &other)
Swap two interfaces.
Definition: handle.h:203
static const Dup_interface DUP_INTERFACE
Symbolic constant to trigger a special constructor in the Handle class.
Definition: handle.h:36
Handle(Interface *ptr, Dup_interface)
Constructor from interface pointer, does not take ownership of interface but duplicates it.
Definition: handle.h:158
bool operator==(const Handle<Interface1> &lhs, const Handle<Interface2> &rhs)
Returns true if the underlying interface pointers are equal.
Definition: handle.h:405
Handle(Handle<Interface2> &&other) noexcept
Converting move constructor.
Definition: handle.h:196
friend bool operator!=(const Handle<Interface> &lhs, const Interface *rhs)
Returns true if the underlying interface pointer of lhs is not equal to rhs.
Definition: handle.h:392
Self & operator=(Self &&other) noexcept
Move assignment operator, releases old interface.
Definition: handle.h:233
Handle<New_interface> get_interface() const
Returns a new handle for a possibly different interface type, similar to a dynamic cast,...
Definition: handle.h:348
Interface value_type
Type of the underlying interface.
Definition: handle.h:123
Handle(Self &&other) noexcept
Move constructor.
Definition: handle.h:188
Handle<Interface> Self
Own type.
Definition: handle.h:115
Handle<Interface> make_handle(Interface *iptr)
Returns a handle that holds the interface pointer passed in as argument.
Definition: handle.h:423
bool(Handle::*)() const bool_conversion_support
Helper typedef.
Definition: handle.h:360
Handle(Interface *ptr)
Constructor from interface pointer, takes ownership of interface.
Definition: handle.h:149
Interface * extract()
Extracts the interface and releases the handle.
Definition: handle.h:294
friend bool operator!=(const Interface *lhs, const Handle<Interface> &rhs)
Returns true if lhs is not equal to the underlying interface pointer of rhs.
Definition: handle.h:398
Self & operator=(const Self &other)
Assignment operator, releases old interface and increments reference count of the new interface if in...
Definition: handle.h:212
Interface Interface_type
Type of the underlying interface.
Definition: handle.h:118
Self & operator=(Interface *ptr)
Assignment operator from interface pointer, releases old interface and assigns new interface ptr,...
Definition: handle.h:261
Interface & reference
Mutable-reference type to underlying interface.
Definition: handle.h:132
Interface * pointer
Mutable-pointer type to underlying interface.
Definition: handle.h:129
Interface * get() const
Access to the interface. Returns 0 for an invalid interface.
Definition: handle.h:289
Self & operator=(const Handle<Interface2> &other)
Assignment operator template, releases old interface and increments reference count of the new interf...
Definition: handle.h:226
Self & operator=(Handle<Interface2> &&other) noexcept
Converting move assignment operator, releases old interface.
Definition: handle.h:246
bool operator!=(const Handle<Interface1> &lhs, const Handle<Interface2> &rhs)
Returns true if the underlying interface pointers are not equal.
Definition: handle.h:412
const Dup_interface_helper * Dup_interface
Type for a symbolic constant to trigger a special constructor in the Handle class.
Definition: handle.h:31
void reset()
Releases the current interface, decrementing the reference count.
Definition: handle.h:268
bool is_valid_interface() const
Returns true if the interface is valid.
Definition: handle.h:286
Sint64 Difference
Signed integral type that is large enough to hold the difference of two pointers.
Definition: types.h:122
The basic extensible interface.
Common namespace for APIs of NVIDIA Advanced Rendering Center GmbH.
Definition: example_derivatives.dox:5