Skip to content

Commit 89a7bdb

Browse files
committed
[libc++] Add the __bind_back and __compose helpers
Those are going to be used to implement range adaptors, see D107098 for details. Differential Revision: https://reviews.llvm.org/D107785
1 parent 683147f commit 89a7bdb

File tree

10 files changed

+662
-7
lines changed

10 files changed

+662
-7
lines changed

libcxx/include/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,12 @@ set(files
130130
__functional_base
131131
__functional/binary_function.h
132132
__functional/binary_negate.h
133+
__functional/bind_back.h
133134
__functional/bind_front.h
134135
__functional/bind.h
135136
__functional/binder1st.h
136137
__functional/binder2nd.h
138+
__functional/compose.h
137139
__functional/default_searcher.h
138140
__functional/function.h
139141
__functional/hash.h
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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_BIND_BACK_H
11+
#define _LIBCPP___FUNCTIONAL_BIND_BACK_H
12+
13+
#include <__config>
14+
#include <__functional/invoke.h>
15+
#include <__functional/perfect_forward.h>
16+
#include <__utility/forward.h>
17+
#include <__utility/integer_sequence.h>
18+
#include <tuple>
19+
#include <type_traits>
20+
21+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22+
#pragma GCC system_header
23+
#endif
24+
25+
_LIBCPP_BEGIN_NAMESPACE_STD
26+
27+
#if _LIBCPP_STD_VER > 17
28+
29+
template <size_t _NBound, class = make_index_sequence<_NBound>>
30+
struct __bind_back_op;
31+
32+
template <size_t _NBound, size_t ..._Ip>
33+
struct __bind_back_op<_NBound, index_sequence<_Ip...>> {
34+
template <class _Fn, class _Bound, class ..._Args>
35+
_LIBCPP_HIDE_FROM_ABI
36+
constexpr auto operator()(_Fn&& __f, _Bound&& __bound, _Args&& ...__args) const
37+
noexcept(noexcept(_VSTD::invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)..., _VSTD::get<_Ip>(_VSTD::forward<_Bound>(__bound))...)))
38+
-> decltype( _VSTD::invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)..., _VSTD::get<_Ip>(_VSTD::forward<_Bound>(__bound))...))
39+
{ return _VSTD::invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)..., _VSTD::get<_Ip>(_VSTD::forward<_Bound>(__bound))...); }
40+
};
41+
42+
template <class _Fn, class _BoundArgs>
43+
struct __bind_back_t : __perfect_forward<__bind_back_op<tuple_size_v<_BoundArgs>>, _Fn, _BoundArgs> {
44+
using __perfect_forward<__bind_back_op<tuple_size_v<_BoundArgs>>, _Fn, _BoundArgs>::__perfect_forward;
45+
};
46+
47+
template <class _Fn, class ..._Args, class = _EnableIf<
48+
_And<
49+
is_constructible<decay_t<_Fn>, _Fn>,
50+
is_move_constructible<decay_t<_Fn>>,
51+
is_constructible<decay_t<_Args>, _Args>...,
52+
is_move_constructible<decay_t<_Args>>...
53+
>::value
54+
>>
55+
_LIBCPP_HIDE_FROM_ABI
56+
constexpr auto __bind_back(_Fn&& __f, _Args&&... __args)
57+
noexcept(noexcept(__bind_back_t<decay_t<_Fn>, tuple<decay_t<_Args>...>>(_VSTD::forward<_Fn>(__f), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...))))
58+
-> decltype( __bind_back_t<decay_t<_Fn>, tuple<decay_t<_Args>...>>(_VSTD::forward<_Fn>(__f), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)))
59+
{ return __bind_back_t<decay_t<_Fn>, tuple<decay_t<_Args>...>>(_VSTD::forward<_Fn>(__f), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); }
60+
61+
#endif // _LIBCPP_STD_VER > 17
62+
63+
_LIBCPP_END_NAMESPACE_STD
64+
65+
#endif // _LIBCPP___FUNCTIONAL_BIND_BACK_H

libcxx/include/__functional/compose.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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_COMPOSE_H
11+
#define _LIBCPP___FUNCTIONAL_COMPOSE_H
12+
13+
#include <__config>
14+
#include <__functional/invoke.h>
15+
#include <__functional/perfect_forward.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+
#if _LIBCPP_STD_VER > 17
26+
27+
struct __compose_op {
28+
template<class _Fn1, class _Fn2, class ..._Args>
29+
_LIBCPP_HIDE_FROM_ABI
30+
constexpr auto operator()(_Fn1&& __f1, _Fn2&& __f2, _Args&&... __args) const
31+
noexcept(noexcept(_VSTD::invoke(_VSTD::forward<_Fn1>(__f1), _VSTD::invoke(_VSTD::forward<_Fn2>(__f2), _VSTD::forward<_Args>(__args)...))))
32+
-> decltype( _VSTD::invoke(_VSTD::forward<_Fn1>(__f1), _VSTD::invoke(_VSTD::forward<_Fn2>(__f2), _VSTD::forward<_Args>(__args)...)))
33+
{ return _VSTD::invoke(_VSTD::forward<_Fn1>(__f1), _VSTD::invoke(_VSTD::forward<_Fn2>(__f2), _VSTD::forward<_Args>(__args)...)); }
34+
};
35+
36+
template <class _Fn1, class _Fn2>
37+
struct __compose_t : __perfect_forward<__compose_op, _Fn1, _Fn2> {
38+
using __perfect_forward<__compose_op, _Fn1, _Fn2>::__perfect_forward;
39+
};
40+
41+
template <class _Fn1, class _Fn2>
42+
_LIBCPP_HIDE_FROM_ABI
43+
constexpr auto __compose(_Fn1&& __f1, _Fn2&& __f2)
44+
noexcept(noexcept(__compose_t<decay_t<_Fn1>, decay_t<_Fn2>>(_VSTD::forward<_Fn1>(__f1), _VSTD::forward<_Fn2>(__f2))))
45+
-> decltype( __compose_t<decay_t<_Fn1>, decay_t<_Fn2>>(_VSTD::forward<_Fn1>(__f1), _VSTD::forward<_Fn2>(__f2)))
46+
{ return __compose_t<decay_t<_Fn1>, decay_t<_Fn2>>(_VSTD::forward<_Fn1>(__f1), _VSTD::forward<_Fn2>(__f2)); }
47+
48+
#endif // _LIBCPP_STD_VER > 17
49+
50+
_LIBCPP_END_NAMESPACE_STD
51+
52+
#endif // _LIBCPP___FUNCTIONAL_COMPOSE_H

libcxx/include/functional

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,10 +492,12 @@ POLICY: For non-variadic implementations, the number of arguments is limited
492492
#include <__debug>
493493
#include <__functional/binary_function.h> // TODO: deprecate
494494
#include <__functional/binary_negate.h>
495+
#include <__functional/bind_back.h>
495496
#include <__functional/bind_front.h>
496497
#include <__functional/bind.h>
497498
#include <__functional/binder1st.h>
498499
#include <__functional/binder2nd.h>
500+
#include <__functional/compose.h>
499501
#include <__functional/default_searcher.h>
500502
#include <__functional/function.h>
501503
#include <__functional/hash.h>

libcxx/include/module.modulemap

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,15 +444,17 @@ module std [system] {
444444
module binary_function { private header "__functional/binary_function.h" }
445445
module binary_negate { private header "__functional/binary_negate.h" }
446446
module bind { private header "__functional/bind.h" }
447+
module bind_back { private header "__functional/bind_back.h" }
447448
module bind_front { private header "__functional/bind_front.h" }
448449
module binder1st { private header "__functional/binder1st.h" }
449450
module binder2nd { private header "__functional/binder2nd.h" }
451+
module compose { private header "__functional/compose.h" }
450452
module default_searcher { private header "__functional/default_searcher.h" }
451453
module function { private header "__functional/function.h" }
452454
module hash { private header "__functional/hash.h" }
453455
module identity { private header "__functional/identity.h" }
454-
module is_transparent { private header "__functional/is_transparent.h" }
455456
module invoke { private header "__functional/invoke.h" }
457+
module is_transparent { private header "__functional/is_transparent.h" }
456458
module mem_fn { private header "__functional/mem_fn.h" }
457459
module mem_fun_ref { private header "__functional/mem_fun_ref.h" }
458460
module not_fn { private header "__functional/not_fn.h" }
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
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+
// REQUIRES: modules-build
11+
12+
// WARNING: This test was generated by 'generate_private_header_tests.py'
13+
// and should not be edited manually.
14+
15+
// expected-error@*:* {{use of private header from outside its module: '__functional/bind_back.h'}}
16+
#include <__functional/bind_back.h>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
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+
// REQUIRES: modules-build
11+
12+
// WARNING: This test was generated by 'generate_private_header_tests.py'
13+
// and should not be edited manually.
14+
15+
// expected-error@*:* {{use of private header from outside its module: '__functional/compose.h'}}
16+
#include <__functional/compose.h>

0 commit comments

Comments
 (0)