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