00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #ifndef ABSL_TYPES_ANY_H_
00054 #define ABSL_TYPES_ANY_H_
00055
00056 #include "absl/base/config.h"
00057 #include "absl/utility/utility.h"
00058
00059 #ifdef ABSL_HAVE_STD_ANY
00060
00061 #include <any>
00062
00063 namespace absl {
00064 using std::any;
00065 using std::any_cast;
00066 using std::bad_any_cast;
00067 using std::make_any;
00068 }
00069
00070 #else // ABSL_HAVE_STD_ANY
00071
00072 #include <algorithm>
00073 #include <cstddef>
00074 #include <initializer_list>
00075 #include <memory>
00076 #include <stdexcept>
00077 #include <type_traits>
00078 #include <typeinfo>
00079 #include <utility>
00080
00081 #include "absl/base/macros.h"
00082 #include "absl/meta/type_traits.h"
00083 #include "absl/types/bad_any_cast.h"
00084
00085
00086
00087 #ifdef ABSL_ANY_DETAIL_HAS_RTTI
00088 #error ABSL_ANY_DETAIL_HAS_RTTI cannot be directly set
00089 #elif !defined(__GNUC__) || defined(__GXX_RTTI)
00090 #define ABSL_ANY_DETAIL_HAS_RTTI 1
00091 #endif // !defined(__GNUC__) || defined(__GXX_RTTI)
00092
00093 namespace absl {
00094
00095 namespace any_internal {
00096
00097 template <typename Type>
00098 struct TypeTag {
00099 constexpr static char dummy_var = 0;
00100 };
00101
00102 template <typename Type>
00103 constexpr char TypeTag<Type>::dummy_var;
00104
00105
00106
00107
00108 template<typename Type>
00109 constexpr inline const void* FastTypeId() {
00110 return &TypeTag<Type>::dummy_var;
00111 }
00112
00113 }
00114
00115 class any;
00116
00117
00118
00119
00120
00121 void swap(any& x, any& y) noexcept;
00122
00123
00124
00125
00126 template <typename T, typename... Args>
00127 any make_any(Args&&... args);
00128
00129
00130
00131 template <typename T, typename U, typename... Args>
00132 any make_any(std::initializer_list<U> il, Args&&... args);
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 template <typename ValueType>
00148 ValueType any_cast(const any& operand);
00149
00150
00151
00152
00153
00154 template <typename ValueType>
00155 ValueType any_cast(any& operand);
00156
00157
00158
00159
00160 template <typename ValueType>
00161 ValueType any_cast(any&& operand);
00162
00163
00164
00165
00166 template <typename ValueType>
00167 const ValueType* any_cast(const any* operand) noexcept;
00168
00169
00170
00171
00172 template <typename ValueType>
00173 ValueType* any_cast(any* operand) noexcept;
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 class any {
00215 private:
00216 template <typename T>
00217 struct IsInPlaceType;
00218
00219 public:
00220
00221
00222
00223
00224 constexpr any() noexcept;
00225
00226
00227
00228
00229 any(const any& other)
00230 : obj_(other.has_value() ? other.obj_->Clone()
00231 : std::unique_ptr<ObjInterface>()) {}
00232
00233
00234
00235
00236 any(any&& other) noexcept = default;
00237
00238
00239
00240
00241
00242
00243 template <
00244 typename T, typename VT = absl::decay_t<T>,
00245 absl::enable_if_t<!absl::disjunction<
00246 std::is_same<any, VT>, IsInPlaceType<VT>,
00247 absl::negation<std::is_copy_constructible<VT> > >::value>* = nullptr>
00248 any(T&& value) : obj_(new Obj<VT>(in_place, std::forward<T>(value))) {}
00249
00250
00251
00252 template <typename T, typename... Args, typename VT = absl::decay_t<T>,
00253 absl::enable_if_t<absl::conjunction<
00254 std::is_copy_constructible<VT>,
00255 std::is_constructible<VT, Args...>>::value>* = nullptr>
00256 explicit any(in_place_type_t<T> , Args&&... args)
00257 : obj_(new Obj<VT>(in_place, std::forward<Args>(args)...)) {}
00258
00259
00260
00261
00262
00263 template <
00264 typename T, typename U, typename... Args, typename VT = absl::decay_t<T>,
00265 absl::enable_if_t<
00266 absl::conjunction<std::is_copy_constructible<VT>,
00267 std::is_constructible<VT, std::initializer_list<U>&,
00268 Args...>>::value>* = nullptr>
00269 explicit any(in_place_type_t<T> , std::initializer_list<U> ilist,
00270 Args&&... args)
00271 : obj_(new Obj<VT>(in_place, ilist, std::forward<Args>(args)...)) {}
00272
00273
00274
00275
00276
00277 any& operator=(const any& rhs) {
00278 any(rhs).swap(*this);
00279 return *this;
00280 }
00281
00282
00283
00284 any& operator=(any&& rhs) noexcept {
00285 any(std::move(rhs)).swap(*this);
00286 return *this;
00287 }
00288
00289
00290 template <typename T, typename VT = absl::decay_t<T>,
00291 absl::enable_if_t<absl::conjunction<
00292 absl::negation<std::is_same<VT, any>>,
00293 std::is_copy_constructible<VT>>::value>* = nullptr>
00294 any& operator=(T&& rhs) {
00295 any tmp(in_place_type_t<VT>(), std::forward<T>(rhs));
00296 tmp.swap(*this);
00297 return *this;
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 template <
00313 typename T, typename... Args, typename VT = absl::decay_t<T>,
00314 absl::enable_if_t<std::is_copy_constructible<VT>::value &&
00315 std::is_constructible<VT, Args...>::value>* = nullptr>
00316 VT& emplace(Args&&... args) {
00317 reset();
00318 Obj<VT>* const object_ptr =
00319 new Obj<VT>(in_place, std::forward<Args>(args)...);
00320 obj_ = std::unique_ptr<ObjInterface>(object_ptr);
00321 return object_ptr->value;
00322 }
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 template <
00336 typename T, typename U, typename... Args, typename VT = absl::decay_t<T>,
00337 absl::enable_if_t<std::is_copy_constructible<VT>::value &&
00338 std::is_constructible<VT, std::initializer_list<U>&,
00339 Args...>::value>* = nullptr>
00340 VT& emplace(std::initializer_list<U> ilist, Args&&... args) {
00341 reset();
00342 Obj<VT>* const object_ptr =
00343 new Obj<VT>(in_place, ilist, std::forward<Args>(args)...);
00344 obj_ = std::unique_ptr<ObjInterface>(object_ptr);
00345 return object_ptr->value;
00346 }
00347
00348
00349
00350
00351
00352 void reset() noexcept { obj_ = nullptr; }
00353
00354
00355
00356
00357 void swap(any& other) noexcept { obj_.swap(other.obj_); }
00358
00359
00360
00361
00362
00363
00364
00365 bool has_value() const noexcept { return obj_ != nullptr; }
00366
00367 #if ABSL_ANY_DETAIL_HAS_RTTI
00368
00369
00370 const std::type_info& type() const noexcept {
00371 if (has_value()) {
00372 return obj_->Type();
00373 }
00374
00375 return typeid(void);
00376 }
00377 #endif // ABSL_ANY_DETAIL_HAS_RTTI
00378
00379 private:
00380
00381 class ObjInterface {
00382 public:
00383 virtual ~ObjInterface() = default;
00384 virtual std::unique_ptr<ObjInterface> Clone() const = 0;
00385 virtual const void* ObjTypeId() const noexcept = 0;
00386 #if ABSL_ANY_DETAIL_HAS_RTTI
00387 virtual const std::type_info& Type() const noexcept = 0;
00388 #endif // ABSL_ANY_DETAIL_HAS_RTTI
00389 };
00390
00391
00392 template <typename T>
00393 class Obj : public ObjInterface {
00394 public:
00395 template <typename... Args>
00396 explicit Obj(in_place_t , Args&&... args)
00397 : value(std::forward<Args>(args)...) {}
00398
00399 std::unique_ptr<ObjInterface> Clone() const final {
00400 return std::unique_ptr<ObjInterface>(new Obj(in_place, value));
00401 }
00402
00403 const void* ObjTypeId() const noexcept final { return IdForType<T>(); }
00404
00405 #if ABSL_ANY_DETAIL_HAS_RTTI
00406 const std::type_info& Type() const noexcept final { return typeid(T); }
00407 #endif // ABSL_ANY_DETAIL_HAS_RTTI
00408
00409 T value;
00410 };
00411
00412 std::unique_ptr<ObjInterface> CloneObj() const {
00413 if (!obj_) return nullptr;
00414 return obj_->Clone();
00415 }
00416
00417 template <typename T>
00418 constexpr static const void* IdForType() {
00419
00420 using NormalizedType =
00421 typename std::remove_cv<typename std::remove_reference<T>::type>::type;
00422
00423 return any_internal::FastTypeId<NormalizedType>();
00424 }
00425
00426 const void* GetObjTypeId() const {
00427 return obj_ ? obj_->ObjTypeId() : any_internal::FastTypeId<void>();
00428 }
00429
00430
00431
00432
00433 template <typename ValueType>
00434 friend ValueType any_cast(const any& operand);
00435
00436
00437 template <typename ValueType>
00438 friend ValueType any_cast(any& operand);
00439
00440
00441 template <typename T>
00442 friend const T* any_cast(const any* operand) noexcept;
00443
00444
00445 template <typename T>
00446 friend T* any_cast(any* operand) noexcept;
00447
00448 std::unique_ptr<ObjInterface> obj_;
00449 };
00450
00451
00452
00453
00454
00455 constexpr any::any() noexcept = default;
00456
00457 template <typename T>
00458 struct any::IsInPlaceType : std::false_type {};
00459
00460 template <typename T>
00461 struct any::IsInPlaceType<in_place_type_t<T>> : std::true_type {};
00462
00463 inline void swap(any& x, any& y) noexcept { x.swap(y); }
00464
00465
00466 template <typename T, typename... Args>
00467 any make_any(Args&&... args) {
00468 return any(in_place_type_t<T>(), std::forward<Args>(args)...);
00469 }
00470
00471
00472 template <typename T, typename U, typename... Args>
00473 any make_any(std::initializer_list<U> il, Args&&... args) {
00474 return any(in_place_type_t<T>(), il, std::forward<Args>(args)...);
00475 }
00476
00477
00478 template <typename ValueType>
00479 ValueType any_cast(const any& operand) {
00480 using U = typename std::remove_cv<
00481 typename std::remove_reference<ValueType>::type>::type;
00482 static_assert(std::is_constructible<ValueType, const U&>::value,
00483 "Invalid ValueType");
00484 auto* const result = (any_cast<U>)(&operand);
00485 if (result == nullptr) {
00486 any_internal::ThrowBadAnyCast();
00487 }
00488 return static_cast<ValueType>(*result);
00489 }
00490
00491
00492 template <typename ValueType>
00493 ValueType any_cast(any& operand) {
00494 using U = typename std::remove_cv<
00495 typename std::remove_reference<ValueType>::type>::type;
00496 static_assert(std::is_constructible<ValueType, U&>::value,
00497 "Invalid ValueType");
00498 auto* result = (any_cast<U>)(&operand);
00499 if (result == nullptr) {
00500 any_internal::ThrowBadAnyCast();
00501 }
00502 return static_cast<ValueType>(*result);
00503 }
00504
00505
00506 template <typename ValueType>
00507 ValueType any_cast(any&& operand) {
00508 using U = typename std::remove_cv<
00509 typename std::remove_reference<ValueType>::type>::type;
00510 static_assert(std::is_constructible<ValueType, U>::value,
00511 "Invalid ValueType");
00512 return static_cast<ValueType>(std::move((any_cast<U&>)(operand)));
00513 }
00514
00515
00516 template <typename T>
00517 const T* any_cast(const any* operand) noexcept {
00518 return operand && operand->GetObjTypeId() == any::IdForType<T>()
00519 ? std::addressof(
00520 static_cast<const any::Obj<T>*>(operand->obj_.get())->value)
00521 : nullptr;
00522 }
00523
00524
00525 template <typename T>
00526 T* any_cast(any* operand) noexcept {
00527 return operand && operand->GetObjTypeId() == any::IdForType<T>()
00528 ? std::addressof(
00529 static_cast<any::Obj<T>*>(operand->obj_.get())->value)
00530 : nullptr;
00531 }
00532
00533 }
00534
00535 #undef ABSL_ANY_DETAIL_HAS_RTTI
00536
00537 #endif // ABSL_HAVE_STD_ANY
00538
00539 #endif // ABSL_TYPES_ANY_H_