1/*
2 * Copyright (C) 2014 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef XPCPtr_h
27#define XPCPtr_h
28
29#include <xpc/xpc.h>
30
31namespace IPC {
32
33struct AdoptXPC { };
34
35template<typename T> class XPCPtr {
36public:
37    XPCPtr()
38        : m_ptr(nullptr)
39    {
40    }
41
42    XPCPtr(AdoptXPC, T ptr)
43        : m_ptr(ptr)
44    {
45    }
46
47    ~XPCPtr()
48    {
49        if (m_ptr)
50            xpc_release(m_ptr);
51    }
52
53    T get() const { return m_ptr; }
54
55    explicit operator bool() const { return m_ptr; }
56    bool operator!() const { return !m_ptr; }
57
58    XPCPtr(const XPCPtr& other)
59        : m_ptr(other.m_ptr)
60    {
61        if (m_ptr)
62            xpc_retain(m_ptr);
63    }
64
65    XPCPtr(XPCPtr&& other)
66        : m_ptr(other.m_ptr)
67    {
68        other.m_ptr = nullptr;
69    }
70
71    XPCPtr& operator=(const XPCPtr& other)
72    {
73        T optr = other.get();
74        if (optr)
75            xpc_retain(optr);
76
77        T ptr = m_ptr;
78        m_ptr = optr;
79
80        if (ptr)
81            xpc_release(ptr);
82
83        return *this;
84    }
85
86    XPCPtr& operator=(std::nullptr_t)
87    {
88        if (m_ptr)
89            xpc_release(m_ptr);
90        m_ptr = nullptr;
91
92        return *this;
93    }
94private:
95    T m_ptr;
96};
97
98template<typename T> inline XPCPtr<T> adoptXPC(T ptr)
99{
100    return XPCPtr<T>(AdoptXPC { }, ptr);
101}
102
103} // namespace IPC
104
105#endif // XPCPtr_h
106