tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
uint128.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2// SPDX-FileCopyrightText: Copyright (C) 2025 Tobias Hienzsch
3
4#ifndef TETL_CSTDINT_UINT128_HPP
5#define TETL_CSTDINT_UINT128_HPP
6
7#include <etl/_config/all.hpp>
8
9#include <etl/_cstdint/uint_t.hpp>
10#include <etl/_limits/numeric_limits.hpp>
11
12namespace etl {
13
14struct uint128 {
15 constexpr uint128() = default;
16
17 constexpr uint128(uint64_t val) noexcept
18 : _low{val}
19 {
20 }
21
22 constexpr uint128(uint64_t high, uint64_t low) noexcept
23#if defined(_MSC_VER) || (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
24 : _low{low}
25 , _high{high}
26#else
27 : _high{high}
28 , _low{low}
29#endif
30 {
31 }
32
33 [[nodiscard]] constexpr explicit operator bool() const noexcept
34 {
35 return (low() | high()) != 0;
36 }
37
38 [[nodiscard]] constexpr explicit operator uint64_t() const noexcept
39 {
40 return low();
41 }
42
43 [[nodiscard]] constexpr auto low() const noexcept -> uint64_t
44 {
45 return _low;
46 }
47
48 [[nodiscard]] constexpr auto high() const noexcept -> uint64_t
49 {
50 return _high;
51 }
52
53 friend constexpr auto operator==(uint128 const& lhs, uint128 const& rhs) noexcept -> bool
54 {
55 return (lhs.low() == rhs.low()) and (lhs.high() == rhs.high());
56 }
57
58 friend constexpr auto operator!=(uint128 const& lhs, uint128 const& rhs) noexcept -> bool
59 {
60 return not(lhs == rhs);
61 }
62
63 friend constexpr auto operator<(uint128 const& a, uint128 const& b) noexcept -> bool
64 {
65 return (a.high() < b.high()) or (a.high() == b.high() and a.low() < b.low());
66 }
67
68 friend constexpr auto operator>(uint128 const& a, uint128 const& b) noexcept -> bool
69 {
70 return b < a;
71 }
72
73 friend constexpr auto operator<=(uint128 const& a, uint128 const& b) noexcept -> bool
74 {
75 return not(b < a);
76 }
77
78 friend constexpr auto operator>=(uint128 const& a, uint128 const& b) noexcept -> bool
79 {
80 return not(a < b);
81 }
82
83 friend constexpr auto operator&(uint128 const& lhs, uint128 const& rhs) noexcept -> uint128
84 {
85 return {lhs.low() & rhs.low(), lhs.high() & rhs.high()};
86 }
87
88 friend constexpr auto operator|(uint128 const& lhs, uint128 const& rhs) noexcept -> uint128
89 {
90 return {lhs.low() | rhs.low(), lhs.high() | rhs.high()};
91 }
92
93 friend constexpr auto operator^(uint128 const& lhs, uint128 const& rhs) noexcept -> uint128
94 {
95 return {lhs.low() ^ rhs.low(), lhs.high() ^ rhs.high()};
96 }
97
98 friend constexpr auto operator+(uint128 const& a, uint128 const& b) noexcept -> uint128
99 {
100 auto const [low, carry] = add_with_carry(a.low(), b.low());
101 return {a.high() + b.high() + carry, low};
102 }
103
104private:
105 struct with_carry {
106 uint64_t val;
107 uint64_t carry;
108 };
109
110 static constexpr auto add_with_carry(uint64_t a, uint64_t b) noexcept -> with_carry
111 {
112 auto const sum = a + b;
113 return with_carry{.val = sum, .carry = static_cast<uint64_t>(sum < a)};
114 }
115
116#if defined(_MSC_VER) || (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
117 uint64_t _low{0};
118 uint64_t _high{0};
119#else
120 uint64_t _high{0};
121 uint64_t _low{0};
122#endif
123};
124
125using uint128_t = uint128;
126
127template <>
129 static constexpr bool is_specialized = true;
130
131 static constexpr auto lowest() noexcept -> uint128
132 {
133 return uint128{0};
134 }
135 static constexpr auto min() noexcept -> uint128
136 {
137 return uint128{0};
138 }
139 static constexpr auto max() noexcept -> uint128
140 {
141 return uint128{~uint64_t{0}, ~uint64_t{0}};
142 }
143};
144
145} // namespace etl
146
147#endif // TETL_CSTDINT_UINT128_HPP
Definition adjacent_find.hpp:9
static constexpr bool is_specialized
Definition uint128.hpp:129
static constexpr auto lowest() noexcept -> uint128
Definition uint128.hpp:131
static constexpr auto max() noexcept -> uint128
Definition uint128.hpp:139
static constexpr auto min() noexcept -> uint128
Definition uint128.hpp:135
Definition numeric_limits.hpp:18
Definition uint128.hpp:14
friend constexpr auto operator!=(uint128 const &lhs, uint128 const &rhs) noexcept -> bool
Definition uint128.hpp:58
friend constexpr auto operator>=(uint128 const &a, uint128 const &b) noexcept -> bool
Definition uint128.hpp:78
constexpr auto high() const noexcept -> uint64_t
Definition uint128.hpp:48
constexpr uint128(uint64_t high, uint64_t low) noexcept
Definition uint128.hpp:22
constexpr auto low() const noexcept -> uint64_t
Definition uint128.hpp:43
constexpr operator bool() const noexcept
Definition uint128.hpp:33
friend constexpr auto operator>(uint128 const &a, uint128 const &b) noexcept -> bool
Definition uint128.hpp:68
constexpr operator uint64_t() const noexcept
Definition uint128.hpp:38
constexpr uint128()=default
friend constexpr auto operator==(uint128 const &lhs, uint128 const &rhs) noexcept -> bool
Definition uint128.hpp:53
friend constexpr auto operator&(uint128 const &lhs, uint128 const &rhs) noexcept -> uint128
Definition uint128.hpp:83
friend constexpr auto operator|(uint128 const &lhs, uint128 const &rhs) noexcept -> uint128
Definition uint128.hpp:88
friend constexpr auto operator<=(uint128 const &a, uint128 const &b) noexcept -> bool
Definition uint128.hpp:73
constexpr uint128(uint64_t val) noexcept
Definition uint128.hpp:17
friend constexpr auto operator^(uint128 const &lhs, uint128 const &rhs) noexcept -> uint128
Definition uint128.hpp:93
friend constexpr auto operator+(uint128 const &a, uint128 const &b) noexcept -> uint128
Definition uint128.hpp:98
friend constexpr auto operator<(uint128 const &a, uint128 const &b) noexcept -> bool
Definition uint128.hpp:63