chromium/base/numerics/checked_math.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_CHECKED_MATH_H_
#define BASE_NUMERICS_CHECKED_MATH_H_

#include <stdint.h>
#include <limits>
#include <type_traits>

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

namespace base {
namespace internal {

template <typename T>
class CheckedNumeric {};

// Convenience functions to avoid the ugly template disambiguator syntax.
template <typename Dst, typename Src>
constexpr bool IsValidForType(const CheckedNumeric<Src> value) {}

template <typename Dst, typename Src>
constexpr StrictNumeric<Dst> ValueOrDieForType(
    const CheckedNumeric<Src> value) {}

template <typename Dst, typename Src, typename Default>
constexpr StrictNumeric<Dst> ValueOrDefaultForType(
    const CheckedNumeric<Src> value,
    const Default default_value) {}

// Convenience wrapper to return a new CheckedNumeric from the provided
// arithmetic or CheckedNumericType.
template <typename T>
constexpr CheckedNumeric<typename UnderlyingType<T>::type> MakeCheckedNum(
    const T value) {}

// These implement the variadic wrapper for the math operations.
template <template <typename, typename> class M, typename L, typename R>
constexpr CheckedNumeric<typename MathWrapper<M, L, R>::type> CheckMathOp(
    const L lhs,
    const R rhs) {}

// General purpose wrapper template for arithmetic operations.
template <template <typename, typename> class M,
          typename L,
          typename R,
          typename... Args>
constexpr auto CheckMathOp(const L lhs, const R rhs, const Args... args) {}

BASE_NUMERIC_ARITHMETIC_OPERATORS(Checked, Check, Add, +, +=)
BASE_NUMERIC_ARITHMETIC_OPERATORS(Checked, Check, Sub, -, -=)
BASE_NUMERIC_ARITHMETIC_OPERATORS(Checked, Check, Mul, *, *=)
BASE_NUMERIC_ARITHMETIC_OPERATORS(Checked, Check, Div, /, /=)
BASE_NUMERIC_ARITHMETIC_OPERATORS(Checked, Check, Mod, %, %=)
BASE_NUMERIC_ARITHMETIC_OPERATORS(Checked, Check, Lsh, <<, <<=)
BASE_NUMERIC_ARITHMETIC_OPERATORS(Checked, Check, Rsh, >>, >>=)
BASE_NUMERIC_ARITHMETIC_OPERATORS(Checked, Check, And, &, &=)
BASE_NUMERIC_ARITHMETIC_OPERATORS(Checked, Check, Or, |, |=)
BASE_NUMERIC_ARITHMETIC_OPERATORS(Checked, Check, Xor, ^, ^=)
BASE_NUMERIC_ARITHMETIC_VARIADIC()
BASE_NUMERIC_ARITHMETIC_VARIADIC()

// These are some extra StrictNumeric operators to support simple pointer
// arithmetic with our result types. Since wrapping on a pointer is always
// bad, we trigger the CHECK condition here.
template <typename L, typename R>
L* operator+(L* lhs, const StrictNumeric<R> rhs) {}

template <typename L, typename R>
L* operator-(L* lhs, const StrictNumeric<R> rhs) {}

}  // namespace internal

CheckAdd;
CheckAnd;
CheckDiv;
CheckedNumeric;
CheckLsh;
CheckMax;
CheckMin;
CheckMod;
CheckMul;
CheckOr;
CheckRsh;
CheckSub;
CheckXor;
IsValidForType;
MakeCheckedNum;
ValueOrDefaultForType;
ValueOrDieForType;

}  // namespace base

#endif  // BASE_NUMERICS_CHECKED_MATH_H_