diff options
author | 2020-06-08 03:10:27 +0200 | |
---|---|---|
committer | 2020-06-08 03:10:27 +0200 | |
commit | 1c635c1bfd50098acb12e690672c883a4e4026c7 (patch) | |
tree | 91767c0eb984574b44bc783db0084fc78b480323 | |
parent | bed452a874c5565b176bae530af76d3af60047ee (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.h | 139 |
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; } - }; |