+// Unaligned loads and stores
+namespace folly {
+#if FOLLY_HAVE_UNALIGNED_ACCESS
+constexpr bool kHasUnalignedAccess = true;
+#else
+constexpr bool kHasUnalignedAccess = false;
+#endif
+
+namespace portability_detail {
+
+template <typename I, I A, I B>
+using integral_max = std::integral_constant<I, (A < B) ? B : A>;
+
+template <typename I, I A, I... Bs>
+struct integral_sequence_max
+ : integral_max<I, A, integral_sequence_max<I, Bs...>::value> {};
+
+template <typename I, I A>
+struct integral_sequence_max<I, A> : std::integral_constant<I, A> {};
+
+template <typename... Ts>
+using max_alignment = integral_sequence_max<size_t, alignof(Ts)...>;
+
+using max_basic_alignment = max_alignment<
+ std::max_align_t,
+ long double,
+ double,
+ float,
+ long long int,
+ long int,
+ int,
+ short int,
+ bool,
+ char,
+ char16_t,
+ char32_t,
+ wchar_t,
+ std::nullptr_t>;
+} // namespace portability_detail
+
+constexpr size_t max_align_v = portability_detail::max_basic_alignment::value;
+
+// max_align_t is a type which is aligned at least as strictly as the
+// most-aligned basic type (see the specification of std::max_align_t). This
+// implementation exists because 32-bit iOS platforms have a broken
+// std::max_align_t (see below).
+//
+// You should refer to this as `::folly::max_align_t` in portable code, even if
+// you have `using namespace folly;` because C11 defines a global namespace
+// `max_align_t` type.
+//
+// To be certain, we consider every non-void fundamental type specified by the
+// standard. On most platforms `long double` would be enough, but iOS 32-bit
+// has an 8-byte aligned `double` and `long long int` and a 4-byte aligned
+// `long double`.
+//
+// So far we've covered locals and other non-allocated storage, but we also need
+// confidence that allocated storage from `malloc`, `new`, etc will also be
+// suitable for objects with this alignment reuirement.
+//
+// Apple document that their implementation of malloc will issue 16-byte
+// granularity chunks for small allocations (large allocations are page-size
+// granularity and page-aligned). We think that allocated storage will be
+// suitable for these objects based on the following assumptions:
+//
+// 1. 16-byte granularity also means 16-byte aligned.
+// 2. `new` and other allocators follow the `malloc` rules.
+//
+// We also have some anecdotal evidence: we don't see lots of misaligned-storage
+// crashes on 32-bit iOS apps that use `double`.
+//
+// Apple's allocation reference: http://bit.ly/malloc-small
+struct alignas(max_align_v) max_align_t {};