Base API nvidia_logo_transpbg.gif Up
handle.h
Go to the documentation of this file.
1/***************************************************************************************************
2 * Copyright 2024 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#ifdef __cpp_variadic_templates
15#include <utility>
16#endif
17
18
19namespace mi {
20namespace base {
21
26// Helper type to define Dup_interface
27struct Dup_interface_helper {};
28
32typedef const Dup_interface_helper* Dup_interface;
33
38
111template <class Interface>
113{
114public:
117
119 typedef Interface Interface_type;
120
121 // STL iterator inspired typedef names
122
124 typedef Interface value_type;
125
128
130 typedef Interface* pointer;
131
133 typedef Interface& reference;
134
135private:
136 template <typename I2> friend class Handle;
137
138 // Pointer to underlying interface, can be \c NULL
139 Interface* m_iptr;
140
141public:
143 Handle() : m_iptr( 0) { }
144
150 explicit Handle( Interface* ptr) : m_iptr( ptr) { }
151
159 Handle( Interface* ptr, Dup_interface)
160 : m_iptr( ptr)
161 {
162 if( m_iptr)
163 m_iptr->retain();
164 }
165
167 Handle( const Self& other)
168 : m_iptr( other.m_iptr)
169 {
170 if( m_iptr)
171 m_iptr->retain();
172 }
173
180 template <class Interface2>
182 : m_iptr( other.get())
183 {
184 if( m_iptr)
185 m_iptr->retain();
186 }
187
188#ifdef MI_CXX_FEATURE_RVALUE_REFERENCES
190 Handle( Self&& other) noexcept
191 : m_iptr( other.m_iptr)
192 {
193 other.m_iptr = 0;
194 }
195
197 template <class Interface2>
198 Handle( Handle<Interface2>&& other) noexcept
199 : m_iptr( other.m_iptr)
200 {
201 other.m_iptr = 0;
202 }
203#endif
204
206 void swap( Self& other)
207 {
208 Interface* tmp_iptr = m_iptr;
209 m_iptr = other.m_iptr;
210 other.m_iptr = tmp_iptr;
211 }
212
215 Self& operator=( const Self& other)
216 {
217 Self( other).swap( *this);
218 return *this;
219 }
220
228 template <class Interface2>
230 {
231 Self( other).swap( *this);
232 return *this;
233 }
234
235#ifdef MI_CXX_FEATURE_RVALUE_REFERENCES
237 Self& operator=( Self&& other) noexcept
238 {
239 if( this != &other) {
240 if( m_iptr)
241 m_iptr->release();
242 m_iptr = other.m_iptr;
243 other.m_iptr = 0;
244 }
245 return *this;
246 }
247
249 template <class Interface2>
251 {
252 if( m_iptr)
253 m_iptr->release();
254 m_iptr = other.m_iptr;
255 other.m_iptr = 0;
256
257 return *this;
258 }
259#endif
260
266 Self& operator=( Interface* ptr)
267 {
268 Self( ptr).swap( *this);
269 return *this;
270 }
271
273 void reset()
274 {
275 if( m_iptr) {
276 m_iptr->release();
277 m_iptr = 0;
278 }
279 }
280
285 {
286 if( m_iptr)
287 m_iptr->release();
288 }
289
291 bool is_valid_interface() const { return m_iptr != 0; }
292
294 Interface* get() const { return m_iptr; }
295
299 Interface* extract()
300 {
301 Interface* ptr = m_iptr;
302 m_iptr = 0;
303 return ptr;
304 }
305
306#ifdef __cpp_variadic_templates
308 template <typename... T>
309 Self& emplace(T&&... args)
310 {
311 return emplace<Interface>(std::forward<T>(args)...);
312 }
313
319 template <typename Impl, typename... T>
320 Self& emplace(T&&... args)
321 {
322 reset();
323 m_iptr = new Impl(std::forward<T>(args)...);
324 return *this;
325 }
326#endif
327
331 Interface& operator*() const
332 {
333 mi_base_assert_msg( is_valid_interface(), "precondition");
334 return *m_iptr;
335 }
336
340 Interface* operator->() const
341 {
342 mi_base_assert_msg( is_valid_interface(), "precondition");
343 return m_iptr;
344 }
345
352 template <class New_interface>
354 {
355 if( !is_valid_interface())
356 return Handle<New_interface>( 0);
357 return Handle<New_interface>( static_cast< New_interface*>(
358 m_iptr->get_interface( typename New_interface::IID())));
359 }
360
365 typedef bool (Handle::*bool_conversion_support)() const;
366
379 operator bool_conversion_support() const
380 {
382 }
383
385 friend bool operator==( const Handle<Interface>& lhs, const Interface* rhs)
386 {
387 return lhs.get() == rhs;
388 }
389
391 friend bool operator==( const Interface* lhs, const Handle<Interface>& rhs)
392 {
393 return lhs == rhs.get();
394 }
395
397 friend bool operator!=( const Handle<Interface>& lhs, const Interface* rhs)
398 {
399 return !( lhs == rhs);
400 }
401
403 friend bool operator!=( const Interface* lhs, const Handle<Interface>& rhs) {
404 return !( lhs == rhs);
405 }
406};
407
409template <class Interface1, class Interface2>
410inline bool operator==( const Handle<Interface1>& lhs, const Handle<Interface2>& rhs)
411{
412 return lhs.get() == rhs.get();
413}
414
416template <class Interface1, class Interface2>
417inline bool operator!=( const Handle<Interface1>& lhs, const Handle<Interface2>& rhs)
418{
419 return !( lhs == rhs);
420}
421
427template <class Interface>
428inline Handle<Interface> make_handle( Interface* iptr)
429{
430 return Handle<Interface>( iptr);
431}
432
438template <class Interface>
439inline Handle<Interface> make_handle_dup( Interface* iptr)
440{
441 return Handle<Interface>( iptr, DUP_INTERFACE);
442}
443
444#ifdef __cpp_variadic_templates
449template <typename Impl, typename... T>
450inline Handle<Impl> construct_handle(T&&... args)
451{
452 return Handle<Impl>{new Impl(std::forward<T>(args)...)};
453}
454
455#endif
456
457 // end group mi_base_iinterface
459
460} // namespace base
461} // namespace mi
462
463#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:113
Configuration of the Base API.
#define mi_base_assert_msg(expr, msg)
Base API assertion macro (with message).
Definition: assert.h:103
Interface * pointer
Mutable-pointer type to underlying interface.
Definition: handle.h:130
Handle()
Default constructor, initializes handle to hold an invalid interface.
Definition: handle.h:143
Interface * operator->() const
The arrow operator accesses the interface.
Definition: handle.h:340
Interface & operator*() const
The dereference operator accesses the interface.
Definition: handle.h:331
Handle(const Handle<Interface2> &other)
Copy constructor template which allows the construction from assignment compatible interface pointers...
Definition: handle.h:181
Handle(const Self &other)
Copy constructor, increments reference count if interface is valid.
Definition: handle.h:167
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:391
~Handle()
Destructor, releases the interface if it is valid, which decrements the reference count,...
Definition: handle.h:284
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:385
Handle<Interface> make_handle_dup(Interface *iptr)
Converts passed-in interface pointer to a handle, without taking interface over.
Definition: handle.h:439
Difference difference_type
Difference type (signed integral type to hold pointer differences).
Definition: handle.h:127
void swap(Self &other)
Swap two interfaces.
Definition: handle.h:206
static const Dup_interface DUP_INTERFACE
Symbolic constant to trigger a special constructor in the Handle class.
Definition: handle.h:37
Handle(Interface *ptr, Dup_interface)
Constructor from interface pointer, does not take ownership of interface but duplicates it.
Definition: handle.h:159
bool operator==(const Handle<Interface1> &lhs, const Handle<Interface2> &rhs)
Returns true if the underlying interface pointers are equal.
Definition: handle.h:410
Handle(Handle<Interface2> &&other) noexcept
Converting move constructor.
Definition: handle.h:198
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:397
Self & operator=(Self &&other) noexcept
Move assignment operator, releases old interface.
Definition: handle.h:237
Handle<New_interface> get_interface() const
Returns a new handle for a possibly different interface type, similar to a dynamic cast,...
Definition: handle.h:353
Handle(Self &&other) noexcept
Move constructor.
Definition: handle.h:190
Handle<Interface> make_handle(Interface *iptr)
Returns a handle that holds the interface pointer passed in as argument.
Definition: handle.h:428
Handle<Interface> Self
Own type.
Definition: handle.h:116
Handle(Interface *ptr)
Constructor from interface pointer, takes ownership of interface.
Definition: handle.h:150
Interface * extract()
Extracts the interface and releases the handle.
Definition: handle.h:299
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:403
Self & operator=(const Self &other)
Assignment operator, releases old interface and increments reference count of the new interface if in...
Definition: handle.h:215
bool(Handle::* bool_conversion_support)() const
Helper typedef.
Definition: handle.h:365
Self & operator=(Interface *ptr)
Assignment operator from interface pointer, releases old interface and assigns new interface ptr,...
Definition: handle.h:266
Interface Interface_type
Type of the underlying interface.
Definition: handle.h:119
const Dup_interface_helper * Dup_interface
Type for a symbolic constant to trigger a special constructor in the Handle class.
Definition: handle.h:32
Interface * get() const
Access to the interface. Returns 0 for an invalid interface.
Definition: handle.h:294
Self & operator=(const Handle<Interface2> &other)
Assignment operator template, releases old interface and increments reference count of the new interf...
Definition: handle.h:229
Interface value_type
Type of the underlying interface.
Definition: handle.h:124
Self & operator=(Handle<Interface2> &&other) noexcept
Converting move assignment operator, releases old interface.
Definition: handle.h:250
bool operator!=(const Handle<Interface1> &lhs, const Handle<Interface2> &rhs)
Returns true if the underlying interface pointers are not equal.
Definition: handle.h:417
Interface & reference
Mutable-reference type to underlying interface.
Definition: handle.h:133
void reset()
Releases the current interface, decrementing the reference count.
Definition: handle.h:273
bool is_valid_interface() const
Returns true if the interface is valid.
Definition: handle.h:291
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: base.h:34