Skip to content

Commit 24c44c3

Browse files
committed
[libcxx] adds std::identity to <functional>
Implements parts of: - P0898R3 Standard Library Concepts Differential Revision: https://reviews.llvm.org/D98151
1 parent f1e0c7f commit 24c44c3

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed

libcxx/include/functional

+15
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@ struct bit_not : unary_function<T, T>
189189
T operator()(const T& x) const;
190190
};
191191
192+
struct identity; // C++20
193+
192194
template <class Predicate>
193195
class unary_negate // deprecated in C++17
194196
: public unary_function<typename Predicate::argument_type, bool>
@@ -3215,6 +3217,19 @@ template <class _Tp>
32153217
using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type;
32163218
#endif // > C++17
32173219

3220+
#if _LIBCPP_STD_VER > 17
3221+
// [func.identity]
3222+
struct identity {
3223+
template<class _Tp>
3224+
constexpr _Tp&& operator()(_Tp&& __t) const noexcept
3225+
{
3226+
return _VSTD::forward<_Tp>(__t);
3227+
}
3228+
3229+
using is_transparent = void;
3230+
};
3231+
#endif // _LIBCPP_STD_VER > 17
3232+
32183233
_LIBCPP_END_NAMESPACE_STD
32193234

32203235
#endif // _LIBCPP_FUNCTIONAL
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14, c++17
10+
// UNSUPPORTED: libcpp-no-concepts
11+
12+
// struct identity;
13+
14+
#include <functional>
15+
16+
#include <cassert>
17+
#include <concepts>
18+
19+
#include "MoveOnly.h"
20+
21+
static_assert(std::semiregular<std::identity>);
22+
static_assert(requires { typename std::identity::is_transparent; });
23+
24+
constexpr bool test() {
25+
std::identity id;
26+
int i = 42;
27+
assert(id(i) == 42);
28+
assert(id(std::move(i)) == 42);
29+
30+
MoveOnly m1 = 2;
31+
MoveOnly m2 = id(std::move(m1));
32+
assert(m2.get() == 2);
33+
34+
assert(&id(i) == &i);
35+
static_assert(&id(id) == &id);
36+
37+
const std::identity idc;
38+
assert(idc(1) == 1);
39+
assert(std::move(id)(1) == 1);
40+
assert(std::move(idc)(1) == 1);
41+
42+
id = idc; // run-time checks assignment
43+
static_assert(std::is_same_v<decltype(id(i)), int&>);
44+
static_assert(std::is_same_v<decltype(id(std::declval<int&&>())), int&&>);
45+
static_assert(
46+
std::is_same_v<decltype(id(std::declval<int const&>())), int const&>);
47+
static_assert(
48+
std::is_same_v<decltype(id(std::declval<int const&&>())), int const&&>);
49+
static_assert(std::is_same_v<decltype(id(std::declval<int volatile&>())),
50+
int volatile&>);
51+
static_assert(std::is_same_v<decltype(id(std::declval<int volatile&&>())),
52+
int volatile&&>);
53+
static_assert(
54+
std::is_same_v<decltype(id(std::declval<int const volatile&>())),
55+
int const volatile&>);
56+
static_assert(
57+
std::is_same_v<decltype(id(std::declval<int const volatile&&>())),
58+
int const volatile&&>);
59+
60+
struct S {
61+
constexpr S() = default;
62+
constexpr S(S&&) noexcept(false) {}
63+
constexpr S(S const&) noexcept(false) {}
64+
};
65+
S x;
66+
static_assert(noexcept(id(x)));
67+
static_assert(noexcept(id(S())));
68+
69+
return true;
70+
}
71+
72+
int main(int, char**) {
73+
test();
74+
static_assert(test());
75+
76+
return 0;
77+
}

0 commit comments

Comments
 (0)