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