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___FUNCTIONAL_REFERENCE_WRAPPER_H 11 #define _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H 12 13 #include <__config> 14 #include <__functional/weak_result_type.h> 15 #include <__memory/addressof.h> 16 #include <__utility/forward.h> 17 #include <type_traits> 18 19 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 20 # pragma GCC system_header 21 #endif 22 23 _LIBCPP_BEGIN_NAMESPACE_STD 24 25 template <class _Tp> 26 class _LIBCPP_TEMPLATE_VIS reference_wrapper : public __weak_result_type<_Tp> 27 { 28 public: 29 // types 30 typedef _Tp type; 31 private: 32 type* __f_; 33 34 static void __fun(_Tp&) _NOEXCEPT; 35 static void __fun(_Tp&&) = delete; 36 37 public: 38 template <class _Up, class = __enable_if_t<!__is_same_uncvref<_Up, reference_wrapper>::value, decltype(__fun(declval<_Up>())) > > 39 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 40 reference_wrapper(_Up&& __u) _NOEXCEPT_(noexcept(__fun(declval<_Up>()))) { 41 type& __f = static_cast<_Up&&>(__u); 42 __f_ = _VSTD::addressof(__f); 43 } 44 45 // access 46 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 47 operator type&() const _NOEXCEPT {return *__f_;} 48 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 49 type& get() const _NOEXCEPT {return *__f_;} 50 51 // invoke 52 template <class... _ArgTypes> 53 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 54 typename __invoke_of<type&, _ArgTypes...>::type 55 operator() (_ArgTypes&&... __args) const { 56 return std::__invoke(get(), std::forward<_ArgTypes>(__args)...); 57 } 58 }; 59 60 #if _LIBCPP_STD_VER > 14 61 template <class _Tp> 62 reference_wrapper(_Tp&) -> reference_wrapper<_Tp>; 63 #endif 64 65 template <class _Tp> 66 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 67 reference_wrapper<_Tp> 68 ref(_Tp& __t) _NOEXCEPT 69 { 70 return reference_wrapper<_Tp>(__t); 71 } 72 73 template <class _Tp> 74 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 75 reference_wrapper<_Tp> 76 ref(reference_wrapper<_Tp> __t) _NOEXCEPT 77 { 78 return __t; 79 } 80 81 template <class _Tp> 82 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 83 reference_wrapper<const _Tp> 84 cref(const _Tp& __t) _NOEXCEPT 85 { 86 return reference_wrapper<const _Tp>(__t); 87 } 88 89 template <class _Tp> 90 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 91 reference_wrapper<const _Tp> 92 cref(reference_wrapper<_Tp> __t) _NOEXCEPT 93 { 94 return __t; 95 } 96 97 template <class _Tp> void ref(const _Tp&&) = delete; 98 template <class _Tp> void cref(const _Tp&&) = delete; 99 100 _LIBCPP_END_NAMESPACE_STD 101 102 #endif // _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H 103