98 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef TRANSPARENT_H10#define TRANSPARENT_H11 12#include "test_macros.h"13 14#include <functional> // for std::equal_to15 16// testing transparent17#if TEST_STD_VER > 1118 19struct transparent_less20{21 template <class T, class U>22 constexpr auto operator()(T&& t, U&& u) const23 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; // correct27};28 29struct transparent_less_not_referenceable30{31 template <class T, class U>32 constexpr auto operator()(T&& t, U&& u) const33 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 type37};38 39// Prevent regression when empty base class optimization is not suitable.40// See llvm.org/PR152543.41struct transparent_less_nonempty {42 template <class T, class U>43 constexpr bool operator()(T&& t, U&& u) const {44 return std::forward<T>(t) < std::forward<U>(u);45 }46 struct is_transparent {47 } pad_; // making this comparator non-empty48};49 50struct transparent_less_no_type51{52 template <class T, class U>53 constexpr auto operator()(T&& t, U&& u) const54 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); }57private:58// using is_transparent = void; // error - should exist59};60 61struct transparent_less_private62{63 template <class T, class U>64 constexpr auto operator()(T&& t, U&& u) const65 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); }68private:69 using is_transparent = void; // error - should be accessible70};71 72struct transparent_less_not_a_type73{74 template <class T, class U>75 constexpr auto operator()(T&& t, U&& u) const76 noexcept(noexcept(std::forward<T>(t) < std::forward<U>(u)))77 -> decltype (std::forward<T>(t) < std::forward<U>(u))78 { return std::forward<T>(t) < std::forward<U>(u); }79 80 int is_transparent; // error - should be a type81};82 83struct C2Int { // comparable to int84 C2Int() : i_(0) {}85 C2Int(int i): i_(i) {}86 int get () const { return i_; }87private:88 int i_;89 };90 91bool operator <(int rhs, const C2Int& lhs) { return rhs < lhs.get(); }92bool operator <(const C2Int& rhs, const C2Int& lhs) { return rhs.get() < lhs.get(); }93bool operator <(const C2Int& rhs, int lhs) { return rhs.get() < lhs; }94 95#endif // TEST_STD_VER > 1196 97#endif // TRANSPARENT_H98