1//===----------------------------------------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef TRANSPARENT_H
11#define TRANSPARENT_H
12
13#include "test_macros.h"
14
15// testing transparent
16#if TEST_STD_VER > 11
17
18struct transparent_less
19{
20    template <class T, class U>
21    constexpr auto operator()(T&& t, U&& u) const
22    noexcept(noexcept(std::forward<T>(t) < std::forward<U>(u)))
23    -> decltype      (std::forward<T>(t) < std::forward<U>(u))
24        { return      std::forward<T>(t) < std::forward<U>(u); }
25    using is_transparent = void;  // correct
26};
27
28struct transparent_less_not_referenceable
29{
30    template <class T, class U>
31    constexpr auto operator()(T&& t, U&& u) const
32    noexcept(noexcept(std::forward<T>(t) < std::forward<U>(u)))
33    -> decltype      (std::forward<T>(t) < std::forward<U>(u))
34        { return      std::forward<T>(t) < std::forward<U>(u); }
35    using is_transparent = void () const &;  // it's a type; a weird one, but a type
36};
37
38struct transparent_less_no_type
39{
40    template <class T, class U>
41    constexpr auto operator()(T&& t, U&& u) const
42    noexcept(noexcept(std::forward<T>(t) < std::forward<U>(u)))
43    -> decltype      (std::forward<T>(t) < std::forward<U>(u))
44        { return      std::forward<T>(t) < std::forward<U>(u); }
45private:
46//    using is_transparent = void;  // error - should exist
47};
48
49struct transparent_less_private
50{
51    template <class T, class U>
52    constexpr auto operator()(T&& t, U&& u) const
53    noexcept(noexcept(std::forward<T>(t) < std::forward<U>(u)))
54    -> decltype      (std::forward<T>(t) < std::forward<U>(u))
55        { return      std::forward<T>(t) < std::forward<U>(u); }
56private:
57    using is_transparent = void;  // error - should be accessible
58};
59
60struct transparent_less_not_a_type
61{
62    template <class T, class U>
63    constexpr auto operator()(T&& t, U&& u) const
64    noexcept(noexcept(std::forward<T>(t) < std::forward<U>(u)))
65    -> decltype      (std::forward<T>(t) < std::forward<U>(u))
66        { return      std::forward<T>(t) < std::forward<U>(u); }
67
68    int is_transparent;  // error - should be a type
69};
70
71struct C2Int { // comparable to int
72    C2Int() : i_(0) {}
73    C2Int(int i): i_(i) {}
74    int get () const { return i_; }
75private:
76    int i_;
77    };
78
79bool operator <(int          rhs,   const C2Int& lhs) { return rhs       < lhs.get(); }
80bool operator <(const C2Int& rhs,   const C2Int& lhs) { return rhs.get() < lhs.get(); }
81bool operator <(const C2Int& rhs,            int lhs) { return rhs.get() < lhs; }
82
83#endif
84
85#endif  // TRANSPARENT_H
86