Skip to content

Commit 72990d4

Browse files
committed
[libc++] Make sure that __desugars_to isn't tripped up by reference_wrapper and cv-refs
Previously, any cv-ref qualification on an operation would cause __desugars_to to report false, which would lead to unnecessary pessimizations. The same holds for reference_wrapper. In practice, cv-ref qualifications on the operation itself are not relevant to determining whether an operation desugars to something else or not. Fixes #129312
1 parent a0ae88b commit 72990d4

File tree

4 files changed

+87
-0
lines changed

4 files changed

+87
-0
lines changed

libcxx/include/__functional/reference_wrapper.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <__config>
1616
#include <__functional/weak_result_type.h>
1717
#include <__memory/addressof.h>
18+
#include <__type_traits/desugars_to.h>
1819
#include <__type_traits/enable_if.h>
1920
#include <__type_traits/invoke.h>
2021
#include <__type_traits/is_const.h>
@@ -149,6 +150,11 @@ void ref(const _Tp&&) = delete;
149150
template <class _Tp>
150151
void cref(const _Tp&&) = delete;
151152

153+
// Let desugars-to pass through std::reference_wrapper
154+
template <class _CanonicalTag, class _Operation, class... _Args>
155+
inline const bool __desugars_to_v<_CanonicalTag, reference_wrapper<_Operation>, _Args...> =
156+
__desugars_to_v<_CanonicalTag, _Operation, _Args...>;
157+
152158
_LIBCPP_END_NAMESPACE_STD
153159

154160
#endif // _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H

libcxx/include/__type_traits/desugars_to.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,24 @@ struct __totally_ordered_less_tag {};
5252
template <class _CanonicalTag, class _Operation, class... _Args>
5353
inline const bool __desugars_to_v = false;
5454

55+
// For the purpose of determining whether something desugars to something else,
56+
// we disregard the cv-refs of the operation itself.
57+
template <class _CanonicalTag, class _Operation, class... _Args>
58+
inline const bool __desugars_to_v<_CanonicalTag, _Operation const, _Args...> =
59+
__desugars_to_v<_CanonicalTag, _Operation, _Args...>;
60+
template <class _CanonicalTag, class _Operation, class... _Args>
61+
inline const bool __desugars_to_v<_CanonicalTag, _Operation volatile, _Args...> =
62+
__desugars_to_v<_CanonicalTag, _Operation, _Args...>;
63+
template <class _CanonicalTag, class _Operation, class... _Args>
64+
inline const bool __desugars_to_v<_CanonicalTag, _Operation const volatile, _Args...> =
65+
__desugars_to_v<_CanonicalTag, _Operation, _Args...>;
66+
template <class _CanonicalTag, class _Operation, class... _Args>
67+
inline const bool __desugars_to_v<_CanonicalTag, _Operation&, _Args...> =
68+
__desugars_to_v<_CanonicalTag, _Operation, _Args...>;
69+
template <class _CanonicalTag, class _Operation, class... _Args>
70+
inline const bool __desugars_to_v<_CanonicalTag, _Operation&&, _Args...> =
71+
__desugars_to_v<_CanonicalTag, _Operation, _Args...>;
72+
5573
_LIBCPP_END_NAMESPACE_STD
5674

5775
#endif // _LIBCPP___TYPE_TRAITS_DESUGARS_TO_H
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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+
#include <__type_traits/desugars_to.h>
10+
11+
struct Tag {};
12+
struct Operation {};
13+
template <>
14+
bool const std::__desugars_to_v<Tag, Operation> = true;
15+
16+
void tests() {
17+
// Make sure that __desugars_to is false by default
18+
{
19+
struct Foo {};
20+
static_assert(!std::__desugars_to_v<Tag, Foo>, "");
21+
}
22+
23+
// Make sure that __desugars_to bypasses cv and ref qualifiers on the operation
24+
{
25+
static_assert(std::__desugars_to_v<Tag, Operation>, ""); // no quals
26+
static_assert(std::__desugars_to_v<Tag, Operation const>, "");
27+
static_assert(std::__desugars_to_v<Tag, Operation volatile>, "");
28+
static_assert(std::__desugars_to_v<Tag, Operation const volatile>, "");
29+
30+
static_assert(std::__desugars_to_v<Tag, Operation&>, "");
31+
static_assert(std::__desugars_to_v<Tag, Operation const&>, "");
32+
static_assert(std::__desugars_to_v<Tag, Operation volatile&>, "");
33+
static_assert(std::__desugars_to_v<Tag, Operation const volatile&>, "");
34+
35+
static_assert(std::__desugars_to_v<Tag, Operation&&>, "");
36+
static_assert(std::__desugars_to_v<Tag, Operation const&&>, "");
37+
static_assert(std::__desugars_to_v<Tag, Operation volatile&&>, "");
38+
static_assert(std::__desugars_to_v<Tag, Operation const volatile&&>, "");
39+
}
40+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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+
// <functional>
10+
11+
// reference_wrapper
12+
13+
// Ensure that std::reference_wrapper does not inhibit optimizations based on the
14+
// std::__desugars_to internal helper.
15+
16+
#include <functional>
17+
18+
static_assert(std::__desugars_to_v<std::__equal_tag, std::equal_to<void>, int, int>,
19+
"something is wrong with the test");
20+
21+
// make sure we pass through reference_wrapper
22+
static_assert(std::__desugars_to_v<std::__equal_tag, std::reference_wrapper<std::equal_to<void> >, int, int>, "");
23+
static_assert(std::__desugars_to_v<std::__equal_tag, std::reference_wrapper<std::equal_to<void> const>, int, int>, "");

0 commit comments

Comments
 (0)