/* * Copyright (c) Facebook, Inc. and its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include #include #include namespace folly { template class aligned { static_assert(!(Align & (Align - 1)), "alignment not a power of two"); static_assert(alignof(T) <= Align, "alignment too small"); public: using alignment = index_constant; using value_type = T; aligned() = default; aligned(aligned const&) = default; aligned(aligned&&) = default; template < typename S = T, std::enable_if_t::value, int> = 0> aligned(T const& value) noexcept(std::is_nothrow_copy_constructible::value) : value_(value) {} template < typename S = T, std::enable_if_t::value, int> = 0> aligned(T&& value) noexcept(std::is_nothrow_move_constructible::value) : value_(static_cast(value)) {} template < typename... A, std::enable_if_t::value, int> = 0> explicit aligned(in_place_t, A&&... a) noexcept( std::is_nothrow_constructible::value) : value_(static_cast(a)...) {} aligned& operator=(aligned const&) = default; aligned& operator=(aligned&&) = default; template < typename S = T, std::enable_if_t::value, int> = 0> aligned& operator=(T const& value) noexcept( std::is_nothrow_copy_assignable::value) { value_ = value; return *this; } template < typename S = T, std::enable_if_t::value, int> = 0> aligned& operator=(T&& value) noexcept( std::is_nothrow_move_assignable::value) { value_ = std::move(value); return *this; } T* get() noexcept { return &value_; } T const* get() const noexcept { return &value_; } T* operator->() noexcept { return &value_; } T const* operator->() const noexcept { return &value_; } T& operator*() noexcept { return value_; } T const& operator*() const noexcept { return value_; } private: alignas(Align) T value_; }; template using cacheline_aligned = aligned< T, (cacheline_align_v < alignof(T) ? alignof(T) : cacheline_align_v)>; } // namespace folly