xref: /freebsd/contrib/llvm-project/libcxx/include/__cxx03/__functional/bind.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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