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// <algorithm> 11// XFAIL: c++98, c++03, c++11, c++14 12 13// template<class T, class Compare> 14// const T& 15// clamp(const T& v, const T& lo, const T& hi, Compare comp); 16 17#include <algorithm> 18#include <functional> 19#include <cassert> 20 21struct Tag { 22 Tag() : val(0), tag("Default") {} 23 Tag(int a, const char *b) : val(a), tag(b) {} 24 ~Tag() {} 25 26 int val; 27 const char *tag; 28 }; 29 30bool eq(const Tag& rhs, const Tag& lhs) { return rhs.val == lhs.val && rhs.tag == lhs.tag; } 31// bool operator==(const Tag& rhs, const Tag& lhs) { return rhs.val == lhs.val; } 32bool comp (const Tag& rhs, const Tag& lhs) { return rhs.val < lhs.val; } 33 34 35template <class T, class C> 36void 37test(const T& v, const T& lo, const T& hi, C c, const T& x) 38{ 39 assert(&std::clamp(v, lo, hi, c) == &x); 40} 41 42int main() 43{ 44 { 45 int x = 0; 46 int y = 0; 47 int z = 0; 48 test(x, y, z, std::greater<int>(), x); 49 test(y, x, z, std::greater<int>(), y); 50 } 51 { 52 int x = 0; 53 int y = 1; 54 int z = -1; 55 test(x, y, z, std::greater<int>(), x); 56 test(y, x, z, std::greater<int>(), x); 57 } 58 { 59 int x = 1; 60 int y = 0; 61 int z = 0; 62 test(x, y, z, std::greater<int>(), y); 63 test(y, x, z, std::greater<int>(), y); 64 } 65 66 { 67// If they're all the same, we should get the value back. 68 Tag x{0, "Zero-x"}; 69 Tag y{0, "Zero-y"}; 70 Tag z{0, "Zero-z"}; 71 assert(eq(std::clamp(x, y, z, comp), x)); 72 assert(eq(std::clamp(y, x, z, comp), y)); 73 } 74 75 { 76// If it's the same as the lower bound, we get the value back. 77 Tag x{0, "Zero-x"}; 78 Tag y{0, "Zero-y"}; 79 Tag z{1, "One-z"}; 80 assert(eq(std::clamp(x, y, z, comp), x)); 81 assert(eq(std::clamp(y, x, z, comp), y)); 82 } 83 84 { 85// If it's the same as the upper bound, we get the value back. 86 Tag x{1, "One-x"}; 87 Tag y{0, "Zero-y"}; 88 Tag z{1, "One-z"}; 89 assert(eq(std::clamp(x, y, z, comp), x)); 90 assert(eq(std::clamp(z, y, x, comp), z)); 91 } 92 93 { 94// If the value is between, we should get the value back 95 Tag x{1, "One-x"}; 96 Tag y{0, "Zero-y"}; 97 Tag z{2, "Two-z"}; 98 assert(eq(std::clamp(x, y, z, comp), x)); 99 assert(eq(std::clamp(y, x, z, comp), x)); 100 } 101 102 { 103// If the value is less than the 'lo', we should get the lo back. 104 Tag x{0, "Zero-x"}; 105 Tag y{1, "One-y"}; 106 Tag z{2, "Two-z"}; 107 assert(eq(std::clamp(x, y, z, comp), y)); 108 assert(eq(std::clamp(y, x, z, comp), y)); 109 } 110 { 111// If the value is greater than 'hi', we should get hi back. 112 Tag x{2, "Two-x"}; 113 Tag y{0, "Zero-y"}; 114 Tag z{1, "One-z"}; 115 assert(eq(std::clamp(x, y, z, comp), z)); 116 assert(eq(std::clamp(y, z, x, comp), z)); 117 } 118 119 { 120 typedef int T; 121 constexpr T x = 1; 122 constexpr T y = 0; 123 constexpr T z = 0; 124 static_assert(std::clamp(x, y, z, std::greater<T>()) == y, "" ); 125 static_assert(std::clamp(y, x, z, std::greater<T>()) == y, "" ); 126 } 127} 128