Skip to content

Commit a0e99b0

Browse files
committed
Add is() specialisations for literals
1 parent 42f7eb6 commit a0e99b0

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
@@ -548,6 +548,94 @@ auto is( X const& x ) -> bool {
548548
return x == X();
549549
}
550550

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

552640
//-------------------------------------------------------------------------------------------------------------
553641
// Built-in as (partial)

0 commit comments

Comments
 (0)