File indexing completed on 2025-12-16 09:41:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053 #ifndef ABSL_TYPES_ANY_H_
0054 #define ABSL_TYPES_ANY_H_
0055
0056 #include "absl/base/attributes.h"
0057 #include "absl/base/config.h"
0058 #include "absl/utility/utility.h"
0059
0060 #ifdef ABSL_USES_STD_ANY
0061
0062 #include <any> // IWYU pragma: export
0063
0064 namespace absl {
0065 ABSL_NAMESPACE_BEGIN
0066 using std::any;
0067 using std::any_cast;
0068 using std::bad_any_cast;
0069 using std::make_any;
0070 ABSL_NAMESPACE_END
0071 }
0072
0073 #else
0074
0075 #include <algorithm>
0076 #include <cstddef>
0077 #include <initializer_list>
0078 #include <memory>
0079 #include <stdexcept>
0080 #include <type_traits>
0081 #include <typeinfo>
0082 #include <utility>
0083
0084 #include "absl/base/internal/fast_type_id.h"
0085 #include "absl/meta/type_traits.h"
0086 #include "absl/types/bad_any_cast.h"
0087
0088 namespace absl {
0089 ABSL_NAMESPACE_BEGIN
0090
0091 class any;
0092
0093
0094
0095
0096
0097 void swap(any& x, any& y) noexcept;
0098
0099
0100
0101
0102 template <typename T, typename... Args>
0103 any make_any(Args&&... args);
0104
0105
0106
0107 template <typename T, typename U, typename... Args>
0108 any make_any(std::initializer_list<U> il, Args&&... args);
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123 template <typename ValueType>
0124 ValueType any_cast(const any& operand);
0125
0126
0127
0128
0129
0130 template <typename ValueType>
0131 ValueType any_cast(any& operand);
0132
0133
0134
0135
0136 template <typename ValueType>
0137 ValueType any_cast(any&& operand);
0138
0139
0140
0141
0142 template <typename ValueType>
0143 const ValueType* any_cast(const any* operand) noexcept;
0144
0145
0146
0147
0148 template <typename ValueType>
0149 ValueType* any_cast(any* operand) noexcept;
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190 class any {
0191 private:
0192 template <typename T>
0193 struct IsInPlaceType;
0194
0195 public:
0196
0197
0198
0199
0200 constexpr any() noexcept;
0201
0202
0203
0204
0205 any(const any& other)
0206 : obj_(other.has_value() ? other.obj_->Clone()
0207 : std::unique_ptr<ObjInterface>()) {}
0208
0209
0210
0211
0212 any(any&& other) noexcept = default;
0213
0214
0215
0216
0217
0218
0219 template <
0220 typename T, typename VT = absl::decay_t<T>,
0221 absl::enable_if_t<!absl::disjunction<
0222 std::is_same<any, VT>, IsInPlaceType<VT>,
0223 absl::negation<std::is_copy_constructible<VT> > >::value>* = nullptr>
0224 any(T&& value) : obj_(new Obj<VT>(in_place, std::forward<T>(value))) {}
0225
0226
0227
0228 template <typename T, typename... Args, typename VT = absl::decay_t<T>,
0229 absl::enable_if_t<absl::conjunction<
0230 std::is_copy_constructible<VT>,
0231 std::is_constructible<VT, Args...>>::value>* = nullptr>
0232 explicit any(in_place_type_t<T> , Args&&... args)
0233 : obj_(new Obj<VT>(in_place, std::forward<Args>(args)...)) {}
0234
0235
0236
0237
0238
0239 template <
0240 typename T, typename U, typename... Args, typename VT = absl::decay_t<T>,
0241 absl::enable_if_t<
0242 absl::conjunction<std::is_copy_constructible<VT>,
0243 std::is_constructible<VT, std::initializer_list<U>&,
0244 Args...>>::value>* = nullptr>
0245 explicit any(in_place_type_t<T> , std::initializer_list<U> ilist,
0246 Args&&... args)
0247 : obj_(new Obj<VT>(in_place, ilist, std::forward<Args>(args)...)) {}
0248
0249
0250
0251
0252
0253 any& operator=(const any& rhs) {
0254 any(rhs).swap(*this);
0255 return *this;
0256 }
0257
0258
0259
0260 any& operator=(any&& rhs) noexcept {
0261 any(std::move(rhs)).swap(*this);
0262 return *this;
0263 }
0264
0265
0266 template <typename T, typename VT = absl::decay_t<T>,
0267 absl::enable_if_t<absl::conjunction<
0268 absl::negation<std::is_same<VT, any>>,
0269 std::is_copy_constructible<VT>>::value>* = nullptr>
0270 any& operator=(T&& rhs) {
0271 any tmp(in_place_type_t<VT>(), std::forward<T>(rhs));
0272 tmp.swap(*this);
0273 return *this;
0274 }
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288 template <
0289 typename T, typename... Args, typename VT = absl::decay_t<T>,
0290 absl::enable_if_t<std::is_copy_constructible<VT>::value &&
0291 std::is_constructible<VT, Args...>::value>* = nullptr>
0292 VT& emplace(Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
0293 reset();
0294 Obj<VT>* const object_ptr =
0295 new Obj<VT>(in_place, std::forward<Args>(args)...);
0296 obj_ = std::unique_ptr<ObjInterface>(object_ptr);
0297 return object_ptr->value;
0298 }
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311 template <
0312 typename T, typename U, typename... Args, typename VT = absl::decay_t<T>,
0313 absl::enable_if_t<std::is_copy_constructible<VT>::value &&
0314 std::is_constructible<VT, std::initializer_list<U>&,
0315 Args...>::value>* = nullptr>
0316 VT& emplace(std::initializer_list<U> ilist,
0317 Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
0318 reset();
0319 Obj<VT>* const object_ptr =
0320 new Obj<VT>(in_place, ilist, std::forward<Args>(args)...);
0321 obj_ = std::unique_ptr<ObjInterface>(object_ptr);
0322 return object_ptr->value;
0323 }
0324
0325
0326
0327
0328
0329 void reset() noexcept { obj_ = nullptr; }
0330
0331
0332
0333
0334 void swap(any& other) noexcept { obj_.swap(other.obj_); }
0335
0336
0337
0338
0339
0340
0341
0342 bool has_value() const noexcept { return obj_ != nullptr; }
0343
0344 #ifdef ABSL_INTERNAL_HAS_RTTI
0345
0346
0347 const std::type_info& type() const noexcept {
0348 if (has_value()) {
0349 return obj_->Type();
0350 }
0351
0352 return typeid(void);
0353 }
0354 #endif
0355
0356 private:
0357
0358 class ObjInterface {
0359 public:
0360 virtual ~ObjInterface() = default;
0361 virtual std::unique_ptr<ObjInterface> Clone() const = 0;
0362 virtual const void* ObjTypeId() const noexcept = 0;
0363 #ifdef ABSL_INTERNAL_HAS_RTTI
0364 virtual const std::type_info& Type() const noexcept = 0;
0365 #endif
0366 };
0367
0368
0369 template <typename T>
0370 class Obj : public ObjInterface {
0371 public:
0372 template <typename... Args>
0373 explicit Obj(in_place_t , Args&&... args)
0374 : value(std::forward<Args>(args)...) {}
0375
0376 std::unique_ptr<ObjInterface> Clone() const final {
0377 return std::unique_ptr<ObjInterface>(new Obj(in_place, value));
0378 }
0379
0380 const void* ObjTypeId() const noexcept final { return IdForType<T>(); }
0381
0382 #ifdef ABSL_INTERNAL_HAS_RTTI
0383 const std::type_info& Type() const noexcept final { return typeid(T); }
0384 #endif
0385
0386 T value;
0387 };
0388
0389 std::unique_ptr<ObjInterface> CloneObj() const {
0390 if (!obj_) return nullptr;
0391 return obj_->Clone();
0392 }
0393
0394 template <typename T>
0395 constexpr static const void* IdForType() {
0396
0397 using NormalizedType =
0398 typename std::remove_cv<typename std::remove_reference<T>::type>::type;
0399
0400 return base_internal::FastTypeId<NormalizedType>();
0401 }
0402
0403 const void* GetObjTypeId() const {
0404 return obj_ ? obj_->ObjTypeId() : base_internal::FastTypeId<void>();
0405 }
0406
0407
0408
0409
0410 template <typename ValueType>
0411 friend ValueType any_cast(const any& operand);
0412
0413
0414 template <typename ValueType>
0415 friend ValueType any_cast(any& operand);
0416
0417
0418 template <typename T>
0419 friend const T* any_cast(const any* operand) noexcept;
0420
0421
0422 template <typename T>
0423 friend T* any_cast(any* operand) noexcept;
0424
0425 std::unique_ptr<ObjInterface> obj_;
0426 };
0427
0428
0429
0430
0431
0432 constexpr any::any() noexcept = default;
0433
0434 template <typename T>
0435 struct any::IsInPlaceType : std::false_type {};
0436
0437 template <typename T>
0438 struct any::IsInPlaceType<in_place_type_t<T>> : std::true_type {};
0439
0440 inline void swap(any& x, any& y) noexcept { x.swap(y); }
0441
0442
0443 template <typename T, typename... Args>
0444 any make_any(Args&&... args) {
0445 return any(in_place_type_t<T>(), std::forward<Args>(args)...);
0446 }
0447
0448
0449 template <typename T, typename U, typename... Args>
0450 any make_any(std::initializer_list<U> il, Args&&... args) {
0451 return any(in_place_type_t<T>(), il, std::forward<Args>(args)...);
0452 }
0453
0454
0455 template <typename ValueType>
0456 ValueType any_cast(const any& operand) {
0457 using U = typename std::remove_cv<
0458 typename std::remove_reference<ValueType>::type>::type;
0459 static_assert(std::is_constructible<ValueType, const U&>::value,
0460 "Invalid ValueType");
0461 auto* const result = (any_cast<U>)(&operand);
0462 if (result == nullptr) {
0463 any_internal::ThrowBadAnyCast();
0464 }
0465 return static_cast<ValueType>(*result);
0466 }
0467
0468
0469 template <typename ValueType>
0470 ValueType any_cast(any& operand) {
0471 using U = typename std::remove_cv<
0472 typename std::remove_reference<ValueType>::type>::type;
0473 static_assert(std::is_constructible<ValueType, U&>::value,
0474 "Invalid ValueType");
0475 auto* result = (any_cast<U>)(&operand);
0476 if (result == nullptr) {
0477 any_internal::ThrowBadAnyCast();
0478 }
0479 return static_cast<ValueType>(*result);
0480 }
0481
0482
0483 template <typename ValueType>
0484 ValueType any_cast(any&& operand) {
0485 using U = typename std::remove_cv<
0486 typename std::remove_reference<ValueType>::type>::type;
0487 static_assert(std::is_constructible<ValueType, U>::value,
0488 "Invalid ValueType");
0489 return static_cast<ValueType>(std::move((any_cast<U&>)(operand)));
0490 }
0491
0492
0493 template <typename T>
0494 const T* any_cast(const any* operand) noexcept {
0495 using U =
0496 typename std::remove_cv<typename std::remove_reference<T>::type>::type;
0497 return operand && operand->GetObjTypeId() == any::IdForType<U>()
0498 ? std::addressof(
0499 static_cast<const any::Obj<U>*>(operand->obj_.get())->value)
0500 : nullptr;
0501 }
0502
0503
0504 template <typename T>
0505 T* any_cast(any* operand) noexcept {
0506 using U =
0507 typename std::remove_cv<typename std::remove_reference<T>::type>::type;
0508 return operand && operand->GetObjTypeId() == any::IdForType<U>()
0509 ? std::addressof(
0510 static_cast<any::Obj<U>*>(operand->obj_.get())->value)
0511 : nullptr;
0512 }
0513
0514 ABSL_NAMESPACE_END
0515 }
0516
0517 #endif
0518
0519 #endif