18bf80f4bSopenharmony_ci/* 28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License. 58bf80f4bSopenharmony_ci * You may obtain a copy of the License at 68bf80f4bSopenharmony_ci * 78bf80f4bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88bf80f4bSopenharmony_ci * 98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and 138bf80f4bSopenharmony_ci * limitations under the License. 148bf80f4bSopenharmony_ci */ 158bf80f4bSopenharmony_ci#include "number.h" 168bf80f4bSopenharmony_ci 178bf80f4bSopenharmony_ci#include <limits> 188bf80f4bSopenharmony_ci 198bf80f4bSopenharmony_ciMETA_BEGIN_NAMESPACE() 208bf80f4bSopenharmony_cinamespace Internal { 218bf80f4bSopenharmony_ci 228bf80f4bSopenharmony_citemplate<typename T> 238bf80f4bSopenharmony_cistruct Type {}; 248bf80f4bSopenharmony_ci 258bf80f4bSopenharmony_citemplate<typename T> 268bf80f4bSopenharmony_cistatic Number::VariantType MapToVariant(const T& v) 278bf80f4bSopenharmony_ci{ 288bf80f4bSopenharmony_ci if constexpr (std::numeric_limits<T>::is_integer) { 298bf80f4bSopenharmony_ci if constexpr (std::numeric_limits<T>::is_signed) { 308bf80f4bSopenharmony_ci return Number::VariantType(static_cast<int64_t>(v)); 318bf80f4bSopenharmony_ci } 328bf80f4bSopenharmony_ci return Number::VariantType(static_cast<uint64_t>(v)); 338bf80f4bSopenharmony_ci } 348bf80f4bSopenharmony_ci return Number::VariantType(static_cast<float>(v)); 358bf80f4bSopenharmony_ci} 368bf80f4bSopenharmony_ci 378bf80f4bSopenharmony_cistruct CompType { 388bf80f4bSopenharmony_ci template<typename T> 398bf80f4bSopenharmony_ci constexpr CompType(Type<T>) 408bf80f4bSopenharmony_ci : uid(UidFromType<T>()), size(sizeof(T)), load([](const void* data) { 418bf80f4bSopenharmony_ci T v = *static_cast<const T*>(data); 428bf80f4bSopenharmony_ci return MapToVariant(v); 438bf80f4bSopenharmony_ci }), 448bf80f4bSopenharmony_ci save([](Number::VariantType var, void* data) { 458bf80f4bSopenharmony_ci T v {}; 468bf80f4bSopenharmony_ci std::visit([&](const auto& arg) { 478bf80f4bSopenharmony_ci v = static_cast<T>(arg); 488bf80f4bSopenharmony_ci }, var); 498bf80f4bSopenharmony_ci *static_cast<T*>(data) = v; 508bf80f4bSopenharmony_ci }), 518bf80f4bSopenharmony_ci loadAny([](const IAny& any, Number::VariantType& var) { 528bf80f4bSopenharmony_ci T v {}; 538bf80f4bSopenharmony_ci bool res = any.GetValue(v); 548bf80f4bSopenharmony_ci if (res) { 558bf80f4bSopenharmony_ci var = MapToVariant(v); 568bf80f4bSopenharmony_ci } 578bf80f4bSopenharmony_ci return res; 588bf80f4bSopenharmony_ci }) 598bf80f4bSopenharmony_ci {} 608bf80f4bSopenharmony_ci 618bf80f4bSopenharmony_ci using LoadFunc = Number::VariantType(const void*); 628bf80f4bSopenharmony_ci using SaveFunc = void(Number::VariantType, void*); 638bf80f4bSopenharmony_ci using LoadAnyFunc = bool(const IAny&, Number::VariantType&); 648bf80f4bSopenharmony_ci 658bf80f4bSopenharmony_ci const TypeId uid; 668bf80f4bSopenharmony_ci const size_t size; 678bf80f4bSopenharmony_ci LoadFunc* const load; 688bf80f4bSopenharmony_ci SaveFunc* const save; 698bf80f4bSopenharmony_ci LoadAnyFunc* const loadAny; 708bf80f4bSopenharmony_ci}; 718bf80f4bSopenharmony_ci 728bf80f4bSopenharmony_ciconstexpr CompType COMPATIBLES[] = { 738bf80f4bSopenharmony_ci Type<float>(), 748bf80f4bSopenharmony_ci Type<double>(), 758bf80f4bSopenharmony_ci Type<bool>(), 768bf80f4bSopenharmony_ci Type<uint8_t>(), 778bf80f4bSopenharmony_ci Type<uint16_t>(), 788bf80f4bSopenharmony_ci Type<uint32_t>(), 798bf80f4bSopenharmony_ci Type<uint64_t>(), 808bf80f4bSopenharmony_ci Type<int8_t>(), 818bf80f4bSopenharmony_ci Type<int16_t>(), 828bf80f4bSopenharmony_ci Type<int32_t>(), 838bf80f4bSopenharmony_ci Type<int64_t>(), 848bf80f4bSopenharmony_ci}; 858bf80f4bSopenharmony_ci 868bf80f4bSopenharmony_cistatic BASE_NS::vector<TypeId> CompatibleTypes() 878bf80f4bSopenharmony_ci{ 888bf80f4bSopenharmony_ci BASE_NS::vector<TypeId> res; 898bf80f4bSopenharmony_ci for (auto&& v : COMPATIBLES) { 908bf80f4bSopenharmony_ci res.push_back(v.uid); 918bf80f4bSopenharmony_ci } 928bf80f4bSopenharmony_ci return res; 938bf80f4bSopenharmony_ci} 948bf80f4bSopenharmony_ci 958bf80f4bSopenharmony_cistatic const CompType* FindCompatible(const TypeId& uid, size_t size) 968bf80f4bSopenharmony_ci{ 978bf80f4bSopenharmony_ci for (auto&& v : COMPATIBLES) { 988bf80f4bSopenharmony_ci if (v.uid == uid && v.size == size) { 998bf80f4bSopenharmony_ci return &v; 1008bf80f4bSopenharmony_ci } 1018bf80f4bSopenharmony_ci } 1028bf80f4bSopenharmony_ci return nullptr; 1038bf80f4bSopenharmony_ci} 1048bf80f4bSopenharmony_ci 1058bf80f4bSopenharmony_cistatic const CompType* FindCompatible(const IAny& any) 1068bf80f4bSopenharmony_ci{ 1078bf80f4bSopenharmony_ci auto anyComps = any.GetCompatibleTypes(CompatibilityDirection::BOTH); 1088bf80f4bSopenharmony_ci for (auto&& v : COMPATIBLES) { 1098bf80f4bSopenharmony_ci for (auto&& av : anyComps) { 1108bf80f4bSopenharmony_ci if (v.uid == av) { 1118bf80f4bSopenharmony_ci return &v; 1128bf80f4bSopenharmony_ci } 1138bf80f4bSopenharmony_ci } 1148bf80f4bSopenharmony_ci } 1158bf80f4bSopenharmony_ci return nullptr; 1168bf80f4bSopenharmony_ci} 1178bf80f4bSopenharmony_ci 1188bf80f4bSopenharmony_ciNumber::Number(VariantType v) : value_(v) {} 1198bf80f4bSopenharmony_ciconst BASE_NS::array_view<const TypeId> Number::GetCompatibleTypes(CompatibilityDirection dir) const 1208bf80f4bSopenharmony_ci{ 1218bf80f4bSopenharmony_ci static BASE_NS::vector<TypeId> types = CompatibleTypes(); 1228bf80f4bSopenharmony_ci return types; 1238bf80f4bSopenharmony_ci} 1248bf80f4bSopenharmony_ciAnyReturnValue Number::GetData(const TypeId& uid, void* data, size_t size) const 1258bf80f4bSopenharmony_ci{ 1268bf80f4bSopenharmony_ci if (auto c = FindCompatible(uid, size)) { 1278bf80f4bSopenharmony_ci c->save(value_, data); 1288bf80f4bSopenharmony_ci return AnyReturn::SUCCESS; 1298bf80f4bSopenharmony_ci } 1308bf80f4bSopenharmony_ci return AnyReturn::INCOMPATIBLE_TYPE; 1318bf80f4bSopenharmony_ci} 1328bf80f4bSopenharmony_ciAnyReturnValue Number::SetData(const TypeId& uid, const void* data, size_t size) 1338bf80f4bSopenharmony_ci{ 1348bf80f4bSopenharmony_ci if (auto c = FindCompatible(uid, size)) { 1358bf80f4bSopenharmony_ci value_ = c->load(data); 1368bf80f4bSopenharmony_ci return AnyReturn::SUCCESS; 1378bf80f4bSopenharmony_ci } 1388bf80f4bSopenharmony_ci return AnyReturn::INCOMPATIBLE_TYPE; 1398bf80f4bSopenharmony_ci} 1408bf80f4bSopenharmony_ciAnyReturnValue Number::CopyFrom(const IAny& any) 1418bf80f4bSopenharmony_ci{ 1428bf80f4bSopenharmony_ci if (auto c = FindCompatible(any)) { 1438bf80f4bSopenharmony_ci c->loadAny(any, value_); 1448bf80f4bSopenharmony_ci } 1458bf80f4bSopenharmony_ci return AnyReturn::INCOMPATIBLE_TYPE; 1468bf80f4bSopenharmony_ci} 1478bf80f4bSopenharmony_ciIAny::Ptr Number::Clone(const AnyCloneOptions& options) const 1488bf80f4bSopenharmony_ci{ 1498bf80f4bSopenharmony_ci if (options.role == TypeIdRole::ARRAY) { 1508bf80f4bSopenharmony_ci CORE_LOG_E("Number: cloning into an array not supported."); 1518bf80f4bSopenharmony_ci return {}; 1528bf80f4bSopenharmony_ci } 1538bf80f4bSopenharmony_ci return IAny::Ptr(new Number(options.value == CloneValueType::COPY_VALUE ? value_ : VariantType {})); 1548bf80f4bSopenharmony_ci} 1558bf80f4bSopenharmony_ciTypeId Number::GetTypeId(TypeIdRole role) const 1568bf80f4bSopenharmony_ci{ 1578bf80f4bSopenharmony_ci if (role == TypeIdRole::ARRAY) { 1588bf80f4bSopenharmony_ci return std::visit([&](auto arg) { return ArrayUidFromType<decltype(arg)>(); }, value_); 1598bf80f4bSopenharmony_ci } 1608bf80f4bSopenharmony_ci return std::visit([&](auto arg) { return UidFromType<decltype(arg)>(); }, value_); 1618bf80f4bSopenharmony_ci} 1628bf80f4bSopenharmony_ci 1638bf80f4bSopenharmony_ciBASE_NS::string Number::GetTypeIdString() const 1648bf80f4bSopenharmony_ci{ 1658bf80f4bSopenharmony_ci return std::visit([&](auto arg) { return MetaType<decltype(arg)>::name; }, value_); 1668bf80f4bSopenharmony_ci} 1678bf80f4bSopenharmony_ci 1688bf80f4bSopenharmony_ci} // namespace Internal 1698bf80f4bSopenharmony_ciMETA_END_NAMESPACE() 170