1fa7767c5Sopenharmony_ci/* 2fa7767c5Sopenharmony_ci * Copyright (c) 2021-2021 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#if defined(__clang__) || defined(__GNUC__) 20fa7767c5Sopenharmony_ci#define CPP_STANDARD __cplusplus 21fa7767c5Sopenharmony_ci#elif defined(_MSC_VER) 22fa7767c5Sopenharmony_ci#define CPP_STANDARD _MSVC_LANG 23fa7767c5Sopenharmony_ci#endif 24fa7767c5Sopenharmony_ci 25fa7767c5Sopenharmony_ci#if CPP_STANDARD >= 201103L 26fa7767c5Sopenharmony_ci 27fa7767c5Sopenharmony_ci#include <array> 28fa7767c5Sopenharmony_ci#include <cstring> 29fa7767c5Sopenharmony_ci#include <string_view> 30fa7767c5Sopenharmony_ci#include <type_traits> 31fa7767c5Sopenharmony_ci#include "plugin/common/type_cast_ext.h" 32fa7767c5Sopenharmony_ci#include "securec.h" 33fa7767c5Sopenharmony_ci 34fa7767c5Sopenharmony_cinamespace { 35fa7767c5Sopenharmony_citemplate <typename T> 36fa7767c5Sopenharmony_ciusing decay_t = typename std::decay<T>::type; 37fa7767c5Sopenharmony_ci 38fa7767c5Sopenharmony_citemplate <bool B, typename T = void> 39fa7767c5Sopenharmony_ciusing enable_if_t = typename std::enable_if<B, T>::type; 40fa7767c5Sopenharmony_ci 41fa7767c5Sopenharmony_citemplate <bool B, typename T, typename F> 42fa7767c5Sopenharmony_ciusing conditional_t = typename std::conditional<B, T, F>::type; 43fa7767c5Sopenharmony_ci 44fa7767c5Sopenharmony_citemplate <typename T> 45fa7767c5Sopenharmony_ciusing remove_cv_t = typename std::remove_cv<T>::type; 46fa7767c5Sopenharmony_ci 47fa7767c5Sopenharmony_citemplate <typename T> 48fa7767c5Sopenharmony_ciusing remove_reference_t = typename std::remove_reference<T>::type; 49fa7767c5Sopenharmony_ciconstexpr size_t STACK_STORAGE_SIZE = 2 * sizeof(void*); // NOLINT: global var 50fa7767c5Sopenharmony_ci 51fa7767c5Sopenharmony_citemplate <typename T> 52fa7767c5Sopenharmony_cistruct IsTrivialStackStorable { 53fa7767c5Sopenharmony_ci static constexpr bool value = 54fa7767c5Sopenharmony_ci alignof(T) <= alignof(max_align_t) && std::is_trivially_copyable<T>::value && sizeof(T) <= STACK_STORAGE_SIZE; 55fa7767c5Sopenharmony_ci}; 56fa7767c5Sopenharmony_ci 57fa7767c5Sopenharmony_citemplate <typename T> 58fa7767c5Sopenharmony_cistruct IsStackStorable { 59fa7767c5Sopenharmony_ci static constexpr bool value = alignof(T) <= alignof(max_align_t) && std::is_nothrow_move_constructible<T>::value && 60fa7767c5Sopenharmony_ci sizeof(T) <= STACK_STORAGE_SIZE; 61fa7767c5Sopenharmony_ci}; 62fa7767c5Sopenharmony_ci 63fa7767c5Sopenharmony_citemplate <typename T> 64fa7767c5Sopenharmony_cistruct IsValidCast { 65fa7767c5Sopenharmony_ci static constexpr bool value = std::is_reference<T>::value || std::is_copy_constructible<T>::value; 66fa7767c5Sopenharmony_ci}; 67fa7767c5Sopenharmony_ci} // namespace 68fa7767c5Sopenharmony_cinamespace OHOS { 69fa7767c5Sopenharmony_cinamespace Media { 70fa7767c5Sopenharmony_cinamespace Plugin { 71fa7767c5Sopenharmony_ci/** 72fa7767c5Sopenharmony_ci * @brief BadAnyCast exception, which is thrown when error occurs in AnyCast 73fa7767c5Sopenharmony_ci * 74fa7767c5Sopenharmony_ci * @since 1.0 75fa7767c5Sopenharmony_ci * @version 1.0 76fa7767c5Sopenharmony_ci */ 77fa7767c5Sopenharmony_ciclass BadAnyCast : public std::bad_cast { 78fa7767c5Sopenharmony_cipublic: 79fa7767c5Sopenharmony_ci const char* what() const noexcept override 80fa7767c5Sopenharmony_ci { 81fa7767c5Sopenharmony_ci return "bad any cast"; 82fa7767c5Sopenharmony_ci } 83fa7767c5Sopenharmony_ci}; 84fa7767c5Sopenharmony_ci 85fa7767c5Sopenharmony_ci/** 86fa7767c5Sopenharmony_ci * @brief This class describes a type-safe container for arbitrary type values which are copy constructible. 87fa7767c5Sopenharmony_ci * 88fa7767c5Sopenharmony_ci * @since 1.0 89fa7767c5Sopenharmony_ci * @version 1.0 90fa7767c5Sopenharmony_ci */ 91fa7767c5Sopenharmony_ciclass Any final { 92fa7767c5Sopenharmony_cipublic: 93fa7767c5Sopenharmony_ci constexpr Any() noexcept 94fa7767c5Sopenharmony_ci { 95fa7767c5Sopenharmony_ci } 96fa7767c5Sopenharmony_ci 97fa7767c5Sopenharmony_ci Any(const Any& other) : functionTable_(other.functionTable_) 98fa7767c5Sopenharmony_ci { 99fa7767c5Sopenharmony_ci if (other.HasValue()) { 100fa7767c5Sopenharmony_ci functionTable_->copy(storage_, other.storage_); 101fa7767c5Sopenharmony_ci } 102fa7767c5Sopenharmony_ci } 103fa7767c5Sopenharmony_ci 104fa7767c5Sopenharmony_ci Any(Any&& other) noexcept : functionTable_(other.functionTable_) 105fa7767c5Sopenharmony_ci { 106fa7767c5Sopenharmony_ci if (other.HasValue()) { 107fa7767c5Sopenharmony_ci functionTable_->move(storage_, other.storage_); 108fa7767c5Sopenharmony_ci other.functionTable_ = nullptr; 109fa7767c5Sopenharmony_ci } 110fa7767c5Sopenharmony_ci } 111fa7767c5Sopenharmony_ci 112fa7767c5Sopenharmony_ci /** 113fa7767c5Sopenharmony_ci * constructor from right reference value with type of ValueType. 114fa7767c5Sopenharmony_ci * 115fa7767c5Sopenharmony_ci * @tparam Type ValueType is not the same as Any itself. The decay type of ValueType must be copy constructible. 116fa7767c5Sopenharmony_ci * @param value content 117fa7767c5Sopenharmony_ci */ 118fa7767c5Sopenharmony_ci template <typename ValueType, enable_if_t<!std::is_same<decay_t<ValueType>, Any>::value && 119fa7767c5Sopenharmony_ci std::is_copy_constructible<decay_t<ValueType>>::value, 120fa7767c5Sopenharmony_ci bool> = true> 121fa7767c5Sopenharmony_ci Any(ValueType&& value) // NOLINT: explicit 122fa7767c5Sopenharmony_ci { 123fa7767c5Sopenharmony_ci DoEmplace<decay_t<ValueType>>(std::forward<ValueType>(value)); 124fa7767c5Sopenharmony_ci } 125fa7767c5Sopenharmony_ci 126fa7767c5Sopenharmony_ci Any& operator=(const Any& other) 127fa7767c5Sopenharmony_ci { 128fa7767c5Sopenharmony_ci *this = Any(other); 129fa7767c5Sopenharmony_ci return *this; 130fa7767c5Sopenharmony_ci } 131fa7767c5Sopenharmony_ci 132fa7767c5Sopenharmony_ci Any& operator=(Any&& other) noexcept 133fa7767c5Sopenharmony_ci { 134fa7767c5Sopenharmony_ci Reset(); 135fa7767c5Sopenharmony_ci MoveFrom(std::forward<Any>(other)); 136fa7767c5Sopenharmony_ci return *this; 137fa7767c5Sopenharmony_ci } 138fa7767c5Sopenharmony_ci 139fa7767c5Sopenharmony_ci /** 140fa7767c5Sopenharmony_ci * Assigns contents to Any. 141fa7767c5Sopenharmony_ci * 142fa7767c5Sopenharmony_ci * @tparam ValueType Type ValueType is not the same as Any itself. The decay type of ValueType must be copy 143fa7767c5Sopenharmony_ci * constructible. 144fa7767c5Sopenharmony_ci * @param value content 145fa7767c5Sopenharmony_ci * @return 146fa7767c5Sopenharmony_ci */ 147fa7767c5Sopenharmony_ci template <typename ValueType, enable_if_t<!std::is_same<decay_t<ValueType>, Any>::value && 148fa7767c5Sopenharmony_ci std::is_copy_constructible<decay_t<ValueType>>::value, 149fa7767c5Sopenharmony_ci bool> = true> 150fa7767c5Sopenharmony_ci Any& operator=(ValueType&& value) 151fa7767c5Sopenharmony_ci { 152fa7767c5Sopenharmony_ci *this = Any(std::forward<ValueType>(value)); 153fa7767c5Sopenharmony_ci return *this; 154fa7767c5Sopenharmony_ci } 155fa7767c5Sopenharmony_ci 156fa7767c5Sopenharmony_ci template<typename T> 157fa7767c5Sopenharmony_ci static constexpr std::string_view GetTypeName() noexcept 158fa7767c5Sopenharmony_ci { 159fa7767c5Sopenharmony_ci const char* charInfo = __PRETTY_FUNCTION__ ; 160fa7767c5Sopenharmony_ci std::string_view stringInfo = charInfo; 161fa7767c5Sopenharmony_ci uint32_t beginIndex = stringInfo.find_first_of('=') + 2; // 2 表示右移两位 162fa7767c5Sopenharmony_ci uint32_t endIndex = stringInfo.find_first_of(']'); 163fa7767c5Sopenharmony_ci std::string_view typeName(charInfo + beginIndex, endIndex - beginIndex + 1); 164fa7767c5Sopenharmony_ci return typeName; 165fa7767c5Sopenharmony_ci } 166fa7767c5Sopenharmony_ci 167fa7767c5Sopenharmony_ci template<typename T> 168fa7767c5Sopenharmony_ci static bool IsSameTypeWith(const Any& other) noexcept 169fa7767c5Sopenharmony_ci { 170fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 171fa7767c5Sopenharmony_ci return other.SameTypeWith(typeid(T)); 172fa7767c5Sopenharmony_ci#else 173fa7767c5Sopenharmony_ci return other.SameTypeWith(Any::GetTypeName<T>()); 174fa7767c5Sopenharmony_ci#endif 175fa7767c5Sopenharmony_ci } 176fa7767c5Sopenharmony_ci 177fa7767c5Sopenharmony_ci ~Any() 178fa7767c5Sopenharmony_ci { 179fa7767c5Sopenharmony_ci Reset(); 180fa7767c5Sopenharmony_ci } 181fa7767c5Sopenharmony_ci 182fa7767c5Sopenharmony_ci /** 183fa7767c5Sopenharmony_ci * Emplace one content with type of ValueType into object. The content is constructed by args. 184fa7767c5Sopenharmony_ci * 185fa7767c5Sopenharmony_ci * @tparam ValueType The decay type of ValueType must be constructible from args and copy constructible. 186fa7767c5Sopenharmony_ci * @tparam Args args type 187fa7767c5Sopenharmony_ci * @param args args 188fa7767c5Sopenharmony_ci * @return content with type of decay ValueType 189fa7767c5Sopenharmony_ci */ 190fa7767c5Sopenharmony_ci template <typename ValueType, typename... Args, 191fa7767c5Sopenharmony_ci enable_if_t<std::is_constructible<decay_t<ValueType>, Args...>::value && 192fa7767c5Sopenharmony_ci std::is_copy_constructible<decay_t<ValueType>>::value, 193fa7767c5Sopenharmony_ci bool> = true> 194fa7767c5Sopenharmony_ci decay_t<ValueType>& Emplace(Args&&... args) 195fa7767c5Sopenharmony_ci { 196fa7767c5Sopenharmony_ci Reset(); 197fa7767c5Sopenharmony_ci return DoEmplace<decay_t<ValueType>>(std::forward<Args>(args)...); 198fa7767c5Sopenharmony_ci } 199fa7767c5Sopenharmony_ci 200fa7767c5Sopenharmony_ci /** 201fa7767c5Sopenharmony_ci * Emplace one content with type of ValueType into object. The content is constructed by il and args. 202fa7767c5Sopenharmony_ci * 203fa7767c5Sopenharmony_ci * @tparam ValueType type of conetent. The decay type of ValueType must be constructible from il and args and copy 204fa7767c5Sopenharmony_ci * constructible 205fa7767c5Sopenharmony_ci * @tparam U type of initializer list. 206fa7767c5Sopenharmony_ci * @tparam Args type of other args 207fa7767c5Sopenharmony_ci * @param il initializer list 208fa7767c5Sopenharmony_ci * @param args args 209fa7767c5Sopenharmony_ci * @return content with type of decay ValueType 210fa7767c5Sopenharmony_ci */ 211fa7767c5Sopenharmony_ci template <typename ValueType, typename U, typename... Args, 212fa7767c5Sopenharmony_ci enable_if_t<std::is_constructible<decay_t<ValueType>, std::initializer_list<U>&, Args...>::value && 213fa7767c5Sopenharmony_ci std::is_copy_constructible<decay_t<ValueType>>::value, 214fa7767c5Sopenharmony_ci bool> = true> 215fa7767c5Sopenharmony_ci decay_t<ValueType>& Emplace(std::initializer_list<U> il, Args&&... args) 216fa7767c5Sopenharmony_ci { 217fa7767c5Sopenharmony_ci Reset(); 218fa7767c5Sopenharmony_ci return DoEmplace<decay_t<ValueType>>(il, std::forward<Args>(args)...); 219fa7767c5Sopenharmony_ci } 220fa7767c5Sopenharmony_ci 221fa7767c5Sopenharmony_ci /** 222fa7767c5Sopenharmony_ci * Destroy the inner content if exists. 223fa7767c5Sopenharmony_ci */ 224fa7767c5Sopenharmony_ci void Reset() noexcept 225fa7767c5Sopenharmony_ci { 226fa7767c5Sopenharmony_ci if (HasValue()) { 227fa7767c5Sopenharmony_ci functionTable_->destroy(storage_); 228fa7767c5Sopenharmony_ci storage_.trivialStack_.fill(0); 229fa7767c5Sopenharmony_ci } 230fa7767c5Sopenharmony_ci functionTable_ = nullptr; 231fa7767c5Sopenharmony_ci } 232fa7767c5Sopenharmony_ci 233fa7767c5Sopenharmony_ci /** 234fa7767c5Sopenharmony_ci * swap contents of two any objects 235fa7767c5Sopenharmony_ci * 236fa7767c5Sopenharmony_ci * @param other object to swap with 237fa7767c5Sopenharmony_ci */ 238fa7767c5Sopenharmony_ci void Swap(Any& other) noexcept 239fa7767c5Sopenharmony_ci { 240fa7767c5Sopenharmony_ci Any tmp(std::move(*this)); 241fa7767c5Sopenharmony_ci *this = std::move(other); 242fa7767c5Sopenharmony_ci other = std::move(tmp); 243fa7767c5Sopenharmony_ci } 244fa7767c5Sopenharmony_ci 245fa7767c5Sopenharmony_ci /** 246fa7767c5Sopenharmony_ci * Checks whether the object has one content. 247fa7767c5Sopenharmony_ci * 248fa7767c5Sopenharmony_ci * @return true if object has one content, otherwise false. 249fa7767c5Sopenharmony_ci */ 250fa7767c5Sopenharmony_ci bool HasValue() const noexcept 251fa7767c5Sopenharmony_ci { 252fa7767c5Sopenharmony_ci return IsFunctionTableValid(); 253fa7767c5Sopenharmony_ci } 254fa7767c5Sopenharmony_ci 255fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 256fa7767c5Sopenharmony_ci /** 257fa7767c5Sopenharmony_ci * Get tye type_info of object 258fa7767c5Sopenharmony_ci * 259fa7767c5Sopenharmony_ci * @return type info of object 260fa7767c5Sopenharmony_ci */ 261fa7767c5Sopenharmony_ci const std::type_info& Type() const noexcept 262fa7767c5Sopenharmony_ci { 263fa7767c5Sopenharmony_ci if (!HasValue()) { 264fa7767c5Sopenharmony_ci return typeid(void); 265fa7767c5Sopenharmony_ci } 266fa7767c5Sopenharmony_ci return functionTable_->type(); 267fa7767c5Sopenharmony_ci } 268fa7767c5Sopenharmony_ci#else 269fa7767c5Sopenharmony_ci std::string_view TypeName() const noexcept 270fa7767c5Sopenharmony_ci { 271fa7767c5Sopenharmony_ci if (!HasValue()) { 272fa7767c5Sopenharmony_ci return "empty"; // no value 273fa7767c5Sopenharmony_ci } 274fa7767c5Sopenharmony_ci return functionTable_->type_name(); 275fa7767c5Sopenharmony_ci } 276fa7767c5Sopenharmony_ci#endif 277fa7767c5Sopenharmony_ci 278fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 279fa7767c5Sopenharmony_ci bool SameTypeWith(const std::type_info& otherInfo) const noexcept 280fa7767c5Sopenharmony_ci { 281fa7767c5Sopenharmony_ci if (functionTable_ == nullptr) { 282fa7767c5Sopenharmony_ci return false; 283fa7767c5Sopenharmony_ci } 284fa7767c5Sopenharmony_ci return IsSameType(functionTable_->type(), otherInfo); 285fa7767c5Sopenharmony_ci } 286fa7767c5Sopenharmony_ci#else 287fa7767c5Sopenharmony_ci bool SameTypeWith(std::string_view otherTypeName) const noexcept 288fa7767c5Sopenharmony_ci { 289fa7767c5Sopenharmony_ci if (functionTable_ == nullptr) { 290fa7767c5Sopenharmony_ci return false; 291fa7767c5Sopenharmony_ci } 292fa7767c5Sopenharmony_ci return IsSameType(functionTable_->type_name(), otherTypeName); 293fa7767c5Sopenharmony_ci } 294fa7767c5Sopenharmony_ci#endif 295fa7767c5Sopenharmony_ci 296fa7767c5Sopenharmony_ci bool SameTypeWith(const Any& other) const noexcept 297fa7767c5Sopenharmony_ci { 298fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 299fa7767c5Sopenharmony_ci return IsSameType(functionTable_->type(), other.Type()); 300fa7767c5Sopenharmony_ci#else 301fa7767c5Sopenharmony_ci return IsSameType(functionTable_->type_name(), other.TypeName()); 302fa7767c5Sopenharmony_ci#endif 303fa7767c5Sopenharmony_ci } 304fa7767c5Sopenharmony_ci 305fa7767c5Sopenharmony_ciprivate: 306fa7767c5Sopenharmony_ci template <typename T> 307fa7767c5Sopenharmony_ci friend const T* AnyCast(const Any* operand) noexcept; 308fa7767c5Sopenharmony_ci template <typename T> 309fa7767c5Sopenharmony_ci friend T* AnyCast(Any* operand) noexcept; 310fa7767c5Sopenharmony_ci template <typename T> 311fa7767c5Sopenharmony_ci friend bool AnyCast(const Any* operand, T& value) noexcept; 312fa7767c5Sopenharmony_ci 313fa7767c5Sopenharmony_ci union Storage { 314fa7767c5Sopenharmony_ci using Stack = std::aligned_storage<STACK_STORAGE_SIZE, std::alignment_of<void*>::value>::type; 315fa7767c5Sopenharmony_ci using Heap = void*; 316fa7767c5Sopenharmony_ci 317fa7767c5Sopenharmony_ci std::array<uint8_t, STACK_STORAGE_SIZE> trivialStack_; 318fa7767c5Sopenharmony_ci Stack nonTrivialStack_; 319fa7767c5Sopenharmony_ci Heap heap_; 320fa7767c5Sopenharmony_ci }; 321fa7767c5Sopenharmony_ci 322fa7767c5Sopenharmony_ci struct FunctionTable { 323fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 324fa7767c5Sopenharmony_ci const std::type_info& (*type)() noexcept; 325fa7767c5Sopenharmony_ci#else 326fa7767c5Sopenharmony_ci std::string_view (*type_name)() noexcept; 327fa7767c5Sopenharmony_ci#endif 328fa7767c5Sopenharmony_ci void (*destroy)(Storage&) noexcept; 329fa7767c5Sopenharmony_ci void (*copy)(Storage&, const Storage&) noexcept; 330fa7767c5Sopenharmony_ci void (*move)(Storage&, Storage&) noexcept; 331fa7767c5Sopenharmony_ci void* (*getPtr)(Storage&) noexcept; 332fa7767c5Sopenharmony_ci const void* (*getConstPtr)(const Storage&) noexcept; 333fa7767c5Sopenharmony_ci }; 334fa7767c5Sopenharmony_ci 335fa7767c5Sopenharmony_ci template <typename T> 336fa7767c5Sopenharmony_ci struct TrivialStackFunctionTable { 337fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 338fa7767c5Sopenharmony_ci static const std::type_info& Type() noexcept 339fa7767c5Sopenharmony_ci { 340fa7767c5Sopenharmony_ci return typeid(T); 341fa7767c5Sopenharmony_ci } 342fa7767c5Sopenharmony_ci#else 343fa7767c5Sopenharmony_ci static std::string_view TypeName() noexcept 344fa7767c5Sopenharmony_ci { 345fa7767c5Sopenharmony_ci return GetTypeName<T>(); 346fa7767c5Sopenharmony_ci } 347fa7767c5Sopenharmony_ci#endif 348fa7767c5Sopenharmony_ci 349fa7767c5Sopenharmony_ci static void Destroy(Storage& storage) noexcept 350fa7767c5Sopenharmony_ci { 351fa7767c5Sopenharmony_ci reinterpret_cast<T*>(storage.trivialStack_.data())->~T(); 352fa7767c5Sopenharmony_ci } 353fa7767c5Sopenharmony_ci 354fa7767c5Sopenharmony_ci static void Copy(Storage& dest, const Storage& source) noexcept 355fa7767c5Sopenharmony_ci { 356fa7767c5Sopenharmony_ci // memcpy_s will always success in this function 357fa7767c5Sopenharmony_ci (void)memcpy_s(GetPtr(dest), sizeof(Storage), GetConstPtr(source), sizeof(Storage)); 358fa7767c5Sopenharmony_ci } 359fa7767c5Sopenharmony_ci 360fa7767c5Sopenharmony_ci static void Move(Storage& dest, Storage& source) noexcept 361fa7767c5Sopenharmony_ci { 362fa7767c5Sopenharmony_ci Copy(dest, source); 363fa7767c5Sopenharmony_ci source.trivialStack_.fill(0); 364fa7767c5Sopenharmony_ci } 365fa7767c5Sopenharmony_ci 366fa7767c5Sopenharmony_ci static const void* GetConstPtr(const Storage& storage) noexcept 367fa7767c5Sopenharmony_ci { 368fa7767c5Sopenharmony_ci return reinterpret_cast<const void*>(storage.trivialStack_.data()); 369fa7767c5Sopenharmony_ci } 370fa7767c5Sopenharmony_ci 371fa7767c5Sopenharmony_ci static void* GetPtr(Storage& storage) noexcept 372fa7767c5Sopenharmony_ci { 373fa7767c5Sopenharmony_ci return reinterpret_cast<void*>(storage.trivialStack_.data()); 374fa7767c5Sopenharmony_ci } 375fa7767c5Sopenharmony_ci }; 376fa7767c5Sopenharmony_ci 377fa7767c5Sopenharmony_ci template <typename T> 378fa7767c5Sopenharmony_ci struct StackFunctionTable { 379fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 380fa7767c5Sopenharmony_ci static const std::type_info& Type() noexcept 381fa7767c5Sopenharmony_ci { 382fa7767c5Sopenharmony_ci return typeid(T); 383fa7767c5Sopenharmony_ci } 384fa7767c5Sopenharmony_ci#else 385fa7767c5Sopenharmony_ci static std::string_view TypeName() noexcept 386fa7767c5Sopenharmony_ci { 387fa7767c5Sopenharmony_ci return GetTypeName<T>(); 388fa7767c5Sopenharmony_ci } 389fa7767c5Sopenharmony_ci#endif 390fa7767c5Sopenharmony_ci 391fa7767c5Sopenharmony_ci static void Destroy(Storage& storage) noexcept 392fa7767c5Sopenharmony_ci { 393fa7767c5Sopenharmony_ci reinterpret_cast<T*>(GetPtr(storage))->~T(); // NOLINT: cast 394fa7767c5Sopenharmony_ci } 395fa7767c5Sopenharmony_ci 396fa7767c5Sopenharmony_ci static void Copy(Storage& dest, const Storage& source) noexcept 397fa7767c5Sopenharmony_ci { 398fa7767c5Sopenharmony_ci // NOLINTNEXTLINE: reinterpret_cast 399fa7767c5Sopenharmony_ci new (reinterpret_cast<T*>(GetPtr(dest))) T(*reinterpret_cast<const T*>(GetConstPtr(source))); 400fa7767c5Sopenharmony_ci } 401fa7767c5Sopenharmony_ci 402fa7767c5Sopenharmony_ci static void Move(Storage& dest, Storage& source) noexcept 403fa7767c5Sopenharmony_ci { 404fa7767c5Sopenharmony_ci // NOLINTNEXTLINE: reinterpret_cast 405fa7767c5Sopenharmony_ci new (reinterpret_cast<T*>(GetPtr(dest))) T(std::move(*reinterpret_cast<T*>(GetPtr(source)))); 406fa7767c5Sopenharmony_ci Destroy(source); 407fa7767c5Sopenharmony_ci } 408fa7767c5Sopenharmony_ci 409fa7767c5Sopenharmony_ci static const void* GetConstPtr(const Storage& storage) noexcept 410fa7767c5Sopenharmony_ci { 411fa7767c5Sopenharmony_ci return reinterpret_cast<const void*>(&storage.nonTrivialStack_); 412fa7767c5Sopenharmony_ci } 413fa7767c5Sopenharmony_ci 414fa7767c5Sopenharmony_ci static void* GetPtr(Storage& storage) noexcept 415fa7767c5Sopenharmony_ci { 416fa7767c5Sopenharmony_ci return reinterpret_cast<void*>(&storage.nonTrivialStack_); 417fa7767c5Sopenharmony_ci } 418fa7767c5Sopenharmony_ci }; 419fa7767c5Sopenharmony_ci 420fa7767c5Sopenharmony_ci template <typename T> 421fa7767c5Sopenharmony_ci struct HeapFunctionTable { 422fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 423fa7767c5Sopenharmony_ci static const std::type_info& Type() noexcept 424fa7767c5Sopenharmony_ci { 425fa7767c5Sopenharmony_ci return typeid(T); 426fa7767c5Sopenharmony_ci } 427fa7767c5Sopenharmony_ci#else 428fa7767c5Sopenharmony_ci static std::string_view TypeName() noexcept 429fa7767c5Sopenharmony_ci { 430fa7767c5Sopenharmony_ci return GetTypeName<T>(); 431fa7767c5Sopenharmony_ci } 432fa7767c5Sopenharmony_ci#endif 433fa7767c5Sopenharmony_ci 434fa7767c5Sopenharmony_ci static void Destroy(Storage& storage) noexcept 435fa7767c5Sopenharmony_ci { 436fa7767c5Sopenharmony_ci delete reinterpret_cast<T*>(storage.heap_); // NOLINT: cast 437fa7767c5Sopenharmony_ci storage.heap_ = nullptr; 438fa7767c5Sopenharmony_ci } 439fa7767c5Sopenharmony_ci static void Copy(Storage& dest, const Storage& source) noexcept 440fa7767c5Sopenharmony_ci { 441fa7767c5Sopenharmony_ci dest.heap_ = new T(*reinterpret_cast<T*>(source.heap_)); // NOLINT: cast 442fa7767c5Sopenharmony_ci } 443fa7767c5Sopenharmony_ci static void Move(Storage& dest, Storage& source) noexcept 444fa7767c5Sopenharmony_ci { 445fa7767c5Sopenharmony_ci dest.heap_ = source.heap_; 446fa7767c5Sopenharmony_ci source.heap_ = nullptr; 447fa7767c5Sopenharmony_ci } 448fa7767c5Sopenharmony_ci static const void* GetConstPtr(const Storage& storage) noexcept 449fa7767c5Sopenharmony_ci { 450fa7767c5Sopenharmony_ci return storage.heap_; 451fa7767c5Sopenharmony_ci } 452fa7767c5Sopenharmony_ci static void* GetPtr(Storage& storage) noexcept 453fa7767c5Sopenharmony_ci { 454fa7767c5Sopenharmony_ci return storage.heap_; 455fa7767c5Sopenharmony_ci } 456fa7767c5Sopenharmony_ci }; 457fa7767c5Sopenharmony_ci 458fa7767c5Sopenharmony_ci template <typename ValueType> 459fa7767c5Sopenharmony_ci static FunctionTable* GetFunctionTable() 460fa7767c5Sopenharmony_ci { 461fa7767c5Sopenharmony_ci using DecayedValueType = decay_t<ValueType>; 462fa7767c5Sopenharmony_ci using DetailFunctionTable = 463fa7767c5Sopenharmony_ci conditional_t<IsTrivialStackStorable<DecayedValueType>::value, 464fa7767c5Sopenharmony_ci TrivialStackFunctionTable<DecayedValueType>, 465fa7767c5Sopenharmony_ci conditional_t<IsStackStorable<DecayedValueType>::value, 466fa7767c5Sopenharmony_ci StackFunctionTable<DecayedValueType>, HeapFunctionTable<DecayedValueType>>>; 467fa7767c5Sopenharmony_ci static FunctionTable table = { 468fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 469fa7767c5Sopenharmony_ci .type = DetailFunctionTable::Type, 470fa7767c5Sopenharmony_ci#else 471fa7767c5Sopenharmony_ci .type_name = DetailFunctionTable::TypeName, 472fa7767c5Sopenharmony_ci#endif 473fa7767c5Sopenharmony_ci .destroy = DetailFunctionTable::Destroy, 474fa7767c5Sopenharmony_ci .copy = DetailFunctionTable::Copy, 475fa7767c5Sopenharmony_ci .move = DetailFunctionTable::Move, 476fa7767c5Sopenharmony_ci .getPtr = DetailFunctionTable::GetPtr, 477fa7767c5Sopenharmony_ci .getConstPtr = DetailFunctionTable::GetConstPtr, 478fa7767c5Sopenharmony_ci }; 479fa7767c5Sopenharmony_ci return &table; 480fa7767c5Sopenharmony_ci } 481fa7767c5Sopenharmony_ci 482fa7767c5Sopenharmony_ci bool IsFunctionTableValid() const noexcept 483fa7767c5Sopenharmony_ci { 484fa7767c5Sopenharmony_ci return functionTable_ != nullptr; 485fa7767c5Sopenharmony_ci } 486fa7767c5Sopenharmony_ci 487fa7767c5Sopenharmony_ci template <typename DecayedValueType, typename... Args> 488fa7767c5Sopenharmony_ci DecayedValueType& DoEmplace(Args&&... args) 489fa7767c5Sopenharmony_ci { 490fa7767c5Sopenharmony_ci functionTable_ = GetFunctionTable<DecayedValueType>(); 491fa7767c5Sopenharmony_ci DecayedValueType* ptr = nullptr; 492fa7767c5Sopenharmony_ci if (IsTrivialStackStorable<DecayedValueType>::value || IsStackStorable<DecayedValueType>::value) { 493fa7767c5Sopenharmony_ci ptr = reinterpret_cast<DecayedValueType*>(functionTable_->getPtr(storage_)); 494fa7767c5Sopenharmony_ci new (ptr) DecayedValueType(std::forward<Args>(args)...); 495fa7767c5Sopenharmony_ci } else { 496fa7767c5Sopenharmony_ci storage_.heap_ = new DecayedValueType(std::forward<Args>(args)...); 497fa7767c5Sopenharmony_ci ptr = reinterpret_cast<DecayedValueType*>(storage_.heap_); 498fa7767c5Sopenharmony_ci } 499fa7767c5Sopenharmony_ci return *ptr; 500fa7767c5Sopenharmony_ci } 501fa7767c5Sopenharmony_ci 502fa7767c5Sopenharmony_ci void MoveFrom(Any&& other) noexcept 503fa7767c5Sopenharmony_ci { 504fa7767c5Sopenharmony_ci if (other.HasValue()) { 505fa7767c5Sopenharmony_ci functionTable_ = other.functionTable_; 506fa7767c5Sopenharmony_ci functionTable_->move(storage_, other.storage_); 507fa7767c5Sopenharmony_ci other.Reset(); 508fa7767c5Sopenharmony_ci } 509fa7767c5Sopenharmony_ci } 510fa7767c5Sopenharmony_ci 511fa7767c5Sopenharmony_ci template <typename ValueType> 512fa7767c5Sopenharmony_ci ValueType* Cast() noexcept 513fa7767c5Sopenharmony_ci { 514fa7767c5Sopenharmony_ci using DecayedValueType = decay_t<ValueType>; 515fa7767c5Sopenharmony_ci if (!IsFunctionTableValid()) { 516fa7767c5Sopenharmony_ci return nullptr; 517fa7767c5Sopenharmony_ci } 518fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 519fa7767c5Sopenharmony_ci if (!SameTypeWith(typeid(DecayedValueType))) { 520fa7767c5Sopenharmony_ci#else 521fa7767c5Sopenharmony_ci if (!SameTypeWith(Any::GetTypeName<DecayedValueType>())) { 522fa7767c5Sopenharmony_ci#endif 523fa7767c5Sopenharmony_ci return nullptr; 524fa7767c5Sopenharmony_ci } 525fa7767c5Sopenharmony_ci return IsTrivialStackStorable<DecayedValueType>::value 526fa7767c5Sopenharmony_ci ? reinterpret_cast<DecayedValueType*>(storage_.trivialStack_.data()) 527fa7767c5Sopenharmony_ci : (IsStackStorable<DecayedValueType>::value 528fa7767c5Sopenharmony_ci ? reinterpret_cast<DecayedValueType*>(&storage_.nonTrivialStack_) 529fa7767c5Sopenharmony_ci : reinterpret_cast<DecayedValueType*>(storage_.heap_)); 530fa7767c5Sopenharmony_ci } 531fa7767c5Sopenharmony_ci template <typename ValueType> 532fa7767c5Sopenharmony_ci const ValueType* Cast() const noexcept 533fa7767c5Sopenharmony_ci { 534fa7767c5Sopenharmony_ci using DecayedValueType = decay_t<ValueType>; 535fa7767c5Sopenharmony_ci if (!IsFunctionTableValid()) { 536fa7767c5Sopenharmony_ci return nullptr; 537fa7767c5Sopenharmony_ci } 538fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 539fa7767c5Sopenharmony_ci if (!SameTypeWith(typeid(DecayedValueType))) { 540fa7767c5Sopenharmony_ci#else 541fa7767c5Sopenharmony_ci if (!SameTypeWith(Any::GetTypeName<DecayedValueType>())) { 542fa7767c5Sopenharmony_ci#endif 543fa7767c5Sopenharmony_ci return nullptr; 544fa7767c5Sopenharmony_ci } 545fa7767c5Sopenharmony_ci return IsTrivialStackStorable<DecayedValueType>::value 546fa7767c5Sopenharmony_ci ? reinterpret_cast<const DecayedValueType*>(storage_.trivialStack_.data()) 547fa7767c5Sopenharmony_ci : (IsStackStorable<DecayedValueType>::value 548fa7767c5Sopenharmony_ci ? reinterpret_cast<const DecayedValueType*>(&storage_.nonTrivialStack_) 549fa7767c5Sopenharmony_ci : reinterpret_cast<const DecayedValueType*>(storage_.heap_)); 550fa7767c5Sopenharmony_ci } 551fa7767c5Sopenharmony_ci 552fa7767c5Sopenharmony_ciprivate: 553fa7767c5Sopenharmony_ci Storage storage_ {}; 554fa7767c5Sopenharmony_ci FunctionTable* functionTable_ {nullptr}; 555fa7767c5Sopenharmony_ci}; 556fa7767c5Sopenharmony_ci 557fa7767c5Sopenharmony_ci/** 558fa7767c5Sopenharmony_ci * cast one Any pointer into ValueType pointer 559fa7767c5Sopenharmony_ci * 560fa7767c5Sopenharmony_ci * @tparam ValueType target value type 561fa7767c5Sopenharmony_ci * @param operand any object 562fa7767c5Sopenharmony_ci * @return nullptr if type mismatch, operand is nullptr, or valueType is function/array. Otherwise, a pointer to the 563fa7767c5Sopenharmony_ci * const value contained by operand. 564fa7767c5Sopenharmony_ci */ 565fa7767c5Sopenharmony_citemplate <typename ValueType> 566fa7767c5Sopenharmony_ciconst ValueType* AnyCast(const Any* operand) noexcept 567fa7767c5Sopenharmony_ci{ 568fa7767c5Sopenharmony_ci static_assert(!std::is_void<ValueType>::value, "ValueType of any_cast must not be void"); 569fa7767c5Sopenharmony_ci if (std::is_function<ValueType>::value || std::is_array<ValueType>::value || operand == nullptr) { 570fa7767c5Sopenharmony_ci return nullptr; 571fa7767c5Sopenharmony_ci } 572fa7767c5Sopenharmony_ci return operand->Cast<ValueType>(); 573fa7767c5Sopenharmony_ci} 574fa7767c5Sopenharmony_ci 575fa7767c5Sopenharmony_ci /** 576fa7767c5Sopenharmony_ci * cast one Any pointer into ValueType object 577fa7767c5Sopenharmony_ci * 578fa7767c5Sopenharmony_ci * @tparam ValueType target value type 579fa7767c5Sopenharmony_ci * @param operand any object 580fa7767c5Sopenharmony_ci * @param value ValueType 581fa7767c5Sopenharmony_ci * @return false if type mismatch, operand is nullptr, or valueType is function/array. Otherwise, true to the 582fa7767c5Sopenharmony_ci * value contained by operand. 583fa7767c5Sopenharmony_ci */ 584fa7767c5Sopenharmony_citemplate <typename ValueType> 585fa7767c5Sopenharmony_cibool AnyCast(const Any* operand, ValueType& value) noexcept 586fa7767c5Sopenharmony_ci{ 587fa7767c5Sopenharmony_ci static_assert(!std::is_void<ValueType>::value, "ValueType of any_cast must not be void"); 588fa7767c5Sopenharmony_ci if (std::is_function<ValueType>::value || std::is_array<ValueType>::value || operand == nullptr) { 589fa7767c5Sopenharmony_ci return false; 590fa7767c5Sopenharmony_ci } 591fa7767c5Sopenharmony_ci#ifndef HST_ANY_WITH_NO_RTTI 592fa7767c5Sopenharmony_ci if (!operand->SameTypeWith(typeid(ValueType))) { 593fa7767c5Sopenharmony_ci#else 594fa7767c5Sopenharmony_ci if (!operand->SameTypeWith(Any::GetTypeName<ValueType>())) { 595fa7767c5Sopenharmony_ci#endif 596fa7767c5Sopenharmony_ci return false; 597fa7767c5Sopenharmony_ci } else { 598fa7767c5Sopenharmony_ci auto casted_value = operand->Cast<ValueType>(); 599fa7767c5Sopenharmony_ci if (casted_value != nullptr) { 600fa7767c5Sopenharmony_ci value = *casted_value; 601fa7767c5Sopenharmony_ci return true; 602fa7767c5Sopenharmony_ci } 603fa7767c5Sopenharmony_ci return false; 604fa7767c5Sopenharmony_ci } 605fa7767c5Sopenharmony_ci} 606fa7767c5Sopenharmony_ci 607fa7767c5Sopenharmony_ci/** 608fa7767c5Sopenharmony_ci * cast one Any pointer into ValueType pointer 609fa7767c5Sopenharmony_ci * 610fa7767c5Sopenharmony_ci * @tparam ValueType target value type 611fa7767c5Sopenharmony_ci * @param operand any object 612fa7767c5Sopenharmony_ci * @return nullptr if type mismatch, operand is nullptr, or valueType is function/array. Otherwise, a pointer to the 613fa7767c5Sopenharmony_ci * value contained by operand. 614fa7767c5Sopenharmony_ci */ 615fa7767c5Sopenharmony_citemplate <typename ValueType> 616fa7767c5Sopenharmony_ciValueType* AnyCast(Any* operand) noexcept 617fa7767c5Sopenharmony_ci{ 618fa7767c5Sopenharmony_ci static_assert(!std::is_void<ValueType>::value, "ValueType of any_cast must not be void"); 619fa7767c5Sopenharmony_ci if (std::is_function<ValueType>::value || std::is_array<ValueType>::value || operand == nullptr) { 620fa7767c5Sopenharmony_ci return nullptr; 621fa7767c5Sopenharmony_ci } 622fa7767c5Sopenharmony_ci return operand->Cast<ValueType>(); 623fa7767c5Sopenharmony_ci} 624fa7767c5Sopenharmony_ci 625fa7767c5Sopenharmony_ci/** 626fa7767c5Sopenharmony_ci * cast one Any object into ValueType object 627fa7767c5Sopenharmony_ci * 628fa7767c5Sopenharmony_ci * @tparam ValueType target value type. It must match both conditions: 629fa7767c5Sopenharmony_ci * 1. ValueType must be reference or constructible 630fa7767c5Sopenharmony_ci * 2. Let U be remove_cv_t<remove_reference_t<ValueType>>, then std::is_constructible<ValueType, const U&> must be true 631fa7767c5Sopenharmony_ci * @param operand any object 632fa7767c5Sopenharmony_ci * @return throws BadAnyCast exception if type mismatch, operand is nullptr, or valueType is function/array. Otherwise, 633fa7767c5Sopenharmony_ci * one object of ValueType contained in Any. 634fa7767c5Sopenharmony_ci */ 635fa7767c5Sopenharmony_citemplate <typename ValueType> 636fa7767c5Sopenharmony_ciValueType AnyCast(const Any& other) 637fa7767c5Sopenharmony_ci{ 638fa7767c5Sopenharmony_ci using U = remove_cv_t<remove_reference_t<ValueType>>; 639fa7767c5Sopenharmony_ci static_assert(IsValidCast<ValueType>::value, "template argument must be a reference or has copy constructors"); 640fa7767c5Sopenharmony_ci static_assert(std::is_constructible<ValueType, const U&>::value, 641fa7767c5Sopenharmony_ci "any_cast<ValueType>(const any&) requires ValueType constructable from const " 642fa7767c5Sopenharmony_ci "remove_cv_t<remove_reference_t<ValueType>>&"); 643fa7767c5Sopenharmony_ci auto ptr = AnyCast<U>(&other); 644fa7767c5Sopenharmony_ci if (ptr == nullptr) { 645fa7767c5Sopenharmony_ci throw BadAnyCast(); 646fa7767c5Sopenharmony_ci } 647fa7767c5Sopenharmony_ci return static_cast<ValueType>(*ptr); 648fa7767c5Sopenharmony_ci} 649fa7767c5Sopenharmony_ci 650fa7767c5Sopenharmony_ci/** 651fa7767c5Sopenharmony_ci * cast one Any object into ValueType object 652fa7767c5Sopenharmony_ci * 653fa7767c5Sopenharmony_ci * @tparam ValueType target value type. It must match both conditions: 654fa7767c5Sopenharmony_ci * 1. ValueType must be reference or constructible 655fa7767c5Sopenharmony_ci * 2. Let U be remove_cv_t<remove_reference_t<ValueType>>, then std::is_constructible<ValueType, U&> must be true 656fa7767c5Sopenharmony_ci * @param operand any object 657fa7767c5Sopenharmony_ci * @return throws BadAnyCast exception if type mismatch, operand is nullptr, or valueType is function/array. Otherwise, 658fa7767c5Sopenharmony_ci * one object of ValueType contained in Any. 659fa7767c5Sopenharmony_ci */ 660fa7767c5Sopenharmony_citemplate <typename ValueType> 661fa7767c5Sopenharmony_ciValueType AnyCast(Any& other) 662fa7767c5Sopenharmony_ci{ 663fa7767c5Sopenharmony_ci using U = remove_cv_t<remove_reference_t<ValueType>>; 664fa7767c5Sopenharmony_ci static_assert(IsValidCast<ValueType>::value, "template argument must be a reference or has copy constructors"); 665fa7767c5Sopenharmony_ci static_assert(std::is_constructible<ValueType, U&>::value, 666fa7767c5Sopenharmony_ci "any_cast<ValueType>(const any&) requires ValueType constructable from " 667fa7767c5Sopenharmony_ci "remove_cv_t<remove_reference_t<ValueType>>&"); 668fa7767c5Sopenharmony_ci auto ptr = AnyCast<U>(&other); 669fa7767c5Sopenharmony_ci if (ptr == nullptr) { 670fa7767c5Sopenharmony_ci throw BadAnyCast(); 671fa7767c5Sopenharmony_ci } 672fa7767c5Sopenharmony_ci return static_cast<ValueType>(*ptr); 673fa7767c5Sopenharmony_ci} 674fa7767c5Sopenharmony_ci 675fa7767c5Sopenharmony_ci/** 676fa7767c5Sopenharmony_ci * cast one Any object into ValueType object 677fa7767c5Sopenharmony_ci * 678fa7767c5Sopenharmony_ci * @tparam ValueType target value type. It must match both conditions: 679fa7767c5Sopenharmony_ci * 1. ValueType must be reference or constructible 680fa7767c5Sopenharmony_ci * 2. Let U be remove_cv_t<remove_reference_t<ValueType>>, then std::is_constructible<ValueType, U> must be true 681fa7767c5Sopenharmony_ci * @param operand any object 682fa7767c5Sopenharmony_ci * @return throws BadAnyCast exception if type mismatch, operand is nullptr, or valueType is function/array. Otherwise, 683fa7767c5Sopenharmony_ci * one object of ValueType contained in Any. 684fa7767c5Sopenharmony_ci */ 685fa7767c5Sopenharmony_citemplate <typename ValueType> 686fa7767c5Sopenharmony_ciValueType AnyCast(Any&& other) 687fa7767c5Sopenharmony_ci{ 688fa7767c5Sopenharmony_ci using U = remove_cv_t<remove_reference_t<ValueType>>; 689fa7767c5Sopenharmony_ci static_assert(IsValidCast<ValueType>::value, "template argument must be a reference or has copy constructors"); 690fa7767c5Sopenharmony_ci static_assert(std::is_constructible<ValueType, U>::value, 691fa7767c5Sopenharmony_ci "any_cast<ValueType>(const any&) requires ValueType constructable from " 692fa7767c5Sopenharmony_ci "remove_cv_t<remove_reference_t<ValueType>>"); 693fa7767c5Sopenharmony_ci auto ptr = AnyCast<U>(&other); 694fa7767c5Sopenharmony_ci if (ptr == nullptr) { 695fa7767c5Sopenharmony_ci throw BadAnyCast(); 696fa7767c5Sopenharmony_ci } 697fa7767c5Sopenharmony_ci return static_cast<ValueType>(std::move(*ptr)); 698fa7767c5Sopenharmony_ci} 699fa7767c5Sopenharmony_ci 700fa7767c5Sopenharmony_ci/** 701fa7767c5Sopenharmony_ci * Constructs Any object, whose content is constructed by args. The content type is T. 702fa7767c5Sopenharmony_ci * 703fa7767c5Sopenharmony_ci * @tparam T type of Any's content 704fa7767c5Sopenharmony_ci * @tparam Args type of args 705fa7767c5Sopenharmony_ci * @param args args used to construct the content 706fa7767c5Sopenharmony_ci * @return Any object 707fa7767c5Sopenharmony_ci */ 708fa7767c5Sopenharmony_citemplate <typename T, typename... Args> 709fa7767c5Sopenharmony_ciAny MakeAny(Args&&... args) 710fa7767c5Sopenharmony_ci{ 711fa7767c5Sopenharmony_ci Any tmp; 712fa7767c5Sopenharmony_ci tmp.Emplace<T, Args...>(std::forward<Args>(args)...); 713fa7767c5Sopenharmony_ci return tmp; 714fa7767c5Sopenharmony_ci} 715fa7767c5Sopenharmony_ci 716fa7767c5Sopenharmony_ci/** 717fa7767c5Sopenharmony_ci * Constructs Any object, whose content is constructed by il and args. The content type is T. 718fa7767c5Sopenharmony_ci * 719fa7767c5Sopenharmony_ci * @tparam T type of Any's content 720fa7767c5Sopenharmony_ci * @tparam U type of initializer list 721fa7767c5Sopenharmony_ci * @tparam Args type of args 722fa7767c5Sopenharmony_ci * @param il initializer list 723fa7767c5Sopenharmony_ci * @param args args 724fa7767c5Sopenharmony_ci * @return Any object 725fa7767c5Sopenharmony_ci */ 726fa7767c5Sopenharmony_citemplate <typename T, typename U, typename... Args> 727fa7767c5Sopenharmony_ciAny MakeAny(std::initializer_list<U> il, Args&&... args) 728fa7767c5Sopenharmony_ci{ 729fa7767c5Sopenharmony_ci Any tmp; 730fa7767c5Sopenharmony_ci tmp.Emplace<T, U, Args...>(il, std::forward<Args>(args)...); 731fa7767c5Sopenharmony_ci return tmp; 732fa7767c5Sopenharmony_ci} 733fa7767c5Sopenharmony_ci} // namespace Plugin 734fa7767c5Sopenharmony_ci} // namespace Media 735fa7767c5Sopenharmony_ci} // namespace OHOS 736fa7767c5Sopenharmony_ci#endif 737fa7767c5Sopenharmony_cinamespace std { 738fa7767c5Sopenharmony_ciinline void swap(OHOS::Media::Plugin::Any& lhs, OHOS::Media::Plugin::Any& rhs) noexcept 739fa7767c5Sopenharmony_ci{ 740fa7767c5Sopenharmony_ci lhs.Swap(rhs); 741fa7767c5Sopenharmony_ci} 742fa7767c5Sopenharmony_ci} // namespace std 743fa7767c5Sopenharmony_ci#endif // HISTREAMER_PLUGIN_COMMON_ANY_H 744