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