13e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow//===----------------------------------------------------------------------===// 23e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow// 33e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow// The LLVM Compiler Infrastructure 43e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow// 53e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow// This file is dual licensed under the MIT and the University of Illinois Open 63e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow// Source Licenses. See LICENSE.TXT for details. 73e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow// 83e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow//===----------------------------------------------------------------------===// 93e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow 103e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow// <algorithm> 111575e3e813f7f7cde31e699802fa1fcf8e84531cAsiri Rathnayake// XFAIL: c++98, c++03, c++11, c++14 123e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow 133e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow// template<class T> 143e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow// const T& 153e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow// clamp(const T& v, const T& lo, const T& hi); 163e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow 173e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow#include <algorithm> 183e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow#include <cassert> 193e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow 200b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clowstruct Tag { 210b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow Tag() : val(0), tag("Default") {} 220b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow Tag(int a, const char *b) : val(a), tag(b) {} 230b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow ~Tag() {} 24e33c0b01f892f8919f66a066a9c4064010104e49Stephan T. Lavavej 250b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow int val; 260b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow const char *tag; 270b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow }; 28e33c0b01f892f8919f66a066a9c4064010104e49Stephan T. Lavavej 290b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clowbool eq(const Tag& rhs, const Tag& lhs) { return rhs.val == lhs.val && rhs.tag == lhs.tag; } 300b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow// bool operator==(const Tag& rhs, const Tag& lhs) { return rhs.val == lhs.val; } 310b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clowbool operator< (const Tag& rhs, const Tag& lhs) { return rhs.val < lhs.val; } 320b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow 333e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clowtemplate <class T> 343e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clowvoid 353e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clowtest(const T& a, const T& lo, const T& hi, const T& x) 363e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow{ 373e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow assert(&std::clamp(a, lo, hi) == &x); 383e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow} 393e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow 403e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clowint main() 413e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow{ 423e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow { 433e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow int x = 0; 443e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow int y = 0; 453e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow int z = 0; 463e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow test(x, y, z, x); 473e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow test(y, x, z, y); 483e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow } 493e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow { 503e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow int x = 0; 513e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow int y = 1; 523e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow int z = 2; 533e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow test(x, y, z, y); 543e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow test(y, x, z, y); 553e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow } 563e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow { 573e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow int x = 1; 583e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow int y = 0; 593e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow int z = 1; 603e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow test(x, y, z, x); 613e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow test(y, x, z, x); 623e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow } 630b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow 640b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow { 650b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow// If they're all the same, we should get the value back. 660b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow Tag x{0, "Zero-x"}; 670b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow Tag y{0, "Zero-y"}; 680b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow Tag z{0, "Zero-z"}; 690b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow assert(eq(std::clamp(x, y, z), x)); 700b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow assert(eq(std::clamp(y, x, z), y)); 710b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow } 720b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow 730b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow { 740b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow// If it's the same as the lower bound, we get the value back. 750b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow Tag x{0, "Zero-x"}; 760b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow Tag y{0, "Zero-y"}; 770b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow Tag z{1, "One-z"}; 780b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow assert(eq(std::clamp(x, y, z), x)); 790b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow assert(eq(std::clamp(y, x, z), y)); 800b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow } 810b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow 820b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow { 830b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow// If it's the same as the upper bound, we get the value back. 840b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow Tag x{1, "One-x"}; 850b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow Tag y{0, "Zero-y"}; 860b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow Tag z{1, "One-z"}; 870b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow assert(eq(std::clamp(x, y, z), x)); 880b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow assert(eq(std::clamp(z, y, x), z)); 890b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow } 900b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow 910b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow { 920b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow// If the value is between, we should get the value back 930b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow Tag x{1, "One-x"}; 940b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow Tag y{0, "Zero-y"}; 950b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow Tag z{2, "Two-z"}; 960b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow assert(eq(std::clamp(x, y, z), x)); 970b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow assert(eq(std::clamp(y, x, z), x)); 980b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow } 990b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow 1000b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow { 1010b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow// If the value is less than the 'lo', we should get the lo back. 1020b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow Tag x{0, "Zero-x"}; 1030b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow Tag y{1, "One-y"}; 1040b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow Tag z{2, "Two-z"}; 1050b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow assert(eq(std::clamp(x, y, z), y)); 1060b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow assert(eq(std::clamp(y, x, z), y)); 1070b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow } 1080b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow { 1090b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow// If the value is greater than 'hi', we should get hi back. 1100b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow Tag x{2, "Two-x"}; 1110b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow Tag y{0, "Zero-y"}; 1120b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow Tag z{1, "One-z"}; 1130b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow assert(eq(std::clamp(x, y, z), z)); 1140b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow assert(eq(std::clamp(y, z, x), z)); 1150b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow } 1160b02cf8cf16919074f88c26d412c34ad2cffc097Marshall Clow 1173e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow { 1183e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow typedef int T; 1193e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow constexpr T x = 1; 1203e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow constexpr T y = 0; 1213e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow constexpr T z = 1; 1223e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow static_assert(std::clamp(x, y, z) == x, "" ); 1233e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow static_assert(std::clamp(y, x, z) == x, "" ); 1243e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow } 1253e0808efb8c19765ee86e950a8a6e340c5565c89Marshall Clow} 126