stdex
Additional custom or not Standard C++ covered algorithms
Loading...
Searching...
No Matches
math.hpp
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 2023-2024 Amebis
4*/
5
6#pragma once
7
8#include "compat.hpp"
9#ifdef _WIN32
10#include "windows.h"
11#include <intrin.h>
12#include <intsafe.h>
13#endif
14#include <stdexcept>
15
16namespace stdex
17{
26 inline size_t mul(size_t a, size_t b)
27 {
28#if _MSC_VER >= 1300
29 SIZE_T result;
30 if (SUCCEEDED(SIZETMult(a, b, &result)))
31 return result;
32#elif defined(_MSC_VER)
33 if (a == 0)
34 return 0;
35 if (b <= SIZE_MAX / a)
36 return a * b;
37#else
38 size_t result;
39 if (!__builtin_mul_overflow(a, b, &result))
40 return result;
41#endif
42 throw std::invalid_argument("multiply overflow");
43 }
44
53 inline size_t add(size_t a, size_t b)
54 {
55#if _MSC_VER >= 1300
56 SIZE_T result;
57 if (SUCCEEDED(SIZETAdd(a, b, &result)))
58 return result;
59#elif defined(_MSC_VER)
60 if (a <= SIZE_MAX - b)
61 return a + b;
62#else
63 size_t result;
64 if (!__builtin_add_overflow(a, b, &result))
65 return result;
66#endif
67 throw std::invalid_argument("add overflow");
68 }
69
78 inline uint32_t rol(_In_ uint32_t value, _In_ int bits)
79 {
80#ifdef _WIN32
81 return _rotl(value, bits);
82#else
83 return (value << bits) | (value >> (32 - bits));
84#endif
85 }
86
96 inline constexpr int32_t muldiv(int32_t n, int32_t k, int32_t q)
97 {
98 return static_cast<int32_t>(static_cast<int64_t>(n) * k / q);
99 }
100
110 inline constexpr uint32_t muldiv(uint32_t n, uint32_t k, uint32_t q)
111 {
112 return static_cast<uint32_t>(static_cast<uint64_t>(n) * k / q);
113 }
114
124 inline constexpr int64_t muldiv(int64_t n, int64_t k, int64_t q)
125 {
126 return n * k / q;
127 }
128
138 inline constexpr uint64_t muldiv(uint64_t n, uint64_t k, uint64_t q)
139 {
140 return n * k / q;
141 }
142}