@@ -2083,6 +2083,142 @@ _sus_pure static constexpr _self from_ne_bytes(
2083
2083
const ::sus::collections::Array<u8, ::sus::mem::size_of<_primitive>()>&
2084
2084
bytes) noexcept ;
2085
2085
2086
+ // / Satisfies the [`Shl`]($sus::num::Shl) concept for signed integers.
2087
+ // /
2088
+ // / This operation supports shifting with primitive signed or unsigned integers
2089
+ // / that convert to the safe numeric, as well as enums.
2090
+ // / However enum class is excluded as they require an explicit conversion to an
2091
+ // / integer.
2092
+ // /
2093
+ // / Thus the bound is `std::convertible_to` (implicit conversion) instead of
2094
+ // / `sus::construct::From` (explicit conversion).
2095
+ // /
2096
+ // / # Panics
2097
+ // / This function will panic when `r` is not less than the number of bits in `l`
2098
+ // / if overflow checks are enabled (they are by default) and will perform a
2099
+ // / wrapping shift if overflow checks are disabled (not the default).
2100
+ // /
2101
+ // / See [overflow checks]($sus::num#overflow-behaviour) for controlling this
2102
+ // / behaviour.
2103
+ // /
2104
+ // / #[doc.overloads=signedint.<<]
2105
+ [[nodiscard]] __sus_pure_const constexpr friend _self operator <<(
2106
+ _self l, std::convertible_to<u64> auto r) noexcept {
2107
+ if constexpr (SUS_CHECK_INTEGER_OVERFLOW) {
2108
+ const auto out = __private::shl_with_overflow (l.primitive_value ,
2109
+ u64 (r).primitive_value );
2110
+ sus_check_with_message (!out.overflow ,
2111
+ " attempt to shift left with overflow" );
2112
+ return out.value ;
2113
+ } else {
2114
+ return l.wrapping_shl (u64 (r).primitive_value );
2115
+ }
2116
+ }
2117
+
2118
+ // / #[doc.overloads=signedint.<<]
2119
+ template <class U >
2120
+ requires (!std::convertible_to<U, u64>)
2121
+ constexpr friend _self operator<<(_self l, U r) noexcept = delete;
2122
+
2123
+ // / Satisfies the [`Shr`]($sus::num::Shr) concept for signed integers.
2124
+ // /
2125
+ // / Performs sign extension, copying the sign bit to the right if its set.
2126
+ // /
2127
+ // / # Panics
2128
+ // / This function will panic when `r` is not less than the number of bits in `l`
2129
+ // / if overflow checks are enabled (they are by default) and will perform a
2130
+ // / wrapping shift if overflow checks are disabled (not the default).
2131
+ // /
2132
+ // / See [overflow checks]($sus::num#overflow-behaviour) for controlling this
2133
+ // / behaviour.
2134
+ // /
2135
+ // / #[doc.overloads=signedint.>>]
2136
+ [[nodiscard]] __sus_pure_const constexpr friend _self operator >>(
2137
+ _self l, std::convertible_to<u64> auto r) noexcept {
2138
+ if constexpr (SUS_CHECK_INTEGER_OVERFLOW) {
2139
+ const auto out = __private::shr_with_overflow (l.primitive_value ,
2140
+ u64 (r).primitive_value );
2141
+ sus_check_with_message (!out.overflow ,
2142
+ " attempt to shift right with overflow" );
2143
+ return out.value ;
2144
+ } else {
2145
+ return l.wrapping_shr (u64 (r).primitive_value );
2146
+ }
2147
+ }
2148
+
2149
+ // / #[doc.overloads=signedint.>>]
2150
+ template <class U >
2151
+ requires (!std::convertible_to<U, u64>)
2152
+ constexpr friend _self operator>>(_self l, U r) noexcept = delete;
2153
+
2154
+ // / Satisfies the [`Shl`]($sus::num::Shl) concept for signed primitive integers
2155
+ // / shifted by [`u64`]($sus::num::u64).
2156
+ // / #[doc.overloads=signed.prim.<<u64]
2157
+ template <class P , class U >
2158
+ requires ((SignedPrimitiveInteger<P> || SignedPrimitiveEnum<P>) &&
2159
+ std::same_as<U, _self> && std::convertible_to<U, u64>)
2160
+ [[nodiscard]] __sus_pure_const constexpr friend P operator<<(P l, U r) noexcept {
2161
+ // No UB checks on primitive types, since there's no promotion to a Subspace
2162
+ // return type?
2163
+ return l << u64 (r).primitive_value ;
2164
+ }
2165
+ // / #[doc.overloads=signed.prim.<<u64]
2166
+ template <class P , class U >
2167
+ requires ((SignedPrimitiveInteger<P> || SignedPrimitiveEnum<P>) &&
2168
+ std::same_as<U, _self> && !std::convertible_to<U, u64>)
2169
+ constexpr friend P operator<<(P l, U r) noexcept = delete;
2170
+
2171
+ // / Satisfies the [`Shr`]($sus::num::Shr) concept for signed primitive integers
2172
+ // / shifted by [`u64`]($sus::num::u64).
2173
+ // /
2174
+ // / Performs sign extension, copying the sign bit to the right if its set.
2175
+ // / #[doc.overloads=signed.prim.>>u64]
2176
+ template <class P , class U >
2177
+ requires ((SignedPrimitiveInteger<P> || SignedPrimitiveEnum<P>) &&
2178
+ std::same_as<U, _self> && std::convertible_to<U, u64>)
2179
+ [[nodiscard]] __sus_pure_const constexpr friend P operator>>(P l, U r) noexcept {
2180
+ // No UB checks on primitive types, since there's no promotion to a Subspace
2181
+ // return type?
2182
+ return l >> u64 (r).primitive_value ;
2183
+ }
2184
+ // / #[doc.overloads=signed.prim.>>u64]
2185
+ template <class P , class U >
2186
+ requires ((SignedPrimitiveInteger<P> || SignedPrimitiveEnum<P>) &&
2187
+ std::same_as<U, _self> && !std::convertible_to<U, u64>)
2188
+ constexpr friend P operator>>(P l, U r) noexcept = delete;
2189
+
2190
+ // / #[doc.overloads=unsigned.prim.<<u64]
2191
+ template <class P , class U >
2192
+ requires ((UnsignedPrimitiveInteger<P> || UnsignedPrimitiveEnum<P>) &&
2193
+ std::same_as<U, _self> && std::convertible_to<U, u64>)
2194
+ [[nodiscard]] __sus_pure_const constexpr friend P operator<<(P l, U r) noexcept {
2195
+ // No UB checks on primitive types, since there's no promotion to a Subspace
2196
+ // return type?
2197
+ return l << u64 (r).primitive_value ;
2198
+ }
2199
+
2200
+ // / #[doc.overloads=unsigned.prim.<<u64]
2201
+ template <class P , class U >
2202
+ requires ((UnsignedPrimitiveInteger<P> || UnsignedPrimitiveEnum<P>) &&
2203
+ std::same_as<U, _self> && !std::convertible_to<U, u64>)
2204
+ constexpr friend P operator<<(P l, U r) noexcept = delete;
2205
+
2206
+ // / #[doc.overloads=unsigned.prim.>>u64]
2207
+ template <class P , class U >
2208
+ requires ((UnsignedPrimitiveInteger<P> || UnsignedPrimitiveEnum<P>) &&
2209
+ std::same_as<U, _self> && std::convertible_to<U, u64>)
2210
+ [[nodiscard]] __sus_pure_const constexpr friend P operator>>(P l, U r) noexcept {
2211
+ // No UB checks on primitive types, since there's no promotion to a Subspace
2212
+ // return type?
2213
+ return l >> u64 (r).primitive_value ;
2214
+ }
2215
+
2216
+ // / #[doc.overloads=unsigned.prim.>>u64]
2217
+ template <class P , class U >
2218
+ requires ((UnsignedPrimitiveInteger<P> || UnsignedPrimitiveEnum<P>) &&
2219
+ std::same_as<U, _self> && !std::convertible_to<U, u64>)
2220
+ constexpr friend P operator>>(P l, U r) noexcept = delete;
2221
+
2086
2222
// Stream support.
2087
2223
_sus_format_to_stream (_self);
2088
2224
0 commit comments