// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- // vi: set et ts=4 sw=4 sts=4: /* This file is part of the Open Porous Media project (OPM). OPM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. OPM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OPM. If not, see . Consult the COPYING file in the top-level source directory of this module for the precise wording of the license and the list of copyright holders. */ /*! * \file * \brief This is a stand-alone version of boost::alignment::aligned_allocator from Boost * 1.58 * * The file has been modified to assume a C++-2011 compatible compiler on a POSIX * operating system to remove the boost dependencies which the original version * contained. The original copyright notice for this file is: *
 (c) 2014 Glen Joseph Fernandes
 glenjofe at gmail dot com

 Distributed under the Boost Software
 License, Version 1.0.
 http://boost.org/LICENSE_1_0.txt
*/ #ifndef EWOMS_ALIGNED_ALLOCATOR_HH #define EWOMS_ALIGNED_ALLOCATOR_HH #include #include #include #include namespace Opm { namespace detail { constexpr inline bool is_alignment(std::size_t value) noexcept { return (value > 0) && ((value & (value - 1)) == 0); } template struct is_alignment_constant : std::integral_constant 0) && ((N & (N - 1)) == 0)> {}; template struct min_size : std::integral_constant { }; template struct offset_object { char offset; T object; }; template struct alignment_of : min_size) - sizeof(T)>::type {}; template struct max_align : std::integral_constant B) ? A : B> {}; template struct max_count_of : std::integral_constant(0) / sizeof(T)> {}; using std::addressof; } inline void* aligned_alloc(std::size_t alignment, std::size_t size) noexcept { assert(detail::is_alignment(alignment)); if (alignment < sizeof(void*)) { alignment = sizeof(void*); } void* p; if (::posix_memalign(&p, alignment, size) != 0) { p = 0; } return p; } inline void aligned_free(void* ptr) noexcept { ::free(ptr); } template class aligned_allocator { static_assert(detail::is_alignment_constant::value, "Alignment must be powers of two!"); public: using value_type = T; using pointer = T*; using const_pointer = const T*; using void_pointer = void*; using const_void_pointer = const void*; using size_type = std::size_t; using difference_type = std::ptrdiff_t; using reference = T&; using const_reference = const T&; private: using MaxAlign = detail::max_align::value>; public: template struct rebind { using other = aligned_allocator; }; aligned_allocator() noexcept = default; template aligned_allocator(const aligned_allocator&) noexcept { } pointer address(reference value) const noexcept { return detail::addressof(value); } const_pointer address(const_reference value) const noexcept { return detail::addressof(value); } pointer allocate(size_type size, const_void_pointer = 0) { void* p = aligned_alloc(MaxAlign::value, sizeof(T) * size); if (!p && size > 0) { throw std::bad_alloc(); } return static_cast(p); } void deallocate(pointer ptr, size_type) { aligned_free(ptr); } constexpr size_type max_size() const noexcept { return detail::max_count_of::value; } template void construct(U* ptr, Args&&... args) { void* p = ptr; ::new(p) U(std::forward(args)...); } template void construct(U* ptr) { void* p = ptr; ::new(p) U(); } template void destroy(U* ptr) { (void)ptr; ptr->~U(); } }; template class aligned_allocator { static_assert(detail::is_alignment_constant::value, "The specified alignment is not a power of two!"); public: using value_type = void; using pointer = void*; using const_pointer = const void*; template struct rebind { using other = aligned_allocator; }; }; template inline bool operator==(const aligned_allocator&, const aligned_allocator&) noexcept { return true; } template inline bool operator!=(const aligned_allocator&, const aligned_allocator&) noexcept { return false; } } #endif