[PowerPC][NFC] Cleanup PPCCTRLoopsVerify pass
[llvm-project.git] / libcxx / test / support / is_transparent.h
blob9088ab67d31bbf232d9b2c3461dae7a24ca637b1
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 //===----------------------------------------------------------------------===//
9 #ifndef TRANSPARENT_H
10 #define TRANSPARENT_H
12 #include "test_macros.h"
14 #include <functional> // for std::equal_to
16 // testing transparent
17 #if TEST_STD_VER > 11
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); }
46 private:
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); }
57 private:
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
73 C2Int() : i_(0) {}
74 C2Int(int i): i_(i) {}
75 int get () const { return i_; }
76 private:
77 int 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
86 #if TEST_STD_VER > 17
88 template <typename T>
89 struct StoredType;
91 template <typename T>
92 struct SearchedType;
94 struct hash_impl {
95 template <typename T>
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
121 // of conversions.
122 operator StoredType<T>() const {
123 ++*conversions_;
124 return StoredType<T>{value_};
127 int get_value() const {
128 return value_;
131 private:
132 T value_;
133 int* conversions_;
136 template <typename T>
137 struct StoredType {
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 {
158 return value_;
161 private:
162 T value_;
165 #endif // TEST_STD_VER > 17
167 #endif // TRANSPARENT_H