1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
12 #include "test_macros.h"
14 #include <functional> // for std::equal_to
16 // testing transparent
19 struct transparent_less
21 template <class T
, class U
>
22 constexpr auto operator()(T
&& t
, U
&& u
) const
23 noexcept(noexcept(std::forward
<T
>(t
) < std::forward
<U
>(u
)))
24 -> decltype (std::forward
<T
>(t
) < std::forward
<U
>(u
))
25 { return std::forward
<T
>(t
) < std::forward
<U
>(u
); }
26 using is_transparent
= void; // correct
29 struct transparent_less_not_referenceable
31 template <class T
, class U
>
32 constexpr auto operator()(T
&& t
, U
&& u
) const
33 noexcept(noexcept(std::forward
<T
>(t
) < std::forward
<U
>(u
)))
34 -> decltype (std::forward
<T
>(t
) < std::forward
<U
>(u
))
35 { return std::forward
<T
>(t
) < std::forward
<U
>(u
); }
36 using is_transparent
= void () const &; // it's a type; a weird one, but a type
39 struct transparent_less_no_type
41 template <class T
, class U
>
42 constexpr auto operator()(T
&& t
, U
&& u
) const
43 noexcept(noexcept(std::forward
<T
>(t
) < std::forward
<U
>(u
)))
44 -> decltype (std::forward
<T
>(t
) < std::forward
<U
>(u
))
45 { return std::forward
<T
>(t
) < std::forward
<U
>(u
); }
47 // using is_transparent = void; // error - should exist
50 struct transparent_less_private
52 template <class T
, class U
>
53 constexpr auto operator()(T
&& t
, U
&& u
) const
54 noexcept(noexcept(std::forward
<T
>(t
) < std::forward
<U
>(u
)))
55 -> decltype (std::forward
<T
>(t
) < std::forward
<U
>(u
))
56 { return std::forward
<T
>(t
) < std::forward
<U
>(u
); }
58 using is_transparent
= void; // error - should be accessible
61 struct transparent_less_not_a_type
63 template <class T
, class U
>
64 constexpr auto operator()(T
&& t
, U
&& u
) const
65 noexcept(noexcept(std::forward
<T
>(t
) < std::forward
<U
>(u
)))
66 -> decltype (std::forward
<T
>(t
) < std::forward
<U
>(u
))
67 { return std::forward
<T
>(t
) < std::forward
<U
>(u
); }
69 int is_transparent
; // error - should be a type
72 struct C2Int
{ // comparable to int
74 C2Int(int i
): i_(i
) {}
75 int get () const { return i_
; }
80 bool operator <(int rhs
, const C2Int
& lhs
) { return rhs
< lhs
.get(); }
81 bool operator <(const C2Int
& rhs
, const C2Int
& lhs
) { return rhs
.get() < lhs
.get(); }
82 bool operator <(const C2Int
& rhs
, int lhs
) { return rhs
.get() < lhs
; }
84 #endif // TEST_STD_VER > 11
96 constexpr std::size_t operator()(SearchedType
<T
> const& t
) const {
97 return static_cast<std::size_t>(t
.get_value());
100 template <typename T
>
101 constexpr std::size_t operator()(StoredType
<T
> const& t
) const {
102 return static_cast<std::size_t>(t
.get_value());
106 struct non_transparent_hash
: hash_impl
{};
108 struct transparent_hash
: hash_impl
{
109 using is_transparent
= void;
112 struct transparent_hash_final final
: transparent_hash
{};
114 struct transparent_equal_final final
: std::equal_to
<> {};
116 template <typename T
>
117 struct SearchedType
{
118 SearchedType(T value
, int* counter
) : value_(value
), conversions_(counter
) { }
120 // Whenever a conversion is performed, increment the counter to keep track
122 operator StoredType
<T
>() const {
124 return StoredType
<T
>{value_
};
127 int get_value() const {
136 template <typename T
>
138 StoredType() = default;
139 StoredType(T value
) : value_(value
) { }
141 friend bool operator==(StoredType
const& lhs
, StoredType
const& rhs
) {
142 return lhs
.value_
== rhs
.value_
;
145 // If we're being passed a SearchedType<T> object, avoid the conversion
146 // to T. This allows testing that the transparent operations are correctly
147 // forwarding the SearchedType all the way to this comparison by checking
148 // that we didn't have a conversion when we search for a SearchedType<T>
149 // in a container full of StoredType<T>.
150 friend bool operator==(StoredType
const& lhs
, SearchedType
<T
> const& rhs
) {
151 return lhs
.value_
== rhs
.get_value();
153 friend bool operator==(SearchedType
<T
> const& lhs
, StoredType
<T
> const& rhs
) {
154 return lhs
.get_value() == rhs
.value_
;
157 int get_value() const {
165 #endif // TEST_STD_VER > 17
167 #endif // TRANSPARENT_H