chromium/base/numerics/clamped_math_impl.h

// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BASE_NUMERICS_CLAMPED_MATH_IMPL_H_
#define BASE_NUMERICS_CLAMPED_MATH_IMPL_H_

// IWYU pragma: private, include "base/numerics/clamped_math.h"

#include <concepts>
#include <limits>
#include <type_traits>

#include "base/numerics/checked_math.h"
#include "base/numerics/safe_conversions.h"
#include "base/numerics/safe_math_shared_impl.h"  // IWYU pragma: export

namespace base {
namespace internal {

template <typename T>
  requires(std::signed_integral<T>)
constexpr T SaturatedNegWrapper(T value) {}

template <typename T>
  requires(std::unsigned_integral<T>)
constexpr T SaturatedNegWrapper(T value) {}

template <typename T>
  requires(std::floating_point<T>)
constexpr T SaturatedNegWrapper(T value) {}

template <typename T>
  requires(std::integral<T>)
constexpr T SaturatedAbsWrapper(T value) {}

template <typename T>
  requires(std::floating_point<T>)
constexpr T SaturatedAbsWrapper(T value) {}

template <typename T, typename U>
struct ClampedAddOp {};

ClampedAddOp<T, U>;

template <typename T, typename U>
struct ClampedSubOp {};

ClampedSubOp<T, U>;

template <typename T, typename U>
struct ClampedMulOp {};

ClampedMulOp<T, U>;

template <typename T, typename U>
struct ClampedDivOp {};

ClampedDivOp<T, U>;

template <typename T, typename U>
struct ClampedModOp {};

ClampedModOp<T, U>;

template <typename T, typename U>
struct ClampedLshOp {};

// Left shift. Non-zero values saturate in the direction of the sign. A zero
// shifted by any value always results in zero.
ClampedLshOp<T, U>;

template <typename T, typename U>
struct ClampedRshOp {};

// Right shift. Negative values saturate to -1. Positive or 0 saturates to 0.
ClampedRshOp<T, U>;

template <typename T, typename U>
struct ClampedAndOp {};

ClampedAndOp<T, U>;

template <typename T, typename U>
struct ClampedOrOp {};

// For simplicity we promote to unsigned integers.
ClampedOrOp<T, U>;

template <typename T, typename U>
struct ClampedXorOp {};

// For simplicity we support only unsigned integers.
ClampedXorOp<T, U>;

template <typename T, typename U>
struct ClampedMaxOp {};

ClampedMaxOp<T, U>;

template <typename T, typename U>
struct ClampedMinOp {};

ClampedMinOp<T, U>;

// This is just boilerplate that wraps the standard floating point arithmetic.
// A macro isn't the nicest solution, but it beats rewriting these repeatedly.
#define BASE_FLOAT_ARITHMETIC_OPS

BASE_FLOAT_ARITHMETIC_OPS
BASE_FLOAT_ARITHMETIC_OPS
BASE_FLOAT_ARITHMETIC_OPS
BASE_FLOAT_ARITHMETIC_OPS

#undef BASE_FLOAT_ARITHMETIC_OPS

}  // namespace internal
}  // namespace base

#endif  // BASE_NUMERICS_CLAMPED_MATH_IMPL_H_