Add jsl::aligned_unique_ptr and jsl::make_aligned
This commit is contained in:
parent
4f0712c489
commit
3fd0d4ee5d
4 changed files with 123 additions and 0 deletions
39
external/jsl/include/jsl/bits/memory/aligned_unique_ptr.tcc
vendored
Normal file
39
external/jsl/include/jsl/bits/memory/aligned_unique_ptr.tcc
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
// Copyright Jean Pierre Cimalando 2018-2020.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// (See accompanying file LICENSE or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
#include "../../memory"
|
||||||
|
|
||||||
|
namespace jsl {
|
||||||
|
|
||||||
|
template <class T, std::size_t Al>
|
||||||
|
void aligned_ptr_delete<T, Al>::operator()(T *p) const noexcept
|
||||||
|
{
|
||||||
|
aligned_allocator<T, Al> allocator;
|
||||||
|
allocator.destroy(p);
|
||||||
|
allocator.deallocate(p, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, std::size_t Al, class... Args>
|
||||||
|
aligned_unique_ptr<typename make_aligned_traits<T>::single_element, Al>
|
||||||
|
make_aligned(Args &&... args)
|
||||||
|
{
|
||||||
|
struct allocation_delete {
|
||||||
|
void operator()(T *p) const noexcept
|
||||||
|
{
|
||||||
|
aligned_allocator<T, Al> allocator;
|
||||||
|
allocator.destroy(p);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
aligned_allocator<T, Al> allocator;
|
||||||
|
std::unique_ptr<T, allocation_delete> allocation(allocator.allocate(1, nullptr));
|
||||||
|
allocator.construct(allocation.get(), std::forward<Args>(args)...);
|
||||||
|
return aligned_unique_ptr<T, Al>(allocation.release());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace jsl
|
||||||
42
external/jsl/include/jsl/memory
vendored
Normal file
42
external/jsl/include/jsl/memory
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
// Copyright Jean Pierre Cimalando 2018-2020.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// (See accompanying file LICENSE or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
#include "./allocator"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace jsl {
|
||||||
|
|
||||||
|
template <class T, std::size_t Al>
|
||||||
|
struct aligned_ptr_delete {
|
||||||
|
void operator()(T *p) const noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, std::size_t Al>
|
||||||
|
using aligned_unique_ptr = std::unique_ptr<T, aligned_ptr_delete<T, Al>>;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <class T> struct make_aligned_traits;
|
||||||
|
template <class T, size_t N> struct make_aligned_traits<T[N]> { struct invalid {}; };
|
||||||
|
template <class T> struct make_aligned_traits<T[]> { struct invalid {}; };
|
||||||
|
template <class T> struct make_aligned_traits { using single_element = T; };
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <class T, std::size_t Al, class... Args>
|
||||||
|
aligned_unique_ptr<typename make_aligned_traits<T>::single_element, Al>
|
||||||
|
make_aligned(Args &&... args);
|
||||||
|
|
||||||
|
template <class T, std::size_t Al, class... Args>
|
||||||
|
typename make_aligned_traits<T>::invalid
|
||||||
|
make_aligned(Args &&... args) = delete;
|
||||||
|
|
||||||
|
} // namespace jsl
|
||||||
|
|
||||||
|
#include "bits/memory/aligned_unique_ptr.tcc"
|
||||||
|
|
@ -49,6 +49,7 @@ set(SFIZZ_TEST_SOURCES
|
||||||
LFOT.cpp
|
LFOT.cpp
|
||||||
MessagingT.cpp
|
MessagingT.cpp
|
||||||
OversamplerT.cpp
|
OversamplerT.cpp
|
||||||
|
MemoryT.cpp
|
||||||
DataHelpers.h
|
DataHelpers.h
|
||||||
DataHelpers.cpp
|
DataHelpers.cpp
|
||||||
)
|
)
|
||||||
|
|
|
||||||
41
tests/MemoryT.cpp
Normal file
41
tests/MemoryT.cpp
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#include "catch2/catch.hpp"
|
||||||
|
#include <jsl/memory>
|
||||||
|
#include <vector>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
TEST_CASE("[Memory] Aligned unique pointers")
|
||||||
|
{
|
||||||
|
constexpr size_t numAllocations = 128;
|
||||||
|
constexpr size_t alignment = 1024;
|
||||||
|
|
||||||
|
static size_t numLiveObjects;
|
||||||
|
numLiveObjects = 0;
|
||||||
|
|
||||||
|
struct Object {
|
||||||
|
explicit Object(size_t id) : id(id) { ++numLiveObjects; }
|
||||||
|
~Object() { --numLiveObjects; }
|
||||||
|
size_t id {};
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<jsl::aligned_unique_ptr<Object, alignment>> ptrs(numAllocations);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < numAllocations; ++i) {
|
||||||
|
ptrs[i] = jsl::make_aligned<Object, alignment>(i);
|
||||||
|
REQUIRE(numLiveObjects == i + 1);
|
||||||
|
|
||||||
|
Object *obj = ptrs[i].get();
|
||||||
|
REQUIRE(obj->id == i);
|
||||||
|
|
||||||
|
uintptr_t addr = reinterpret_cast<uintptr_t>(obj);
|
||||||
|
REQUIRE(addr % alignment == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ptrs.clear();
|
||||||
|
REQUIRE(numLiveObjects == 0);
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue