From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- mfbt/tests/TestSaturate.cpp | 181 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 mfbt/tests/TestSaturate.cpp (limited to 'mfbt/tests/TestSaturate.cpp') diff --git a/mfbt/tests/TestSaturate.cpp b/mfbt/tests/TestSaturate.cpp new file mode 100644 index 0000000000..500c9eed7f --- /dev/null +++ b/mfbt/tests/TestSaturate.cpp @@ -0,0 +1,181 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include + +#include + +#include + +using mozilla::detail::Saturate; + +#define A(a) MOZ_RELEASE_ASSERT(a, "Test \'" #a "\' failed.") + +static const unsigned long sNumOps = 32; + +template +static T StartValue() { + // Specialize |StartValue| for the given type. + A(false); +} + +template <> +int8_t StartValue() { + return 0; +} + +template <> +int16_t StartValue() { + return 0; +} + +template <> +int32_t StartValue() { + return 0; +} + +template <> +uint8_t StartValue() { + // Picking a value near middle of uint8_t's range. + return static_cast(std::numeric_limits::max()); +} + +template <> +uint16_t StartValue() { + // Picking a value near middle of uint16_t's range. + return static_cast(std::numeric_limits::max()); +} + +template <> +uint32_t StartValue() { + // Picking a value near middle of uint32_t's range. + return static_cast(std::numeric_limits::max()); +} + +// Add +// + +template +static void TestPrefixIncr() { + T value = StartValue(); + Saturate satValue(value); + + for (T i = 0; i < static_cast(sNumOps); ++i) { + A(++value == ++satValue); + } +} + +template +static void TestPostfixIncr() { + T value = StartValue(); + Saturate satValue(value); + + for (T i = 0; i < static_cast(sNumOps); ++i) { + A(value++ == satValue++); + } +} + +template +static void TestAdd() { + T value = StartValue(); + Saturate satValue(value); + + for (T i = 0; i < static_cast(sNumOps); ++i) { + A((value + i) == (satValue + i)); + } +} + +// Subtract +// + +template +static void TestPrefixDecr() { + T value = StartValue(); + Saturate satValue(value); + + for (T i = 0; i < static_cast(sNumOps); ++i) { + A(--value == --satValue); + } +} + +template +static void TestPostfixDecr() { + T value = StartValue(); + Saturate satValue(value); + + for (T i = 0; i < static_cast(sNumOps); ++i) { + A(value-- == satValue--); + } +} + +template +static void TestSub() { + T value = StartValue(); + Saturate satValue(value); + + for (T i = 0; i < static_cast(sNumOps); ++i) { + A((value - i) == (satValue - i)); + } +} + +// Corner cases near bounds +// + +template +static void TestUpperBound() { + Saturate satValue(std::numeric_limits::max()); + + A(--satValue == (std::numeric_limits::max() - 1)); + A(++satValue == (std::numeric_limits::max())); + A(++satValue == (std::numeric_limits::max())); // don't overflow here + A(++satValue == (std::numeric_limits::max())); // don't overflow here + A(--satValue == (std::numeric_limits::max() - 1)); // back at (max - 1) + A(--satValue == (std::numeric_limits::max() - 2)); +} + +template +static void TestLowerBound() { + Saturate satValue(std::numeric_limits::min()); + + A(++satValue == (std::numeric_limits::min() + 1)); + A(--satValue == (std::numeric_limits::min())); + A(--satValue == (std::numeric_limits::min())); // don't overflow here + A(--satValue == (std::numeric_limits::min())); // don't overflow here + A(++satValue == (std::numeric_limits::min() + 1)); // back at (max + 1) + A(++satValue == (std::numeric_limits::min() + 2)); +} + +// Framework +// + +template +static void TestAll() { + // Assert that we don't accidently hit type's range limits in tests. + const T value = StartValue(); + A(std::numeric_limits::min() + static_cast(sNumOps) <= value); + A(std::numeric_limits::max() - static_cast(sNumOps) >= value); + + TestPrefixIncr(); + TestPostfixIncr(); + TestAdd(); + + TestPrefixDecr(); + TestPostfixDecr(); + TestSub(); + + TestUpperBound(); + TestLowerBound(); +} + +int main() { + TestAll(); + TestAll(); + TestAll(); + TestAll(); + TestAll(); + TestAll(); + return 0; +} -- cgit v1.2.3