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