summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author couriersud <couriersud@gmx.org>2020-06-08 03:10:27 +0200
committer couriersud <couriersud@gmx.org>2020-06-08 03:10:27 +0200
commit1c635c1bfd50098acb12e690672c883a4e4026c7 (patch)
tree91767c0eb984574b44bc783db0084fc78b480323
parentbed452a874c5565b176bae530af76d3af60047ee (diff)
netlist: Fix MSVC build. [Couriersud]
MSVC has an issue with SFINAE and overloading resolution. A discussion can be found here: https://stackoverflow.com/questions/31062892/overloading-on-static-in-conjunction-with-sfinae The previous code compiled with gcc and clang on all platforms and compilers apart from MSVC. Replaced with double template specialization.
-rw-r--r--src/lib/netlist/plib/palloc.h139
1 files changed, 83 insertions, 56 deletions
diff --git a/src/lib/netlist/plib/palloc.h b/src/lib/netlist/plib/palloc.h
index a2abe820899..1e103577da4 100644
--- a/src/lib/netlist/plib/palloc.h
+++ b/src/lib/netlist/plib/palloc.h
@@ -288,8 +288,16 @@ namespace plib {
// Memory allocation
//============================================================
- template <typename P, bool HSD, bool HSA>
- struct arena_base
+ // MSVC has an issue with SFINAE and overloading resolution.
+ // A discussion can be found here:
+ //
+ // https://stackoverflow.com/questions/31062892/overloading-on-static-in-conjunction-with-sfinae
+ //
+ // The previous code compiled with gcc and clang on all platforms and
+ // compilers apart from MSVC.
+
+ template <typename P, bool HSD>
+ struct arena_core
{
static constexpr const bool has_static_deallocator = HSD;
using size_type = std::size_t;
@@ -297,6 +305,46 @@ namespace plib {
template <class T, size_type ALIGN = alignof(T)>
using allocator_type = arena_allocator<P, T, ALIGN>;
+ static inline P &instance() noexcept
+ {
+ static P s_arena;
+ return s_arena;
+ }
+
+ size_type cur_alloc() const noexcept { return m_stat_cur_alloc(); } // NOLINT(readability-convert-member-functions-to-static)
+ size_type max_alloc() const noexcept { return m_stat_max_alloc(); } // NOLINT(readability-convert-member-functions-to-static)
+ protected:
+ static size_t &m_stat_cur_alloc() noexcept { static size_t val = 0; return val; }
+ static size_t &m_stat_max_alloc() noexcept { static size_t val = 0; return val; }
+
+ };
+
+ template <typename P, bool HSD>
+ struct arena_hsd : public arena_core<P, HSD>
+ {
+ template<typename T>
+ inline void free(T *ptr) noexcept
+ {
+ ptr->~T();
+ static_cast<P *>(this)->deallocate(ptr, sizeof(T));
+ }
+ };
+
+ template <typename P>
+ struct arena_hsd<P, true> : public arena_core<P, true>
+ {
+ template<typename T>
+ static inline void free(T *ptr) noexcept
+ {
+ ptr->~T();
+ P::deallocate(ptr, sizeof(T));
+ }
+ };
+
+
+ template <typename P, bool HSD, bool HSA>
+ struct arena_base : public arena_hsd<P, HSD>
+ {
template <class T>
using deleter_type = arena_deleter<P, T>;
@@ -306,17 +354,10 @@ namespace plib {
template <typename T>
using owned_ptr = plib::owned_ptr<T, deleter_type<T>>;
- static inline P &instance() noexcept
- {
- static P s_arena;
- return s_arena;
- }
-
template<typename T, typename... Args>
- static inline std::enable_if_t<HSA, unique_ptr<T>>
- make_unique(Args&&... args)
+ inline unique_ptr<T> make_unique(Args&&... args)
{
- auto *mem = P::allocate(alignof(T), sizeof(T));
+ auto *mem = static_cast<P *>(this)->allocate(alignof(T), sizeof(T));
try
{
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
@@ -325,21 +366,20 @@ namespace plib {
}
catch (...)
{
- P::deallocate(mem, sizeof(T));
+ static_cast<P *>(this)->deallocate(mem, sizeof(T));
throw;
}
}
template<typename T, typename... Args>
- inline std::enable_if_t<!HSA, unique_ptr<T>>
- make_unique(Args&&... args)
+ inline owned_ptr<T> make_owned(Args&&... args)
{
auto *mem = static_cast<P *>(this)->allocate(alignof(T), sizeof(T));
try
{
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
auto *mema = new (mem) T(std::forward<Args>(args)...);
- return unique_ptr<T>(mema, deleter_type<T>());
+ return owned_ptr<T>(mema, true, deleter_type<T>());
}
catch (...)
{
@@ -349,15 +389,36 @@ namespace plib {
}
template<typename T, typename... Args>
- static inline std::enable_if_t<HSA, owned_ptr<T>>
- make_owned(Args&&... args)
+ inline T * alloc(Args&&... args)
+ {
+ auto *p = static_cast<P *>(this)->allocate(alignof(T), sizeof(T));
+ // NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
+ return new(p) T(std::forward<Args>(args)...);
+ }
+
+ };
+
+ template <typename P, bool HSD>
+ struct arena_base<P, HSD, true> : public arena_hsd<P, HSD>
+ {
+ template <class T>
+ using deleter_type = arena_deleter<P, T>;
+
+ template <typename T>
+ using unique_ptr = std::unique_ptr<T, deleter_type<T>>;
+
+ template <typename T>
+ using owned_ptr = plib::owned_ptr<T, deleter_type<T>>;
+
+ template<typename T, typename... Args>
+ static inline unique_ptr<T> make_unique(Args&&... args)
{
auto *mem = P::allocate(alignof(T), sizeof(T));
try
{
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
auto *mema = new (mem) T(std::forward<Args>(args)...);
- return owned_ptr<T>(mema, true, deleter_type<T>());
+ return unique_ptr<T>(mema, deleter_type<T>());
}
catch (...)
{
@@ -367,10 +428,9 @@ namespace plib {
}
template<typename T, typename... Args>
- inline std::enable_if_t<!HSA, owned_ptr<T>>
- make_owned(Args&&... args)
+ static inline owned_ptr<T> make_owned(Args&&... args)
{
- auto *mem = static_cast<P *>(this)->allocate(alignof(T), sizeof(T));
+ auto *mem = P::allocate(alignof(T), sizeof(T));
try
{
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
@@ -379,51 +439,18 @@ namespace plib {
}
catch (...)
{
- static_cast<P *>(this)->deallocate(mem, sizeof(T));
+ P::deallocate(mem, sizeof(T));
throw;
}
}
template<typename T, typename... Args>
- static inline std::enable_if_t<HSA, T *>
- alloc(Args&&... args)
+ static inline T * alloc(Args&&... args)
{
auto *p = P::allocate(alignof(T), sizeof(T));
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
return new(p) T(std::forward<Args>(args)...);
}
-
- template<typename T, typename... Args>
- inline std::enable_if_t<!HSA, T *>
- alloc(Args&&... args)
- {
- auto *p = static_cast<P *>(this)->allocate(alignof(T), sizeof(T));
- // NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
- return new(p) T(std::forward<Args>(args)...);
- }
-
- template<typename T>
- static inline void
- free(T *ptr, std::enable_if_t<HSD, T *> = nullptr) noexcept
- {
- ptr->~T();
- P::deallocate(ptr, sizeof(T));
- }
-
- template<typename T>
- inline void
- free(T *ptr, std::enable_if_t<!HSD, T *> = nullptr) noexcept
- {
- ptr->~T();
- static_cast<P *>(this)->deallocate(ptr, sizeof(T));
- }
-
- size_type cur_alloc() const noexcept { return m_stat_cur_alloc(); } // NOLINT(readability-convert-member-functions-to-static)
- size_type max_alloc() const noexcept { return m_stat_max_alloc(); } // NOLINT(readability-convert-member-functions-to-static)
- protected:
- static size_t &m_stat_cur_alloc() noexcept { static size_t val = 0; return val; }
- static size_t &m_stat_max_alloc() noexcept { static size_t val = 0; return val; }
-
};