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