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 #ifndef TRANSPARENT_H
10 #define TRANSPARENT_H
11 
12 #include "test_macros.h"
13 
14 #include <functional> // for std::equal_to
15 
16 // testing transparent
17 #if TEST_STD_VER > 11
18 
19 struct transparent_less
20 {
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
27 };
28 
29 struct transparent_less_not_referenceable
30 {
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
37 };
38 
39 struct transparent_less_no_type
40 {
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
48 };
49 
50 struct transparent_less_private
51 {
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
59 };
60 
61 struct transparent_less_not_a_type
62 {
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); }
68 
69     int is_transparent;  // error - should be a type
70 };
71 
72 struct C2Int { // comparable to int
C2IntC2Int73     C2Int() : i_(0) {}
C2IntC2Int74     C2Int(int i): i_(i) {}
getC2Int75     int get () const { return i_; }
76 private:
77     int i_;
78     };
79 
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; }
83 
84 #endif // TEST_STD_VER > 11
85 
86 #endif // TRANSPARENT_H
87