• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef META_INTERFACE_DETAIL_ENUM_H
16 #define META_INTERFACE_DETAIL_ENUM_H
17 
18 #include <meta/interface/detail/multi_type_any.h>
19 #include <meta/interface/enum_macros.h>
20 
META_BEGIN_NAMESPACE()21 META_BEGIN_NAMESPACE()
22 namespace Internal {
23 
24 template<typename Enum, size_t... Index>
25 BASE_NS::array_view<const META_NS::EnumValue> GetValues(const EnumValue<Enum>* const values, IndexSequence<Index...>)
26 {
27     static const META_NS::EnumValue arr[] { values[Index].info... };
28     return BASE_NS::array_view<const META_NS::EnumValue> { arr };
29 }
30 
31 } // namespace Internal
32 
33 template<typename T>
34 using EnumCompatType = BASE_NS::conditional_t<BASE_NS::is_unsigned_v<BASE_NS::underlying_type_t<T>>, uint64_t, int64_t>;
35 
36 template<typename Type>
37 class EnumBase : public MultiTypeAny<Type, StaticCastConv, EnumCompatType<Type>> {
38 public:
39     explicit EnumBase(Type v = {})
40     {
41         InternalSetValue(v);
42     }
43 
44     using IAny::Clone;
45     IAny::Ptr Clone(const AnyCloneOptions& options) const override;
46 
47 private:
InternalSetValue(const Type & value)48     AnyReturnValue InternalSetValue(const Type& value) override
49     {
50         if (value != value_) {
51             value_ = value;
52             return AnyReturn::SUCCESS;
53         }
54         return AnyReturn::NOTHING_TO_DO;
55     }
InternalGetValue()56     const Type& InternalGetValue() const override
57     {
58         return value_;
59     }
60 
61     Type value_ {};
62 };
63 
64 template<typename Type>
65 class ArrayEnumBase : public ArrayMultiTypeAnyBase<Type> {
66     using Super = ArrayMultiTypeAnyBase<Type>;
67 
68 public:
69     using Super::Super;
70 
GetItemCompatibleTypes(CompatibilityDirection dir)71     const BASE_NS::array_view<const TypeId> GetItemCompatibleTypes(CompatibilityDirection dir) const override
72     {
73         return EnumBase<Type>::StaticGetCompatibleTypes(dir);
74     }
75 
Clone(const AnyCloneOptions & options)76     IAny::Ptr Clone(const AnyCloneOptions& options) const override
77     {
78         if (options.role == TypeIdRole::ITEM) {
79             return IAny::Ptr(new EnumBase<Type>);
80         }
81         return IAny::Ptr(new ArrayEnumBase {
82             options.value == CloneValueType::COPY_VALUE ? this->value_ : typename Super::ArrayType {} });
83     }
84 };
85 
86 template<typename Type>
Clone(const AnyCloneOptions & options)87 IAny::Ptr EnumBase<Type>::Clone(const AnyCloneOptions& options) const
88 {
89     if (options.role == TypeIdRole::ARRAY) {
90         return IAny::Ptr(new ArrayEnumBase<Type>());
91     }
92     return IAny::Ptr(new EnumBase { options.value == CloneValueType::COPY_VALUE ? this->value_ : Type {} });
93 }
94 
95 template<typename EnumType>
96 class Enum : public IntroduceInterfaces<EnumBase<typename EnumType::Type>, IEnum> {
97 public:
98     using Super = IntroduceInterfaces<EnumBase<typename EnumType::Type>, IEnum>;
99     using Type = typename EnumType::Type;
100     using RealType = BASE_NS::underlying_type_t<Type>;
101 
102     explicit Enum(Type v = EnumType::DEFAULT_VALUE)
103     {
104         InternalSetValue(v);
105     }
106 
GetName()107     BASE_NS::string_view GetName() const override
108     {
109         return EnumType::NAME;
110     }
GetDescription()111     BASE_NS::string_view GetDescription() const override
112     {
113         return EnumType::DESC;
114     }
GetEnumType()115     META_NS::EnumType GetEnumType() const override
116     {
117         return EnumType::ENUM_TYPE;
118     }
GetValues()119     BASE_NS::array_view<const EnumValue> GetValues() const override
120     {
121         return Internal::GetValues(EnumType::VALUES, MakeIndexSequence<EnumType::VALUES_SIZE>());
122     }
GetValueIndex(const Type & v)123     size_t GetValueIndex(const Type& v) const
124     {
125         for (size_t i = 0; i != EnumType::VALUES_SIZE; ++i) {
126             if (v == EnumType::VALUES[i].value) {
127                 return i;
128             }
129         }
130         return -1;
131     }
GetValueIndex()132     size_t GetValueIndex() const override
133     {
134         return GetValueIndex(value_);
135     }
SetValueIndex(size_t index)136     bool SetValueIndex(size_t index) override
137     {
138         if (index < EnumType::VALUES_SIZE) {
139             value_ = EnumType::VALUES[index].value;
140             return true;
141         }
142         return false;
143     }
IsValueSet(size_t index)144     bool IsValueSet(size_t index) const override
145     {
146         if (index < EnumType::VALUES_SIZE) {
147             return RealType(value_) & RealType(EnumType::VALUES[index].value);
148         }
149         return false;
150     }
FlipValue(size_t index,bool isSet)151     bool FlipValue(size_t index, bool isSet) override
152     {
153         if (EnumType::ENUM_TYPE == META_NS::EnumType::BIT_FIELD && index < EnumType::VALUES_SIZE) {
154             if (isSet) {
155                 value_ = Type(RealType(value_) | RealType(EnumType::VALUES[index].value));
156             } else {
157                 value_ = Type(RealType(value_) & ~RealType(EnumType::VALUES[index].value));
158             }
159             return true;
160         }
161         return false;
162     }
163 
ResetValue()164     AnyReturnValue ResetValue() override
165     {
166         return InternalSetValue(EnumType::DEFAULT_VALUE);
167     }
168 
169     using IAny::Clone;
170     IAny::Ptr Clone(const AnyCloneOptions& options) const override;
171 
172 private:
InternalSetValue(const Type & value)173     AnyReturnValue InternalSetValue(const Type& value) override
174     {
175         if (EnumType::ENUM_TYPE == META_NS::EnumType::SINGLE_VALUE && GetValueIndex(value) == -1) {
176             return AnyReturn::INVALID_ARGUMENT;
177         }
178         if (value != value_) {
179             value_ = value;
180             return AnyReturn::SUCCESS;
181         }
182         return AnyReturn::NOTHING_TO_DO;
183     }
InternalGetValue()184     const Type& InternalGetValue() const override
185     {
186         return value_;
187     }
188 
189     Type value_ { EnumType::DEFAULT_VALUE };
190 };
191 
192 template<typename EnumType>
193 class ArrayEnum : public ArrayEnumBase<typename EnumType::Type> {
194     using Type = typename EnumType::Type;
195     using Super = ArrayEnumBase<Type>;
196 
197 public:
198     using Super::Super;
199 
GetItemCompatibleTypes(CompatibilityDirection dir)200     const BASE_NS::array_view<const TypeId> GetItemCompatibleTypes(CompatibilityDirection dir) const override
201     {
202         return Enum<EnumType>::StaticGetCompatibleTypes(dir);
203     }
204 
Clone(const AnyCloneOptions & options)205     IAny::Ptr Clone(const AnyCloneOptions& options) const override
206     {
207         if (options.role == TypeIdRole::ITEM) {
208             return IAny::Ptr(new Enum<EnumType>);
209         }
210         return IAny::Ptr(new ArrayEnum {
211             options.value == CloneValueType::COPY_VALUE ? this->value_ : typename Super::ArrayType {} });
212     }
213 };
214 
215 template<typename EnumType>
Clone(const AnyCloneOptions & options)216 IAny::Ptr Enum<EnumType>::Clone(const AnyCloneOptions& options) const
217 {
218     if (options.role == TypeIdRole::ARRAY) {
219         return IAny::Ptr(new ArrayEnum<EnumType>());
220     }
221     return IAny::Ptr(new Enum { options.value == CloneValueType::COPY_VALUE ? this->value_ : EnumType::DEFAULT_VALUE });
222 }
223 
224 META_END_NAMESPACE()
225 
226 #endif
227