From 1e5547e6dfd0605fa62be67899c6c893aa61f9fc Mon Sep 17 00:00:00 2001 From: mutouyun Date: Sat, 28 Nov 2020 22:26:07 +0800 Subject: [PATCH] update IPC_CONCEPT_ --- src/libipc/memory/alloc.h | 11 +++--- src/libipc/memory/wrapper.h | 17 +++++---- src/libipc/platform/tls_pointer_win.cpp | 1 - src/libipc/platform/to_tchar.h | 15 +++----- src/libipc/utility/concept.h | 47 ++++++++++++++++--------- src/libipc/utility/pimpl.h | 17 +++++---- 6 files changed, 62 insertions(+), 46 deletions(-) diff --git a/src/libipc/memory/alloc.h b/src/libipc/memory/alloc.h index 16bebc9..820361a 100755 --- a/src/libipc/memory/alloc.h +++ b/src/libipc/memory/alloc.h @@ -44,7 +44,8 @@ constexpr std::size_t aligned(std::size_t size, size_t alignment) noexcept { return ( (size - 1) & ~(alignment - 1) ) + alignment; } -IPC_CONCEPT_(has_take, take(std::move(std::declval()))); +template +IPC_CONCEPT_(has_take, require([](auto && t)->decltype(t.take(std::move(t))) {})); class scope_alloc_base { protected: @@ -116,13 +117,13 @@ public: } template - auto take(scope_alloc && rhs) -> ipc::require::value> { + auto take(scope_alloc && rhs) -> std::enable_if_t::value> { base_t::take(std::move(rhs)); alloc_.take(std::move(rhs.alloc_)); } template - auto take(scope_alloc && rhs) -> ipc::require::value> { + auto take(scope_alloc && rhs) -> std::enable_if_t::value> { base_t::take(std::move(rhs)); } @@ -255,7 +256,7 @@ public: } template - auto take(fixed_alloc && rhs) -> ipc::require::value> { + auto take(fixed_alloc && rhs) -> std::enable_if_t::value> { base_t::take(std::move(rhs)); alloc_.take(std::move(rhs.alloc_)); } @@ -394,7 +395,7 @@ public: } template - auto take(variable_alloc && rhs) -> ipc::require::value> { + auto take(variable_alloc && rhs) -> std::enable_if_t::value> { base_t::take(std::move(rhs)); alloc_.take(std::move(rhs.alloc_)); } diff --git a/src/libipc/memory/wrapper.h b/src/libipc/memory/wrapper.h index 5e76f88..7f84838 100755 --- a/src/libipc/memory/wrapper.h +++ b/src/libipc/memory/wrapper.h @@ -27,7 +27,8 @@ namespace mem { namespace detail { -IPC_CONCEPT_(is_comparable, operator<(std::declval())); +template +IPC_CONCEPT_(is_comparable, require([](auto && t)->decltype(t < t) {})); } // namespace detail @@ -71,8 +72,10 @@ public: template class default_recycler : public limited_recycler { - IPC_CONCEPT_(has_remain, remain()); - IPC_CONCEPT_(has_empty , empty()); + template + IPC_CONCEPT_(has_remain, require([](auto && t)->decltype(t.remain()) {})); + template + IPC_CONCEPT_(has_empty, require([](auto && t)->decltype(t.empty()) {})); template void try_fill(A & alc) { @@ -86,28 +89,28 @@ public: template auto try_replenish(alloc_policy & alc, std::size_t size) - -> ipc::require::value && has_remain::value> { + -> std::enable_if_t::value && has_remain::value> { if (alc.remain() >= size) return; this->try_fill(alc); } template auto try_replenish(alloc_policy & alc, std::size_t /*size*/) - -> ipc::require::value && !has_remain::value && has_empty::value> { + -> std::enable_if_t::value && !has_remain::value && has_empty::value> { if (!alc.empty()) return; this->try_fill(alc); } template auto try_replenish(alloc_policy & alc, std::size_t /*size*/) - -> ipc::require::value && has_empty::value> { + -> std::enable_if_t::value && has_empty::value> { if (!alc.empty()) return; this->try_recover(alc); } template IPC_CONSTEXPR_ auto try_replenish(alloc_policy & /*alc*/, std::size_t /*size*/) noexcept - -> ipc::require<(!detail::has_take::value || !has_remain::value) && !has_empty::value> { + -> std::enable_if_t<(!detail::has_take::value || !has_remain::value) && !has_empty::value> { // Do Nothing. } }; diff --git a/src/libipc/platform/tls_pointer_win.cpp b/src/libipc/platform/tls_pointer_win.cpp index cdbe208..3d56909 100755 --- a/src/libipc/platform/tls_pointer_win.cpp +++ b/src/libipc/platform/tls_pointer_win.cpp @@ -7,7 +7,6 @@ * @remarks * Windows doesn't support a per-thread destructor with its TLS primitives. * So, here will build it manually by inserting a function to be called on each thread's exit. - * * @see * - https://www.codeproject.com/Articles/8113/Thread-Local-Storage-The-C-Way * - https://src.chromium.org/viewvc/chrome/trunk/src/base/threading/thread_local_storage_win.cc diff --git a/src/libipc/platform/to_tchar.h b/src/libipc/platform/to_tchar.h index df67b2d..2598b83 100755 --- a/src/libipc/platform/to_tchar.h +++ b/src/libipc/platform/to_tchar.h @@ -15,19 +15,14 @@ namespace ipc { namespace detail { -struct has_value_type_ { - template static std::true_type check(typename T::value_type *); - template static std::false_type check(...); -}; - -template (nullptr))> -struct is_same_char : std::is_same {}; - template -struct is_same_char : std::is_same {}; +IPC_CONCEPT_(has_same_char, + require([]()->std::enable_if_t::value> {}) || + require([]()->std::enable_if_t::value> {}) +); template -using IsSameChar = ipc::require::value, R>; +using IsSameChar = std::enable_if_t::value, R>; //////////////////////////////////////////////////////////////// /// to_tchar implementation diff --git a/src/libipc/utility/concept.h b/src/libipc/utility/concept.h index 9325ddc..5192c07 100755 --- a/src/libipc/utility/concept.h +++ b/src/libipc/utility/concept.h @@ -1,29 +1,42 @@ #pragma once -#include // std::enable_if +#include // std::declval namespace ipc { -// concept helpers +/** + * @remarks + * <> Concepts TS Improve on C++17 + * @see + * - http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0726r0.html + * - https://www.youtube.com/watch?v=TorW5ekkL_w +*/ +namespace detail { -template -using require = typename std::enable_if::type; +template ()(std::declval()...))> +constexpr bool require_impl(int) { return true; } + +template +constexpr bool require_impl(...) { return false; } + +} // namespace detail + +template +constexpr bool require(F&&) { + return detail::require_impl(int{}); +} + +} // namespace ipc + +/// concept helpers #ifdef IPC_CONCEPT_ # error "IPC_CONCEPT_ has been defined." #endif -#define IPC_CONCEPT_(NAME, WHAT) \ -template \ -class NAME { \ -private: \ - template \ - static std::true_type check(decltype(std::declval().WHAT)*); \ - template \ - static std::false_type check(...); \ -public: \ - using type = decltype(check(nullptr)); \ - constexpr static auto value = type::value; \ +#define IPC_CONCEPT_($$name, $$what) \ +class $$name { \ +public: \ + constexpr static bool value = $$what; \ } - -} // namespace ipc diff --git a/src/libipc/utility/pimpl.h b/src/libipc/utility/pimpl.h index 25074e7..fbb5ea2 100755 --- a/src/libipc/utility/pimpl.h +++ b/src/libipc/utility/pimpl.h @@ -8,14 +8,19 @@ namespace ipc { +template +IPC_CONCEPT_(is_impl_comfortable, + require([](auto && t)->std::enable_if_t<(sizeof(t) <= sizeof(T*))> {}) +); + +template +using IsImplComfortable = std::enable_if_t::value, R>; + +template +using IsImplUncomfortable = std::enable_if_t::value, R>; + // pimpl small object optimization helpers -template -using IsImplComfortable = ipc::require<(sizeof(T) <= sizeof(T*)), R>; - -template -using IsImplUncomfortable = ipc::require<(sizeof(T) > sizeof(T*)), R>; - template constexpr auto make_impl(P&&... params) -> IsImplComfortable { T* buf {};