Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
safe_conversions.h
Go to the documentation of this file.
1// Copyright 2024 The PDFium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CORE_FXCRT_NUMERICS_SAFE_CONVERSIONS_H_
6#define CORE_FXCRT_NUMERICS_SAFE_CONVERSIONS_H_
7
8#include <stddef.h>
9
10#include <cmath>
11#include <limits>
12#include <type_traits>
13
14#include "core/fxcrt/numerics/safe_conversions_impl.h"
15
16#if defined(__ARMEL__) && !defined(__native_client__)
17#include "core/fxcrt/numerics/safe_conversions_arm_impl.h"
18#define BASE_HAS_OPTIMIZED_SAFE_CONVERSIONS (1)
19#else
20#define BASE_HAS_OPTIMIZED_SAFE_CONVERSIONS (0)
21#endif
22
23namespace pdfium {
24namespace internal {
25
27template <typename Dst, typename Src>
29 static constexpr bool is_supported = false;
30 static constexpr Dst Do(Src) {
31 // Force a compile failure if instantiated.
32 return CheckOnFailure::template HandleFailure<Dst>();
33 }
34};
35#endif // BASE_HAS_OPTIMIZED_SAFE_CONVERSIONS
36#undef BASE_HAS_OPTIMIZED_SAFE_CONVERSIONS
37
38// The following special case a few specific integer conversions where we can
39// eke out better performance than range checking.
40template <typename Dst, typename Src, typename Enable = void>
42 static constexpr bool is_supported = false;
43 static constexpr bool Do(Src value) {
44 // Force a compile failure if instantiated.
45 return CheckOnFailure::template HandleFailure<bool>();
46 }
47};
48
49// Signed to signed range comparison.
50template <typename Dst, typename Src>
52 Dst,
53 Src,
54 typename std::enable_if<
58 static constexpr bool is_supported = true;
59
60 static constexpr bool Do(Src value) {
61 // Just downcast to the smaller type, sign extend it back to the original
62 // type, and then see if it matches the original value.
63 return value == static_cast<Dst>(value);
64 }
65};
66
67// Signed to unsigned range comparison.
68template <typename Dst, typename Src>
70 Dst,
71 Src,
72 typename std::enable_if<
76 static constexpr bool is_supported = true;
77
78 static constexpr bool Do(Src value) {
79 // We cast a signed as unsigned to overflow negative values to the top,
80 // then compare against whichever maximum is smaller, as our upper bound.
82 }
83};
84
85// Convenience function that returns true if the supplied value is in range
86// for the destination type.
87template <typename Dst, typename Src>
88constexpr bool IsValueInRangeForNumericType(Src value) {
89 using SrcType = typename internal::UnderlyingType<Src>::type;
90 return internal::IsValueInRangeFastOp<Dst, SrcType>::is_supported
91 ? internal::IsValueInRangeFastOp<Dst, SrcType>::Do(
92 static_cast<SrcType>(value))
93 : internal::DstRangeRelationToSrcRange<Dst>(
94 static_cast<SrcType>(value))
95 .IsValid();
96}
97
98// checked_cast<> is analogous to static_cast<> for numeric types,
99// except that it CHECKs that the specified numeric conversion will not
100// overflow or underflow. NaN source will always trigger a CHECK.
101template <typename Dst,
102 class CheckHandler = internal::CheckOnFailure,
103 typename Src>
104constexpr Dst checked_cast(Src value) {
105 // This throws a compile-time error on evaluating the constexpr if it can be
106 // determined at compile-time as failing, otherwise it will CHECK at runtime.
107 using SrcType = typename internal::UnderlyingType<Src>::type;
108 return BASE_NUMERICS_LIKELY((IsValueInRangeForNumericType<Dst>(value)))
109 ? static_cast<Dst>(static_cast<SrcType>(value))
110 : CheckHandler::template HandleFailure<Dst>();
111}
112
113// Default boundaries for integral/float: max/infinity, lowest/-infinity, 0/NaN.
114// You may provide your own limits (e.g. to saturated_cast) so long as you
115// implement all of the static constexpr member functions in the class below.
116template <typename T>
117struct SaturationDefaultLimits : public std::numeric_limits<T> {
118 static constexpr T NaN() {
119 if constexpr (std::numeric_limits<T>::has_quiet_NaN) {
120 return std::numeric_limits<T>::quiet_NaN();
121 } else {
122 return T();
123 }
124 }
125 using std::numeric_limits<T>::max;
126 static constexpr T Overflow() {
127 if constexpr (std::numeric_limits<T>::has_infinity) {
128 return std::numeric_limits<T>::infinity();
129 } else {
130 return std::numeric_limits<T>::max();
131 }
132 }
133 using std::numeric_limits<T>::lowest;
134 static constexpr T Underflow() {
135 if constexpr (std::numeric_limits<T>::has_infinity) {
136 return std::numeric_limits<T>::infinity() * -1;
137 } else {
138 return std::numeric_limits<T>::lowest();
139 }
140 }
141};
142
143template <typename Dst, template <typename> class S, typename Src>
144constexpr Dst saturated_cast_impl(Src value, RangeCheck constraint) {
145 // For some reason clang generates much better code when the branch is
146 // structured exactly this way, rather than a sequence of checks.
147 return !constraint.IsOverflowFlagSet()
148 ? (!constraint.IsUnderflowFlagSet() ? static_cast<Dst>(value)
149 : S<Dst>::Underflow())
150 // Skip this check for integral Src, which cannot be NaN.
151 : (std::is_integral<Src>::value || !constraint.IsUnderflowFlagSet()
152 ? S<Dst>::Overflow()
153 : S<Dst>::NaN());
154}
155
156// We can reduce the number of conditions and get slightly better performance
157// for normal signed and unsigned integer ranges. And in the specific case of
158// Arm, we can use the optimized saturation instructions.
159template <typename Dst, typename Src, typename Enable = void>
161 static constexpr bool is_supported = false;
162 static constexpr Dst Do(Src value) {
163 // Force a compile failure if instantiated.
164 return CheckOnFailure::template HandleFailure<Dst>();
165 }
166};
167
168template <typename Dst, typename Src>
170 Dst,
171 Src,
172 typename std::enable_if<std::is_integral<Src>::value &&
175 static constexpr bool is_supported = true;
176 static constexpr Dst Do(Src value) {
177 return SaturateFastAsmOp<Dst, Src>::Do(value);
178 }
179};
180
181template <typename Dst, typename Src>
183 Dst,
184 Src,
185 typename std::enable_if<std::is_integral<Src>::value &&
188 static constexpr bool is_supported = true;
189 static constexpr Dst Do(Src value) {
190 // The exact order of the following is structured to hit the correct
191 // optimization heuristics across compilers. Do not change without
192 // checking the emitted code.
197 ? static_cast<Dst>(value)
198 : saturated;
199 }
200};
201
202// saturated_cast<> is analogous to static_cast<> for numeric types, except
203// that the specified numeric conversion will saturate by default rather than
204// overflow or underflow, and NaN assignment to an integral will return 0.
205// All boundary condition behaviors can be overridden with a custom handler.
206template <typename Dst,
207 template <typename> class SaturationHandler = SaturationDefaultLimits,
208 typename Src>
209constexpr Dst saturated_cast(Src value) {
210 using SrcType = typename UnderlyingType<Src>::type;
211 return !IsConstantEvaluated() && SaturateFastOp<Dst, SrcType>::is_supported &&
212 std::is_same<SaturationHandler<Dst>,
213 SaturationDefaultLimits<Dst>>::value
214 ? SaturateFastOp<Dst, SrcType>::Do(static_cast<SrcType>(value))
215 : saturated_cast_impl<Dst, SaturationHandler, SrcType>(
216 static_cast<SrcType>(value),
217 DstRangeRelationToSrcRange<Dst, SaturationHandler, SrcType>(
218 static_cast<SrcType>(value)));
219}
220
221// strict_cast<> is analogous to static_cast<> for numeric types, except that
222// it will cause a compile failure if the destination type is not large enough
223// to contain any value in the source type. It performs no runtime checking.
224template <typename Dst, typename Src>
225constexpr Dst strict_cast(Src value) {
226 using SrcType = typename UnderlyingType<Src>::type;
227 static_assert(UnderlyingType<Src>::is_numeric, "Argument must be numeric.");
228 static_assert(std::is_arithmetic<Dst>::value, "Result must be numeric.");
229
230 // If you got here from a compiler error, it's because you tried to assign
231 // from a source type to a destination type that has insufficient range.
232 // The solution may be to change the destination type you're assigning to,
233 // and use one large enough to represent the source.
234 // Alternatively, you may be better served with the checked_cast<> or
235 // saturated_cast<> template functions for your particular use case.
236 static_assert(StaticDstRangeRelationToSrcRange<Dst, SrcType>::value ==
237 NUMERIC_RANGE_CONTAINED,
238 "The source type is out of range for the destination type. "
239 "Please see strict_cast<> comments for more information.");
240
241 return static_cast<Dst>(static_cast<SrcType>(value));
242}
243
244// Some wrappers to statically check that a type is in range.
245template <typename Dst, typename Src, class Enable = void>
247 static constexpr bool value = false;
248};
249
250template <typename Dst, typename Src>
260
261// StrictNumeric implements compile time range checking between numeric types by
262// wrapping assignment operations in a strict_cast. This class is intended to be
263// used for function arguments and return types, to ensure the destination type
264// can always contain the source type. This is essentially the same as enforcing
265// -Wconversion in gcc and C4302 warnings on MSVC, but it can be applied
266// incrementally at API boundaries, making it easier to convert code so that it
267// compiles cleanly with truncation warnings enabled.
268// This template should introduce no runtime overhead, but it also provides no
269// runtime checking of any of the associated mathematical operations. Use
270// CheckedNumeric for runtime range checks of the actual value being assigned.
271template <typename T>
273 public:
274 using type = T;
275
276 constexpr StrictNumeric() : value_(0) {}
277
278 // Copy constructor.
279 template <typename Src>
280 constexpr StrictNumeric(const StrictNumeric<Src>& rhs)
281 : value_(strict_cast<T>(rhs.value_)) {}
282
283 // Strictly speaking, this is not necessary, but declaring this allows class
284 // template argument deduction to be used so that it is possible to simply
285 // write `StrictNumeric(777)` instead of `StrictNumeric<int>(777)`.
286 // NOLINTNEXTLINE(google-explicit-constructor)
287 constexpr StrictNumeric(T value) : value_(value) {}
288
289 // This is not an explicit constructor because we implicitly upgrade regular
290 // numerics to StrictNumerics to make them easier to use.
291 template <typename Src>
292 // NOLINTNEXTLINE(google-explicit-constructor)
293 constexpr StrictNumeric(Src value) : value_(strict_cast<T>(value)) {}
294
295 // If you got here from a compiler error, it's because you tried to assign
296 // from a source type to a destination type that has insufficient range.
297 // The solution may be to change the destination type you're assigning to,
298 // and use one large enough to represent the source.
299 // If you're assigning from a CheckedNumeric<> class, you may be able to use
300 // the AssignIfValid() member function, specify a narrower destination type to
301 // the member value functions (e.g. val.template ValueOrDie<Dst>()), use one
302 // of the value helper functions (e.g. ValueOrDieForType<Dst>(val)).
303 // If you've encountered an _ambiguous overload_ you can use a static_cast<>
304 // to explicitly cast the result to the destination type.
305 // If none of that works, you may be better served with the checked_cast<> or
306 // saturated_cast<> template functions for your particular use case.
307 template <typename Dst,
308 typename std::enable_if<
309 IsNumericRangeContained<Dst, T>::value>::type* = nullptr>
310 constexpr operator Dst() const {
311 return static_cast<typename ArithmeticOrUnderlyingEnum<Dst>::type>(value_);
312 }
313
314 private:
315 const T value_;
316};
317
318// Convenience wrapper returns a StrictNumeric from the provided arithmetic
319// type.
320template <typename T>
322 const T value) {
323 return value;
324}
325
326#define BASE_NUMERIC_COMPARISON_OPERATORS(CLASS, NAME, OP)
327 template <typename L, typename R,
328 typename std::enable_if<
329 internal::Is##CLASS##Op<L, R>::value>::type* = nullptr>
330 constexpr bool operator OP(const L lhs, const R rhs) {
331 return SafeCompare<NAME, typename UnderlyingType<L>::type,
332 typename UnderlyingType<R>::type>(lhs, rhs);
333 }
334
341
342} // namespace internal
343
344using internal::as_signed;
345using internal::as_unsigned;
346using internal::checked_cast;
347using internal::IsTypeInRangeForNumericType;
348using internal::IsValueInRangeForNumericType;
349using internal::IsValueNegative;
350using internal::MakeStrictNum;
351using internal::SafeUnsignedAbs;
352using internal::saturated_cast;
353using internal::strict_cast;
354using internal::StrictNumeric;
355
356// Explicitly make a shorter size_t alias for convenience.
358
359// floating -> integral conversions that saturate and thus can actually return
360// an integral type. In most cases, these should be preferred over the std::
361// versions.
362template <typename Dst = int,
363 typename Src,
364 typename = std::enable_if_t<std::is_integral<Dst>::value &&
366Dst ClampFloor(Src value) {
367 return saturated_cast<Dst>(std::floor(value));
368}
369template <typename Dst = int,
370 typename Src,
371 typename = std::enable_if_t<std::is_integral<Dst>::value &&
373Dst ClampCeil(Src value) {
374 return saturated_cast<Dst>(std::ceil(value));
375}
376template <typename Dst = int,
377 typename Src,
378 typename = std::enable_if_t<std::is_integral<Dst>::value &&
380Dst ClampRound(Src value) {
381 const Src rounded =
382 (value >= 0.0f) ? std::floor(value + 0.5f) : std::ceil(value - 0.5f);
383 return saturated_cast<Dst>(rounded);
384}
385
386} // namespace pdfium
387
388#endif // CORE_FXCRT_NUMERICS_SAFE_CONVERSIONS_H_
#define FXCRT_BYTESWAPS_CONSTEXPR
Definition byteorder.h:27
#define DCHECK
Definition check.h:33
#define CHECK_GE(x, y)
Definition check_op.h:15
constexpr bool IsOverflowFlagSet() const
constexpr bool IsUnderflowFlagSet() const
constexpr StrictNumeric(const StrictNumeric< Src > &rhs)
T & reference
Definition span.h:195
constexpr span(T(&array)[N]) noexcept
Definition span.h:211
constexpr reverse_iterator rend() const noexcept
Definition span.h:348
span last() const
Definition span.h:283
constexpr reverse_iterator rbegin() const noexcept
Definition span.h:345
T * iterator
Definition span.h:196
constexpr const_reverse_iterator crend() const noexcept
Definition span.h:355
span first() const
Definition span.h:269
std::reverse_iterator< iterator > reverse_iterator
Definition span.h:198
const span first(size_t count) const
Definition span.h:276
typename std::remove_cv< T >::type value_type
Definition span.h:193
span & operator=(const span &other) noexcept
Definition span.h:258
constexpr const_iterator cbegin() const noexcept
Definition span.h:342
constexpr const_iterator cend() const noexcept
Definition span.h:343
constexpr const_reverse_iterator crbegin() const noexcept
Definition span.h:352
const span last(size_t count) const
Definition span.h:290
constexpr bool empty() const noexcept
Definition span.h:316
constexpr size_t size() const noexcept
Definition span.h:314
constexpr span(Container &container)
Definition span.h:238
friend constexpr span< U > make_span(U *data, size_t size) noexcept
span subspan() const
Definition span.h:297
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition span.h:199
const span subspan(size_t pos, size_t count=dynamic_extent) const
Definition span.h:305
constexpr iterator begin() const noexcept
Definition span.h:337
constexpr size_t size_bytes() const noexcept
Definition span.h:315
constexpr span() noexcept=default
span(const Container &container)
Definition span.h:245
constexpr span(std::array< T, N > &array) noexcept
Definition span.h:216
T * pointer
Definition span.h:194
constexpr T & back() const noexcept
Definition span.h:329
constexpr span(const std::array< std::remove_cv_t< T >, N > &array) noexcept
Definition span.h:221
constexpr T * data() const noexcept
Definition span.h:334
constexpr T & front() const noexcept
Definition span.h:324
constexpr span(const span &other) noexcept=default
UNSAFE_BUFFER_USAGE constexpr span(T *data, size_t size) noexcept
Definition span.h:204
constexpr span(const span< U, M, R > &other)
Definition span.h:255
T & operator[](size_t index) const noexcept
Definition span.h:319
constexpr iterator end() const noexcept
Definition span.h:338
const T * const_iterator
Definition span.h:197
~span() noexcept=default
#define NOINLINE
#define UNSAFE_BUFFERS(...)
#define GSL_POINTER
#define TRIVIAL_ABI
#define UNLIKELY(x)
#define HAS_ATTRIBUTE(x)
#define UNSAFE_BUFFER_USAGE
void CRYPT_MD5Finish(CRYPT_md5_context *context, pdfium::span< uint8_t, 16 > digest)
Definition fx_crypt.cpp:203
#define P(a, b, c, d, k, s, t)
void CRYPT_MD5Generate(pdfium::span< const uint8_t > data, pdfium::span< uint8_t, 16 > digest)
Definition fx_crypt.cpp:219
#define S(x, n)
void CRYPT_ArcFourCryptBlock(pdfium::span< uint8_t > data, pdfium::span< const uint8_t > key)
Definition fx_crypt.cpp:157
void CRYPT_ArcFourSetup(CRYPT_rc4_context *context, pdfium::span< const uint8_t > key)
Definition fx_crypt.cpp:131
void CRYPT_MD5Update(CRYPT_md5_context *context, pdfium::span< const uint8_t > data)
Definition fx_crypt.cpp:175
void CRYPT_ArcFourCrypt(CRYPT_rc4_context *context, pdfium::span< uint8_t > data)
Definition fx_crypt.cpp:146
CRYPT_md5_context CRYPT_MD5Start()
Definition fx_crypt.cpp:164
void CRYPT_AESEncrypt(CRYPT_aes_context *ctx, pdfium::span< uint8_t > dest, pdfium::span< const uint8_t > src)
void CRYPT_AESSetIV(CRYPT_aes_context *ctx, const uint8_t *iv)
void CRYPT_AESDecrypt(CRYPT_aes_context *ctx, uint8_t *dest, const uint8_t *src, uint32_t size)
void CRYPT_AESSetKey(CRYPT_aes_context *ctx, const uint8_t *key, uint32_t keylen)
void CRYPT_SHA512Update(CRYPT_sha2_context *context, pdfium::span< const uint8_t > data)
void CRYPT_SHA384Update(CRYPT_sha2_context *context, pdfium::span< const uint8_t > data)
DataVector< uint8_t > CRYPT_SHA256Generate(pdfium::span< const uint8_t > data)
void CRYPT_SHA1Finish(CRYPT_sha1_context *context, pdfium::span< uint8_t, 20 > digest)
void CRYPT_SHA1Update(CRYPT_sha1_context *context, pdfium::span< const uint8_t > data)
void CRYPT_SHA512Finish(CRYPT_sha2_context *context, pdfium::span< uint8_t, 64 > digest)
DataVector< uint8_t > CRYPT_SHA384Generate(pdfium::span< const uint8_t > data)
void CRYPT_SHA384Start(CRYPT_sha2_context *context)
void CRYPT_SHA384Finish(CRYPT_sha2_context *context, pdfium::span< uint8_t, 48 > digest)
void CRYPT_SHA512Start(CRYPT_sha2_context *context)
DataVector< uint8_t > CRYPT_SHA1Generate(pdfium::span< const uint8_t > data)
void CRYPT_SHA256Start(CRYPT_sha2_context *context)
DataVector< uint8_t > CRYPT_SHA512Generate(pdfium::span< const uint8_t > data)
void CRYPT_SHA1Start(CRYPT_sha1_context *context)
void CRYPT_SHA256Finish(CRYPT_sha2_context *context, pdfium::span< uint8_t, 32 > digest)
void CRYPT_SHA256Update(CRYPT_sha2_context *context, pdfium::span< const uint8_t > data)
NOINLINE void FX_OutOfMemoryTerminate(size_t size)
Definition fx_memory.cpp:82
void * FX_AlignedAlloc(size_t size, size_t alignment)
void FXMEM_DefaultFree(void *pointer)
Definition fx_memory.cpp:78
void * FXMEM_DefaultAlloc(size_t byte_size)
Definition fx_memory.cpp:66
void * FXMEM_DefaultCalloc(size_t num_elems, size_t byte_size)
Definition fx_memory.cpp:70
void * FXMEM_DefaultRealloc(void *pointer, size_t new_size)
Definition fx_memory.cpp:74
void * FX_ArrayBufferAllocate(size_t length)
void FX_DestroyMemoryAllocators()
void FX_InitializeMemoryAllocators()
void FX_ArrayBufferFree(void *data)
void * FX_ArrayBufferAllocateUninitialized(size_t length)
#define IMMEDIATE_CRASH_ALWAYS_INLINE
#define TRAP_SEQUENCE_()
FXCRT_BYTESWAPS_CONSTEXPR uint16_t ByteSwap(uint16_t x)
Definition byteorder.h:32
FXCRT_BYTESWAPS_CONSTEXPR uint32_t ByteSwap(uint32_t x)
Definition byteorder.h:40
uint32_t FromBE32(uint32_t x)
Definition byteorder.h:82
constexpr std::array< U, N > ToArrayImpl(const T(&data)[N], std::index_sequence< I... >)
Definition stl_util.h:76
uint16_t GetUInt16LSBFirst(pdfium::span< const uint8_t, 2 > span)
Definition byteorder.h:101
void PutUInt32MSBFirst(uint32_t value, pdfium::span< uint8_t, 4 > span)
Definition byteorder.h:116
ResultType CollectionSize(const Collection &collection)
Definition stl_util.h:37
FakeUniquePtr< T > MakeFakeUniquePtr(T *arg)
Definition stl_util.h:30
void PutUInt16LSBFirst(uint16_t value, pdfium::span< uint8_t, 2 > span)
Definition byteorder.h:123
uint16_t FromBE16(uint16_t x)
Definition byteorder.h:74
void PutUInt32LSBFirst(uint32_t value, pdfium::span< uint8_t, 4 > span)
Definition byteorder.h:128
uint16_t GetUInt16MSBFirst(pdfium::span< const uint8_t, 2 > span)
Definition byteorder.h:91
constexpr std::array< U, N > ToArray(const U(&data)[N])
Definition stl_util.h:83
uint32_t GetUInt32MSBFirst(pdfium::span< const uint8_t, 4 > span)
Definition byteorder.h:95
bool IndexInBounds(const Collection &collection, IndexType index)
Definition stl_util.h:44
void PutUInt16MSBFirst(uint16_t value, pdfium::span< uint8_t, 2 > span)
Definition byteorder.h:111
void Copy(const T &source_container, U &&dest_container)
Definition stl_util.h:57
void Fill(T &&container, const V &value)
Definition stl_util.h:50
uint32_t FromLE32(uint32_t x)
Definition byteorder.h:64
uint32_t GetUInt32LSBFirst(pdfium::span< const uint8_t, 4 > span)
Definition byteorder.h:105
uint16_t FromLE16(uint16_t x)
Definition byteorder.h:56
void * CallocOrDie2D(size_t w, size_t h, size_t member_size)
void * AllocOrDie2D(size_t w, size_t h, size_t member_size)
constexpr Dst saturated_cast(Src value)
std::is_integral< decltype(std::declval< Container >().size())> ContainerHasIntegralSize
Definition span.h:63
void * StringAllocOrDie(size_t num_members, size_t member_size)
void * Alloc(size_t num_members, size_t member_size)
IsSpanImpl< typename std::decay< T >::type > IsSpan
Definition span.h:43
void * StringAlloc(size_t num_members, size_t member_size)
void * ReallocOrDie(void *ptr, size_t num_members, size_t member_size)
std::is_convertible< From *, To * > IsLegalSpanConversion
Definition span.h:55
void * Realloc(void *ptr, size_t num_members, size_t member_size)
IsStdArrayImpl< typename std::decay< T >::type > IsStdArray
Definition span.h:52
void StringDealloc(void *ptr)
constexpr bool IsValueInRangeForNumericType(Src value)
void * AllocOrDie(size_t num_members, size_t member_size)
constexpr Dst checked_cast(Src value)
void * Alloc2D(size_t w, size_t h, size_t member_size)
void * Calloc(size_t num_members, size_t member_size)
constexpr Dst strict_cast(Src value)
constexpr StrictNumeric< typename UnderlyingType< T >::type > MakeStrictNum(const T value)
void * CallocOrDie(size_t num_members, size_t member_size)
void Dealloc(void *ptr)
constexpr Dst saturated_cast_impl(Src value, RangeCheck constraint)
constexpr span< T > make_span(T(&array)[N]) noexcept
Definition span.h:374
span< char > as_writable_chars(span< T, N, P > s) noexcept
Definition span.h:427
span< const uint8_t > as_bytes(span< T, N, P > s) noexcept
Definition span.h:400
constexpr size_t dynamic_extent
Definition span.h:24
static constexpr span< T > span_from_ref(T &single_object) noexcept
Definition span.h:437
static constexpr span< const uint8_t > byte_span_from_ref(const T &single_object) noexcept
Definition span.h:446
Dst ClampRound(Src value)
UNSAFE_BUFFER_USAGE constexpr span< T > make_span(T *data, size_t size) noexcept
Definition span.h:369
span< const uint8_t > as_byte_span(T &&arg)
Definition span.h:465
span< const char > as_chars(span< T, N, P > s) noexcept
Definition span.h:417
span< const uint8_t > as_byte_span(const T &arg)
Definition span.h:461
UNOWNED_PTR_EXCLUSION T * DefaultSpanInternalPtr
Definition span.h:27
span< uint8_t > as_writable_bytes(span< T, N, P > s) noexcept
Definition span.h:410
constexpr span< T > make_span(std::array< T, N > &array) noexcept
Definition span.h:379
constexpr span< T > make_span(Container &container)
Definition span.h:386
constexpr span< uint8_t > as_writable_byte_span(T &&arg)
Definition span.h:475
Dst ClampCeil(Src value)
IMMEDIATE_CRASH_ALWAYS_INLINE void ImmediateCrash()
static constexpr span< uint8_t > byte_span_from_ref(T &single_object) noexcept
Definition span.h:451
Dst ClampFloor(Src value)
constexpr span< T > make_span(const Container &container)
Definition span.h:394
#define CHECK(cvref)
#define assert
#define __has_attribute(x)
#define BASE_HAS_OPTIMIZED_SAFE_CONVERSIONS
#define BASE_NUMERIC_COMPARISON_OPERATORS(CLASS, NAME, OP)
#define BASE_NUMERICS_LIKELY(x)
#define IsConstantEvaluated()
std::array< uint32_t, kMaxNb > iv
std::array< uint32_t, kSchedSize > invkeysched
static constexpr int kMaxNr
static constexpr int kSchedSize
static constexpr int kMaxNb
std::array< uint32_t, kSchedSize > keysched
uint8_t buffer[64]
Definition fx_crypt.h:28
std::array< uint32_t, 4 > state
Definition fx_crypt.h:27
std::array< uint32_t, 2 > total
Definition fx_crypt.h:26
std::array< int32_t, kPermutationLength > m
Definition fx_crypt.h:22
static constexpr int32_t kPermutationLength
Definition fx_crypt.h:18
std::array< uint32_t, 5 > h
std::array< uint8_t, 64 > block
std::array< uint64_t, 8 > state
uint8_t buffer[128]
void operator()(void *ptr) const
FxPartitionAllocAllocator< U, Alloc, Free > other
pointer allocate(size_type n, const void *hint=0)
void deallocate(pointer p, size_type n)
const_pointer address(const_reference x) const noexcept
FxPartitionAllocAllocator() noexcept=default
size_type max_size() const noexcept
~FxPartitionAllocAllocator()=default
pointer address(reference x) const noexcept
FxPartitionAllocAllocator(const FxPartitionAllocAllocator< U, Alloc, Free > &other) noexcept
bool operator!=(const FxPartitionAllocAllocator &that)
void construct(U *p, Args &&... args)
bool operator==(const FxPartitionAllocAllocator &that)
FxPartitionAllocAllocator(const FxPartitionAllocAllocator &other) noexcept=default
static constexpr bool Do(Src value)
static constexpr Dst Do(Src value)
#define UNOWNED_PTR_EXCLUSION