xref: /llvm-project-15.0.7/libcxx/include/any (revision d3cbcc4e)
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_ANY
11#define _LIBCPP_ANY
12
13/*
14   any synopsis
15
16namespace std {
17
18  class bad_any_cast : public bad_cast
19  {
20  public:
21    virtual const char* what() const noexcept;
22  };
23
24  class any
25  {
26  public:
27
28    // 6.3.1 any construct/destruct
29    any() noexcept;
30
31    any(const any& other);
32    any(any&& other) noexcept;
33
34    template <class ValueType>
35      any(ValueType&& value);
36
37    ~any();
38
39    // 6.3.2 any assignments
40    any& operator=(const any& rhs);
41    any& operator=(any&& rhs) noexcept;
42
43    template <class ValueType>
44      any& operator=(ValueType&& rhs);
45
46    // 6.3.3 any modifiers
47    template <class ValueType, class... Args>
48      decay_t<ValueType>& emplace(Args&&... args);
49    template <class ValueType, class U, class... Args>
50      decay_t<ValueType>& emplace(initializer_list<U>, Args&&...);
51    void reset() noexcept;
52    void swap(any& rhs) noexcept;
53
54    // 6.3.4 any observers
55    bool has_value() const noexcept;
56    const type_info& type() const noexcept;
57  };
58
59   // 6.4 Non-member functions
60  void swap(any& x, any& y) noexcept;
61
62  template <class T, class ...Args>
63    any make_any(Args&& ...args);
64  template <class T, class U, class ...Args>
65    any make_any(initializer_list<U>, Args&& ...args);
66
67  template<class ValueType>
68    ValueType any_cast(const any& operand);
69  template<class ValueType>
70    ValueType any_cast(any& operand);
71  template<class ValueType>
72    ValueType any_cast(any&& operand);
73
74  template<class ValueType>
75    const ValueType* any_cast(const any* operand) noexcept;
76  template<class ValueType>
77    ValueType* any_cast(any* operand) noexcept;
78
79} // namespace std
80
81*/
82
83#include <__assert> // all public C++ headers provide the assertion handler
84#include <__availability>
85#include <__config>
86#include <__utility/forward.h>
87#include <__utility/in_place.h>
88#include <__utility/move.h>
89#include <__utility/unreachable.h>
90#include <cstdlib>
91#include <initializer_list>
92#include <memory>
93#include <type_traits>
94#include <typeinfo>
95#include <version>
96
97#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
98#  pragma GCC system_header
99#endif
100
101namespace std {
102class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast
103{
104public:
105    virtual const char* what() const _NOEXCEPT;
106};
107} // namespace std
108
109_LIBCPP_BEGIN_NAMESPACE_STD
110
111#if _LIBCPP_STD_VER > 14
112
113_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
114_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
115void __throw_bad_any_cast()
116{
117#ifndef _LIBCPP_NO_EXCEPTIONS
118    throw bad_any_cast();
119#else
120    _VSTD::abort();
121#endif
122}
123
124// Forward declarations
125class _LIBCPP_TEMPLATE_VIS any;
126
127template <class _ValueType>
128_LIBCPP_INLINE_VISIBILITY
129add_pointer_t<add_const_t<_ValueType>>
130any_cast(any const *) _NOEXCEPT;
131
132template <class _ValueType>
133_LIBCPP_INLINE_VISIBILITY
134add_pointer_t<_ValueType> any_cast(any *) _NOEXCEPT;
135
136namespace __any_imp
137{
138  using _Buffer = aligned_storage_t<3*sizeof(void*), alignment_of<void*>::value>;
139
140  template <class _Tp>
141  using _IsSmallObject = integral_constant<bool
142        , sizeof(_Tp) <= sizeof(_Buffer)
143          && alignment_of<_Buffer>::value
144             % alignment_of<_Tp>::value == 0
145          && is_nothrow_move_constructible<_Tp>::value
146        >;
147
148  enum class _Action {
149    _Destroy,
150    _Copy,
151    _Move,
152    _Get,
153    _TypeInfo
154  };
155
156  template <class _Tp> struct _SmallHandler;
157  template <class _Tp> struct _LargeHandler;
158
159  template <class _Tp>
160  struct  _LIBCPP_TEMPLATE_VIS __unique_typeinfo { static constexpr int __id = 0; };
161  template <class _Tp> constexpr int __unique_typeinfo<_Tp>::__id;
162
163  template <class _Tp>
164  inline _LIBCPP_INLINE_VISIBILITY
165  constexpr const void* __get_fallback_typeid() {
166      return &__unique_typeinfo<remove_cv_t<remove_reference_t<_Tp>>>::__id;
167  }
168
169  template <class _Tp>
170  inline _LIBCPP_INLINE_VISIBILITY
171  bool __compare_typeid(type_info const* __id, const void* __fallback_id)
172  {
173#if !defined(_LIBCPP_NO_RTTI)
174      if (__id && *__id == typeid(_Tp))
175          return true;
176#endif
177      if (!__id && __fallback_id == __any_imp::__get_fallback_typeid<_Tp>())
178          return true;
179      return false;
180  }
181
182  template <class _Tp>
183  using _Handler = conditional_t<
184    _IsSmallObject<_Tp>::value, _SmallHandler<_Tp>, _LargeHandler<_Tp>>;
185
186} // namespace __any_imp
187
188class _LIBCPP_TEMPLATE_VIS any
189{
190public:
191  // construct/destruct
192  _LIBCPP_INLINE_VISIBILITY
193  constexpr any() _NOEXCEPT : __h(nullptr) {}
194
195  _LIBCPP_INLINE_VISIBILITY
196  any(any const & __other) : __h(nullptr)
197  {
198    if (__other.__h) __other.__call(_Action::_Copy, this);
199  }
200
201  _LIBCPP_INLINE_VISIBILITY
202  any(any && __other) _NOEXCEPT : __h(nullptr)
203  {
204    if (__other.__h) __other.__call(_Action::_Move, this);
205  }
206
207  template <
208      class _ValueType
209    , class _Tp = decay_t<_ValueType>
210    , class = enable_if_t<
211        !is_same<_Tp, any>::value &&
212        !__is_inplace_type<_ValueType>::value &&
213        is_copy_constructible<_Tp>::value>
214    >
215  _LIBCPP_INLINE_VISIBILITY
216  any(_ValueType && __value);
217
218  template <class _ValueType, class ..._Args,
219    class _Tp = decay_t<_ValueType>,
220    class = enable_if_t<
221        is_constructible<_Tp, _Args...>::value &&
222        is_copy_constructible<_Tp>::value
223    >
224  >
225  _LIBCPP_INLINE_VISIBILITY
226  explicit any(in_place_type_t<_ValueType>, _Args&&... __args);
227
228  template <class _ValueType, class _Up, class ..._Args,
229    class _Tp = decay_t<_ValueType>,
230    class = enable_if_t<
231        is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
232        is_copy_constructible<_Tp>::value>
233  >
234  _LIBCPP_INLINE_VISIBILITY
235  explicit any(in_place_type_t<_ValueType>, initializer_list<_Up>, _Args&&... __args);
236
237  _LIBCPP_INLINE_VISIBILITY
238  ~any() { this->reset(); }
239
240  // assignments
241  _LIBCPP_INLINE_VISIBILITY
242  any & operator=(any const & __rhs) {
243    any(__rhs).swap(*this);
244    return *this;
245  }
246
247  _LIBCPP_INLINE_VISIBILITY
248  any & operator=(any && __rhs) _NOEXCEPT {
249    any(_VSTD::move(__rhs)).swap(*this);
250    return *this;
251  }
252
253  template <
254      class _ValueType
255    , class _Tp = decay_t<_ValueType>
256    , class = enable_if_t<
257          !is_same<_Tp, any>::value
258          && is_copy_constructible<_Tp>::value>
259    >
260  _LIBCPP_INLINE_VISIBILITY
261  any & operator=(_ValueType && __rhs);
262
263  template <class _ValueType, class ..._Args,
264    class _Tp = decay_t<_ValueType>,
265    class = enable_if_t<
266        is_constructible<_Tp, _Args...>::value &&
267        is_copy_constructible<_Tp>::value>
268    >
269  _LIBCPP_INLINE_VISIBILITY
270  _Tp& emplace(_Args&&... args);
271
272  template <class _ValueType, class _Up, class ..._Args,
273    class _Tp = decay_t<_ValueType>,
274    class = enable_if_t<
275        is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
276        is_copy_constructible<_Tp>::value>
277  >
278  _LIBCPP_INLINE_VISIBILITY
279  _Tp& emplace(initializer_list<_Up>, _Args&&...);
280
281  // 6.3.3 any modifiers
282  _LIBCPP_INLINE_VISIBILITY
283  void reset() _NOEXCEPT { if (__h) this->__call(_Action::_Destroy); }
284
285  _LIBCPP_INLINE_VISIBILITY
286  void swap(any & __rhs) _NOEXCEPT;
287
288  // 6.3.4 any observers
289  _LIBCPP_INLINE_VISIBILITY
290  bool has_value() const _NOEXCEPT { return __h != nullptr; }
291
292#if !defined(_LIBCPP_NO_RTTI)
293  _LIBCPP_INLINE_VISIBILITY
294  const type_info & type() const _NOEXCEPT {
295    if (__h) {
296        return *static_cast<type_info const *>(this->__call(_Action::_TypeInfo));
297    } else {
298        return typeid(void);
299    }
300  }
301#endif
302
303private:
304    typedef __any_imp::_Action _Action;
305    using _HandleFuncPtr =  void* (*)(_Action, any const *, any *, const type_info *,
306      const void* __fallback_info);
307
308    union _Storage {
309        constexpr _Storage() : __ptr(nullptr) {}
310        void *  __ptr;
311        __any_imp::_Buffer __buf;
312    };
313
314    _LIBCPP_INLINE_VISIBILITY
315    void * __call(_Action __a, any * __other = nullptr,
316                  type_info const * __info = nullptr,
317                   const void* __fallback_info = nullptr) const
318    {
319        return __h(__a, this, __other, __info, __fallback_info);
320    }
321
322    _LIBCPP_INLINE_VISIBILITY
323    void * __call(_Action __a, any * __other = nullptr,
324                  type_info const * __info = nullptr,
325                  const void* __fallback_info = nullptr)
326    {
327        return __h(__a, this, __other, __info, __fallback_info);
328    }
329
330    template <class>
331    friend struct __any_imp::_SmallHandler;
332    template <class>
333    friend struct __any_imp::_LargeHandler;
334
335    template <class _ValueType>
336    friend add_pointer_t<add_const_t<_ValueType>>
337    any_cast(any const *) _NOEXCEPT;
338
339    template <class _ValueType>
340    friend add_pointer_t<_ValueType>
341    any_cast(any *) _NOEXCEPT;
342
343    _HandleFuncPtr __h = nullptr;
344    _Storage __s;
345};
346
347namespace __any_imp
348{
349  template <class _Tp>
350  struct _LIBCPP_TEMPLATE_VIS _SmallHandler
351  {
352     _LIBCPP_INLINE_VISIBILITY
353     static void* __handle(_Action __act, any const * __this, any * __other,
354                           type_info const * __info, const void* __fallback_info)
355     {
356        switch (__act)
357        {
358        case _Action::_Destroy:
359          __destroy(const_cast<any &>(*__this));
360          return nullptr;
361        case _Action::_Copy:
362            __copy(*__this, *__other);
363            return nullptr;
364        case _Action::_Move:
365          __move(const_cast<any &>(*__this), *__other);
366          return nullptr;
367        case _Action::_Get:
368            return __get(const_cast<any &>(*__this), __info, __fallback_info);
369        case _Action::_TypeInfo:
370          return __type_info();
371        }
372        __libcpp_unreachable();
373    }
374
375    template <class ..._Args>
376    _LIBCPP_INLINE_VISIBILITY
377    static _Tp& __create(any & __dest, _Args&&... __args) {
378        typedef allocator<_Tp> _Alloc;
379        typedef allocator_traits<_Alloc> _ATraits;
380        _Alloc __a;
381        _Tp * __ret = static_cast<_Tp*>(static_cast<void*>(&__dest.__s.__buf));
382        _ATraits::construct(__a, __ret, _VSTD::forward<_Args>(__args)...);
383        __dest.__h = &_SmallHandler::__handle;
384        return *__ret;
385    }
386
387  private:
388    _LIBCPP_INLINE_VISIBILITY
389    static void __destroy(any & __this) {
390        typedef allocator<_Tp> _Alloc;
391        typedef allocator_traits<_Alloc> _ATraits;
392        _Alloc __a;
393        _Tp * __p = static_cast<_Tp *>(static_cast<void*>(&__this.__s.__buf));
394        _ATraits::destroy(__a, __p);
395        __this.__h = nullptr;
396    }
397
398    _LIBCPP_INLINE_VISIBILITY
399    static void __copy(any const & __this, any & __dest) {
400        _SmallHandler::__create(__dest, *static_cast<_Tp const *>(
401            static_cast<void const *>(&__this.__s.__buf)));
402    }
403
404    _LIBCPP_INLINE_VISIBILITY
405    static void __move(any & __this, any & __dest) {
406        _SmallHandler::__create(__dest, _VSTD::move(
407            *static_cast<_Tp*>(static_cast<void*>(&__this.__s.__buf))));
408        __destroy(__this);
409    }
410
411    _LIBCPP_INLINE_VISIBILITY
412    static void* __get(any & __this,
413                       type_info const * __info,
414                       const void* __fallback_id)
415    {
416        if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_id))
417            return static_cast<void*>(&__this.__s.__buf);
418        return nullptr;
419    }
420
421    _LIBCPP_INLINE_VISIBILITY
422    static void* __type_info()
423    {
424#if !defined(_LIBCPP_NO_RTTI)
425        return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
426#else
427        return nullptr;
428#endif
429    }
430  };
431
432  template <class _Tp>
433  struct _LIBCPP_TEMPLATE_VIS _LargeHandler
434  {
435    _LIBCPP_INLINE_VISIBILITY
436    static void* __handle(_Action __act, any const * __this,
437                          any * __other, type_info const * __info,
438                          void const* __fallback_info)
439    {
440        switch (__act)
441        {
442        case _Action::_Destroy:
443          __destroy(const_cast<any &>(*__this));
444          return nullptr;
445        case _Action::_Copy:
446          __copy(*__this, *__other);
447          return nullptr;
448        case _Action::_Move:
449          __move(const_cast<any &>(*__this), *__other);
450          return nullptr;
451        case _Action::_Get:
452            return __get(const_cast<any &>(*__this), __info, __fallback_info);
453        case _Action::_TypeInfo:
454          return __type_info();
455        }
456        __libcpp_unreachable();
457    }
458
459    template <class ..._Args>
460    _LIBCPP_INLINE_VISIBILITY
461    static _Tp& __create(any & __dest, _Args&&... __args) {
462        typedef allocator<_Tp> _Alloc;
463        typedef allocator_traits<_Alloc> _ATraits;
464        typedef __allocator_destructor<_Alloc> _Dp;
465        _Alloc __a;
466        unique_ptr<_Tp, _Dp> __hold(_ATraits::allocate(__a, 1), _Dp(__a, 1));
467        _Tp * __ret = __hold.get();
468        _ATraits::construct(__a, __ret, _VSTD::forward<_Args>(__args)...);
469        __dest.__s.__ptr = __hold.release();
470        __dest.__h = &_LargeHandler::__handle;
471        return *__ret;
472    }
473
474  private:
475
476    _LIBCPP_INLINE_VISIBILITY
477    static void __destroy(any & __this){
478        typedef allocator<_Tp> _Alloc;
479        typedef allocator_traits<_Alloc> _ATraits;
480        _Alloc __a;
481        _Tp * __p = static_cast<_Tp *>(__this.__s.__ptr);
482        _ATraits::destroy(__a, __p);
483        _ATraits::deallocate(__a, __p, 1);
484        __this.__h = nullptr;
485    }
486
487    _LIBCPP_INLINE_VISIBILITY
488    static void __copy(any const & __this, any & __dest) {
489        _LargeHandler::__create(__dest, *static_cast<_Tp const *>(__this.__s.__ptr));
490    }
491
492    _LIBCPP_INLINE_VISIBILITY
493    static void __move(any & __this, any & __dest) {
494      __dest.__s.__ptr = __this.__s.__ptr;
495      __dest.__h = &_LargeHandler::__handle;
496      __this.__h = nullptr;
497    }
498
499    _LIBCPP_INLINE_VISIBILITY
500    static void* __get(any & __this, type_info const * __info,
501                       void const* __fallback_info)
502    {
503        if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_info))
504            return static_cast<void*>(__this.__s.__ptr);
505        return nullptr;
506
507    }
508
509    _LIBCPP_INLINE_VISIBILITY
510    static void* __type_info()
511    {
512#if !defined(_LIBCPP_NO_RTTI)
513        return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
514#else
515        return nullptr;
516#endif
517    }
518  };
519
520} // namespace __any_imp
521
522
523template <class _ValueType, class _Tp, class>
524any::any(_ValueType && __v) : __h(nullptr)
525{
526  __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_ValueType>(__v));
527}
528
529template <class _ValueType, class ..._Args, class _Tp, class>
530any::any(in_place_type_t<_ValueType>, _Args&&... __args) {
531  __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...);
532}
533
534template <class _ValueType, class _Up, class ..._Args, class _Tp, class>
535any::any(in_place_type_t<_ValueType>, initializer_list<_Up> __il, _Args&&... __args) {
536  __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...);
537}
538
539template <class _ValueType, class, class>
540inline _LIBCPP_INLINE_VISIBILITY
541any & any::operator=(_ValueType && __v)
542{
543  any(_VSTD::forward<_ValueType>(__v)).swap(*this);
544  return *this;
545}
546
547template <class _ValueType, class ..._Args, class _Tp, class>
548inline _LIBCPP_INLINE_VISIBILITY
549_Tp& any::emplace(_Args&&... __args) {
550  reset();
551  return __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...);
552}
553
554template <class _ValueType, class _Up, class ..._Args, class _Tp, class>
555inline _LIBCPP_INLINE_VISIBILITY
556_Tp& any::emplace(initializer_list<_Up> __il, _Args&&... __args) {
557  reset();
558  return __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...);
559}
560
561inline _LIBCPP_INLINE_VISIBILITY
562void any::swap(any & __rhs) _NOEXCEPT
563{
564    if (this == &__rhs)
565      return;
566    if (__h && __rhs.__h) {
567        any __tmp;
568        __rhs.__call(_Action::_Move, &__tmp);
569        this->__call(_Action::_Move, &__rhs);
570        __tmp.__call(_Action::_Move, this);
571    }
572    else if (__h) {
573        this->__call(_Action::_Move, &__rhs);
574    }
575    else if (__rhs.__h) {
576        __rhs.__call(_Action::_Move, this);
577    }
578}
579
580// 6.4 Non-member functions
581
582inline _LIBCPP_INLINE_VISIBILITY
583void swap(any & __lhs, any & __rhs) _NOEXCEPT
584{
585    __lhs.swap(__rhs);
586}
587
588template <class _Tp, class ..._Args>
589inline _LIBCPP_INLINE_VISIBILITY
590any make_any(_Args&&... __args) {
591    return any(in_place_type<_Tp>, _VSTD::forward<_Args>(__args)...);
592}
593
594template <class _Tp, class _Up, class ..._Args>
595inline _LIBCPP_INLINE_VISIBILITY
596any make_any(initializer_list<_Up> __il, _Args&&... __args) {
597    return any(in_place_type<_Tp>, __il, _VSTD::forward<_Args>(__args)...);
598}
599
600template <class _ValueType>
601inline _LIBCPP_INLINE_VISIBILITY
602_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
603_ValueType any_cast(any const & __v)
604{
605    using _RawValueType = __uncvref_t<_ValueType>;
606    static_assert(is_constructible<_ValueType, _RawValueType const &>::value,
607                  "ValueType is required to be a const lvalue reference "
608                  "or a CopyConstructible type");
609    auto __tmp = _VSTD::any_cast<add_const_t<_RawValueType>>(&__v);
610    if (__tmp == nullptr)
611        __throw_bad_any_cast();
612    return static_cast<_ValueType>(*__tmp);
613}
614
615template <class _ValueType>
616inline _LIBCPP_INLINE_VISIBILITY
617_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
618_ValueType any_cast(any & __v)
619{
620    using _RawValueType = __uncvref_t<_ValueType>;
621    static_assert(is_constructible<_ValueType, _RawValueType &>::value,
622                  "ValueType is required to be an lvalue reference "
623                  "or a CopyConstructible type");
624    auto __tmp = _VSTD::any_cast<_RawValueType>(&__v);
625    if (__tmp == nullptr)
626        __throw_bad_any_cast();
627    return static_cast<_ValueType>(*__tmp);
628}
629
630template <class _ValueType>
631inline _LIBCPP_INLINE_VISIBILITY
632_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
633_ValueType any_cast(any && __v)
634{
635    using _RawValueType = __uncvref_t<_ValueType>;
636    static_assert(is_constructible<_ValueType, _RawValueType>::value,
637                  "ValueType is required to be an rvalue reference "
638                  "or a CopyConstructible type");
639    auto __tmp = _VSTD::any_cast<_RawValueType>(&__v);
640    if (__tmp == nullptr)
641        __throw_bad_any_cast();
642    return static_cast<_ValueType>(_VSTD::move(*__tmp));
643}
644
645template <class _ValueType>
646inline _LIBCPP_INLINE_VISIBILITY
647add_pointer_t<add_const_t<_ValueType>>
648any_cast(any const * __any) _NOEXCEPT
649{
650    static_assert(!is_reference<_ValueType>::value,
651                  "_ValueType may not be a reference.");
652    return _VSTD::any_cast<_ValueType>(const_cast<any *>(__any));
653}
654
655template <class _RetType>
656inline _LIBCPP_INLINE_VISIBILITY
657_RetType __pointer_or_func_cast(void* __p, /*IsFunction*/false_type) noexcept {
658  return static_cast<_RetType>(__p);
659}
660
661template <class _RetType>
662inline _LIBCPP_INLINE_VISIBILITY
663_RetType __pointer_or_func_cast(void*, /*IsFunction*/true_type) noexcept {
664  return nullptr;
665}
666
667template <class _ValueType>
668_LIBCPP_HIDE_FROM_ABI
669add_pointer_t<_ValueType>
670any_cast(any * __any) _NOEXCEPT
671{
672    using __any_imp::_Action;
673    static_assert(!is_reference<_ValueType>::value,
674                  "_ValueType may not be a reference.");
675    typedef typename add_pointer<_ValueType>::type _ReturnType;
676    if (__any && __any->__h) {
677      void *__p = __any->__call(_Action::_Get, nullptr,
678#if !defined(_LIBCPP_NO_RTTI)
679                          &typeid(_ValueType),
680#else
681                          nullptr,
682#endif
683                          __any_imp::__get_fallback_typeid<_ValueType>());
684        return _VSTD::__pointer_or_func_cast<_ReturnType>(
685            __p, is_function<_ValueType>{});
686    }
687    return nullptr;
688}
689
690#endif // _LIBCPP_STD_VER > 14
691
692_LIBCPP_END_NAMESPACE_STD
693
694#endif // _LIBCPP_ANY
695