1fb299fa2Sopenharmony_ci/*
2fb299fa2Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3fb299fa2Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fb299fa2Sopenharmony_ci * you may not use this file except in compliance with the License.
5fb299fa2Sopenharmony_ci * You may obtain a copy of the License at
6fb299fa2Sopenharmony_ci *
7fb299fa2Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8fb299fa2Sopenharmony_ci *
9fb299fa2Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fb299fa2Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fb299fa2Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fb299fa2Sopenharmony_ci * See the License for the specific language governing permissions and
13fb299fa2Sopenharmony_ci * limitations under the License.
14fb299fa2Sopenharmony_ci */
15fb299fa2Sopenharmony_ci
16fb299fa2Sopenharmony_ci#ifndef MACRO_UPDATER_H
17fb299fa2Sopenharmony_ci#define MACRO_UPDATER_H
18fb299fa2Sopenharmony_ci
19fb299fa2Sopenharmony_ci#define DISALLOW_COPY_MOVE_ASSIGN(ClassName)            \
20fb299fa2Sopenharmony_ci    ClassName &operator = (const ClassName &) = delete; \
21fb299fa2Sopenharmony_ci    ClassName &operator = (ClassName &&) = delete
22fb299fa2Sopenharmony_ci
23fb299fa2Sopenharmony_ci#define DISALLOW_COPY_MOVE_CONSTRUCT(ClassName) \
24fb299fa2Sopenharmony_ci    ClassName(const ClassName &) = delete;      \
25fb299fa2Sopenharmony_ci    ClassName(ClassName &&) = delete
26fb299fa2Sopenharmony_ci
27fb299fa2Sopenharmony_ci#define DISALLOW_COPY_MOVE(ClassName)     \
28fb299fa2Sopenharmony_ci    DISALLOW_COPY_MOVE_ASSIGN(ClassName); \
29fb299fa2Sopenharmony_ci    DISALLOW_COPY_MOVE_CONSTRUCT(ClassName)
30fb299fa2Sopenharmony_ci
31fb299fa2Sopenharmony_ci#define STRINGFY_WRAPPER(x) #x
32fb299fa2Sopenharmony_ci#define STRINGFY(x) STRINGFY_WRAPPER(x)
33fb299fa2Sopenharmony_ci
34fb299fa2Sopenharmony_ci#define SIZE(...) SIZE_IMPL(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
35fb299fa2Sopenharmony_ci#define SIZE_IMPL(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, N, ...) N
36fb299fa2Sopenharmony_ci
37fb299fa2Sopenharmony_ci#define CONCAT(x, y) CONCAT_WRAPPER(x, y)
38fb299fa2Sopenharmony_ci#define CONCAT_WRAPPER(x, y) x##y
39fb299fa2Sopenharmony_ci
40fb299fa2Sopenharmony_ci#define GET_TYPE_2(e1, e2) e1
41fb299fa2Sopenharmony_ci#define GET_TYPE_3(e1, e2, e3) e1, e2
42fb299fa2Sopenharmony_ci#define GET_TYPE_4(e1, e2, e3, e4) e1, e2, e3
43fb299fa2Sopenharmony_ci
44fb299fa2Sopenharmony_ci#define GET_NAME_2(e1, e2) e2
45fb299fa2Sopenharmony_ci#define GET_NAME_3(e1, e2, e3) e3
46fb299fa2Sopenharmony_ci#define GET_NAME_4(e1, e2, e3, e4) e4
47fb299fa2Sopenharmony_ci
48fb299fa2Sopenharmony_ci#define GET_TYPE(...) CONCAT(GET_TYPE_, SIZE(__VA_ARGS__))(__VA_ARGS__)
49fb299fa2Sopenharmony_ci#define GET_NAME(...) CONCAT(GET_NAME_, SIZE(__VA_ARGS__))(__VA_ARGS__)
50fb299fa2Sopenharmony_ci#define GET_KEY(...) STRINGFY(GET_NAME(__VA_ARGS__))
51fb299fa2Sopenharmony_ci
52fb299fa2Sopenharmony_ci#define REPEAT(MACRO, ...) CONCAT(REPEAT_, SIZE(__VA_ARGS__))(MACRO, __VA_ARGS__)
53fb299fa2Sopenharmony_ci#define REPEAT_1(MACRO, element, ...) MACRO(0, element)
54fb299fa2Sopenharmony_ci#define REPEAT_2(MACRO, element, ...) MACRO(1, element) REPEAT_1(MACRO, __VA_ARGS__)
55fb299fa2Sopenharmony_ci#define REPEAT_3(MACRO, element, ...) MACRO(2, element) REPEAT_2(MACRO, __VA_ARGS__)
56fb299fa2Sopenharmony_ci#define REPEAT_4(MACRO, element, ...) MACRO(3, element) REPEAT_3(MACRO, __VA_ARGS__)
57fb299fa2Sopenharmony_ci#define REPEAT_5(MACRO, element, ...) MACRO(4, element) REPEAT_4(MACRO, __VA_ARGS__)
58fb299fa2Sopenharmony_ci#define REPEAT_6(MACRO, element, ...) MACRO(5, element) REPEAT_5(MACRO, __VA_ARGS__)
59fb299fa2Sopenharmony_ci#define REPEAT_7(MACRO, element, ...) MACRO(6, element) REPEAT_6(MACRO, __VA_ARGS__)
60fb299fa2Sopenharmony_ci#define REPEAT_8(MACRO, element, ...) MACRO(7, element) REPEAT_7(MACRO, __VA_ARGS__)
61fb299fa2Sopenharmony_ci#define REPEAT_9(MACRO, element, ...) MACRO(8, element) REPEAT_8(MACRO, __VA_ARGS__)
62fb299fa2Sopenharmony_ci#define REPEAT_10(MACRO, element, ...) MACRO(9, element) REPEAT_9(MACRO, __VA_ARGS__)
63fb299fa2Sopenharmony_ci
64fb299fa2Sopenharmony_ci#define COMMA_IF(i) CONCAT(COMMA_IF_, i)
65fb299fa2Sopenharmony_ci#define COMMA_IF_0
66fb299fa2Sopenharmony_ci#define COMMA_IF_1 ,
67fb299fa2Sopenharmony_ci#define COMMA_IF_2 ,
68fb299fa2Sopenharmony_ci#define COMMA_IF_3 ,
69fb299fa2Sopenharmony_ci#define COMMA_IF_4 ,
70fb299fa2Sopenharmony_ci#define COMMA_IF_5 ,
71fb299fa2Sopenharmony_ci#define COMMA_IF_6 ,
72fb299fa2Sopenharmony_ci#define COMMA_IF_7 ,
73fb299fa2Sopenharmony_ci#define COMMA_IF_8 ,
74fb299fa2Sopenharmony_ci#define COMMA_IF_9 ,
75fb299fa2Sopenharmony_ci
76fb299fa2Sopenharmony_ci#define GET_MEMBER_DECLARTION(idx, tuple) GET_TYPE tuple GET_NAME tuple;
77fb299fa2Sopenharmony_ci#define GET_MEMBER_KEY(idx, tuple) GET_KEY tuple COMMA_IF(idx)
78fb299fa2Sopenharmony_ci#define GET_MEMBER(idx, tuple) obj.GET_NAME tuple COMMA_IF(idx)
79fb299fa2Sopenharmony_ci
80fb299fa2Sopenharmony_ci#define DEFINE_STRUCT_TRAIT(NAME, KEY, ...) \
81fb299fa2Sopenharmony_ci    DEFINE_STRUCT(NAME, __VA_ARGS__);       \
82fb299fa2Sopenharmony_ci    DEFINE_TRAIT(NAME, KEY, __VA_ARGS__)
83fb299fa2Sopenharmony_ci
84fb299fa2Sopenharmony_ci#define DEFINE_STRUCT(NAME, ...)                   \
85fb299fa2Sopenharmony_ci    struct NAME {                                  \
86fb299fa2Sopenharmony_ci        REPEAT(GET_MEMBER_DECLARTION, __VA_ARGS__) \
87fb299fa2Sopenharmony_ci    }
88fb299fa2Sopenharmony_ci
89fb299fa2Sopenharmony_ci#define DEFINE_TRAIT(NAME, KEY, ...)                                                       \
90fb299fa2Sopenharmony_ci    template <> struct Traits<NAME> {                                                      \
91fb299fa2Sopenharmony_ci        constexpr static const char *STRUCT_KEY = KEY;                                     \
92fb299fa2Sopenharmony_ci        constexpr static const char *MEMBER_KEY[] = {REPEAT(GET_MEMBER_KEY, __VA_ARGS__)}; \
93fb299fa2Sopenharmony_ci        constexpr static int COUNT = sizeof(MEMBER_KEY) / sizeof(char *);                  \
94fb299fa2Sopenharmony_ci        template <std::size_t idx> constexpr static auto &Get(NAME &obj)                   \
95fb299fa2Sopenharmony_ci        {                                                                                  \
96fb299fa2Sopenharmony_ci            return Detail::Get<idx>(REPEAT(GET_MEMBER, __VA_ARGS__));                      \
97fb299fa2Sopenharmony_ci        }                                                                                  \
98fb299fa2Sopenharmony_ci    }
99fb299fa2Sopenharmony_ci#endif