18bf80f4bSopenharmony_ci/* 28bf80f4bSopenharmony_ci * Copyright (C) 2023-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 168bf80f4bSopenharmony_ci#ifndef CORE__ECS_HELPER__PROPERTY_TOOLS__PROPERTY_VALUE_H 178bf80f4bSopenharmony_ci#define CORE__ECS_HELPER__PROPERTY_TOOLS__PROPERTY_VALUE_H 188bf80f4bSopenharmony_ci 198bf80f4bSopenharmony_ci#include <cassert> 208bf80f4bSopenharmony_ci#include <cstddef> 218bf80f4bSopenharmony_ci#include <cstdint> 228bf80f4bSopenharmony_ci 238bf80f4bSopenharmony_ci#include <base/containers/array_view.h> 248bf80f4bSopenharmony_ci#include <base/containers/iterator.h> 258bf80f4bSopenharmony_ci#include <base/containers/string_view.h> 268bf80f4bSopenharmony_ci#include <base/namespace.h> 278bf80f4bSopenharmony_ci#include <core/namespace.h> 288bf80f4bSopenharmony_ci#include <core/property/property.h> 298bf80f4bSopenharmony_ci#include <base/util/log.h> 308bf80f4bSopenharmony_ci#include <base/containers/type_traits.h> 318bf80f4bSopenharmony_ci#include <core/property/property_types.h> 328bf80f4bSopenharmony_ci 338bf80f4bSopenharmony_ciCORE_BEGIN_NAMESPACE() 348bf80f4bSopenharmony_ciclass PropertyValue { 358bf80f4bSopenharmony_cipublic: 368bf80f4bSopenharmony_ci PropertyValue() noexcept : count_(0), data_(nullptr), index_(0) {} 378bf80f4bSopenharmony_ci ~PropertyValue() = default; 388bf80f4bSopenharmony_ci PropertyValue(const PropertyValue& other) noexcept = default; 398bf80f4bSopenharmony_ci 408bf80f4bSopenharmony_ci PropertyValue(PropertyValue&& other) noexcept 418bf80f4bSopenharmony_ci : type_(other.type_), // exchange(other.type_, PropertyType::INVALID)), 428bf80f4bSopenharmony_ci count_(BASE_NS::exchange(other.count_, 0U)), data_(BASE_NS::exchange(other.data_, nullptr)), 438bf80f4bSopenharmony_ci index_(BASE_NS::exchange(other.index_, 0U)) 448bf80f4bSopenharmony_ci {} 458bf80f4bSopenharmony_ci explicit constexpr PropertyValue(const Property* type, void* rawData, size_t cnt) noexcept 468bf80f4bSopenharmony_ci : type_(type), count_(cnt), data_(rawData), index_(0U) 478bf80f4bSopenharmony_ci {} 488bf80f4bSopenharmony_ci 498bf80f4bSopenharmony_ci constexpr size_t Size() const 508bf80f4bSopenharmony_ci { 518bf80f4bSopenharmony_ci return count_; 528bf80f4bSopenharmony_ci } 538bf80f4bSopenharmony_ci constexpr PropertyTypeDecl GetType() const 548bf80f4bSopenharmony_ci { 558bf80f4bSopenharmony_ci return type_->type; 568bf80f4bSopenharmony_ci } 578bf80f4bSopenharmony_ci constexpr operator PropertyTypeDecl() const 588bf80f4bSopenharmony_ci { 598bf80f4bSopenharmony_ci return type_->type; 608bf80f4bSopenharmony_ci } 618bf80f4bSopenharmony_ci constexpr bool operator==(const PropertyTypeDecl& other) const 628bf80f4bSopenharmony_ci { 638bf80f4bSopenharmony_ci return type_->type.compareHash == other.compareHash; 648bf80f4bSopenharmony_ci } 658bf80f4bSopenharmony_ci 668bf80f4bSopenharmony_ci BASE_NS::array_view<const Property> MetaData() const 678bf80f4bSopenharmony_ci { 688bf80f4bSopenharmony_ci if (type_) { 698bf80f4bSopenharmony_ci return type_->metaData.memberProperties; 708bf80f4bSopenharmony_ci } 718bf80f4bSopenharmony_ci return {}; 728bf80f4bSopenharmony_ci } 738bf80f4bSopenharmony_ci const Property* MetaData(size_t index) const 748bf80f4bSopenharmony_ci { 758bf80f4bSopenharmony_ci if (type_) { 768bf80f4bSopenharmony_ci const auto& meta = type_->metaData.memberProperties; 778bf80f4bSopenharmony_ci if (index < meta.size()) { 788bf80f4bSopenharmony_ci return &meta[index]; 798bf80f4bSopenharmony_ci } 808bf80f4bSopenharmony_ci } 818bf80f4bSopenharmony_ci return nullptr; 828bf80f4bSopenharmony_ci } 838bf80f4bSopenharmony_ci 848bf80f4bSopenharmony_ci // void* access 858bf80f4bSopenharmony_ci explicit constexpr operator void*() 868bf80f4bSopenharmony_ci { 878bf80f4bSopenharmony_ci return data_; 888bf80f4bSopenharmony_ci } 898bf80f4bSopenharmony_ci explicit constexpr operator void const*() const 908bf80f4bSopenharmony_ci { 918bf80f4bSopenharmony_ci return data_; 928bf80f4bSopenharmony_ci } 938bf80f4bSopenharmony_ci 948bf80f4bSopenharmony_ci // safe 958bf80f4bSopenharmony_ci PropertyValue operator[](const size_t index) const 968bf80f4bSopenharmony_ci { 978bf80f4bSopenharmony_ci BASE_ASSERT(type_->type.isArray); // This accessor type is valid only for arrays. 988bf80f4bSopenharmony_ci BASE_ASSERT(index < type_->count); 998bf80f4bSopenharmony_ci return PropertyValue(type_, data_, 1, index); 1008bf80f4bSopenharmony_ci } 1018bf80f4bSopenharmony_ci PropertyValue operator[](const size_t index) 1028bf80f4bSopenharmony_ci { 1038bf80f4bSopenharmony_ci BASE_ASSERT(type_->type.isArray); // This accessor type is valid only for arrays. 1048bf80f4bSopenharmony_ci BASE_ASSERT(index < type_->count); 1058bf80f4bSopenharmony_ci return PropertyValue(type_, data_, 1, index); 1068bf80f4bSopenharmony_ci } 1078bf80f4bSopenharmony_ci 1088bf80f4bSopenharmony_ci PropertyValue operator[](BASE_NS::string_view name) const 1098bf80f4bSopenharmony_ci { 1108bf80f4bSopenharmony_ci uintptr_t offset = reinterpret_cast<uintptr_t>(data_); 1118bf80f4bSopenharmony_ci const auto nameHash = BASE_NS::FNV1aHash(name.data(), name.size()); 1128bf80f4bSopenharmony_ci for (const auto& p : type_->metaData.memberProperties) { 1138bf80f4bSopenharmony_ci if ((nameHash == p.hash) && (p.name == name)) { 1148bf80f4bSopenharmony_ci return PropertyValue(&p, reinterpret_cast<void*>(offset + p.offset), p.count); 1158bf80f4bSopenharmony_ci } 1168bf80f4bSopenharmony_ci } 1178bf80f4bSopenharmony_ci // no such member property 1188bf80f4bSopenharmony_ci return {}; 1198bf80f4bSopenharmony_ci } 1208bf80f4bSopenharmony_ci 1218bf80f4bSopenharmony_ci // unsafe 1228bf80f4bSopenharmony_ci template<typename T> 1238bf80f4bSopenharmony_ci [[deprecated]] constexpr operator T() const 1248bf80f4bSopenharmony_ci { 1258bf80f4bSopenharmony_ci return reinterpret_cast<T*>(data_)[index_]; 1268bf80f4bSopenharmony_ci } 1278bf80f4bSopenharmony_ci 1288bf80f4bSopenharmony_ci template<typename T> 1298bf80f4bSopenharmony_ci [[deprecated]] constexpr operator T&() 1308bf80f4bSopenharmony_ci { 1318bf80f4bSopenharmony_ci return reinterpret_cast<T*>(data_)[index_]; 1328bf80f4bSopenharmony_ci } 1338bf80f4bSopenharmony_ci 1348bf80f4bSopenharmony_ci template<typename T> 1358bf80f4bSopenharmony_ci [[deprecated]] PropertyValue& operator=(T v) 1368bf80f4bSopenharmony_ci { 1378bf80f4bSopenharmony_ci reinterpret_cast<T*>(data_)[index_] = v; 1388bf80f4bSopenharmony_ci return *this; 1398bf80f4bSopenharmony_ci } 1408bf80f4bSopenharmony_ci 1418bf80f4bSopenharmony_ci PropertyValue& operator=(const PropertyValue& other) noexcept = default; 1428bf80f4bSopenharmony_ci 1438bf80f4bSopenharmony_ci PropertyValue& operator=(PropertyValue&& other) noexcept 1448bf80f4bSopenharmony_ci { 1458bf80f4bSopenharmony_ci if (this != &other) { 1468bf80f4bSopenharmony_ci type_ = BASE_NS::exchange(other.type_, {}); 1478bf80f4bSopenharmony_ci count_ = BASE_NS::exchange(other.count_, 0U); 1488bf80f4bSopenharmony_ci data_ = BASE_NS::exchange(other.data_, nullptr); 1498bf80f4bSopenharmony_ci index_ = BASE_NS::exchange(other.index_, 0U); 1508bf80f4bSopenharmony_ci } 1518bf80f4bSopenharmony_ci return *this; 1528bf80f4bSopenharmony_ci } 1538bf80f4bSopenharmony_ci 1548bf80f4bSopenharmony_ciprivate: 1558bf80f4bSopenharmony_ci const Property* type_ { nullptr }; 1568bf80f4bSopenharmony_ci size_t count_; 1578bf80f4bSopenharmony_ci void* data_; 1588bf80f4bSopenharmony_ci size_t index_; 1598bf80f4bSopenharmony_ci explicit constexpr PropertyValue(const Property* type, void* rawData, size_t cnt, size_t index) 1608bf80f4bSopenharmony_ci : type_(type), count_(cnt), data_(rawData), index_(index) 1618bf80f4bSopenharmony_ci {} 1628bf80f4bSopenharmony_ci}; 1638bf80f4bSopenharmony_ciCORE_END_NAMESPACE() 1648bf80f4bSopenharmony_ci 1658bf80f4bSopenharmony_ci#endif // CORE__ECS_HELPER__PROPERTY_TOOLS__PROPERTY_VALUE_H 166