8b878d401659723a88e685ff24c3b04ddab7c0fc
[folly.git] / folly / lang / Align.h
1 /*
2  * Copyright 2017-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #pragma once
18
19 #include <cstddef>
20
21 namespace folly {
22
23 namespace detail {
24
25 union max_align_ {
26   std::max_align_t mat;
27   long double ld;
28   double d;
29   float f;
30   long long int lli;
31   long int li;
32   int i;
33   short int si;
34   bool b;
35   char c;
36   char16_t c16;
37   char32_t c32;
38   wchar_t wc;
39   std::nullptr_t n;
40 };
41
42 } // namespace detail
43
44 // max_align_v is the alignment of max_align_t.
45 //
46 // max_align_t is a type which is aligned at least as strictly as the
47 // most-aligned basic type (see the specification of std::max_align_t). This
48 // implementation exists because 32-bit iOS platforms have a broken
49 // std::max_align_t (see below).
50 //
51 // You should refer to this as `::folly::max_align_t` in portable code, even if
52 // you have `using namespace folly;` because C11 defines a global namespace
53 // `max_align_t` type.
54 //
55 // To be certain, we consider every non-void fundamental type specified by the
56 // standard. On most platforms `long double` would be enough, but iOS 32-bit
57 // has an 8-byte aligned `double` and `long long int` and a 4-byte aligned
58 // `long double`.
59 //
60 // So far we've covered locals and other non-allocated storage, but we also need
61 // confidence that allocated storage from `malloc`, `new`, etc will also be
62 // suitable for objects with this alignment requirement.
63 //
64 // Apple document that their implementation of malloc will issue 16-byte
65 // granularity chunks for small allocations (large allocations are page-size
66 // granularity and page-aligned). We think that allocated storage will be
67 // suitable for these objects based on the following assumptions:
68 //
69 // 1. 16-byte granularity also means 16-byte aligned.
70 // 2. `new` and other allocators follow the `malloc` rules.
71 //
72 // We also have some anecdotal evidence: we don't see lots of misaligned-storage
73 // crashes on 32-bit iOS apps that use `double`.
74 //
75 // Apple's allocation reference: http://bit.ly/malloc-small
76 constexpr std::size_t max_align_v = alignof(detail::max_align_);
77 struct alignas(max_align_v) max_align_t {};
78
79 } // namespace folly