Pigweed
 
Loading...
Searching...
No Matches
alignment.h
1// Copyright 2023 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14#pragma once
15
16// todo-check: ignore
17// TODO(fxbug.dev/42072051): Once this bug is addressed, this module can likely
18// be removed and we could just inline the using statements.
19
20#include <atomic>
21#if __cplusplus >= 202002L
22#include <bit>
23#endif // __cplusplus >= 202002L
24#include <limits>
25#include <type_traits>
26
27namespace pw {
28
29#if defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L
30using std::bit_ceil;
31#else
32constexpr size_t countl_zero(size_t x) noexcept {
33 size_t size_digits = std::numeric_limits<size_t>::digits;
34
35 if (sizeof(x) <= sizeof(unsigned int))
36 return __builtin_clz(static_cast<unsigned int>(x)) -
37 (std::numeric_limits<unsigned int>::digits - size_digits);
38
39 if (sizeof(x) <= sizeof(unsigned long))
40 return __builtin_clzl(static_cast<unsigned long>(x)) -
41 (std::numeric_limits<unsigned long>::digits - size_digits);
42
43 static_assert(sizeof(x) <= sizeof(unsigned long long));
44 return __builtin_clzll(static_cast<unsigned long long>(x)) -
45 (std::numeric_limits<unsigned long long>::digits - size_digits);
46}
47
48constexpr size_t bit_width(size_t x) noexcept {
49 return std::numeric_limits<size_t>::digits - countl_zero(x);
50}
51
52constexpr size_t bit_ceil(size_t x) noexcept {
53 if (x == 0)
54 return 1;
55 return size_t{1} << bit_width(size_t{x - 1});
56}
57#endif // defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L
58
60
73template <typename T>
74struct [[gnu::aligned(bit_ceil(sizeof(T)))]] NaturallyAligned : public T {
75 NaturallyAligned() : T() {}
76 NaturallyAligned(const T& t) : T(t) {}
77 template <class U>
78 NaturallyAligned(const U& u) : T(u) {}
79 NaturallyAligned& operator=(T other) {
80 T::operator=(other);
81 return *this;
82 } // namespace pw
83};
84
104template <typename T>
105using AlignedAtomic = std::atomic<NaturallyAligned<T>>;
106
107} // namespace pw
std::atomic< NaturallyAligned< T > > AlignedAtomic
Definition: alignment.h:105
Provides basic helpers for reading and writing UTF-8 encoded strings.
Definition: alignment.h:27
Definition: alignment.h:74