1fa7767c5Sopenharmony_ci/* 2fa7767c5Sopenharmony_ci * Copyright (c) 2023-2023 Huawei Device Co., Ltd. 3fa7767c5Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fa7767c5Sopenharmony_ci * you may not use this file except in compliance with the License. 5fa7767c5Sopenharmony_ci * You may obtain a copy of the License at 6fa7767c5Sopenharmony_ci * 7fa7767c5Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fa7767c5Sopenharmony_ci * 9fa7767c5Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fa7767c5Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fa7767c5Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fa7767c5Sopenharmony_ci * See the License for the specific language governing permissions and 13fa7767c5Sopenharmony_ci * limitations under the License. 14fa7767c5Sopenharmony_ci */ 15fa7767c5Sopenharmony_ci 16fa7767c5Sopenharmony_ci#ifndef HISTREAMER_PLUGIN_COMMON_ANY_H 17fa7767c5Sopenharmony_ci#define HISTREAMER_PLUGIN_COMMON_ANY_H 18fa7767c5Sopenharmony_ci 19fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_RTTI 20fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 21fa7767c5Sopenharmony_ci#define HST_ANY_WITH_NO_RTTI 22fa7767c5Sopenharmony_ci#endif 23fa7767c5Sopenharmony_ci#else 24fa7767c5Sopenharmony_ci#ifdef HST_ANY_WITH_NO_RTTI 25fa7767c5Sopenharmony_ci#undef HST_ANY_WITH_NO_RTTI 26fa7767c5Sopenharmony_ci#endif 27fa7767c5Sopenharmony_ci#endif 28fa7767c5Sopenharmony_ci 29fa7767c5Sopenharmony_ci#ifndef MEDIA_NO_OHOS 30fa7767c5Sopenharmony_ci#ifndef MEDIA_OHOS 31fa7767c5Sopenharmony_ci#define MEDIA_OHOS 32fa7767c5Sopenharmony_ci#endif 33fa7767c5Sopenharmony_ci#else 34fa7767c5Sopenharmony_ci#ifdef MEDIA_OHOS 35fa7767c5Sopenharmony_ci#undef MEDIA_OHOS 36fa7767c5Sopenharmony_ci#endif 37fa7767c5Sopenharmony_ci#endif 38fa7767c5Sopenharmony_ci 39fa7767c5Sopenharmony_ci#if defined(__clang__) || defined(__GNUC__) 40fa7767c5Sopenharmony_ci#define CPP_STANDARD __cplusplus 41fa7767c5Sopenharmony_ci#elif defined(_MSC_VER) 42fa7767c5Sopenharmony_ci#define CPP_STANDARD _MSVC_LANG 43fa7767c5Sopenharmony_ci#endif 44fa7767c5Sopenharmony_ci 45fa7767c5Sopenharmony_ci#if CPP_STANDARD >= 201103L 46fa7767c5Sopenharmony_ci 47fa7767c5Sopenharmony_ci#include <array> 48fa7767c5Sopenharmony_ci#include <cstring> 49fa7767c5Sopenharmony_ci#include "cpp_ext/type_cast_ext.h" 50fa7767c5Sopenharmony_ci#include "securec.h" 51fa7767c5Sopenharmony_ci#include <type_traits> 52fa7767c5Sopenharmony_ci#include "message_parcel.h" 53fa7767c5Sopenharmony_ci 54fa7767c5Sopenharmony_cinamespace { 55fa7767c5Sopenharmony_ci#if CPP_STANDARD < 201402L 56fa7767c5Sopenharmony_citemplate <typename T> 57fa7767c5Sopenharmony_ciusing decay_t = typename std::decay<T>::type; 58fa7767c5Sopenharmony_ci 59fa7767c5Sopenharmony_citemplate <bool B, typename T = void> 60fa7767c5Sopenharmony_ciusing enable_if_t = typename std::enable_if<B, T>::type; 61fa7767c5Sopenharmony_ci 62fa7767c5Sopenharmony_citemplate <bool B, typename T, typename F> 63fa7767c5Sopenharmony_ciusing conditional_t = typename std::conditional<B, T, F>::type; 64fa7767c5Sopenharmony_ci 65fa7767c5Sopenharmony_citemplate <typename T> 66fa7767c5Sopenharmony_ciusing remove_cv_t = typename std::remove_cv<T>::type; 67fa7767c5Sopenharmony_ci 68fa7767c5Sopenharmony_citemplate <typename T> 69fa7767c5Sopenharmony_ciusing remove_reference_t = typename std::remove_reference<T>::type; 70fa7767c5Sopenharmony_ci#else 71fa7767c5Sopenharmony_ciusing std::decay_t; 72fa7767c5Sopenharmony_ciusing std::enable_if_t; 73fa7767c5Sopenharmony_ciusing std::conditional_t; 74fa7767c5Sopenharmony_ciusing std::remove_cv_t; 75fa7767c5Sopenharmony_ciusing std::remove_reference_t; 76fa7767c5Sopenharmony_ci#endif 77fa7767c5Sopenharmony_ci 78fa7767c5Sopenharmony_ciconstexpr size_t STACK_STORAGE_SIZE = 2 * sizeof(void*); // NOLINT: global var 79fa7767c5Sopenharmony_ci 80fa7767c5Sopenharmony_citemplate <typename T> 81fa7767c5Sopenharmony_cistruct IsTrivialStackStorable { 82fa7767c5Sopenharmony_ci static constexpr bool value = 83fa7767c5Sopenharmony_ci alignof(T) <= alignof(max_align_t) && std::is_trivially_copyable<T>::value && sizeof(T) <= STACK_STORAGE_SIZE; 84fa7767c5Sopenharmony_ci}; 85fa7767c5Sopenharmony_ci 86fa7767c5Sopenharmony_citemplate <typename T> 87fa7767c5Sopenharmony_cistruct IsStackStorable { 88fa7767c5Sopenharmony_ci static constexpr bool value = alignof(T) <= alignof(max_align_t) && std::is_nothrow_move_constructible<T>::value && 89fa7767c5Sopenharmony_ci sizeof(T) <= STACK_STORAGE_SIZE; 90fa7767c5Sopenharmony_ci}; 91fa7767c5Sopenharmony_ci 92fa7767c5Sopenharmony_citemplate <typename T> 93fa7767c5Sopenharmony_cistruct IsValidCast { 94fa7767c5Sopenharmony_ci static constexpr bool value = std::is_reference<T>::value || std::is_copy_constructible<T>::value; 95fa7767c5Sopenharmony_ci}; 96fa7767c5Sopenharmony_ci} // namespace 97fa7767c5Sopenharmony_cinamespace OHOS { 98fa7767c5Sopenharmony_cinamespace Media { 99fa7767c5Sopenharmony_ci 100fa7767c5Sopenharmony_cienum struct AnyValueType : int32_t { 101fa7767c5Sopenharmony_ci INVALID_TYPE = 1, 102fa7767c5Sopenharmony_ci BOOL, 103fa7767c5Sopenharmony_ci INT8_T, 104fa7767c5Sopenharmony_ci UINT8_T, 105fa7767c5Sopenharmony_ci INT32_T, 106fa7767c5Sopenharmony_ci UINT32_T, 107fa7767c5Sopenharmony_ci INT64_T, 108fa7767c5Sopenharmony_ci UINT64_T, 109fa7767c5Sopenharmony_ci FLOAT, 110fa7767c5Sopenharmony_ci DOUBLE, 111fa7767c5Sopenharmony_ci VECTOR_UINT8, 112fa7767c5Sopenharmony_ci VECTOR_UINT32, 113fa7767c5Sopenharmony_ci STRING 114fa7767c5Sopenharmony_ci}; 115fa7767c5Sopenharmony_ci/** 116fa7767c5Sopenharmony_ci * @brief BadAnyCast exception, which is thrown when error occurs in AnyCast 117fa7767c5Sopenharmony_ci * 118fa7767c5Sopenharmony_ci * @since 1.0 119fa7767c5Sopenharmony_ci * @version 1.0 120fa7767c5Sopenharmony_ci */ 121fa7767c5Sopenharmony_ciclass BadAnyCast : public std::bad_cast { 122fa7767c5Sopenharmony_cipublic: 123fa7767c5Sopenharmony_ci const char* what() const noexcept override 124fa7767c5Sopenharmony_ci { 125fa7767c5Sopenharmony_ci return "bad any cast"; 126fa7767c5Sopenharmony_ci } 127fa7767c5Sopenharmony_ci}; 128fa7767c5Sopenharmony_ciclass Any; 129fa7767c5Sopenharmony_citemplate <typename T> 130fa7767c5Sopenharmony_ciinline typename std::enable_if<std::is_enum<T>::value, bool>::type MakeAnyFromParcel(Any& value, MessageParcel& parcel); 131fa7767c5Sopenharmony_citemplate <typename T> 132fa7767c5Sopenharmony_ciinline typename std::enable_if<!std::is_enum<T>::value, bool>::type MakeAnyFromParcel(Any& value, MessageParcel& parcel) 133fa7767c5Sopenharmony_ci{ 134fa7767c5Sopenharmony_ci (void)value; 135fa7767c5Sopenharmony_ci (void)parcel; 136fa7767c5Sopenharmony_ci // current only support enum from parcel 137fa7767c5Sopenharmony_ci return false; 138fa7767c5Sopenharmony_ci} 139fa7767c5Sopenharmony_citemplate <typename T> 140fa7767c5Sopenharmony_ciinline typename std::enable_if<std::is_enum<T>::value, bool>::type WriteValueToParcel(const T &value, 141fa7767c5Sopenharmony_ci MessageParcel &parcel) 142fa7767c5Sopenharmony_ci{ 143fa7767c5Sopenharmony_ci parcel.WriteInt32(static_cast<int32_t>(value)); 144fa7767c5Sopenharmony_ci return true; 145fa7767c5Sopenharmony_ci} 146fa7767c5Sopenharmony_citemplate <typename T> 147fa7767c5Sopenharmony_ciinline typename std::enable_if<!std::is_enum<T>::value, bool>::type WriteValueToParcel(const T &value, 148fa7767c5Sopenharmony_ci MessageParcel &parcel) 149fa7767c5Sopenharmony_ci{ 150fa7767c5Sopenharmony_ci (void)value; 151fa7767c5Sopenharmony_ci (void)parcel; 152fa7767c5Sopenharmony_ci // current only support write enum to parcel 153fa7767c5Sopenharmony_ci return false; 154fa7767c5Sopenharmony_ci} 155fa7767c5Sopenharmony_citemplate <typename T> 156fa7767c5Sopenharmony_ciinline typename std::enable_if<std::is_enum<T>::value, bool>::type WriteValueToParcelInt64(const T &value, 157fa7767c5Sopenharmony_ci MessageParcel &parcel) 158fa7767c5Sopenharmony_ci{ 159fa7767c5Sopenharmony_ci parcel.WriteInt64(static_cast<int64_t>(value)); 160fa7767c5Sopenharmony_ci return true; 161fa7767c5Sopenharmony_ci} 162fa7767c5Sopenharmony_citemplate <typename T> 163fa7767c5Sopenharmony_ciinline typename std::enable_if<!std::is_enum<T>::value, bool>::type WriteValueToParcelInt64(const T &value, 164fa7767c5Sopenharmony_ci MessageParcel &parcel) 165fa7767c5Sopenharmony_ci{ 166fa7767c5Sopenharmony_ci (void)value; 167fa7767c5Sopenharmony_ci (void)parcel; 168fa7767c5Sopenharmony_ci // current only support write enum to parcel 169fa7767c5Sopenharmony_ci return false; 170fa7767c5Sopenharmony_ci} 171fa7767c5Sopenharmony_ci/** 172fa7767c5Sopenharmony_ci * @brief This class describes a type-safe container for arbitrary type values which are copy constructible. 173fa7767c5Sopenharmony_ci * 174fa7767c5Sopenharmony_ci * @since 1.0 175fa7767c5Sopenharmony_ci * @version 1.0 176fa7767c5Sopenharmony_ci */ 177fa7767c5Sopenharmony_ciclass Any final { 178fa7767c5Sopenharmony_cipublic: 179fa7767c5Sopenharmony_ci constexpr Any() noexcept 180fa7767c5Sopenharmony_ci { 181fa7767c5Sopenharmony_ci } 182fa7767c5Sopenharmony_ci 183fa7767c5Sopenharmony_ci __attribute__((no_sanitize("cfi"))) Any(const Any &other) : functionTable_(other.functionTable_) 184fa7767c5Sopenharmony_ci { 185fa7767c5Sopenharmony_ci if (other.HasValue()) { 186fa7767c5Sopenharmony_ci functionTable_->copy(storage_, other.storage_); 187fa7767c5Sopenharmony_ci } 188fa7767c5Sopenharmony_ci } 189fa7767c5Sopenharmony_ci 190fa7767c5Sopenharmony_ci __attribute__((no_sanitize("cfi"))) Any(Any &&other) noexcept : functionTable_(other.functionTable_) 191fa7767c5Sopenharmony_ci { 192fa7767c5Sopenharmony_ci if (other.HasValue()) { 193fa7767c5Sopenharmony_ci functionTable_->move(storage_, other.storage_); 194fa7767c5Sopenharmony_ci other.functionTable_ = nullptr; 195fa7767c5Sopenharmony_ci } 196fa7767c5Sopenharmony_ci } 197fa7767c5Sopenharmony_ci 198fa7767c5Sopenharmony_ci /** 199fa7767c5Sopenharmony_ci * constructor from right reference value with type of ValueType. 200fa7767c5Sopenharmony_ci * 201fa7767c5Sopenharmony_ci * @tparam Type ValueType is not the same as Any itself. The decay type of ValueType must be copy constructible. 202fa7767c5Sopenharmony_ci * @param value content 203fa7767c5Sopenharmony_ci */ 204fa7767c5Sopenharmony_ci template <typename ValueType, enable_if_t<!std::is_same<decay_t<ValueType>, Any>::value && 205fa7767c5Sopenharmony_ci std::is_copy_constructible<decay_t<ValueType>>::value, 206fa7767c5Sopenharmony_ci bool> = true> 207fa7767c5Sopenharmony_ci Any(ValueType&& value) // NOLINT: explicit 208fa7767c5Sopenharmony_ci { 209fa7767c5Sopenharmony_ci DoEmplace<decay_t<ValueType>>(std::forward<ValueType>(value)); 210fa7767c5Sopenharmony_ci } 211fa7767c5Sopenharmony_ci 212fa7767c5Sopenharmony_ci Any& operator=(const Any& other) 213fa7767c5Sopenharmony_ci { 214fa7767c5Sopenharmony_ci *this = Any(other); 215fa7767c5Sopenharmony_ci return *this; 216fa7767c5Sopenharmony_ci } 217fa7767c5Sopenharmony_ci 218fa7767c5Sopenharmony_ci Any& operator=(Any&& other) noexcept 219fa7767c5Sopenharmony_ci { 220fa7767c5Sopenharmony_ci Reset(); 221fa7767c5Sopenharmony_ci MoveFrom(std::forward<Any>(other)); 222fa7767c5Sopenharmony_ci return *this; 223fa7767c5Sopenharmony_ci } 224fa7767c5Sopenharmony_ci 225fa7767c5Sopenharmony_ci /** 226fa7767c5Sopenharmony_ci * Assigns contents to Any. 227fa7767c5Sopenharmony_ci * 228fa7767c5Sopenharmony_ci * @tparam ValueType Type ValueType is not the same as Any itself. The decay type of ValueType must be copy 229fa7767c5Sopenharmony_ci * constructible. 230fa7767c5Sopenharmony_ci * @param value content 231fa7767c5Sopenharmony_ci * @return 232fa7767c5Sopenharmony_ci */ 233fa7767c5Sopenharmony_ci template <typename ValueType, enable_if_t<!std::is_same<decay_t<ValueType>, Any>::value && 234fa7767c5Sopenharmony_ci std::is_copy_constructible<decay_t<ValueType>>::value, 235fa7767c5Sopenharmony_ci bool> = true> 236fa7767c5Sopenharmony_ci Any& operator=(ValueType&& value) 237fa7767c5Sopenharmony_ci { 238fa7767c5Sopenharmony_ci *this = Any(std::forward<ValueType>(value)); 239fa7767c5Sopenharmony_ci return *this; 240fa7767c5Sopenharmony_ci } 241fa7767c5Sopenharmony_ci 242fa7767c5Sopenharmony_ci /** 243fa7767c5Sopenharmony_ci * Get TypeName From function info. 244fa7767c5Sopenharmony_ci * @return Name of Type T 245fa7767c5Sopenharmony_ci */ 246fa7767c5Sopenharmony_ci template<typename T> 247fa7767c5Sopenharmony_ci static constexpr std::string_view GetTypeName() noexcept 248fa7767c5Sopenharmony_ci { 249fa7767c5Sopenharmony_ci const char* functionInfo = __PRETTY_FUNCTION__ ; 250fa7767c5Sopenharmony_ci return GetTypeNameFromFunctionInfo(functionInfo); 251fa7767c5Sopenharmony_ci } 252fa7767c5Sopenharmony_ci 253fa7767c5Sopenharmony_ci template<typename T> 254fa7767c5Sopenharmony_ci static bool IsSameTypeWith(const Any& other) noexcept 255fa7767c5Sopenharmony_ci { 256fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 257fa7767c5Sopenharmony_ci return other.SameTypeWith(typeid(T)); 258fa7767c5Sopenharmony_ci#else 259fa7767c5Sopenharmony_ci return other.SameTypeWith(Any::GetTypeName<T>()); 260fa7767c5Sopenharmony_ci#endif 261fa7767c5Sopenharmony_ci } 262fa7767c5Sopenharmony_ci 263fa7767c5Sopenharmony_ci ~Any() 264fa7767c5Sopenharmony_ci { 265fa7767c5Sopenharmony_ci Reset(); 266fa7767c5Sopenharmony_ci } 267fa7767c5Sopenharmony_ci 268fa7767c5Sopenharmony_ci /** 269fa7767c5Sopenharmony_ci * Emplace one content with type of ValueType into object. The content is constructed by args. 270fa7767c5Sopenharmony_ci * 271fa7767c5Sopenharmony_ci * @tparam ValueType The decay type of ValueType must be constructible from args and copy constructible. 272fa7767c5Sopenharmony_ci * @tparam Args args type 273fa7767c5Sopenharmony_ci * @param args args 274fa7767c5Sopenharmony_ci * @return content with type of decay ValueType 275fa7767c5Sopenharmony_ci */ 276fa7767c5Sopenharmony_ci template <typename ValueType, typename... Args, 277fa7767c5Sopenharmony_ci enable_if_t<std::is_constructible<decay_t<ValueType>, Args...>::value && 278fa7767c5Sopenharmony_ci std::is_copy_constructible<decay_t<ValueType>>::value, 279fa7767c5Sopenharmony_ci bool> = true> 280fa7767c5Sopenharmony_ci decay_t<ValueType>& Emplace(Args&&... args) 281fa7767c5Sopenharmony_ci { 282fa7767c5Sopenharmony_ci Reset(); 283fa7767c5Sopenharmony_ci return DoEmplace<decay_t<ValueType>>(std::forward<Args>(args)...); 284fa7767c5Sopenharmony_ci } 285fa7767c5Sopenharmony_ci 286fa7767c5Sopenharmony_ci /** 287fa7767c5Sopenharmony_ci * Emplace one content with type of ValueType into object. The content is constructed by il and args. 288fa7767c5Sopenharmony_ci * 289fa7767c5Sopenharmony_ci * @tparam ValueType type of conetent. The decay type of ValueType must be constructible from il and args and copy 290fa7767c5Sopenharmony_ci * constructible 291fa7767c5Sopenharmony_ci * @tparam U type of initializer list. 292fa7767c5Sopenharmony_ci * @tparam Args type of other args 293fa7767c5Sopenharmony_ci * @param il initializer list 294fa7767c5Sopenharmony_ci * @param args args 295fa7767c5Sopenharmony_ci * @return content with type of decay ValueType 296fa7767c5Sopenharmony_ci */ 297fa7767c5Sopenharmony_ci template <typename ValueType, typename U, typename... Args, 298fa7767c5Sopenharmony_ci enable_if_t<std::is_constructible<decay_t<ValueType>, std::initializer_list<U>&, Args...>::value && 299fa7767c5Sopenharmony_ci std::is_copy_constructible<decay_t<ValueType>>::value, 300fa7767c5Sopenharmony_ci bool> = true> 301fa7767c5Sopenharmony_ci decay_t<ValueType>& Emplace(std::initializer_list<U> il, Args&&... args) 302fa7767c5Sopenharmony_ci { 303fa7767c5Sopenharmony_ci Reset(); 304fa7767c5Sopenharmony_ci return DoEmplace<decay_t<ValueType>>(il, std::forward<Args>(args)...); 305fa7767c5Sopenharmony_ci } 306fa7767c5Sopenharmony_ci 307fa7767c5Sopenharmony_ci /** 308fa7767c5Sopenharmony_ci * Destroy the inner content if exists. 309fa7767c5Sopenharmony_ci */ 310fa7767c5Sopenharmony_ci void __attribute__((no_sanitize("cfi"))) Reset() noexcept 311fa7767c5Sopenharmony_ci { 312fa7767c5Sopenharmony_ci if (HasValue()) { 313fa7767c5Sopenharmony_ci functionTable_->destroy(storage_); 314fa7767c5Sopenharmony_ci storage_.trivialStack_.fill(0); 315fa7767c5Sopenharmony_ci } 316fa7767c5Sopenharmony_ci functionTable_ = nullptr; 317fa7767c5Sopenharmony_ci } 318fa7767c5Sopenharmony_ci 319fa7767c5Sopenharmony_ci /** 320fa7767c5Sopenharmony_ci * swap contents of two any objects 321fa7767c5Sopenharmony_ci * 322fa7767c5Sopenharmony_ci * @param other object to swap with 323fa7767c5Sopenharmony_ci */ 324fa7767c5Sopenharmony_ci void Swap(Any& other) noexcept 325fa7767c5Sopenharmony_ci { 326fa7767c5Sopenharmony_ci Any tmp(std::move(*this)); 327fa7767c5Sopenharmony_ci *this = std::move(other); 328fa7767c5Sopenharmony_ci other = std::move(tmp); 329fa7767c5Sopenharmony_ci } 330fa7767c5Sopenharmony_ci 331fa7767c5Sopenharmony_ci /** 332fa7767c5Sopenharmony_ci * Checks whether the object has one content. 333fa7767c5Sopenharmony_ci * 334fa7767c5Sopenharmony_ci * @return true if object has one content, otherwise false. 335fa7767c5Sopenharmony_ci */ 336fa7767c5Sopenharmony_ci bool HasValue() const noexcept 337fa7767c5Sopenharmony_ci { 338fa7767c5Sopenharmony_ci return IsFunctionTableValid(); 339fa7767c5Sopenharmony_ci } 340fa7767c5Sopenharmony_ci 341fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 342fa7767c5Sopenharmony_ci /** 343fa7767c5Sopenharmony_ci * Get tye type_info of object 344fa7767c5Sopenharmony_ci * 345fa7767c5Sopenharmony_ci * @return type info of object 346fa7767c5Sopenharmony_ci */ 347fa7767c5Sopenharmony_ci const std::type_info& Type() const noexcept 348fa7767c5Sopenharmony_ci { 349fa7767c5Sopenharmony_ci if (!HasValue()) { 350fa7767c5Sopenharmony_ci return typeid(void); 351fa7767c5Sopenharmony_ci } 352fa7767c5Sopenharmony_ci return functionTable_->type(); 353fa7767c5Sopenharmony_ci } 354fa7767c5Sopenharmony_ci#else 355fa7767c5Sopenharmony_ci std::string_view __attribute__((no_sanitize("cfi"))) TypeName() const noexcept 356fa7767c5Sopenharmony_ci { 357fa7767c5Sopenharmony_ci if (!HasValue()) { 358fa7767c5Sopenharmony_ci return "empty"; // no value 359fa7767c5Sopenharmony_ci } 360fa7767c5Sopenharmony_ci return functionTable_->type_name(); 361fa7767c5Sopenharmony_ci } 362fa7767c5Sopenharmony_ci bool __attribute__((no_sanitize("cfi"))) ToParcel(MessageParcel &parcel) const noexcept 363fa7767c5Sopenharmony_ci { 364fa7767c5Sopenharmony_ci if (!HasValue()) { 365fa7767c5Sopenharmony_ci return false; // no value 366fa7767c5Sopenharmony_ci } 367fa7767c5Sopenharmony_ci return functionTable_->toParcel(this, parcel); 368fa7767c5Sopenharmony_ci } 369fa7767c5Sopenharmony_ci bool __attribute__((no_sanitize("cfi"))) FromParcel(MessageParcel &parcel) const noexcept 370fa7767c5Sopenharmony_ci { 371fa7767c5Sopenharmony_ci return functionTable_->fromParcel(const_cast<Any *>(this), parcel); 372fa7767c5Sopenharmony_ci } 373fa7767c5Sopenharmony_ci#endif 374fa7767c5Sopenharmony_ci 375fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 376fa7767c5Sopenharmony_ci bool SameTypeWith(const std::type_info& otherInfo) const noexcept 377fa7767c5Sopenharmony_ci { 378fa7767c5Sopenharmony_ci if (functionTable_ == nullptr) { 379fa7767c5Sopenharmony_ci return false; 380fa7767c5Sopenharmony_ci } 381fa7767c5Sopenharmony_ci return IsSameType(functionTable_->type(), otherInfo); 382fa7767c5Sopenharmony_ci } 383fa7767c5Sopenharmony_ci#else 384fa7767c5Sopenharmony_ci bool __attribute__((no_sanitize("cfi"))) SameTypeWith(std::string_view otherTypeName) const noexcept 385fa7767c5Sopenharmony_ci { 386fa7767c5Sopenharmony_ci if (functionTable_ == nullptr) { 387fa7767c5Sopenharmony_ci return false; 388fa7767c5Sopenharmony_ci } 389fa7767c5Sopenharmony_ci return IsSameType(functionTable_->type_name(), otherTypeName); 390fa7767c5Sopenharmony_ci } 391fa7767c5Sopenharmony_ci#endif 392fa7767c5Sopenharmony_ci 393fa7767c5Sopenharmony_ci bool __attribute__((no_sanitize("cfi"))) SameTypeWith(const Any &other) const noexcept 394fa7767c5Sopenharmony_ci { 395fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 396fa7767c5Sopenharmony_ci return IsSameType(functionTable_->type(), other.Type()); 397fa7767c5Sopenharmony_ci#else 398fa7767c5Sopenharmony_ci return IsSameType(functionTable_->type_name(), other.TypeName()); 399fa7767c5Sopenharmony_ci#endif 400fa7767c5Sopenharmony_ci } 401fa7767c5Sopenharmony_ci 402fa7767c5Sopenharmony_ciprivate: 403fa7767c5Sopenharmony_ci template <typename T> 404fa7767c5Sopenharmony_ci friend const T* AnyCast(const Any* operand) noexcept; 405fa7767c5Sopenharmony_ci template <typename T> 406fa7767c5Sopenharmony_ci friend T* AnyCast(Any* operand) noexcept; 407fa7767c5Sopenharmony_ci template <typename T> 408fa7767c5Sopenharmony_ci friend bool AnyCast(const Any* operand, T& value) noexcept; 409fa7767c5Sopenharmony_ci 410fa7767c5Sopenharmony_ci union Storage { 411fa7767c5Sopenharmony_ci using Stack = std::aligned_storage<STACK_STORAGE_SIZE, std::alignment_of<void*>::value>::type; 412fa7767c5Sopenharmony_ci using Heap = void*; 413fa7767c5Sopenharmony_ci 414fa7767c5Sopenharmony_ci std::array<uint8_t, STACK_STORAGE_SIZE> trivialStack_; 415fa7767c5Sopenharmony_ci Stack nonTrivialStack_; 416fa7767c5Sopenharmony_ci Heap heap_; 417fa7767c5Sopenharmony_ci }; 418fa7767c5Sopenharmony_ci 419fa7767c5Sopenharmony_ci struct FunctionTable { 420fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 421fa7767c5Sopenharmony_ci const std::type_info& (*type)() noexcept; 422fa7767c5Sopenharmony_ci#else 423fa7767c5Sopenharmony_ci std::string_view (*type_name)() noexcept; 424fa7767c5Sopenharmony_ci bool (*toParcel)(const Any *operand, MessageParcel& parcel) noexcept; 425fa7767c5Sopenharmony_ci bool (*fromParcel)(Any *operand, MessageParcel& parcel) noexcept; 426fa7767c5Sopenharmony_ci#endif 427fa7767c5Sopenharmony_ci void (*destroy)(Storage&) noexcept; 428fa7767c5Sopenharmony_ci void (*copy)(Storage&, const Storage&) noexcept; 429fa7767c5Sopenharmony_ci void (*move)(Storage&, Storage&) noexcept; 430fa7767c5Sopenharmony_ci void* (*getPtr)(Storage&) noexcept; 431fa7767c5Sopenharmony_ci const void* (*getConstPtr)(const Storage&) noexcept; 432fa7767c5Sopenharmony_ci }; 433fa7767c5Sopenharmony_ci static bool BaseTypesToParcel(const Any *operand, MessageParcel& parcel) noexcept; 434fa7767c5Sopenharmony_ci // returnValue : 0 -- success; 1 -- retry enum; 2 -- failed no retry 435fa7767c5Sopenharmony_ci static int BaseTypesFromParcel(Any *operand, MessageParcel& parcel) noexcept; 436fa7767c5Sopenharmony_ci 437fa7767c5Sopenharmony_ci static std::string_view GetTypeNameFromFunctionInfo(const char* functionInfo) noexcept; 438fa7767c5Sopenharmony_ci 439fa7767c5Sopenharmony_ci template <typename T> 440fa7767c5Sopenharmony_ci struct TrivialStackFunctionTable { 441fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 442fa7767c5Sopenharmony_ci static const std::type_info& Type() noexcept 443fa7767c5Sopenharmony_ci { 444fa7767c5Sopenharmony_ci return typeid(T); 445fa7767c5Sopenharmony_ci } 446fa7767c5Sopenharmony_ci#else 447fa7767c5Sopenharmony_ci static std::string_view TypeName() noexcept 448fa7767c5Sopenharmony_ci { 449fa7767c5Sopenharmony_ci return GetTypeName<T>(); 450fa7767c5Sopenharmony_ci } 451fa7767c5Sopenharmony_ci // Only support parcel enum value to int32_t except base types 452fa7767c5Sopenharmony_ci static bool ToParcel(const Any *operand, MessageParcel& parcel) noexcept 453fa7767c5Sopenharmony_ci { 454fa7767c5Sopenharmony_ci if (BaseTypesToParcel(operand, parcel)) { 455fa7767c5Sopenharmony_ci return true; 456fa7767c5Sopenharmony_ci } 457fa7767c5Sopenharmony_ci if (sizeof(T) > sizeof(int64_t)) { // Only support enum 458fa7767c5Sopenharmony_ci return false; 459fa7767c5Sopenharmony_ci } 460fa7767c5Sopenharmony_ci if (sizeof(T) == sizeof(int64_t)) { // support Int64 enum 461fa7767c5Sopenharmony_ci T value; 462fa7767c5Sopenharmony_ci if (AnyCast(operand, value)) { 463fa7767c5Sopenharmony_ci WriteValueToParcelInt64(value, parcel); 464fa7767c5Sopenharmony_ci return true; 465fa7767c5Sopenharmony_ci } 466fa7767c5Sopenharmony_ci return false; 467fa7767c5Sopenharmony_ci } 468fa7767c5Sopenharmony_ci T value; 469fa7767c5Sopenharmony_ci if (AnyCast(operand, value)) { 470fa7767c5Sopenharmony_ci WriteValueToParcel(value, parcel); 471fa7767c5Sopenharmony_ci return true; 472fa7767c5Sopenharmony_ci } 473fa7767c5Sopenharmony_ci return false; 474fa7767c5Sopenharmony_ci } 475fa7767c5Sopenharmony_ci 476fa7767c5Sopenharmony_ci static bool FromParcel(Any *operand, MessageParcel& parcel) noexcept 477fa7767c5Sopenharmony_ci { 478fa7767c5Sopenharmony_ci int ret = BaseTypesFromParcel(operand, parcel); 479fa7767c5Sopenharmony_ci if (ret == 0) { 480fa7767c5Sopenharmony_ci return true; 481fa7767c5Sopenharmony_ci } 482fa7767c5Sopenharmony_ci MakeAnyFromParcel<T>(*operand, parcel); 483fa7767c5Sopenharmony_ci return true; 484fa7767c5Sopenharmony_ci } 485fa7767c5Sopenharmony_ci#endif 486fa7767c5Sopenharmony_ci 487fa7767c5Sopenharmony_ci static void Destroy(Storage& storage) noexcept 488fa7767c5Sopenharmony_ci { 489fa7767c5Sopenharmony_ci reinterpret_cast<T*>(storage.trivialStack_.data())->~T(); 490fa7767c5Sopenharmony_ci } 491fa7767c5Sopenharmony_ci 492fa7767c5Sopenharmony_ci static void Copy(Storage& dest, const Storage& source) noexcept 493fa7767c5Sopenharmony_ci { 494fa7767c5Sopenharmony_ci // memcpy_s will always success in this function 495fa7767c5Sopenharmony_ci (void)memcpy_s(GetPtr(dest), sizeof(Storage), GetConstPtr(source), sizeof(Storage)); 496fa7767c5Sopenharmony_ci } 497fa7767c5Sopenharmony_ci 498fa7767c5Sopenharmony_ci static void Move(Storage& dest, Storage& source) noexcept 499fa7767c5Sopenharmony_ci { 500fa7767c5Sopenharmony_ci Copy(dest, source); 501fa7767c5Sopenharmony_ci source.trivialStack_.fill(0); 502fa7767c5Sopenharmony_ci } 503fa7767c5Sopenharmony_ci 504fa7767c5Sopenharmony_ci static const void* GetConstPtr(const Storage& storage) noexcept 505fa7767c5Sopenharmony_ci { 506fa7767c5Sopenharmony_ci return reinterpret_cast<const void *>(storage.trivialStack_.data()); 507fa7767c5Sopenharmony_ci } 508fa7767c5Sopenharmony_ci 509fa7767c5Sopenharmony_ci static void* GetPtr(Storage& storage) noexcept 510fa7767c5Sopenharmony_ci { 511fa7767c5Sopenharmony_ci return reinterpret_cast<void *>(storage.trivialStack_.data()); 512fa7767c5Sopenharmony_ci } 513fa7767c5Sopenharmony_ci }; 514fa7767c5Sopenharmony_ci 515fa7767c5Sopenharmony_ci template <typename T> 516fa7767c5Sopenharmony_ci struct StackFunctionTable { 517fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 518fa7767c5Sopenharmony_ci static const std::type_info& Type() noexcept 519fa7767c5Sopenharmony_ci { 520fa7767c5Sopenharmony_ci return typeid(T); 521fa7767c5Sopenharmony_ci } 522fa7767c5Sopenharmony_ci#else 523fa7767c5Sopenharmony_ci static std::string_view TypeName() noexcept 524fa7767c5Sopenharmony_ci { 525fa7767c5Sopenharmony_ci return GetTypeName<T>(); 526fa7767c5Sopenharmony_ci } 527fa7767c5Sopenharmony_ci // Only support parcel enum value to int32_t except base types 528fa7767c5Sopenharmony_ci static bool ToParcel(const Any *operand, MessageParcel& parcel) noexcept 529fa7767c5Sopenharmony_ci { 530fa7767c5Sopenharmony_ci if (BaseTypesToParcel(operand, parcel)) { 531fa7767c5Sopenharmony_ci return true; 532fa7767c5Sopenharmony_ci } 533fa7767c5Sopenharmony_ci if (sizeof(T) > sizeof(int64_t)) { // Only support enum 534fa7767c5Sopenharmony_ci return false; 535fa7767c5Sopenharmony_ci } 536fa7767c5Sopenharmony_ci if (sizeof(T) == sizeof(int64_t)) { // support Int64 enum 537fa7767c5Sopenharmony_ci T value; 538fa7767c5Sopenharmony_ci if (AnyCast(operand, value)) { 539fa7767c5Sopenharmony_ci WriteValueToParcelInt64(value, parcel); 540fa7767c5Sopenharmony_ci return true; 541fa7767c5Sopenharmony_ci } 542fa7767c5Sopenharmony_ci return false; 543fa7767c5Sopenharmony_ci } 544fa7767c5Sopenharmony_ci T value; 545fa7767c5Sopenharmony_ci if (AnyCast(operand, value)) { 546fa7767c5Sopenharmony_ci WriteValueToParcel(value, parcel); 547fa7767c5Sopenharmony_ci return true; 548fa7767c5Sopenharmony_ci } 549fa7767c5Sopenharmony_ci return false; 550fa7767c5Sopenharmony_ci } 551fa7767c5Sopenharmony_ci 552fa7767c5Sopenharmony_ci static bool FromParcel(Any *operand, MessageParcel& parcel) noexcept 553fa7767c5Sopenharmony_ci { 554fa7767c5Sopenharmony_ci int ret = BaseTypesFromParcel(operand, parcel); 555fa7767c5Sopenharmony_ci if (ret == 0) { 556fa7767c5Sopenharmony_ci return true; 557fa7767c5Sopenharmony_ci } 558fa7767c5Sopenharmony_ci MakeAnyFromParcel<T>(*operand, parcel); 559fa7767c5Sopenharmony_ci return true; 560fa7767c5Sopenharmony_ci } 561fa7767c5Sopenharmony_ci#endif 562fa7767c5Sopenharmony_ci 563fa7767c5Sopenharmony_ci static void Destroy(Storage& storage) noexcept 564fa7767c5Sopenharmony_ci { 565fa7767c5Sopenharmony_ci reinterpret_cast<T*>(GetPtr(storage))->~T(); // NOLINT: cast 566fa7767c5Sopenharmony_ci } 567fa7767c5Sopenharmony_ci 568fa7767c5Sopenharmony_ci static void Copy(Storage& dest, const Storage& source) noexcept 569fa7767c5Sopenharmony_ci { 570fa7767c5Sopenharmony_ci // NOLINTNEXTLINE: reinterpret_cast 571fa7767c5Sopenharmony_ci new (reinterpret_cast<T*>(GetPtr(dest))) T(*reinterpret_cast<const T*>(GetConstPtr(source))); 572fa7767c5Sopenharmony_ci } 573fa7767c5Sopenharmony_ci 574fa7767c5Sopenharmony_ci static void Move(Storage& dest, Storage& source) noexcept 575fa7767c5Sopenharmony_ci { 576fa7767c5Sopenharmony_ci // NOLINTNEXTLINE: reinterpret_cast 577fa7767c5Sopenharmony_ci new (reinterpret_cast<T*>(GetPtr(dest))) T(std::move(*reinterpret_cast<T*>(GetPtr(source)))); 578fa7767c5Sopenharmony_ci Destroy(source); 579fa7767c5Sopenharmony_ci } 580fa7767c5Sopenharmony_ci 581fa7767c5Sopenharmony_ci static const void* GetConstPtr(const Storage& storage) noexcept 582fa7767c5Sopenharmony_ci { 583fa7767c5Sopenharmony_ci return reinterpret_cast<const void*>(&storage.nonTrivialStack_); 584fa7767c5Sopenharmony_ci } 585fa7767c5Sopenharmony_ci 586fa7767c5Sopenharmony_ci static void* GetPtr(Storage& storage) noexcept 587fa7767c5Sopenharmony_ci { 588fa7767c5Sopenharmony_ci return reinterpret_cast<void*>(&storage.nonTrivialStack_); 589fa7767c5Sopenharmony_ci } 590fa7767c5Sopenharmony_ci }; 591fa7767c5Sopenharmony_ci 592fa7767c5Sopenharmony_ci template <typename T> 593fa7767c5Sopenharmony_ci struct HeapFunctionTable { 594fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 595fa7767c5Sopenharmony_ci static const std::type_info& Type() noexcept 596fa7767c5Sopenharmony_ci { 597fa7767c5Sopenharmony_ci return typeid(T); 598fa7767c5Sopenharmony_ci } 599fa7767c5Sopenharmony_ci#else 600fa7767c5Sopenharmony_ci static std::string_view TypeName() noexcept 601fa7767c5Sopenharmony_ci { 602fa7767c5Sopenharmony_ci return GetTypeName<T>(); 603fa7767c5Sopenharmony_ci } 604fa7767c5Sopenharmony_ci // Only support parcel enum value to int32_t except base types 605fa7767c5Sopenharmony_ci static bool ToParcel(const Any *operand, MessageParcel& parcel) noexcept 606fa7767c5Sopenharmony_ci { 607fa7767c5Sopenharmony_ci if (BaseTypesToParcel(operand, parcel)) { 608fa7767c5Sopenharmony_ci return true; 609fa7767c5Sopenharmony_ci } 610fa7767c5Sopenharmony_ci if (sizeof(T) > sizeof(int64_t)) { // Only support enum 611fa7767c5Sopenharmony_ci return false; 612fa7767c5Sopenharmony_ci } 613fa7767c5Sopenharmony_ci if (sizeof(T) == sizeof(int64_t)) { // support Int64 enum 614fa7767c5Sopenharmony_ci T value; 615fa7767c5Sopenharmony_ci if (AnyCast(operand, value)) { 616fa7767c5Sopenharmony_ci WriteValueToParcelInt64(value, parcel); 617fa7767c5Sopenharmony_ci return true; 618fa7767c5Sopenharmony_ci } 619fa7767c5Sopenharmony_ci return false; 620fa7767c5Sopenharmony_ci } 621fa7767c5Sopenharmony_ci T value; 622fa7767c5Sopenharmony_ci if (AnyCast(operand, value)) { 623fa7767c5Sopenharmony_ci WriteValueToParcel(value, parcel); 624fa7767c5Sopenharmony_ci return true; 625fa7767c5Sopenharmony_ci } 626fa7767c5Sopenharmony_ci return false; 627fa7767c5Sopenharmony_ci } 628fa7767c5Sopenharmony_ci 629fa7767c5Sopenharmony_ci static bool FromParcel(Any *operand, MessageParcel& parcel) noexcept 630fa7767c5Sopenharmony_ci { 631fa7767c5Sopenharmony_ci int ret = BaseTypesFromParcel(operand, parcel); 632fa7767c5Sopenharmony_ci if (ret == 0) { 633fa7767c5Sopenharmony_ci return true; 634fa7767c5Sopenharmony_ci } 635fa7767c5Sopenharmony_ci MakeAnyFromParcel<T>(*operand, parcel); 636fa7767c5Sopenharmony_ci return true; 637fa7767c5Sopenharmony_ci } 638fa7767c5Sopenharmony_ci#endif 639fa7767c5Sopenharmony_ci 640fa7767c5Sopenharmony_ci static void Destroy(Storage& storage) noexcept 641fa7767c5Sopenharmony_ci { 642fa7767c5Sopenharmony_ci delete reinterpret_cast<T*>(storage.heap_); // NOLINT: cast 643fa7767c5Sopenharmony_ci storage.heap_ = nullptr; 644fa7767c5Sopenharmony_ci } 645fa7767c5Sopenharmony_ci static void Copy(Storage& dest, const Storage& source) noexcept 646fa7767c5Sopenharmony_ci { 647fa7767c5Sopenharmony_ci dest.heap_ = new T(*reinterpret_cast<T*>(source.heap_)); // NOLINT: cast 648fa7767c5Sopenharmony_ci } 649fa7767c5Sopenharmony_ci static void Move(Storage& dest, Storage& source) noexcept 650fa7767c5Sopenharmony_ci { 651fa7767c5Sopenharmony_ci dest.heap_ = source.heap_; 652fa7767c5Sopenharmony_ci source.heap_ = nullptr; 653fa7767c5Sopenharmony_ci } 654fa7767c5Sopenharmony_ci static const void* GetConstPtr(const Storage& storage) noexcept 655fa7767c5Sopenharmony_ci { 656fa7767c5Sopenharmony_ci return storage.heap_; 657fa7767c5Sopenharmony_ci } 658fa7767c5Sopenharmony_ci static void* GetPtr(Storage& storage) noexcept 659fa7767c5Sopenharmony_ci { 660fa7767c5Sopenharmony_ci return storage.heap_; 661fa7767c5Sopenharmony_ci } 662fa7767c5Sopenharmony_ci }; 663fa7767c5Sopenharmony_ci 664fa7767c5Sopenharmony_ci template <typename ValueType> 665fa7767c5Sopenharmony_ci static FunctionTable* GetFunctionTable() 666fa7767c5Sopenharmony_ci { 667fa7767c5Sopenharmony_ci using DecayedValueType = decay_t<ValueType>; 668fa7767c5Sopenharmony_ci using DetailFunctionTable = 669fa7767c5Sopenharmony_ci conditional_t<IsTrivialStackStorable<DecayedValueType>::value, 670fa7767c5Sopenharmony_ci TrivialStackFunctionTable<DecayedValueType>, 671fa7767c5Sopenharmony_ci conditional_t<IsStackStorable<DecayedValueType>::value, 672fa7767c5Sopenharmony_ci StackFunctionTable<DecayedValueType>, HeapFunctionTable<DecayedValueType>>>; 673fa7767c5Sopenharmony_ci static FunctionTable table = { 674fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 675fa7767c5Sopenharmony_ci .type = DetailFunctionTable::Type, 676fa7767c5Sopenharmony_ci#else 677fa7767c5Sopenharmony_ci .type_name = DetailFunctionTable::TypeName, 678fa7767c5Sopenharmony_ci .toParcel = DetailFunctionTable::ToParcel, 679fa7767c5Sopenharmony_ci .fromParcel = DetailFunctionTable::FromParcel, 680fa7767c5Sopenharmony_ci#endif 681fa7767c5Sopenharmony_ci .destroy = DetailFunctionTable::Destroy, 682fa7767c5Sopenharmony_ci .copy = DetailFunctionTable::Copy, 683fa7767c5Sopenharmony_ci .move = DetailFunctionTable::Move, 684fa7767c5Sopenharmony_ci .getPtr = DetailFunctionTable::GetPtr, 685fa7767c5Sopenharmony_ci .getConstPtr = DetailFunctionTable::GetConstPtr, 686fa7767c5Sopenharmony_ci }; 687fa7767c5Sopenharmony_ci return &table; 688fa7767c5Sopenharmony_ci } 689fa7767c5Sopenharmony_ci 690fa7767c5Sopenharmony_ci bool IsFunctionTableValid() const noexcept 691fa7767c5Sopenharmony_ci { 692fa7767c5Sopenharmony_ci return functionTable_ != nullptr; 693fa7767c5Sopenharmony_ci } 694fa7767c5Sopenharmony_ci 695fa7767c5Sopenharmony_ci template <typename DecayedValueType, typename... Args> 696fa7767c5Sopenharmony_ci DecayedValueType &__attribute__((no_sanitize("cfi"))) DoEmplace(Args &&...args) 697fa7767c5Sopenharmony_ci { 698fa7767c5Sopenharmony_ci functionTable_ = GetFunctionTable<DecayedValueType>(); 699fa7767c5Sopenharmony_ci DecayedValueType* ptr = nullptr; 700fa7767c5Sopenharmony_ci if (IsTrivialStackStorable<DecayedValueType>::value || IsStackStorable<DecayedValueType>::value) { 701fa7767c5Sopenharmony_ci ptr = reinterpret_cast<DecayedValueType*>(functionTable_->getPtr(storage_)); 702fa7767c5Sopenharmony_ci new (ptr) DecayedValueType(std::forward<Args>(args)...); 703fa7767c5Sopenharmony_ci } else { 704fa7767c5Sopenharmony_ci storage_.heap_ = new DecayedValueType(std::forward<Args>(args)...); 705fa7767c5Sopenharmony_ci ptr = reinterpret_cast<DecayedValueType*>(storage_.heap_); 706fa7767c5Sopenharmony_ci } 707fa7767c5Sopenharmony_ci return *ptr; 708fa7767c5Sopenharmony_ci } 709fa7767c5Sopenharmony_ci 710fa7767c5Sopenharmony_ci void __attribute__((no_sanitize("cfi"))) MoveFrom(Any &&other) noexcept 711fa7767c5Sopenharmony_ci { 712fa7767c5Sopenharmony_ci if (other.HasValue()) { 713fa7767c5Sopenharmony_ci functionTable_ = other.functionTable_; 714fa7767c5Sopenharmony_ci functionTable_->move(storage_, other.storage_); 715fa7767c5Sopenharmony_ci other.Reset(); 716fa7767c5Sopenharmony_ci } 717fa7767c5Sopenharmony_ci } 718fa7767c5Sopenharmony_ci 719fa7767c5Sopenharmony_ci template <typename ValueType> 720fa7767c5Sopenharmony_ci ValueType* Cast() noexcept 721fa7767c5Sopenharmony_ci { 722fa7767c5Sopenharmony_ci using DecayedValueType = decay_t<ValueType>; 723fa7767c5Sopenharmony_ci if (!IsFunctionTableValid()) { 724fa7767c5Sopenharmony_ci return nullptr; 725fa7767c5Sopenharmony_ci } 726fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 727fa7767c5Sopenharmony_ci if (!SameTypeWith(typeid(DecayedValueType))) { 728fa7767c5Sopenharmony_ci#else 729fa7767c5Sopenharmony_ci if (!SameTypeWith(Any::GetTypeName<DecayedValueType>())) { 730fa7767c5Sopenharmony_ci#endif 731fa7767c5Sopenharmony_ci return nullptr; 732fa7767c5Sopenharmony_ci } 733fa7767c5Sopenharmony_ci return IsTrivialStackStorable<DecayedValueType>::value 734fa7767c5Sopenharmony_ci ? reinterpret_cast<DecayedValueType*>(storage_.trivialStack_.data()) 735fa7767c5Sopenharmony_ci : (IsStackStorable<DecayedValueType>::value 736fa7767c5Sopenharmony_ci ? reinterpret_cast<DecayedValueType*>(&storage_.nonTrivialStack_) 737fa7767c5Sopenharmony_ci : reinterpret_cast<DecayedValueType*>(storage_.heap_)); 738fa7767c5Sopenharmony_ci } 739fa7767c5Sopenharmony_ci template <typename ValueType> 740fa7767c5Sopenharmony_ci const ValueType* Cast() const noexcept 741fa7767c5Sopenharmony_ci { 742fa7767c5Sopenharmony_ci using DecayedValueType = decay_t<ValueType>; 743fa7767c5Sopenharmony_ci if (!IsFunctionTableValid()) { 744fa7767c5Sopenharmony_ci return nullptr; 745fa7767c5Sopenharmony_ci } 746fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 747fa7767c5Sopenharmony_ci if (!SameTypeWith(typeid(DecayedValueType))) { 748fa7767c5Sopenharmony_ci#else 749fa7767c5Sopenharmony_ci if (!SameTypeWith(Any::GetTypeName<DecayedValueType>())) { 750fa7767c5Sopenharmony_ci#endif 751fa7767c5Sopenharmony_ci return nullptr; 752fa7767c5Sopenharmony_ci } 753fa7767c5Sopenharmony_ci return IsTrivialStackStorable<DecayedValueType>::value 754fa7767c5Sopenharmony_ci ? reinterpret_cast<const DecayedValueType*>(storage_.trivialStack_.data()) 755fa7767c5Sopenharmony_ci : (IsStackStorable<DecayedValueType>::value 756fa7767c5Sopenharmony_ci ? reinterpret_cast<const DecayedValueType*>(&storage_.nonTrivialStack_) 757fa7767c5Sopenharmony_ci : reinterpret_cast<const DecayedValueType*>(storage_.heap_)); 758fa7767c5Sopenharmony_ci } 759fa7767c5Sopenharmony_ci 760fa7767c5Sopenharmony_ciprivate: 761fa7767c5Sopenharmony_ci Storage storage_ {}; 762fa7767c5Sopenharmony_ci FunctionTable* functionTable_ {nullptr}; 763fa7767c5Sopenharmony_ci}; 764fa7767c5Sopenharmony_ci 765fa7767c5Sopenharmony_ci/** 766fa7767c5Sopenharmony_ci * cast one Any pointer into ValueType pointer 767fa7767c5Sopenharmony_ci * 768fa7767c5Sopenharmony_ci * @tparam ValueType target value type 769fa7767c5Sopenharmony_ci * @param operand any object 770fa7767c5Sopenharmony_ci * @return nullptr if type mismatch, operand is nullptr, or valueType is function/array. Otherwise, a pointer to the 771fa7767c5Sopenharmony_ci * const value contained by operand. 772fa7767c5Sopenharmony_ci */ 773fa7767c5Sopenharmony_citemplate <typename ValueType> 774fa7767c5Sopenharmony_ciconst ValueType* AnyCast(const Any* operand) noexcept 775fa7767c5Sopenharmony_ci{ 776fa7767c5Sopenharmony_ci static_assert(!std::is_void<ValueType>::value, "ValueType of any_cast must not be void"); 777fa7767c5Sopenharmony_ci if (std::is_function<ValueType>::value || std::is_array<ValueType>::value || operand == nullptr) { 778fa7767c5Sopenharmony_ci return nullptr; 779fa7767c5Sopenharmony_ci } 780fa7767c5Sopenharmony_ci return operand->Cast<ValueType>(); 781fa7767c5Sopenharmony_ci} 782fa7767c5Sopenharmony_ci 783fa7767c5Sopenharmony_ci /** 784fa7767c5Sopenharmony_ci * cast one Any pointer into ValueType object 785fa7767c5Sopenharmony_ci * 786fa7767c5Sopenharmony_ci * @tparam ValueType target value type 787fa7767c5Sopenharmony_ci * @param operand any object 788fa7767c5Sopenharmony_ci * @param value ValueType 789fa7767c5Sopenharmony_ci * @return false if type mismatch, operand is nullptr, or valueType is function/array. Otherwise, true to the 790fa7767c5Sopenharmony_ci * value contained by operand. 791fa7767c5Sopenharmony_ci */ 792fa7767c5Sopenharmony_citemplate <typename ValueType> 793fa7767c5Sopenharmony_cibool AnyCast(const Any* operand, ValueType& value) noexcept 794fa7767c5Sopenharmony_ci{ 795fa7767c5Sopenharmony_ci static_assert(!std::is_void<ValueType>::value, "ValueType of any_cast must not be void"); 796fa7767c5Sopenharmony_ci if (std::is_function<ValueType>::value || std::is_array<ValueType>::value || operand == nullptr) { 797fa7767c5Sopenharmony_ci return false; 798fa7767c5Sopenharmony_ci } 799fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 800fa7767c5Sopenharmony_ci if (!operand->SameTypeWith(typeid(ValueType))) { 801fa7767c5Sopenharmony_ci#else 802fa7767c5Sopenharmony_ci if (!operand->SameTypeWith(Any::GetTypeName<ValueType>())) { 803fa7767c5Sopenharmony_ci#endif 804fa7767c5Sopenharmony_ci return false; 805fa7767c5Sopenharmony_ci } else { 806fa7767c5Sopenharmony_ci auto casted_value = operand->Cast<ValueType>(); 807fa7767c5Sopenharmony_ci if (casted_value != nullptr) { 808fa7767c5Sopenharmony_ci value = *casted_value; 809fa7767c5Sopenharmony_ci return true; 810fa7767c5Sopenharmony_ci } 811fa7767c5Sopenharmony_ci return false; 812fa7767c5Sopenharmony_ci } 813fa7767c5Sopenharmony_ci} 814fa7767c5Sopenharmony_ci 815fa7767c5Sopenharmony_ci/** 816fa7767c5Sopenharmony_ci * cast one Any pointer into ValueType pointer 817fa7767c5Sopenharmony_ci * 818fa7767c5Sopenharmony_ci * @tparam ValueType target value type 819fa7767c5Sopenharmony_ci * @param operand any object 820fa7767c5Sopenharmony_ci * @return nullptr if type mismatch, operand is nullptr, or valueType is function/array. Otherwise, a pointer to the 821fa7767c5Sopenharmony_ci * value contained by operand. 822fa7767c5Sopenharmony_ci */ 823fa7767c5Sopenharmony_citemplate <typename ValueType> 824fa7767c5Sopenharmony_ciValueType* AnyCast(Any* operand) noexcept 825fa7767c5Sopenharmony_ci{ 826fa7767c5Sopenharmony_ci static_assert(!std::is_void<ValueType>::value, "ValueType of any_cast must not be void"); 827fa7767c5Sopenharmony_ci if (std::is_function<ValueType>::value || std::is_array<ValueType>::value || operand == nullptr) { 828fa7767c5Sopenharmony_ci return nullptr; 829fa7767c5Sopenharmony_ci } 830fa7767c5Sopenharmony_ci return operand->Cast<ValueType>(); 831fa7767c5Sopenharmony_ci} 832fa7767c5Sopenharmony_ci 833fa7767c5Sopenharmony_ci/** 834fa7767c5Sopenharmony_ci * cast one Any object into ValueType object 835fa7767c5Sopenharmony_ci * 836fa7767c5Sopenharmony_ci * @tparam ValueType target value type. It must match both conditions: 837fa7767c5Sopenharmony_ci * 1. ValueType must be reference or constructible 838fa7767c5Sopenharmony_ci * 2. Let U be remove_cv_t<remove_reference_t<ValueType>>, then std::is_constructible<ValueType, const U&> must be true 839fa7767c5Sopenharmony_ci * @param operand any object 840fa7767c5Sopenharmony_ci * @return throws BadAnyCast exception if type mismatch, operand is nullptr, or valueType is function/array. Otherwise, 841fa7767c5Sopenharmony_ci * one object of ValueType contained in Any. 842fa7767c5Sopenharmony_ci */ 843fa7767c5Sopenharmony_citemplate <typename ValueType> 844fa7767c5Sopenharmony_ciValueType AnyCast(const Any& other) 845fa7767c5Sopenharmony_ci{ 846fa7767c5Sopenharmony_ci using U = remove_cv_t<remove_reference_t<ValueType>>; 847fa7767c5Sopenharmony_ci static_assert(IsValidCast<ValueType>::value, "template argument must be a reference or has copy constructors"); 848fa7767c5Sopenharmony_ci static_assert(std::is_constructible<ValueType, const U&>::value, 849fa7767c5Sopenharmony_ci "any_cast<ValueType>(const any&) requires ValueType constructable from const " 850fa7767c5Sopenharmony_ci "remove_cv_t<remove_reference_t<ValueType>>&"); 851fa7767c5Sopenharmony_ci auto ptr = AnyCast<U>(&other); 852fa7767c5Sopenharmony_ci return static_cast<ValueType>(*ptr); 853fa7767c5Sopenharmony_ci} 854fa7767c5Sopenharmony_ci 855fa7767c5Sopenharmony_ci/** 856fa7767c5Sopenharmony_ci * cast one Any object into ValueType object 857fa7767c5Sopenharmony_ci * 858fa7767c5Sopenharmony_ci * @tparam ValueType target value type. It must match both conditions: 859fa7767c5Sopenharmony_ci * 1. ValueType must be reference or constructible 860fa7767c5Sopenharmony_ci * 2. Let U be remove_cv_t<remove_reference_t<ValueType>>, then std::is_constructible<ValueType, U&> must be true 861fa7767c5Sopenharmony_ci * @param operand any object 862fa7767c5Sopenharmony_ci * @return throws BadAnyCast exception if type mismatch, operand is nullptr, or valueType is function/array. Otherwise, 863fa7767c5Sopenharmony_ci * one object of ValueType contained in Any. 864fa7767c5Sopenharmony_ci */ 865fa7767c5Sopenharmony_citemplate <typename ValueType> 866fa7767c5Sopenharmony_ciValueType AnyCast(Any& other) 867fa7767c5Sopenharmony_ci{ 868fa7767c5Sopenharmony_ci using U = remove_cv_t<remove_reference_t<ValueType>>; 869fa7767c5Sopenharmony_ci static_assert(IsValidCast<ValueType>::value, "template argument must be a reference or has copy constructors"); 870fa7767c5Sopenharmony_ci static_assert(std::is_constructible<ValueType, U&>::value, 871fa7767c5Sopenharmony_ci "any_cast<ValueType>(const any&) requires ValueType constructable from " 872fa7767c5Sopenharmony_ci "remove_cv_t<remove_reference_t<ValueType>>&"); 873fa7767c5Sopenharmony_ci auto ptr = AnyCast<U>(&other); 874fa7767c5Sopenharmony_ci return static_cast<ValueType>(*ptr); 875fa7767c5Sopenharmony_ci} 876fa7767c5Sopenharmony_ci 877fa7767c5Sopenharmony_ci/** 878fa7767c5Sopenharmony_ci * cast one Any object into ValueType object 879fa7767c5Sopenharmony_ci * 880fa7767c5Sopenharmony_ci * @tparam ValueType target value type. It must match both conditions: 881fa7767c5Sopenharmony_ci * 1. ValueType must be reference or constructible 882fa7767c5Sopenharmony_ci * 2. Let U be remove_cv_t<remove_reference_t<ValueType>>, then std::is_constructible<ValueType, U> must be true 883fa7767c5Sopenharmony_ci * @param operand any object 884fa7767c5Sopenharmony_ci * @return throws BadAnyCast exception if type mismatch, operand is nullptr, or valueType is function/array. Otherwise, 885fa7767c5Sopenharmony_ci * one object of ValueType contained in Any. 886fa7767c5Sopenharmony_ci */ 887fa7767c5Sopenharmony_citemplate <typename ValueType> 888fa7767c5Sopenharmony_ciValueType AnyCast(Any&& other) 889fa7767c5Sopenharmony_ci{ 890fa7767c5Sopenharmony_ci using U = remove_cv_t<remove_reference_t<ValueType>>; 891fa7767c5Sopenharmony_ci static_assert(IsValidCast<ValueType>::value, "template argument must be a reference or has copy constructors"); 892fa7767c5Sopenharmony_ci static_assert(std::is_constructible<ValueType, U>::value, 893fa7767c5Sopenharmony_ci "any_cast<ValueType>(const any&) requires ValueType constructable from " 894fa7767c5Sopenharmony_ci "remove_cv_t<remove_reference_t<ValueType>>"); 895fa7767c5Sopenharmony_ci auto ptr = AnyCast<U>(&other); 896fa7767c5Sopenharmony_ci return static_cast<ValueType>(std::move(*ptr)); 897fa7767c5Sopenharmony_ci} 898fa7767c5Sopenharmony_ci 899fa7767c5Sopenharmony_ci/** 900fa7767c5Sopenharmony_ci * Constructs Any object, whose content is constructed by args. The content type is T. 901fa7767c5Sopenharmony_ci * 902fa7767c5Sopenharmony_ci * @tparam T type of Any's content 903fa7767c5Sopenharmony_ci * @tparam Args type of args 904fa7767c5Sopenharmony_ci * @param args args used to construct the content 905fa7767c5Sopenharmony_ci * @return Any object 906fa7767c5Sopenharmony_ci */ 907fa7767c5Sopenharmony_citemplate <typename T, typename... Args> 908fa7767c5Sopenharmony_ciAny MakeAny(Args&&... args) 909fa7767c5Sopenharmony_ci{ 910fa7767c5Sopenharmony_ci Any tmp; 911fa7767c5Sopenharmony_ci tmp.Emplace<T, Args...>(std::forward<Args>(args)...); 912fa7767c5Sopenharmony_ci return tmp; 913fa7767c5Sopenharmony_ci} 914fa7767c5Sopenharmony_ci 915fa7767c5Sopenharmony_ci/** 916fa7767c5Sopenharmony_ci * Constructs Any object, whose content is constructed by il and args. The content type is T. 917fa7767c5Sopenharmony_ci * 918fa7767c5Sopenharmony_ci * @tparam T type of Any's content 919fa7767c5Sopenharmony_ci * @tparam U type of initializer list 920fa7767c5Sopenharmony_ci * @tparam Args type of args 921fa7767c5Sopenharmony_ci * @param il initializer list 922fa7767c5Sopenharmony_ci * @param args args 923fa7767c5Sopenharmony_ci * @return Any object 924fa7767c5Sopenharmony_ci */ 925fa7767c5Sopenharmony_citemplate <typename T, typename U, typename... Args> 926fa7767c5Sopenharmony_ciAny MakeAny(std::initializer_list<U> il, Args&&... args) 927fa7767c5Sopenharmony_ci{ 928fa7767c5Sopenharmony_ci Any tmp; 929fa7767c5Sopenharmony_ci tmp.Emplace<T, U, Args...>(il, std::forward<Args>(args)...); 930fa7767c5Sopenharmony_ci return tmp; 931fa7767c5Sopenharmony_ci} 932fa7767c5Sopenharmony_ci 933fa7767c5Sopenharmony_citemplate <typename T> 934fa7767c5Sopenharmony_ciinline typename std::enable_if<std::is_enum<T>::value, bool>::type MakeAnyFromParcel(Any& value, MessageParcel 935fa7767c5Sopenharmony_ci& parcel) 936fa7767c5Sopenharmony_ci{ 937fa7767c5Sopenharmony_ci if (sizeof(T) == sizeof(int64_t)) { 938fa7767c5Sopenharmony_ci value.Emplace<T>(static_cast<T>(parcel.ReadInt64())); 939fa7767c5Sopenharmony_ci return true; 940fa7767c5Sopenharmony_ci } 941fa7767c5Sopenharmony_ci value.Emplace<T>(static_cast<T>(parcel.ReadInt32())); 942fa7767c5Sopenharmony_ci return true; 943fa7767c5Sopenharmony_ci} 944fa7767c5Sopenharmony_ci} // namespace Media 945fa7767c5Sopenharmony_ci} // namespace OHOS 946fa7767c5Sopenharmony_ci#endif 947fa7767c5Sopenharmony_cinamespace std { 948fa7767c5Sopenharmony_ciinline void swap(OHOS::Media::Any& lhs, OHOS::Media::Any& rhs) noexcept 949fa7767c5Sopenharmony_ci{ 950fa7767c5Sopenharmony_ci lhs.Swap(rhs); 951fa7767c5Sopenharmony_ci} 952fa7767c5Sopenharmony_ci} // namespace std 953fa7767c5Sopenharmony_ci#endif // HISTREAMER_PLUGIN_COMMON_ANY_H 954