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