Bug 1838484 - Don't create module loader for template contents owner document r=smaug
[gecko.git] / mfbt / Alignment.h
blobc38e00d12c466e8380930092352175b4db6bde74
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* Functionality related to memory alignment. */
9 #ifndef mozilla_Alignment_h
10 #define mozilla_Alignment_h
12 #include "mozilla/Attributes.h"
13 #include <stddef.h>
14 #include <stdint.h>
16 namespace mozilla {
19 * This class, and the corresponding macro MOZ_ALIGNOF, figures out how many
20 * bytes of alignment a given type needs.
22 template <typename T>
23 class AlignmentFinder {
24 struct Aligner {
25 char mChar;
26 T mT;
28 // Aligner may be used to check alignment of types with deleted dtors. This
29 // results in such specializations having implicitly deleted dtors, which
30 // causes fatal warnings on MSVC (see bug 1481005). As we don't create
31 // Aligners, we can avoid this warning by explicitly deleting the dtor.
32 ~Aligner() = delete;
35 public:
36 static const size_t alignment = sizeof(Aligner) - sizeof(T);
39 #define MOZ_ALIGNOF(T) mozilla::AlignmentFinder<T>::alignment
41 namespace detail {
42 template <typename T>
43 struct AlignasHelper {
44 T mT;
46 } // namespace detail
49 * Use this instead of alignof to align struct field as if it is inside
50 * a struct. On some platforms, there exist types which have different
51 * alignment between when it is used on its own and when it is used on
52 * a struct field.
54 * Known examples are 64bit types (uint64_t, double) on 32bit Linux,
55 * where they have 8byte alignment on their own, and 4byte alignment
56 * when in struct.
58 #define MOZ_ALIGNAS_IN_STRUCT(T) alignas(mozilla::detail::AlignasHelper<T>)
61 * Declare the MOZ_ALIGNED_DECL macro for declaring aligned types.
63 * For instance,
65 * MOZ_ALIGNED_DECL(8, char arr[2]);
67 * will declare a two-character array |arr| aligned to 8 bytes.
70 #if defined(__GNUC__)
71 # define MOZ_ALIGNED_DECL(_align, _type) _type __attribute__((aligned(_align)))
72 #elif defined(_MSC_VER)
73 # define MOZ_ALIGNED_DECL(_align, _type) __declspec(align(_align)) _type
74 #else
75 # warning "We don't know how to align variables on this compiler."
76 # define MOZ_ALIGNED_DECL(_align, _type) _type
77 #endif
80 * AlignedElem<N> is a structure whose alignment is guaranteed to be at least N
81 * bytes.
83 * We support 1, 2, 4, 8, and 16-byte alignment.
85 template <size_t Align>
86 struct AlignedElem;
89 * We have to specialize this template because GCC doesn't like
90 * __attribute__((aligned(foo))) where foo is a template parameter.
93 template <>
94 struct AlignedElem<1> {
95 MOZ_ALIGNED_DECL(1, uint8_t elem);
98 template <>
99 struct AlignedElem<2> {
100 MOZ_ALIGNED_DECL(2, uint8_t elem);
103 template <>
104 struct AlignedElem<4> {
105 MOZ_ALIGNED_DECL(4, uint8_t elem);
108 template <>
109 struct AlignedElem<8> {
110 MOZ_ALIGNED_DECL(8, uint8_t elem);
113 template <>
114 struct AlignedElem<16> {
115 MOZ_ALIGNED_DECL(16, uint8_t elem);
118 template <typename T>
119 struct MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS AlignedStorage2 {
120 union U {
121 char mBytes[sizeof(T)];
122 uint64_t mDummy;
123 } u;
125 const T* addr() const { return reinterpret_cast<const T*>(u.mBytes); }
126 T* addr() { return static_cast<T*>(static_cast<void*>(u.mBytes)); }
128 AlignedStorage2() = default;
130 // AlignedStorage2 is non-copyable: the default copy constructor violates
131 // strict aliasing rules, per bug 1269319.
132 AlignedStorage2(const AlignedStorage2&) = delete;
133 void operator=(const AlignedStorage2&) = delete;
136 } /* namespace mozilla */
138 #endif /* mozilla_Alignment_h */