1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 Jochen Becher
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25 
26 #pragma once
27 
28 #include "uid.h"
29 #include "qmtassert.h"
30 
31 namespace qmt {
32 
33 template<class T>
34 class Handle
35 {
36 public:
37     Handle() = default;
Handle(const Uid & uid)38     explicit Handle(const Uid &uid) : m_uid(uid) { }
Handle(T * t)39     explicit Handle(T *t) : m_uid(t ? t->uid() : Uid()), m_target(t) { }
Handle(const Handle & rhs)40     Handle(const Handle &rhs) : m_uid(rhs.m_uid), m_target(rhs.m_target) { }
41     template<class U>
Handle(const Handle<U> & rhs)42     Handle(const Handle<U> &rhs) : m_uid(rhs.uid()), m_target(rhs.target()) { }
43 
44     Handle &operator=(const Handle &) = default;
45 
isNull()46     bool isNull() const { return !m_uid.isValid(); }
hasTarget()47     bool hasTarget() const { return m_target != nullptr; }
uid()48     Uid uid() const { return m_uid; }
target()49     T *target() const { return m_target; }
50 
setUid(const Uid & uid)51     void setUid(const Uid &uid)
52     {
53         QMT_CHECK(m_target ? (m_target->uid() == uid) : true);
54         m_uid = uid;
55     }
56 
setTarget(T * t)57     void setTarget(T *t)
58     {
59         m_uid = t ? t->uid() : Uid();
60         m_target = t;
61     }
62 
clear()63     void clear()
64     {
65         m_uid = Uid();
66         m_target = nullptr;
67     }
68 
clearTarget()69     void clearTarget() { m_target = nullptr; }
70 
71 private:
72     Uid m_uid;
73     T *m_target = nullptr;
74 };
75 
76 template<class T>
qHash(const Handle<T> & handle)77 inline int qHash(const Handle<T> &handle)
78 {
79     return qHash(handle.uid());
80 }
81 
82 template<class T, class U>
83 bool operator==(const Handle<T> &lhs, const Handle<U> &rhs)
84 {
85     return lhs.uid() == rhs.uid();
86 }
87 
88 template<class T>
makeHandle(T * t)89 Handle<T> makeHandle(T *t)
90 {
91     return Handle<T>(t);
92 }
93 
94 template<class T, class U>
handle_dynamic_cast(const Handle<U> & handle)95 Handle<T> handle_dynamic_cast(const Handle<U> &handle)
96 {
97     if (!handle.hasTarget())
98         return Handle<T>(handle.uid());
99     return Handle<T>(dynamic_cast<T *>(handle.target()));
100 }
101 
102 } // namespace qmt
103