File indexing completed on 2026-05-10 08:43:01
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef LLVM_ADT_ANY_H
0017 #define LLVM_ADT_ANY_H
0018
0019 #include "llvm/ADT/STLForwardCompat.h"
0020 #include "llvm/Support/Compiler.h"
0021
0022 #include <cassert>
0023 #include <memory>
0024 #include <type_traits>
0025
0026 namespace llvm {
0027
0028 class LLVM_ABI Any {
0029
0030
0031
0032
0033
0034
0035
0036 template <typename T> struct TypeId { static char Id; };
0037
0038 struct StorageBase {
0039 virtual ~StorageBase() = default;
0040 virtual std::unique_ptr<StorageBase> clone() const = 0;
0041 virtual const void *id() const = 0;
0042 };
0043
0044 template <typename T> struct StorageImpl : public StorageBase {
0045 explicit StorageImpl(const T &Value) : Value(Value) {}
0046
0047 explicit StorageImpl(T &&Value) : Value(std::move(Value)) {}
0048
0049 std::unique_ptr<StorageBase> clone() const override {
0050 return std::make_unique<StorageImpl<T>>(Value);
0051 }
0052
0053 const void *id() const override { return &TypeId<T>::Id; }
0054
0055 T Value;
0056
0057 private:
0058 StorageImpl &operator=(const StorageImpl &Other) = delete;
0059 StorageImpl(const StorageImpl &Other) = delete;
0060 };
0061
0062 public:
0063 Any() = default;
0064
0065 Any(const Any &Other)
0066 : Storage(Other.Storage ? Other.Storage->clone() : nullptr) {}
0067
0068
0069
0070
0071 template <typename T,
0072 std::enable_if_t<
0073 std::conjunction<
0074 std::negation<std::is_same<std::decay_t<T>, Any>>,
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085 std::negation<std::is_convertible<Any, std::decay_t<T>>>,
0086 std::is_copy_constructible<std::decay_t<T>>>::value,
0087 int> = 0>
0088 Any(T &&Value) {
0089 Storage =
0090 std::make_unique<StorageImpl<std::decay_t<T>>>(std::forward<T>(Value));
0091 }
0092
0093 Any(Any &&Other) : Storage(std::move(Other.Storage)) {}
0094
0095 Any &swap(Any &Other) {
0096 std::swap(Storage, Other.Storage);
0097 return *this;
0098 }
0099
0100 Any &operator=(Any Other) {
0101 Storage = std::move(Other.Storage);
0102 return *this;
0103 }
0104
0105 bool has_value() const { return !!Storage; }
0106
0107 void reset() { Storage.reset(); }
0108
0109 private:
0110
0111 template <typename T> bool isa() const {
0112 if (!Storage)
0113 return false;
0114 return Storage->id() == &Any::TypeId<remove_cvref_t<T>>::Id;
0115 }
0116
0117 template <class T> friend T any_cast(const Any &Value);
0118 template <class T> friend T any_cast(Any &Value);
0119 template <class T> friend T any_cast(Any &&Value);
0120 template <class T> friend const T *any_cast(const Any *Value);
0121 template <class T> friend T *any_cast(Any *Value);
0122 template <typename T> friend bool any_isa(const Any &Value);
0123
0124 std::unique_ptr<StorageBase> Storage;
0125 };
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136 template <typename T> char Any::TypeId<T>::Id = 1;
0137
0138 template <class T> T any_cast(const Any &Value) {
0139 assert(Value.isa<T>() && "Bad any cast!");
0140 return static_cast<T>(*any_cast<remove_cvref_t<T>>(&Value));
0141 }
0142
0143 template <class T> T any_cast(Any &Value) {
0144 assert(Value.isa<T>() && "Bad any cast!");
0145 return static_cast<T>(*any_cast<remove_cvref_t<T>>(&Value));
0146 }
0147
0148 template <class T> T any_cast(Any &&Value) {
0149 assert(Value.isa<T>() && "Bad any cast!");
0150 return static_cast<T>(std::move(*any_cast<remove_cvref_t<T>>(&Value)));
0151 }
0152
0153 template <class T> const T *any_cast(const Any *Value) {
0154 using U = remove_cvref_t<T>;
0155 if (!Value || !Value->isa<U>())
0156 return nullptr;
0157 return &static_cast<Any::StorageImpl<U> &>(*Value->Storage).Value;
0158 }
0159
0160 template <class T> T *any_cast(Any *Value) {
0161 using U = std::decay_t<T>;
0162 if (!Value || !Value->isa<U>())
0163 return nullptr;
0164 return &static_cast<Any::StorageImpl<U> &>(*Value->Storage).Value;
0165 }
0166
0167 }
0168
0169 #endif