clamp.comp.pass.cpp 3.2 KB

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