• 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 #include "number.h"
16 
17 #include <limits>
18 
19 META_BEGIN_NAMESPACE()
20 namespace Internal {
21 
22 template<typename T>
23 struct Type {};
24 
25 template<typename T>
MapToVariant(const T & v)26 static Number::VariantType MapToVariant(const T& v)
27 {
28     if constexpr (std::numeric_limits<T>::is_integer) {
29         if constexpr (std::numeric_limits<T>::is_signed) {
30             return Number::VariantType(static_cast<int64_t>(v));
31         }
32         return Number::VariantType(static_cast<uint64_t>(v));
33     }
34     return Number::VariantType(static_cast<float>(v));
35 }
36 
37 struct CompType {
38     template<typename T>
CompTypeInternal::CompType39     constexpr CompType(Type<T>)
40         : uid(UidFromType<T>()), size(sizeof(T)), load([](const void* data) {
41               T v = *static_cast<const T*>(data);
42               return MapToVariant(v);
43           }),
__anonfa3506bd0202Internal::CompType44           save([](Number::VariantType var, void* data) {
45               T v {};
46               std::visit([&](const auto& arg) { v = static_cast<T>(arg); }, var);
47               *static_cast<T*>(data) = v;
48           }),
__anonfa3506bd0402Internal::CompType49           loadAny([](const IAny& any, Number::VariantType& var) {
50               T v {};
51               bool res = any.GetValue(v);
52               if (res) {
53                   var = MapToVariant(v);
54               }
55               return res;
56           })
57     {}
58 
59     using LoadFunc = Number::VariantType(const void*);
60     using SaveFunc = void(Number::VariantType, void*);
61     using LoadAnyFunc = bool(const IAny&, Number::VariantType&);
62 
63     const TypeId uid;
64     const size_t size;
65     LoadFunc* const load;
66     SaveFunc* const save;
67     LoadAnyFunc* const loadAny;
68 };
69 
70 constexpr CompType COMPATIBLES[] = {
71     Type<float>(),
72     Type<double>(),
73     Type<bool>(),
74     Type<uint8_t>(),
75     Type<uint16_t>(),
76     Type<uint32_t>(),
77     Type<uint64_t>(),
78     Type<int8_t>(),
79     Type<int16_t>(),
80     Type<int32_t>(),
81     Type<int64_t>(),
82 };
83 
CompatibleTypes()84 static BASE_NS::vector<TypeId> CompatibleTypes()
85 {
86     BASE_NS::vector<TypeId> res;
87     for (auto&& v : COMPATIBLES) {
88         res.push_back(v.uid);
89     }
90     return res;
91 }
92 
FindCompatible(const TypeId & uid,size_t size)93 static const CompType* FindCompatible(const TypeId& uid, size_t size)
94 {
95     for (auto&& v : COMPATIBLES) {
96         if (v.uid == uid && v.size == size) {
97             return &v;
98         }
99     }
100     return nullptr;
101 }
102 
FindCompatible(const IAny & any)103 static const CompType* FindCompatible(const IAny& any)
104 {
105     auto anyComps = any.GetCompatibleTypes(CompatibilityDirection::BOTH);
106     for (auto&& v : COMPATIBLES) {
107         for (auto&& av : anyComps) {
108             if (v.uid == av) {
109                 return &v;
110             }
111         }
112     }
113     return nullptr;
114 }
115 
Number(VariantType v)116 Number::Number(VariantType v) : value_(v) {}
GetCompatibleTypes(CompatibilityDirection dir) const117 const BASE_NS::array_view<const TypeId> Number::GetCompatibleTypes(CompatibilityDirection dir) const
118 {
119     static BASE_NS::vector<TypeId> types = CompatibleTypes();
120     return types;
121 }
GetData(const TypeId & uid,void * data,size_t size) const122 AnyReturnValue Number::GetData(const TypeId& uid, void* data, size_t size) const
123 {
124     if (auto c = FindCompatible(uid, size)) {
125         c->save(value_, data);
126         return AnyReturn::SUCCESS;
127     }
128     return AnyReturn::INCOMPATIBLE_TYPE;
129 }
SetData(const TypeId & uid,const void * data,size_t size)130 AnyReturnValue Number::SetData(const TypeId& uid, const void* data, size_t size)
131 {
132     if (auto c = FindCompatible(uid, size)) {
133         value_ = c->load(data);
134         return AnyReturn::SUCCESS;
135     }
136     return AnyReturn::INCOMPATIBLE_TYPE;
137 }
CopyFrom(const IAny & any)138 AnyReturnValue Number::CopyFrom(const IAny& any)
139 {
140     if (auto c = FindCompatible(any)) {
141         c->loadAny(any, value_);
142     }
143     return AnyReturn::INCOMPATIBLE_TYPE;
144 }
ResetValue()145 AnyReturnValue Number::ResetValue()
146 {
147     value_ = {};
148     return AnyReturn::SUCCESS;
149 }
Clone(const AnyCloneOptions & options) const150 IAny::Ptr Number::Clone(const AnyCloneOptions& options) const
151 {
152     if (options.role == TypeIdRole::ARRAY) {
153         CORE_LOG_E("Number: cloning into an array not supported.");
154         return {};
155     }
156     return IAny::Ptr(new Number(options.value == CloneValueType::COPY_VALUE ? value_ : VariantType {}));
157 }
GetTypeId(TypeIdRole role) const158 TypeId Number::GetTypeId(TypeIdRole role) const
159 {
160     if (role == TypeIdRole::ARRAY) {
161         return std::visit([&](auto arg) { return ArrayUidFromType<decltype(arg)>(); }, value_);
162     }
163     return std::visit([&](auto arg) { return UidFromType<decltype(arg)>(); }, value_);
164 }
165 
GetTypeIdString() const166 BASE_NS::string Number::GetTypeIdString() const
167 {
168     return std::visit([&](auto arg) { return MetaType<decltype(arg)>::name; }, value_);
169 }
170 
171 } // namespace Internal
172 META_END_NAMESPACE()
173