Skip to content

Commit 170df2b

Browse files
committed
Update expression-decomposition.hpp
1 parent 15fdd9a commit 170df2b

File tree

1 file changed

+21
-20
lines changed

1 file changed

+21
-20
lines changed

include/libassert/expression-decomposition.hpp

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
LIBASSERT_BEGIN_NAMESPACE
1616
namespace detail {
17+
template<typename T>
18+
inline constexpr bool is_pointer_or_member_pointer = std::is_pointer_v<strip<T>> || std::is_member_pointer_v<strip<T>>;
1719
// Lots of boilerplate
1820
// std:: implementations don't allow two separate types for lhs/rhs
1921
// Note: is this macro potentially bad when it comes to debugging(?)
@@ -168,10 +170,11 @@ namespace detail {
168170
struct expression_decomposer<nothing, nothing, nothing> {
169171
explicit constexpr expression_decomposer() = default;
170172
#define LIBASSERT_GEN_BITFIELD_BOILERPLATE(type)\
171-
template<typename Delay = type>[[nodiscard]] constexpr auto operator<<(const type& operand)&& {\
173+
template<typename Delay = type>[[nodiscard]] constexpr auto operator<<(type operand)&& {\
172174
return expression_decomposer<Delay, nothing, nothing>(operand);\
173175
}
174176

177+
LIBASSERT_GEN_BITFIELD_BOILERPLATE(bool)
175178
LIBASSERT_GEN_BITFIELD_BOILERPLATE(char)
176179
LIBASSERT_GEN_BITFIELD_BOILERPLATE(signed char)
177180
LIBASSERT_GEN_BITFIELD_BOILERPLATE(unsigned char)
@@ -188,7 +191,7 @@ namespace detail {
188191
#undef LIBASSERT_GEN_BITFIELD_BOILERPLATE
189192

190193

191-
template<typename O> [[nodiscard]] constexpr auto operator<<(O&& operand) && {
194+
template<typename O,std::enable_if_t<!std::is_integral_v<strip<O>>,int> = 0> [[nodiscard]] constexpr auto operator<<(O&& operand) && {
192195
return expression_decomposer<O, nothing, nothing>(std::forward<O>(operand));
193196
}
194197
};
@@ -262,38 +265,36 @@ namespace detail {
262265
// and rvalues as rvalues.
263266
return std::forward<A>(a);
264267
}
265-
template<typename Depend = std::remove_reference_t<A>,std::enable_if_t<
266-
std::is_member_pointer_v<Depend> || std::is_pointer_v<Depend>,int> = 0
267-
>
268-
constexpr auto operator==(decltype(NULL)) &&
268+
template<typename Null,std::enable_if_t<
269+
std::is_integral_v<Null> && is_pointer_or_member_pointer<A>,int> = 0>
270+
constexpr auto operator==(Null) &&
269271
{
270272
return expression_decomposer<A, std::nullptr_t, ops::eq>(std::forward<A>(a), nullptr);
271273
}
272274

273-
template<typename Depend = A, std::enable_if_t<isa<Depend,decltype(NULL)>, int> = 0
274-
,typename Pointer>
275-
constexpr auto operator==(Pointer* pointer)&&
275+
template<typename Pointer, std::enable_if_t<
276+
is_pointer_or_member_pointer<Pointer> && std::is_integral_v<strip<A>>, int> = 0>
277+
constexpr auto operator==(Pointer&& pointer) &&
276278
{
277-
return expression_decomposer<std::nullptr_t , Pointer*, ops::eq > (nullptr, pointer);
279+
return expression_decomposer<std::nullptr_t , Pointer, ops::eq > (nullptr, std::forward<Pointer>(pointer));
278280
}
279281

280-
template<typename Depend = std::remove_reference_t<A>, std::enable_if_t<
281-
std::is_member_pointer_v<Depend> || std::is_pointer_v<Depend>, int> = 0
282-
>
283-
constexpr auto operator!=(decltype(NULL))&&
282+
template<typename Null, std::enable_if_t<std::is_integral_v<Null> && is_pointer_or_member_pointer<A>, int> = 0>
283+
constexpr auto operator!=(Null) &&
284284
{
285285
return expression_decomposer<A, std::nullptr_t, ops::neq>(std::forward<A>(a), nullptr);
286286
}
287287

288-
template<typename Depend = A, std::enable_if_t<isa<Depend, decltype(NULL)>, int> = 0
289-
, typename Pointer>
290-
constexpr auto operator!=(Pointer* pointer)&&
288+
template<typename Pointer, std::enable_if_t<
289+
is_pointer_or_member_pointer<Pointer> &&
290+
std::is_integral_v<strip<A>>,int> = 0>
291+
constexpr auto operator!=(Pointer&& pointer) &&
291292
{
292-
return expression_decomposer<std::nullptr_t, Pointer*, ops::neq>(nullptr, pointer);
293+
return expression_decomposer<std::nullptr_t, Pointer, ops::neq>(nullptr, std::forward<Pointer>(pointer));
293294
}
294-
295+
295296
#define LIBASSERT_GEN_OP_BOILERPLATE(functor, op) \
296-
template<typename O> [[nodiscard]] constexpr auto operator op(O&& operand) && { \
297+
template<typename O,std::enable_if_t<!((std::is_integral_v<strip<O>> && is_pointer_or_member_pointer<A>) || (std::is_integral_v<strip<A>> && is_pointer_or_member_pointer<O>)),int> = 0> [[nodiscard]] constexpr auto operator op(O&& operand) && { \
297298
return expression_decomposer<A, O, functor>(std::forward<A>(a), std::forward<O>(operand)); \
298299
}
299300
LIBASSERT_DO_GEN_OP_BOILERPLATE

0 commit comments

Comments
 (0)