1 /*
2 * Copyright (c) 2024 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 META_BASE_INTERFACE_MACROS_H
17 #define META_BASE_INTERFACE_MACROS_H
18
19 #include <base/containers/atomics.h>
20
21 #include "types.h"
22
23 /**
24 * @brief Implement plain reference counting (see IInterface).
25 */
26 #define META_IMPLEMENT_REF_COUNT_NO_ONDESTROY() \
27 int32_t refcnt_ { 0 }; \
28 void Ref() override \
29 { \
30 BASE_NS::AtomicIncrement(&refcnt_); \
31 } \
32 void Unref() override \
33 { \
34 if (BASE_NS::AtomicDecrement(&refcnt_) == 0) { \
35 delete this; \
36 } \
37 }
38
39 #define META_DEFAULT_COPY(className) \
40 className(const className&) noexcept = default; \
41 className& operator=(const className&) noexcept = default;
42
43 #define META_DEFAULT_MOVE(className) \
44 className(className&&) noexcept = default; \
45 className& operator=(className&&) noexcept = default;
46
47 #define META_DEFAULT_COPY_MOVE(className) \
48 META_DEFAULT_COPY(className) \
49 META_DEFAULT_MOVE(className)
50
51 /**
52 * @brief Make class non-copyable.
53 */
54 #define META_NO_COPY(className) \
55 className(const className&) = delete; \
56 className& operator=(const className&) = delete;
57
58 /**
59 * @brief Make class non-movable.
60 */
61 #define META_NO_MOVE(className) \
62 className(className&&) = delete; \
63 className& operator=(className&&) = delete;
64
65 /**
66 * @brief Make class non-copyable and non-movable.
67 */
68 #define META_NO_COPY_MOVE(className) \
69 META_NO_COPY(className) \
70 META_NO_MOVE(className)
71
72 /**
73 * @brief Add compiler generated default constructor and virtual destructor to a class.
74 */
75 #define META_INTERFACE_CTOR_DTOR(className) \
76 className() noexcept = default; \
77 virtual ~className() = default;
78
79 /**
80 * @brief Make class non-copyable and non-movable with compiler generated default constructor and virtual destructor.
81 */
82 #define META_NO_COPY_MOVE_INTERFACE(className) \
83 META_INTERFACE_CTOR_DTOR(className) \
84 META_NO_COPY_MOVE(className)
85
META_BEGIN_NAMESPACE()86 META_BEGIN_NAMESPACE()
87 namespace Internal {
88 constexpr const InterfaceInfo ToInterfaceInfoImpl(const InterfaceInfo& info, BASE_NS::string_view)
89 {
90 return info;
91 }
92 constexpr const InterfaceInfo ToInterfaceInfoImpl(TypeId uid, BASE_NS::string_view name)
93 {
94 return InterfaceInfo { uid, name };
95 }
96 constexpr const InterfaceInfo ToInterfaceInfoImpl(const char (&str)[37], BASE_NS::string_view name)
97 {
98 return InterfaceInfo { TypeId { str }, name };
99 }
100 } // namespace Internal
101 META_END_NAMESPACE()
102
103 #define META_INTERFACE3(basename, name, intf_name) \
104 public: \
105 using base = basename; \
106 using base::GetInterface; \
107 /* NOLINTNEXTLINE(readability-identifier-naming) */ \
108 constexpr static const META_NS::InterfaceInfo INTERFACE_INFO { META_NS::Internal::ToInterfaceInfoImpl( \
109 intf_name, #name) }; \
110 constexpr static const BASE_NS::Uid UID { intf_name }; \
111 static_assert(META_NS::IsValidUid(UID), "invalid UID"); \
112 using Ptr = BASE_NS::shared_ptr<name>; \
113 using ConstPtr = BASE_NS::shared_ptr<const name>; \
114 using WeakPtr = BASE_NS::weak_ptr<name>; \
115 using ConstWeakPtr = BASE_NS::weak_ptr<const name>; \
116 \
117 protected: \
118 name() noexcept = default; \
119 ~name() override = default; \
120 META_NO_COPY_MOVE(name) \
121 private:
122
123 #define META_INTERFACE2(basename, name) META_INTERFACE3(basename, name, InterfaceId::name)
124
125 /**
126 * @brief Implement "interface"-interface for class. Supports two and three parameter versions.
127 * Example:
128 * META_INTERFACE(CORE_NS::IInterface, ICallContext, "2e9cac45-0e61-4152-8b2a-bc1c65fded3d")
129 * META_INTERFACE(CORE_NS::IInterface, ICallContext)
130 *
131 * The two parameter version expects to find InterfaceId::ICallContext for the UID (see META_REGISTER_INTERFACE)
132 */
133 #define META_INTERFACE(...) \
134 META_EXPAND(META_GET_MACRO3_IMPL(__VA_ARGS__, META_INTERFACE3, META_INTERFACE2)(__VA_ARGS__))
135
136 #include <base/containers/shared_ptr.h>
137
138 #endif
139