neuray API Programmer's Manual

handle.h File Reference

Description

Smart-pointer handle class for interfaces, const and non-const version.

Code Example

handle.h

‎//*****************************************************************************
// Copyright 1986, 2016 NVIDIA Corporation. All rights reserved.
//*****************************************************************************
//*****************************************************************************

#ifndef MI_BASE_HANDLE_H
#define MI_BASE_HANDLE_H

#include <mi/base/assert.h>
#include <mi/base/iinterface.h>

namespace mi {
namespace base {

// Helper type to define Dup_interface
struct Dup_interface_helper {};

typedef const Dup_interface_helper* Dup_interface;

static const Dup_interface 
               DUP_INTERFACE = 0;

template < class Interface>
class Handle
{
public:
    typedef Handle< Interface>                                          
               Self;

    typedef Interface                                                  Interface_type;

    // STL iterator inspired typedef names

    typedef Interface                                                  value_type;

    typedef Difference                                                 
               difference_type;

    typedef Interface*                                                 pointer;

    typedef Interface&                                                 reference;

private:
    Interface*   m_iptr;     // pointer to underlying interface, can be 0

public:
    Handle() : m_iptr(0) {}

    explicit Handle( Interface* ptr) : m_iptr(ptr) {}

    Handle( Interface* ptr, Dup_interface) : m_iptr(ptr) {
        if ( m_iptr)
            m_iptr->retain();
    }

    Handle( const Self& other) : m_iptr( other.m_iptr) {
        if ( m_iptr)
            m_iptr->retain();
    }

    template <class Interface2>
    Handle( const Handle< Interface2>& other) : m_iptr( other.get()) {
        if ( m_iptr)
            m_iptr->retain();
    }

    void swap( Self& other) {
        Interface* tmp_iptr = m_iptr;
        m_iptr = other.m_iptr;
        other.m_iptr = tmp_iptr;
    }

    Self& operator=( const Self& other) {
        Self(other).swap(*this);
        return *this;
    }

    template <class Interface2>
    Self& operator=( const Handle< Interface2>& other) {
        Self(other).swap(*this);
        return *this;
    }

    Self& operator=( Interface* ptr) {
        Self(ptr).swap(*this);
        return *this;
    }

    void reset() {
        if(m_iptr != NULL)
        {
            m_iptr->release();
            m_iptr = NULL;
        }
    }

    ~Handle() {
        if ( m_iptr)
            m_iptr->release();
    }

    bool is_valid_interface() const { return m_iptr != 0; }

    Interface*  get()         const { return  m_iptr; }

    Interface&  operator*() const {
        mi_base_assert_msg( is_valid_interface(), "precondition");
        return  * m_iptr;
    }

    Interface*  operator->() const {
        mi_base_assert_msg( is_valid_interface(), "precondition");
        return  m_iptr;
    }

    template <class New_interface>
    Handle< New_interface> 
               get_interface() const {
        if ( ! is_valid_interface())
            return Handle< New_interface>(0);
        return Handle< New_interface>( static_cast< New_interface*>(
            m_iptr->get_interface( typename New_interface::IID())));
    }

    typedef bool (Handle::*bool_conversion_support)() const;

    operator bool_conversion_support() const {
        return is_valid_interface() ? &Handle< Interface>::is_valid_interface : 0;
    }

    friend bool operator==( const Handle< Interface>& lhs, const Interface* rhs) {
        return lhs.get() == rhs;
    }

    friend bool operator==( const Interface* lhs, const Handle< Interface>& rhs) {
        return lhs == rhs.get();
    }

    friend bool operator!=( const Handle< Interface>& lhs, const Interface* rhs) {
        return ! ( lhs == rhs);
    }

    friend bool operator!=( const Interface* lhs, const Handle< Interface>& rhs) {
        return ! ( lhs == rhs);
    }
};

template <class Interface1, class Interface2>
inline bool operator==( const Handle< Interface1>& lhs, const Handle< Interface2>& rhs) {
    return lhs.get() == rhs.get();
}

template <class Interface1, class Interface2>
inline bool operator!=( const Handle< Interface1>& lhs, const Handle< Interface2>& rhs) {
    return ! ( lhs == rhs);
}


template <class Interface>
inline Handle< Interface> 
               make_handle( Interface* iptr) {
    return Handle< Interface>(iptr);
}


template <class Interface>
inline Handle< Interface> 
               make_handle_dup( Interface* iptr) {
    return Handle< Interface>(iptr, DUP_INTERFACE);
}
 // end group mi_base_iinterface

} // namespace base
} // namespace mi

#endif // MI_BASE_HANDLE_H

Namespaces

namespace 
Common namespace for APIs of NVIDIA Advanced Rendering Center GmbH. More...
namespace 
Namespace for the Base API. More...

Classes

class 
Handle class template for interfaces, automatizing the lifetime control via reference counting. More...

Typedefs

typedef Dup_interface_helper *  
Type for a symbolic constant to trigger a special constructor in the Handle class. More...

Functions

template< class Interface> Handle < Interface >  ( Interface* iptr)
Returns a handle that holds the interface pointer passed in as argument. More...
template< class Interface> Handle < Interface >  ( Interface* iptr)
Converts passed-in interface pointer to a handle, without taking interface over. More...
template< class Interface1, class Interface2>bool   ( const Handle < Interface1 >& lhs, const Handle < Interface2 >& rhs)
Returns true if the underlying interface pointers are not equal. More...
template< class Interface1, class Interface2>bool   ( const Handle < Interface1 >& lhs, const Handle < Interface2 >& rhs)
Returns true if the underlying interface pointers are equal. More...

Variables

static const Dup_interface  
Symbolic constant to trigger a special constructor in the Handle class. More...