File indexing completed on 2025-01-31 10:12:06
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 #ifndef GOOGLE_PROTOBUF_ARENA_ALIGN_H__
0053 #define GOOGLE_PROTOBUF_ARENA_ALIGN_H__
0054
0055 #include <cstddef>
0056 #include <cstdint>
0057
0058 #include "absl/base/macros.h"
0059 #include "absl/log/absl_check.h"
0060 #include "absl/numeric/bits.h"
0061
0062
0063 #include "google/protobuf/port_def.inc"
0064
0065 namespace google {
0066 namespace protobuf {
0067 namespace internal {
0068
0069 struct ArenaAlignDefault {
0070 PROTOBUF_EXPORT static constexpr size_t align = 8;
0071
0072 static constexpr bool IsAligned(size_t n) { return (n & (align - 1)) == 0U; }
0073
0074 template <typename T>
0075 static inline PROTOBUF_ALWAYS_INLINE bool IsAligned(T* ptr) {
0076 return (reinterpret_cast<uintptr_t>(ptr) & (align - 1)) == 0U;
0077 }
0078
0079 static inline PROTOBUF_ALWAYS_INLINE constexpr size_t Ceil(size_t n) {
0080 return (n + align - 1) & ~(align - 1);
0081 }
0082 static inline PROTOBUF_ALWAYS_INLINE constexpr size_t Floor(size_t n) {
0083 return (n & ~(align - 1));
0084 }
0085
0086 static inline PROTOBUF_ALWAYS_INLINE size_t Padded(size_t n) {
0087 ABSL_ASSERT(IsAligned(n));
0088 return n;
0089 }
0090
0091 template <typename T>
0092 static inline PROTOBUF_ALWAYS_INLINE T* Ceil(T* ptr) {
0093 uintptr_t intptr = reinterpret_cast<uintptr_t>(ptr);
0094 return reinterpret_cast<T*>((intptr + align - 1) & ~(align - 1));
0095 }
0096
0097 template <typename T>
0098 static inline PROTOBUF_ALWAYS_INLINE T* CeilDefaultAligned(T* ptr) {
0099 ABSL_ASSERT(IsAligned(ptr));
0100 return ptr;
0101 }
0102
0103
0104 template <typename T>
0105 static inline PROTOBUF_ALWAYS_INLINE T* CheckAligned(T* ptr) {
0106 ABSL_ASSERT(IsAligned(ptr));
0107 return ptr;
0108 }
0109 };
0110
0111 struct ArenaAlign {
0112 static constexpr bool IsDefault() { return false; };
0113
0114 size_t align;
0115
0116 constexpr bool IsAligned(size_t n) const { return (n & (align - 1)) == 0U; }
0117
0118 template <typename T>
0119 bool IsAligned(T* ptr) const {
0120 return (reinterpret_cast<uintptr_t>(ptr) & (align - 1)) == 0U;
0121 }
0122
0123 constexpr size_t Ceil(size_t n) const {
0124 return (n + align - 1) & ~(align - 1);
0125 }
0126 constexpr size_t Floor(size_t n) const { return (n & ~(align - 1)); }
0127
0128 constexpr size_t Padded(size_t n) const {
0129
0130
0131
0132 ABSL_ASSERT(ArenaAlignDefault::IsAligned(align));
0133 return n + align - ArenaAlignDefault::align;
0134 }
0135
0136 template <typename T>
0137 T* Ceil(T* ptr) const {
0138 uintptr_t intptr = reinterpret_cast<uintptr_t>(ptr);
0139 return reinterpret_cast<T*>((intptr + align - 1) & ~(align - 1));
0140 }
0141
0142 template <typename T>
0143 T* CeilDefaultAligned(T* ptr) const {
0144 ABSL_ASSERT(ArenaAlignDefault::IsAligned(ptr));
0145 return Ceil(ptr);
0146 }
0147
0148
0149 template <typename T>
0150 T* CheckAligned(T* ptr) const {
0151 ABSL_ASSERT(IsAligned(ptr));
0152 return ptr;
0153 }
0154 };
0155
0156 inline ArenaAlign ArenaAlignAs(size_t align) {
0157
0158 ABSL_DCHECK_NE(align, 0U);
0159 ABSL_DCHECK(absl::has_single_bit(align)) << "Invalid alignment " << align;
0160 return ArenaAlign{align};
0161 }
0162
0163 template <bool, size_t align>
0164 struct AlignFactory {
0165 static_assert(align > ArenaAlignDefault::align, "Not over-aligned");
0166 static_assert((align & (align - 1)) == 0U, "Not power of 2");
0167 static constexpr ArenaAlign Create() { return ArenaAlign{align}; }
0168 };
0169
0170 template <size_t align>
0171 struct AlignFactory<true, align> {
0172 static_assert(align <= ArenaAlignDefault::align, "Over-aligned");
0173 static_assert((align & (align - 1)) == 0U, "Not power of 2");
0174 static constexpr ArenaAlignDefault Create() { return ArenaAlignDefault{}; }
0175 };
0176
0177
0178
0179
0180
0181
0182 template <size_t align>
0183 inline constexpr auto ArenaAlignAs() {
0184 return AlignFactory<align <= ArenaAlignDefault::align, align>::Create();
0185 }
0186
0187
0188 template <typename T>
0189 inline constexpr auto ArenaAlignOf() {
0190 return ArenaAlignAs<alignof(T)>();
0191 }
0192
0193 }
0194 }
0195 }
0196
0197 #include "google/protobuf/port_undef.inc"
0198
0199 #endif