/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef META_INTERFACE_DETAIL_ARRAY_PROPERTY_H
#define META_INTERFACE_DETAIL_ARRAY_PROPERTY_H
#include
#include
META_BEGIN_NAMESPACE()
template
class ConstTypelessArrayPropertyInterfaceImpl : public Base {
public:
using IndexType = IArrayAny::IndexType;
template
explicit ConstTypelessArrayPropertyInterfaceImpl(Prop* p) : Base(p)
{}
IndexType GetSize() const
{
if (auto arr = interface_cast(&this->GetValueAny())) {
return arr->GetSize();
}
return {};
}
AnyReturnValue GetAnyAt(IndexType index, IAny& any) const
{
if (auto arr = interface_cast(&this->GetValueAny())) {
return arr->GetAnyAt(index, any);
}
return AnyReturn::INCOMPATIBLE_TYPE;
}
};
using ConstTypelessArrayPropertyInterface = ConstTypelessArrayPropertyInterfaceImpl;
class TypelessArrayPropertyInterface : public ConstTypelessArrayPropertyInterfaceImpl {
public:
using PropertyType = IProperty*;
using IndexType = IArrayAny::IndexType;
TypelessArrayPropertyInterface(PropertyType p)
: ConstTypelessArrayPropertyInterfaceImpl(p)
{}
AnyReturnValue SetAnyAt(IndexType index, const IAny& v)
{
if (auto c = this->GetValueAny().Clone(true)) {
if (auto arr = interface_cast(c)) {
arr->SetAnyAt(index, v);
return this->SetValueAny(*arr);
}
}
return AnyReturn::INCOMPATIBLE_TYPE;
}
AnyReturnValue AddAny(const IAny& v)
{
return InsertAnyAt(-1, v);
}
AnyReturnValue InsertAnyAt(IndexType index, const IAny& v)
{
if (auto c = this->GetValueAny().Clone(true)) {
if (auto arr = interface_cast(c)) {
arr->InsertAnyAt(index, v);
return this->SetValueAny(*arr);
}
}
return AnyReturn::INCOMPATIBLE_TYPE;
}
bool RemoveAt(IndexType index)
{
if (auto c = this->GetValueAny().Clone(true)) {
if (auto arr = interface_cast(c)) {
arr->RemoveAt(index);
return this->SetValueAny(*arr);
}
}
return false;
}
};
template
using ArrayPropertyBaseType = BASE_NS::conditional_t, ConstTypelessArrayPropertyInterface,
TypelessArrayPropertyInterface>;
template
class ArrayPropertyInterface : public ArrayPropertyBaseType {
using Super = ArrayPropertyBaseType;
public:
using ValueType = BASE_NS::remove_const_t;
using PropertyType = typename PropertyBaseType::PropertyType;
using IndexType = IArrayAny::IndexType;
explicit ArrayPropertyInterface(PropertyType p) : Super(p) {}
ValueType GetValueAt(IndexType index) const
{
Any any;
if (auto arr = interface_cast(&this->GetValueAny())) {
arr->GetAnyAt(index, any);
}
return any.InternalGetValue();
}
bool SetValueAt(IndexType index, const Type& v)
{
BASE_NS::vector vec;
if (this->GetValueAny().GetValue(vec)) {
if (index < vec.size()) {
vec[index] = v;
return this->SetValueAny(ArrayAny(BASE_NS::move(vec)));
}
}
return false;
}
bool AddValue(const Type& v)
{
return InsertValueAt(-1, v);
}
bool InsertValueAt(IndexType index, const Type& v)
{
BASE_NS::vector vec;
if (this->GetValueAny().GetValue(vec)) {
index = index < vec.size() ? index : vec.size();
vec.insert(vec.begin() + index, v);
return this->SetValueAny(ArrayAny(BASE_NS::move(vec)));
}
return false;
}
BASE_NS::vector GetDefaultValue() const
{
BASE_NS::vector v;
this->GetDefaultValueAny().GetValue(v);
return v;
}
AnyReturnValue SetDefaultValue(BASE_NS::array_view value)
{
return this->SetDefaultValueAny(ArrayAny(value));
}
template>>
AnyReturnValue SetDefaultValue(BASE_NS::vector value)
{
return this->SetDefaultValueAny(ArrayAny(BASE_NS::move(value)));
}
AnyReturnValue SetDefaultValue(BASE_NS::vector value, bool resetToDefault)
{
auto ret = this->SetDefaultValueAny(ArrayAny(BASE_NS::move(value)));
if (resetToDefault && ret) {
this->ResetValue();
}
return ret;
}
BASE_NS::vector GetValue() const
{
BASE_NS::vector v {};
this->GetValueAny().GetValue(v);
return v;
}
AnyReturnValue SetValue(BASE_NS::array_view value)
{
return this->SetValueAny(ArrayAny(value));
}
template>>
AnyReturnValue SetValue(BASE_NS::vector value)
{
return this->SetValueAny(ArrayAny(BASE_NS::move(value)));
}
IndexType FindFirstValueOf(const Type& v) const
{
for (IndexType i = 0; i != this->GetSize(); ++i) {
if (GetValueAt(i) == v) {
return i;
}
}
return -1;
}
};
template
class TypedArrayPropertyLock final : public ArrayPropertyInterface {
using PropertyType = typename ArrayPropertyInterface::PropertyType;
using IT = ArrayPropertyInterface;
using InterfaceType = BASE_NS::conditional_t, const IT*, IT*>;
META_NO_COPY_MOVE(TypedArrayPropertyLock)
public:
explicit TypedArrayPropertyLock(PropertyType p) : ArrayPropertyInterface(p)
{
if (auto i = interface_cast(p)) {
i->Lock();
}
}
~TypedArrayPropertyLock()
{
if (auto i = interface_cast(this->GetProperty())) {
i->Unlock();
}
}
InterfaceType operator->() const
{
return const_cast(this);
}
};
template
class ArrayPropertyLock final : public ArrayPropertyBaseType {
using InterfaceType = ArrayPropertyBaseType*;
META_NO_COPY_MOVE(ArrayPropertyLock)
public:
explicit ArrayPropertyLock(BASE_NS::shared_ptr p) : ArrayPropertyBaseType(p.get())
{
if (auto i = interface_cast(p)) {
i->Lock();
}
}
~ArrayPropertyLock()
{
if (auto i = interface_cast(this->GetProperty())) {
i->Unlock();
}
}
InterfaceType operator->() const
{
return const_cast(this);
}
};
META_END_NAMESPACE()
#endif