Skip to content

Commit 50b7932

Browse files
committed
Add is() specialisations for literals
1 parent 3141cc0 commit 50b7932

File tree

1 file changed

+88
-0
lines changed

1 file changed

+88
-0
lines changed

include/cpp2util.h

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,94 @@ auto is( X const& x ) -> bool {
552552
return x == X();
553553
}
554554

555+
//-------------------------------------------------------------------------------------------------------------
556+
// Built-in is (literals)
557+
//
558+
559+
template< auto value, typename X, typename V = CPP2_TYPEOF(value)>
560+
// This requires are needed for gcc compiler to avoid ambiguity when value is double
561+
requires (
562+
(std::floating_point<V> && !std::floating_point<X>) ||
563+
(std::integral<V> && !std::integral<X>) ||
564+
(std::is_enum_v<V> && !std::is_same_v<V, X> )
565+
)
566+
constexpr auto is( X const& x ) -> bool {
567+
return false;
568+
}
569+
570+
template< auto value, typename X >
571+
requires (std::is_enum_v<CPP2_TYPEOF(value)> && std::is_same_v<X,CPP2_TYPEOF(value)>)
572+
constexpr auto is( X const& x ) -> bool {
573+
return x == value;
574+
}
575+
576+
template< auto value, typename X >
577+
requires std::integral<CPP2_TYPEOF(value)> && std::integral<X>
578+
constexpr auto is( X const& x ) -> bool {
579+
return x == value;
580+
}
581+
582+
// Workaroud for lack of support for floating point template argument by clang and MSVC
583+
struct double_wrapper {
584+
double value = {};
585+
586+
template <typename T>
587+
requires std::is_floating_point_v<T>
588+
constexpr double_wrapper(T d) : value(d) {}
589+
590+
operator double() const {
591+
return value;
592+
}
593+
594+
template <typename T>
595+
bool operator==(T rhs) const {
596+
return value == rhs;
597+
}
598+
};
599+
600+
// This is needed to solve some issue with clang - probably clang bug.
601+
// Without it clang is not able to match with default specialisation:
602+
// template< auto value, typename X > auto is( X const& x ) -> bool;
603+
#if defined(__clang__)
604+
605+
template< double_wrapper value, typename X >
606+
constexpr auto is( X const& x ) -> bool {
607+
if constexpr (std::is_floating_point_v<X>)
608+
return x == value;
609+
else
610+
return false;
611+
}
612+
613+
#else
614+
615+
template< double_wrapper value, typename X >
616+
requires std::is_floating_point_v<X>
617+
constexpr auto is( X const& x ) -> bool {
618+
return x == value;
619+
}
620+
621+
#endif
622+
623+
template <auto N>
624+
struct cstring_wrapper {
625+
char cs[N];
626+
627+
constexpr cstring_wrapper(const char (&s)[N]) noexcept {
628+
std::copy(s, s+N, cs);
629+
}
630+
631+
constexpr bool operator==(const std::string_view& sv) const noexcept {
632+
return std::equal(cs, cs+N-1, sv.begin(), sv.end()); // N-1 as sv is not null-terminated
633+
}
634+
};
635+
636+
template< cstring_wrapper value, typename X >
637+
constexpr auto is( X const& x ) -> bool {
638+
if constexpr (std::is_convertible_v<X, std::string_view>)
639+
return value == x;
640+
else
641+
return false;
642+
}
555643

556644
//-------------------------------------------------------------------------------------------------------------
557645
// Built-in as (partial)

0 commit comments

Comments
 (0)