Skip to content

Commit 1e5547e

Browse files
committed
update IPC_CONCEPT_
1 parent ef2988b commit 1e5547e

File tree

6 files changed

+59
-43
lines changed

6 files changed

+59
-43
lines changed

src/libipc/memory/alloc.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ constexpr std::size_t aligned(std::size_t size, size_t alignment) noexcept {
4444
return ( (size - 1) & ~(alignment - 1) ) + alignment;
4545
}
4646

47-
IPC_CONCEPT_(has_take, take(std::move(std::declval<Type>())));
47+
template <typename T>
48+
IPC_CONCEPT_(has_take, require<T>([](auto && t)->decltype(t.take(std::move(t))) {}));
4849

4950
class scope_alloc_base {
5051
protected:
@@ -116,13 +117,13 @@ class scope_alloc : public detail::scope_alloc_base {
116117
}
117118

118119
template <typename A = AllocP>
119-
auto take(scope_alloc && rhs) -> ipc::require<detail::has_take<A>::value> {
120+
auto take(scope_alloc && rhs) -> std::enable_if_t<detail::has_take<A>::value> {
120121
base_t::take(std::move(rhs));
121122
alloc_.take(std::move(rhs.alloc_));
122123
}
123124

124125
template <typename A = AllocP>
125-
auto take(scope_alloc && rhs) -> ipc::require<!detail::has_take<A>::value> {
126+
auto take(scope_alloc && rhs) -> std::enable_if_t<!detail::has_take<A>::value> {
126127
base_t::take(std::move(rhs));
127128
}
128129

@@ -255,7 +256,7 @@ class fixed_alloc : public detail::fixed_alloc_base {
255256
}
256257

257258
template <typename A = AllocP>
258-
auto take(fixed_alloc && rhs) -> ipc::require<detail::has_take<A>::value> {
259+
auto take(fixed_alloc && rhs) -> std::enable_if_t<detail::has_take<A>::value> {
259260
base_t::take(std::move(rhs));
260261
alloc_.take(std::move(rhs.alloc_));
261262
}
@@ -394,7 +395,7 @@ class variable_alloc : public detail::variable_alloc_base {
394395
}
395396

396397
template <typename A = AllocP>
397-
auto take(variable_alloc && rhs) -> ipc::require<detail::has_take<A>::value> {
398+
auto take(variable_alloc && rhs) -> std::enable_if_t<detail::has_take<A>::value> {
398399
base_t::take(std::move(rhs));
399400
alloc_.take(std::move(rhs.alloc_));
400401
}

src/libipc/memory/wrapper.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ namespace mem {
2727

2828
namespace detail {
2929

30-
IPC_CONCEPT_(is_comparable, operator<(std::declval<Type>()));
30+
template <typename T>
31+
IPC_CONCEPT_(is_comparable, require<const T>([](auto && t)->decltype(t < t) {}));
3132

3233
} // namespace detail
3334

@@ -71,8 +72,10 @@ class limited_recycler<AllocP, true> {
7172
template <typename AllocP>
7273
class default_recycler : public limited_recycler<AllocP> {
7374

74-
IPC_CONCEPT_(has_remain, remain());
75-
IPC_CONCEPT_(has_empty , empty());
75+
template <typename T>
76+
IPC_CONCEPT_(has_remain, require<const T>([](auto && t)->decltype(t.remain()) {}));
77+
template <typename T>
78+
IPC_CONCEPT_(has_empty, require<const T>([](auto && t)->decltype(t.empty()) {}));
7679

7780
template <typename A>
7881
void try_fill(A & alc) {
@@ -86,28 +89,28 @@ class default_recycler : public limited_recycler<AllocP> {
8689

8790
template <typename A = AllocP>
8891
auto try_replenish(alloc_policy & alc, std::size_t size)
89-
-> ipc::require<detail::has_take<A>::value && has_remain<A>::value> {
92+
-> std::enable_if_t<detail::has_take<A>::value && has_remain<A>::value> {
9093
if (alc.remain() >= size) return;
9194
this->try_fill(alc);
9295
}
9396

9497
template <typename A = AllocP>
9598
auto try_replenish(alloc_policy & alc, std::size_t /*size*/)
96-
-> ipc::require<detail::has_take<A>::value && !has_remain<A>::value && has_empty<A>::value> {
99+
-> std::enable_if_t<detail::has_take<A>::value && !has_remain<A>::value && has_empty<A>::value> {
97100
if (!alc.empty()) return;
98101
this->try_fill(alc);
99102
}
100103

101104
template <typename A = AllocP>
102105
auto try_replenish(alloc_policy & alc, std::size_t /*size*/)
103-
-> ipc::require<!detail::has_take<A>::value && has_empty<A>::value> {
106+
-> std::enable_if_t<!detail::has_take<A>::value && has_empty<A>::value> {
104107
if (!alc.empty()) return;
105108
this->try_recover(alc);
106109
}
107110

108111
template <typename A = AllocP>
109112
IPC_CONSTEXPR_ auto try_replenish(alloc_policy & /*alc*/, std::size_t /*size*/) noexcept
110-
-> ipc::require<(!detail::has_take<A>::value || !has_remain<A>::value) && !has_empty<A>::value> {
113+
-> std::enable_if_t<(!detail::has_take<A>::value || !has_remain<A>::value) && !has_empty<A>::value> {
111114
// Do Nothing.
112115
}
113116
};

src/libipc/platform/tls_pointer_win.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
* @remarks
88
* Windows doesn't support a per-thread destructor with its TLS primitives.
99
* So, here will build it manually by inserting a function to be called on each thread's exit.
10-
*
1110
* @see
1211
* - https://www.codeproject.com/Articles/8113/Thread-Local-Storage-The-C-Way
1312
* - https://src.chromium.org/viewvc/chrome/trunk/src/base/threading/thread_local_storage_win.cc

src/libipc/platform/to_tchar.h

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,14 @@
1515
namespace ipc {
1616
namespace detail {
1717

18-
struct has_value_type_ {
19-
template <typename T> static std::true_type check(typename T::value_type *);
20-
template <typename T> static std::false_type check(...);
21-
};
22-
23-
template <typename T, typename U, typename = decltype(has_value_type_::check<U>(nullptr))>
24-
struct is_same_char : std::is_same<T, U> {};
25-
2618
template <typename T, typename U>
27-
struct is_same_char<T, U, std::true_type> : std::is_same<T, typename U::value_type> {};
19+
IPC_CONCEPT_(has_same_char,
20+
require([]()->std::enable_if_t<std::is_same<T, typename U::value_type>::value> {}) ||
21+
require([]()->std::enable_if_t<std::is_same<T, U>::value> {})
22+
);
2823

2924
template <typename T, typename S, typename R = S>
30-
using IsSameChar = ipc::require<is_same_char<T, S>::value, R>;
25+
using IsSameChar = std::enable_if_t<has_same_char<T, S>::value, R>;
3126

3227
////////////////////////////////////////////////////////////////
3328
/// to_tchar implementation

src/libipc/utility/concept.h

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,42 @@
11
#pragma once
22

3-
#include <type_traits> // std::enable_if
3+
#include <type_traits> // std::declval
44

55
namespace ipc {
66

7-
// concept helpers
7+
/**
8+
* @remarks
9+
* <<Concepts emulation>> Concepts TS Improve on C++17
10+
* @see
11+
* - http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0726r0.html
12+
* - https://www.youtube.com/watch?v=TorW5ekkL_w
13+
*/
14+
namespace detail {
815

9-
template <bool Cond, typename R = void>
10-
using require = typename std::enable_if<Cond, R>::type;
16+
template <typename F, typename... Args,
17+
typename = decltype(std::declval<F&&>()(std::declval<Args&&>()...))>
18+
constexpr bool require_impl(int) { return true; }
19+
20+
template <typename F, typename... Args>
21+
constexpr bool require_impl(...) { return false; }
22+
23+
} // namespace detail
24+
25+
template <typename... Args, typename F>
26+
constexpr bool require(F&&) {
27+
return detail::require_impl<F&&, Args&&...>(int{});
28+
}
29+
30+
} // namespace ipc
31+
32+
/// concept helpers
1133

1234
#ifdef IPC_CONCEPT_
1335
# error "IPC_CONCEPT_ has been defined."
1436
#endif
1537

16-
#define IPC_CONCEPT_(NAME, WHAT) \
17-
template <typename T> \
18-
class NAME { \
19-
private: \
20-
template <typename Type> \
21-
static std::true_type check(decltype(std::declval<Type>().WHAT)*); \
22-
template <typename Type> \
23-
static std::false_type check(...); \
24-
public: \
25-
using type = decltype(check<T>(nullptr)); \
26-
constexpr static auto value = type::value; \
38+
#define IPC_CONCEPT_($$name, $$what) \
39+
class $$name { \
40+
public: \
41+
constexpr static bool value = $$what; \
2742
}
28-
29-
} // namespace ipc

src/libipc/utility/pimpl.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,18 @@
88

99
namespace ipc {
1010

11-
// pimpl small object optimization helpers
11+
template <typename T>
12+
IPC_CONCEPT_(is_impl_comfortable,
13+
require<T>([](auto && t)->std::enable_if_t<(sizeof(t) <= sizeof(T*))> {})
14+
);
1215

1316
template <typename T, typename R = T*>
14-
using IsImplComfortable = ipc::require<(sizeof(T) <= sizeof(T*)), R>;
17+
using IsImplComfortable = std::enable_if_t<is_impl_comfortable<T>::value, R>;
1518

1619
template <typename T, typename R = T*>
17-
using IsImplUncomfortable = ipc::require<(sizeof(T) > sizeof(T*)), R>;
20+
using IsImplUncomfortable = std::enable_if_t<!is_impl_comfortable<T>::value, R>;
21+
22+
// pimpl small object optimization helpers
1823

1924
template <typename T, typename... P>
2025
constexpr auto make_impl(P&&... params) -> IsImplComfortable<T> {

0 commit comments

Comments
 (0)