File: comptr.h

package info (click to toggle)
wxpython4.0 4.2.3%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 221,752 kB
  • sloc: cpp: 962,555; python: 230,573; ansic: 170,731; makefile: 51,756; sh: 9,342; perl: 1,564; javascript: 584; php: 326; xml: 200
file content (134 lines) | stat: -rw-r--r-- 3,094 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
///////////////////////////////////////////////////////////////////////////////
// Name:        wx/msw/private/comptr.h
// Purpose:     Smart pointer for COM interfaces.
// Author:      PB
// Created:     2012-04-16
// Copyright:   (c) 2012 wxWidgets team
// Licence:     wxWindows licence
///////////////////////////////////////////////////////////////////////////////

#ifndef _WX_MSW_PRIVATE_COMPTR_H_
#define _WX_MSW_PRIVATE_COMPTR_H_

// ----------------------------------------------------------------------------
// wxCOMPtr: A minimalistic smart pointer for use with COM interfaces.
// ----------------------------------------------------------------------------

template <class T>
class wxCOMPtr
{
public:
    typedef T element_type;

    wxCOMPtr()
        : m_ptr(NULL)
    {
    }

    explicit wxCOMPtr(T* ptr)
        : m_ptr(ptr)
    {
        if ( m_ptr )
            m_ptr->AddRef();
    }

    wxCOMPtr(const wxCOMPtr& ptr)
        : m_ptr(ptr.get())
    {
        if ( m_ptr )
            m_ptr->AddRef();
    }

    ~wxCOMPtr()
    {
        if ( m_ptr )
            m_ptr->Release();
    }

    void reset(T* ptr = NULL)
    {
        if ( m_ptr != ptr)
        {
            if ( ptr )
                ptr->AddRef();
            if ( m_ptr )
                m_ptr->Release();
            m_ptr = ptr;
        }
    }

    wxCOMPtr& operator=(const wxCOMPtr& ptr)
    {
        reset(ptr.get());
        return *this;
    }

    wxCOMPtr& operator=(T* ptr)
    {
        reset(ptr);
        return *this;
    }

    operator T*() const
    {
        return m_ptr;
    }

    T& operator*() const
    {
        return *m_ptr;
    }

    T* operator->() const
    {
        return m_ptr;
    }

    // It would be better to forbid direct access completely but we do need
    // for QueryInterface() and similar functions, so provide it but it can
    // only be used to initialize the pointer, not to modify an existing one.
    T** operator&()
    {
        wxASSERT_MSG(!m_ptr,
                     wxS("Can't get direct access to initialized pointer"));

        return &m_ptr;
    }

    T* get() const
    {
        return m_ptr;
    }

    T* Get() const
    {
        return m_ptr;
    }

    bool operator<(T* ptr) const
    {
        return get() < ptr;
    }

private:
    T* m_ptr;
};

// Define a helper for the macro below: we just need a function taking a
// pointer and not returning anything to avoid warnings about unused return
// value of the cast in the macro itself.
namespace wxPrivate { inline void PPV_ARGS_CHECK(void*) { } }

// Takes the interface name and a pointer to a pointer of the interface type
// and expands into the IID of this interface and the same pointer but after a
// type-safety check.
//
// This is similar to the standard IID_PPV_ARGS macro but takes the pointer
// type instead of relying on the non-standard Microsoft __uuidof().
#define wxIID_PPV_ARGS(IType, pType) \
    IID_##IType, \
    (wxPrivate::PPV_ARGS_CHECK(static_cast<IType*>(*pType)), \
     reinterpret_cast<void**>(pType))

#endif // _WX_MSW_PRIVATE_COMPTR_H_