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_PERFECT_FORWARD_H 11 #define _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H 12 13 #include <__config> 14 #include <tuple> 15 #include <type_traits> 16 #include <utility> 17 18 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 19 #pragma GCC system_header 20 #endif 21 22 _LIBCPP_BEGIN_NAMESPACE_STD 23 24 #if _LIBCPP_STD_VER > 14 25 26 template<class _Op, class _Tuple, 27 class _Idxs = typename __make_tuple_indices<tuple_size<_Tuple>::value>::type> 28 struct __perfect_forward_impl; 29 30 template<class _Op, class... _Bound, size_t... _Idxs> 31 struct __perfect_forward_impl<_Op, __tuple_types<_Bound...>, __tuple_indices<_Idxs...>> 32 { 33 tuple<_Bound...> __bound_; 34 35 template<class... _Args> 36 _LIBCPP_INLINE_VISIBILITY constexpr auto operator()(_Args&&... __args) & 37 noexcept(noexcept(_Op::__call(_VSTD::get<_Idxs>(__bound_)..., _VSTD::forward<_Args>(__args)...))) 38 -> decltype( _Op::__call(_VSTD::get<_Idxs>(__bound_)..., _VSTD::forward<_Args>(__args)...)) 39 {return _Op::__call(_VSTD::get<_Idxs>(__bound_)..., _VSTD::forward<_Args>(__args)...);} 40 41 template<class... _Args> 42 _LIBCPP_INLINE_VISIBILITY constexpr auto operator()(_Args&&... __args) const& 43 noexcept(noexcept(_Op::__call(_VSTD::get<_Idxs>(__bound_)..., _VSTD::forward<_Args>(__args)...))) 44 -> decltype( _Op::__call(_VSTD::get<_Idxs>(__bound_)..., _VSTD::forward<_Args>(__args)...)) 45 {return _Op::__call(_VSTD::get<_Idxs>(__bound_)..., _VSTD::forward<_Args>(__args)...);} 46 47 template<class... _Args> 48 _LIBCPP_INLINE_VISIBILITY constexpr auto operator()(_Args&&... __args) && 49 noexcept(noexcept(_Op::__call(_VSTD::get<_Idxs>(_VSTD::move(__bound_))..., 50 _VSTD::forward<_Args>(__args)...))) 51 -> decltype( _Op::__call(_VSTD::get<_Idxs>(_VSTD::move(__bound_))..., 52 _VSTD::forward<_Args>(__args)...)) 53 {return _Op::__call(_VSTD::get<_Idxs>(_VSTD::move(__bound_))..., 54 _VSTD::forward<_Args>(__args)...);} 55 56 template<class... _Args> 57 _LIBCPP_INLINE_VISIBILITY constexpr auto operator()(_Args&&... __args) const&& 58 noexcept(noexcept(_Op::__call(_VSTD::get<_Idxs>(_VSTD::move(__bound_))..., 59 _VSTD::forward<_Args>(__args)...))) 60 -> decltype( _Op::__call(_VSTD::get<_Idxs>(_VSTD::move(__bound_))..., 61 _VSTD::forward<_Args>(__args)...)) 62 {return _Op::__call(_VSTD::get<_Idxs>(_VSTD::move(__bound_))..., 63 _VSTD::forward<_Args>(__args)...);} 64 65 template<class _Fn = typename tuple_element<0, tuple<_Bound...>>::type, 66 class = _EnableIf<is_copy_constructible_v<_Fn>>> 67 constexpr __perfect_forward_impl(__perfect_forward_impl const& __other) 68 : __bound_(__other.__bound_) {} 69 70 template<class _Fn = typename tuple_element<0, tuple<_Bound...>>::type, 71 class = _EnableIf<is_move_constructible_v<_Fn>>> 72 constexpr __perfect_forward_impl(__perfect_forward_impl && __other) 73 : __bound_(_VSTD::move(__other.__bound_)) {} 74 75 template<class... _BoundArgs> 76 explicit constexpr __perfect_forward_impl(_BoundArgs&&... __bound) : 77 __bound_(_VSTD::forward<_BoundArgs>(__bound)...) { } 78 }; 79 80 template<class _Op, class... _Args> 81 using __perfect_forward = 82 __perfect_forward_impl<_Op, __tuple_types<decay_t<_Args>...>>; 83 84 #endif // _LIBCPP_STD_VER > 14 85 86 _LIBCPP_END_NAMESPACE_STD 87 88 #endif // _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H 89