• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef API_CORE_PLUGIN_IINTERFACE_H
17 #define API_CORE_PLUGIN_IINTERFACE_H
18 
19 #include <base/containers/refcnt_ptr.h>
20 #include <base/containers/shared_ptr.h>
21 #include <base/namespace.h>
22 #include <base/util/uid.h>
23 #include <core/namespace.h>
24 
CORE_BEGIN_NAMESPACE()25 CORE_BEGIN_NAMESPACE()
26 /** Base type for named interfaces provided by plugin.
27  */
28 class IInterface {
29 public:
30     static constexpr BASE_NS::Uid UID { "00000000-0000-0000-0000-000000000000" };
31 
32     using Ptr = BASE_NS::refcnt_ptr<IInterface>;
33 
34     /** Access to provided sub-interfaces
35      */
36     virtual const IInterface* GetInterface(const BASE_NS::Uid& uid) const = 0;
37     virtual IInterface* GetInterface(const BASE_NS::Uid& uid) = 0;
38 
39     template<typename InterfaceType>
40     const InterfaceType* GetInterface() const
41     {
42         return static_cast<const InterfaceType*>(GetInterface(InterfaceType::UID));
43     }
44 
45     template<typename InterfaceType>
46     InterfaceType* GetInterface()
47     {
48         return static_cast<InterfaceType*>(GetInterface(InterfaceType::UID));
49     }
50 
51     /** Take a new reference of the object.
52      */
53     virtual void Ref() = 0;
54 
55     /* Releases one reference of the object.
56      * No methods of the class shall be called after unref.
57      * The object could be destroyed, if last reference
58      */
59     virtual void Unref() = 0;
60 
61 protected:
62     IInterface() = default;
63     virtual ~IInterface() = default;
64 };
CORE_END_NAMESPACE()65 CORE_END_NAMESPACE()
66 
67 // NOLINTBEGIN(readability-identifier-naming) to keep std like syntax
68 template<class U, class T>
69 BASE_NS::shared_ptr<U> interface_pointer_cast(const BASE_NS::shared_ptr<T>& ptr)
70 {
71     static_assert(BASE_NS::is_base_of_v<CORE_NS::IInterface, T>, "T is not an IInterface");
72     static_assert(BASE_NS::is_base_of_v<CORE_NS::IInterface, U>, "U is not an IInterface");
73     if (ptr) {
74         if constexpr (BASE_NS::is_same_v<U, T>) {
75             // same type.
76             return ptr;
77         } else {
78             return BASE_NS::shared_ptr<U>(ptr, static_cast<U*>(static_cast<void*>(ptr->GetInterface(U::UID))));
79         }
80     }
81     return {};
82 }
83 
84 template<class U, class T>
interface_pointer_cast(const BASE_NS::shared_ptr<const T> & ptr)85 BASE_NS::shared_ptr<const U> interface_pointer_cast(const BASE_NS::shared_ptr<const T>& ptr)
86 {
87     static_assert(BASE_NS::is_base_of_v<CORE_NS::IInterface, T>, "T is not an IInterface");
88     static_assert(BASE_NS::is_base_of_v<CORE_NS::IInterface, U>, "U is not an IInterface");
89     if (ptr) {
90         if constexpr (BASE_NS::is_same_v<U, T>) {
91             // same type.
92             return ptr;
93         } else {
94             return BASE_NS::shared_ptr<const U>(
95                 ptr, static_cast<const U*>(static_cast<const void*>(ptr->GetInterface(U::UID))));
96         }
97     }
98     return {};
99 }
100 
101 template<class U, class T>
interface_pointer_cast(const BASE_NS::weak_ptr<T> & weak)102 BASE_NS::shared_ptr<U> interface_pointer_cast(const BASE_NS::weak_ptr<T>& weak)
103 {
104     return interface_pointer_cast<U>(weak.lock());
105 }
106 
107 template<class U, class T>
interface_pointer_cast(const BASE_NS::weak_ptr<const T> & weak)108 BASE_NS::shared_ptr<const U> interface_pointer_cast(const BASE_NS::weak_ptr<const T>& weak)
109 {
110     return interface_pointer_cast<const U>(weak.lock());
111 }
112 
113 template<class U, class T>
interface_cast(const BASE_NS::shared_ptr<T> & ptr)114 U* interface_cast(const BASE_NS::shared_ptr<T>& ptr)
115 {
116     static_assert(BASE_NS::is_base_of_v<CORE_NS::IInterface, T>, "T is not an IInterface");
117     static_assert(BASE_NS::is_base_of_v<CORE_NS::IInterface, U>, "U is not an IInterface");
118     if (ptr) {
119         if constexpr (BASE_NS::is_same_v<U, T>) {
120             // same type.
121             return ptr.get();
122         } else {
123             return static_cast<U*>(static_cast<void*>(ptr->GetInterface(U::UID)));
124         }
125     }
126     return {};
127 }
128 
129 template<class U, class T>
interface_cast(const BASE_NS::shared_ptr<const T> & ptr)130 const U* interface_cast(const BASE_NS::shared_ptr<const T>& ptr)
131 {
132     static_assert(BASE_NS::is_base_of_v<CORE_NS::IInterface, T>, "T is not an IInterface");
133     static_assert(BASE_NS::is_base_of_v<CORE_NS::IInterface, U>, "U is not an IInterface");
134     if (ptr) {
135         if constexpr (BASE_NS::is_same_v<U, T>) {
136             // same type.
137             return ptr.get();
138         } else {
139             return static_cast<const U*>(static_cast<const void*>(ptr->GetInterface(U::UID)));
140         }
141     }
142     return {};
143 }
144 
145 template<class U>
interface_cast(CORE_NS::IInterface * ptr)146 U* interface_cast(CORE_NS::IInterface* ptr)
147 {
148     static_assert(BASE_NS::is_base_of_v<CORE_NS::IInterface, U>, "U is not an IInterface");
149     if (ptr) {
150         return static_cast<U*>(static_cast<void*>(ptr->GetInterface(U::UID)));
151     }
152     return {};
153 }
154 
155 template<class U>
interface_cast(const CORE_NS::IInterface * ptr)156 const U* interface_cast(const CORE_NS::IInterface* ptr)
157 {
158     static_assert(BASE_NS::is_base_of_v<CORE_NS::IInterface, U>, "U is not an IInterface");
159     if (ptr) {
160         return static_cast<const U*>(static_cast<const void*>(ptr->GetInterface(U::UID)));
161     }
162     return {};
163 }
164 // NOLINTEND(readability-identifier-naming) to keep std like syntax
165 #endif // API_CORE_PLUGIN_IINTERFACE_H
166