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