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
|
||||
MessagingT.cpp
|
||||
OversamplerT.cpp
|
||||
MemoryT.cpp
|
||||
DataHelpers.h
|
||||
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