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