summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/plib/palloc.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/plib/palloc.h')
-rw-r--r--src/lib/netlist/plib/palloc.h109
1 files changed, 63 insertions, 46 deletions
diff --git a/src/lib/netlist/plib/palloc.h b/src/lib/netlist/plib/palloc.h
index 45c19ef7b3a..44f3bdb395e 100644
--- a/src/lib/netlist/plib/palloc.h
+++ b/src/lib/netlist/plib/palloc.h
@@ -34,11 +34,11 @@ namespace plib {
#if defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
return _aligned_malloc(size, alignment);
#elif defined(__APPLE__)
- void* p;
- if (::posix_memalign(&p, alignment, size) != 0) {
- p = nullptr;
- }
- return p;
+ void* p;
+ if (::posix_memalign(&p, alignment, size) != 0) {
+ p = nullptr;
+ }
+ return p;
#else
return aligned_alloc(alignment, size);
#endif
@@ -46,12 +46,20 @@ namespace plib {
static inline void pfree( void *ptr )
{
+ // NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
free(ptr);
}
+ static constexpr bool is_pow2(std::size_t v) noexcept { return !(v & (v-1)); }
+
template <typename T, std::size_t ALIGN>
inline C14CONSTEXPR T *assume_aligned_ptr(T *p) noexcept
{
+ static_assert(ALIGN >= alignof(T), "Alignment must be greater or equal to alignof(T)");
+ static_assert(is_pow2(ALIGN), "Alignment must be a power of 2");
+ //auto t = reinterpret_cast<std::uintptr_t>(p);
+ //if (t & (ALIGN-1))
+ // printf("alignment error!");
return reinterpret_cast<T *>(__builtin_assume_aligned(p, ALIGN));
}
@@ -116,8 +124,8 @@ namespace plib {
constexpr pdefault_deleter() noexcept = default;
template<typename U, typename = typename
- std::enable_if<std::is_convertible< U*, T*>::value>::type>
- pdefault_deleter(const pdefault_deleter<U>&) noexcept { }
+ std::enable_if<std::is_convertible< U*, T*>::value>::type>
+ pdefault_deleter(const pdefault_deleter<U>&) noexcept { }
void operator()(T *p) const
{
@@ -241,58 +249,62 @@ namespace plib {
class aligned_allocator
{
public:
- using value_type = T;
+ using value_type = T;
+
+ static_assert(ALIGN >= alignof(T) && (ALIGN % alignof(T)) == 0,
+ "ALIGN must be greater than alignof(T) and a multiple");
- static_assert(ALIGN >= alignof(T) && (ALIGN % alignof(T)) == 0,
- "ALIGN must be greater than alignof(T) and a multiple");
+ aligned_allocator() noexcept = default;
+ ~aligned_allocator() noexcept = default;
- aligned_allocator() = default;
+ aligned_allocator(const aligned_allocator&) noexcept = default;
+ aligned_allocator& operator=(const aligned_allocator&) noexcept = delete;
- aligned_allocator(const aligned_allocator&) = default;
- aligned_allocator& operator=(const aligned_allocator&) = delete;
+ aligned_allocator(aligned_allocator&&) noexcept = default;
+ aligned_allocator& operator=(aligned_allocator&&) = delete;
- template <class U>
- aligned_allocator(const aligned_allocator<U, ALIGN>& rhs) noexcept
- {
- unused_var(rhs);
- }
+ template <class U>
+ aligned_allocator(const aligned_allocator<U, ALIGN>& rhs) noexcept
+ {
+ unused_var(rhs);
+ }
- template <class U> struct rebind
+ template <class U> struct rebind
{
- using other = aligned_allocator<U, ALIGN>;
+ using other = aligned_allocator<U, ALIGN>;
};
- T* allocate(std::size_t n)
- {
- return reinterpret_cast<T *>(paligned_alloc(ALIGN, sizeof(T) * n));
- }
+ T* allocate(std::size_t n)
+ {
+ return reinterpret_cast<T *>(paligned_alloc(ALIGN, sizeof(T) * n));
+ }
- void deallocate(T* p, std::size_t n) noexcept
- {
- unused_var(n);
- pfree(p);
- }
+ void deallocate(T* p, std::size_t n) noexcept
+ {
+ unused_var(n);
+ pfree(p);
+ }
- template <class T1, std::size_t A1, class U, std::size_t A2>
- friend bool operator==(const aligned_allocator<T1, A1>& lhs,
- const aligned_allocator<U, A2>& rhs) noexcept;
+ template <class T1, std::size_t A1, class U, std::size_t A2>
+ friend bool operator==(const aligned_allocator<T1, A1>& lhs,
+ const aligned_allocator<U, A2>& rhs) noexcept;
- template <class U, std::size_t A> friend class aligned_allocator;
+ template <class U, std::size_t A> friend class aligned_allocator;
};
- template <class T1, std::size_t A1, class U, std::size_t A2>
- /*friend*/ inline bool operator==(const aligned_allocator<T1, A1>& lhs,
- const aligned_allocator<U, A2>& rhs) noexcept
- {
- unused_var(lhs, rhs);
- return A1 == A2;
- }
- template <class T1, std::size_t A1, class U, std::size_t A2>
- /*friend*/ inline bool operator!=(const aligned_allocator<T1, A1>& lhs,
- const aligned_allocator<U, A2>& rhs) noexcept
- {
- return !(lhs == rhs);
- }
+ template <class T1, std::size_t A1, class U, std::size_t A2>
+ /*friend*/ inline bool operator==(const aligned_allocator<T1, A1>& lhs,
+ const aligned_allocator<U, A2>& rhs) noexcept
+ {
+ unused_var(lhs, rhs);
+ return A1 == A2;
+ }
+ template <class T1, std::size_t A1, class U, std::size_t A2>
+ /*friend*/ inline bool operator!=(const aligned_allocator<T1, A1>& lhs,
+ const aligned_allocator<U, A2>& rhs) noexcept
+ {
+ return !(lhs == rhs);
+ }
// FIXME: needs to be somewhere else
#if 0
@@ -308,6 +320,8 @@ namespace plib {
using reference = typename base::reference;
using const_reference = typename base::const_reference;
+ using pointer = typename base::pointer;
+ using const_pointer = typename base::const_pointer;
using size_type = typename base::size_type;
using base::base;
@@ -321,6 +335,9 @@ namespace plib {
return assume_aligned_ptr<T, ALIGN>(this->data())[i];
}
+ pointer data() noexcept { return assume_aligned_ptr<T, ALIGN>(base::data()); }
+ const_pointer data() const noexcept { return assume_aligned_ptr<T, ALIGN>(base::data()); }
+
};