1*700637cbSDimitry Andric // -*- C++ -*- 2*700637cbSDimitry Andric //===----------------------------------------------------------------------===// 3*700637cbSDimitry Andric // 4*700637cbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*700637cbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 6*700637cbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*700637cbSDimitry Andric // 8*700637cbSDimitry Andric //===----------------------------------------------------------------------===// 9*700637cbSDimitry Andric 10*700637cbSDimitry Andric #ifndef _LIBCPP___CXX03___FUNCTIONAL_BIND_H 11*700637cbSDimitry Andric #define _LIBCPP___CXX03___FUNCTIONAL_BIND_H 12*700637cbSDimitry Andric 13*700637cbSDimitry Andric #include <__cxx03/__config> 14*700637cbSDimitry Andric #include <__cxx03/__functional/weak_result_type.h> 15*700637cbSDimitry Andric #include <__cxx03/__fwd/functional.h> 16*700637cbSDimitry Andric #include <__cxx03/__type_traits/decay.h> 17*700637cbSDimitry Andric #include <__cxx03/__type_traits/invoke.h> 18*700637cbSDimitry Andric #include <__cxx03/__type_traits/is_reference_wrapper.h> 19*700637cbSDimitry Andric #include <__cxx03/__type_traits/is_void.h> 20*700637cbSDimitry Andric #include <__cxx03/__type_traits/remove_cvref.h> 21*700637cbSDimitry Andric #include <__cxx03/cstddef> 22*700637cbSDimitry Andric 23*700637cbSDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 24*700637cbSDimitry Andric # pragma GCC system_header 25*700637cbSDimitry Andric #endif 26*700637cbSDimitry Andric 27*700637cbSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 28*700637cbSDimitry Andric 29*700637cbSDimitry Andric template <class _Tp> 30*700637cbSDimitry Andric struct is_bind_expression 31*700637cbSDimitry Andric : _If< _IsSame<_Tp, __remove_cvref_t<_Tp> >::value, false_type, is_bind_expression<__remove_cvref_t<_Tp> > > {}; 32*700637cbSDimitry Andric 33*700637cbSDimitry Andric template <class _Tp> 34*700637cbSDimitry Andric struct is_placeholder 35*700637cbSDimitry Andric : _If< _IsSame<_Tp, __remove_cvref_t<_Tp> >::value, 36*700637cbSDimitry Andric integral_constant<int, 0>, 37*700637cbSDimitry Andric is_placeholder<__remove_cvref_t<_Tp> > > {}; 38*700637cbSDimitry Andric 39*700637cbSDimitry Andric namespace placeholders { 40*700637cbSDimitry Andric 41*700637cbSDimitry Andric template <int _Np> 42*700637cbSDimitry Andric struct __ph {}; 43*700637cbSDimitry Andric 44*700637cbSDimitry Andric // C++17 recommends that we implement placeholders as `inline constexpr`, but allows 45*700637cbSDimitry Andric // implementing them as `extern <implementation-defined>`. Libc++ implements them as 46*700637cbSDimitry Andric // `extern const` in all standard modes to avoid an ABI break in C++03: making them 47*700637cbSDimitry Andric // `inline constexpr` requires removing their definition in the shared library to 48*700637cbSDimitry Andric // avoid ODR violations, which is an ABI break. 49*700637cbSDimitry Andric // 50*700637cbSDimitry Andric // In practice, since placeholders are empty, `extern const` is almost impossible 51*700637cbSDimitry Andric // to distinguish from `inline constexpr` from a usage stand point. 52*700637cbSDimitry Andric _LIBCPP_EXPORTED_FROM_ABI extern const __ph<1> _1; 53*700637cbSDimitry Andric _LIBCPP_EXPORTED_FROM_ABI extern const __ph<2> _2; 54*700637cbSDimitry Andric _LIBCPP_EXPORTED_FROM_ABI extern const __ph<3> _3; 55*700637cbSDimitry Andric _LIBCPP_EXPORTED_FROM_ABI extern const __ph<4> _4; 56*700637cbSDimitry Andric _LIBCPP_EXPORTED_FROM_ABI extern const __ph<5> _5; 57*700637cbSDimitry Andric _LIBCPP_EXPORTED_FROM_ABI extern const __ph<6> _6; 58*700637cbSDimitry Andric _LIBCPP_EXPORTED_FROM_ABI extern const __ph<7> _7; 59*700637cbSDimitry Andric _LIBCPP_EXPORTED_FROM_ABI extern const __ph<8> _8; 60*700637cbSDimitry Andric _LIBCPP_EXPORTED_FROM_ABI extern const __ph<9> _9; 61*700637cbSDimitry Andric _LIBCPP_EXPORTED_FROM_ABI extern const __ph<10> _10; 62*700637cbSDimitry Andric 63*700637cbSDimitry Andric } // namespace placeholders 64*700637cbSDimitry Andric 65*700637cbSDimitry Andric template <int _Np> 66*700637cbSDimitry Andric struct is_placeholder<placeholders::__ph<_Np> > : public integral_constant<int, _Np> {}; 67*700637cbSDimitry Andric 68*700637cbSDimitry Andric _LIBCPP_END_NAMESPACE_STD 69*700637cbSDimitry Andric 70*700637cbSDimitry Andric #endif // _LIBCPP___CXX03___FUNCTIONAL_BIND_H 71