Skip to content

Commit b7668e9

Browse files
committed
Add is() specialisations for literals
1 parent 2a1ec5c commit b7668e9

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
@@ -615,6 +615,94 @@ auto is( X const& x ) -> bool {
615615
return x == X();
616616
}
617617

618+
//-------------------------------------------------------------------------------------------------------------
619+
// Built-in is (literals)
620+
//
621+
622+
template< auto value, typename X, typename V = CPP2_TYPEOF(value)>
623+
// This requires are needed for gcc compiler to avoid ambiguity when value is double
624+
requires (
625+
(std::floating_point<V> && !std::floating_point<X>) ||
626+
(std::integral<V> && !std::integral<X>) ||
627+
(std::is_enum_v<V> && !std::is_same_v<V, X> )
628+
)
629+
constexpr auto is( X const& x ) -> bool {
630+
return false;
631+
}
632+
633+
template< auto value, typename X >
634+
requires (std::is_enum_v<CPP2_TYPEOF(value)> && std::is_same_v<X,CPP2_TYPEOF(value)>)
635+
constexpr auto is( X const& x ) -> bool {
636+
return x == value;
637+
}
638+
639+
template< auto value, typename X >
640+
requires std::integral<CPP2_TYPEOF(value)> && std::integral<X>
641+
constexpr auto is( X const& x ) -> bool {
642+
return x == value;
643+
}
644+
645+
// Workaroud for lack of support for floating point template argument by clang and MSVC
646+
struct double_wrapper {
647+
double value = {};
648+
649+
template <typename T>
650+
requires std::is_floating_point_v<T>
651+
constexpr double_wrapper(T d) : value(d) {}
652+
653+
constexpr operator double() const {
654+
return value;
655+
}
656+
657+
template <typename T>
658+
constexpr bool operator==(T rhs) const {
659+
return value == rhs;
660+
}
661+
};
662+
663+
// This is needed to solve some issue with clang - probably clang bug.
664+
// Without it clang is not able to match with default specialisation:
665+
// template< auto value, typename X > auto is( X const& x ) -> bool;
666+
#if defined(__clang__)
667+
668+
template< double_wrapper value, typename X >
669+
constexpr auto is( X const& x ) -> bool {
670+
if constexpr (std::is_floating_point_v<X>)
671+
return x == value;
672+
else
673+
return false;
674+
}
675+
676+
#else
677+
678+
template< double_wrapper value, typename X >
679+
requires std::is_floating_point_v<X>
680+
constexpr auto is( X const& x ) -> bool {
681+
return x == value;
682+
}
683+
684+
#endif
685+
686+
template <auto N>
687+
struct cstring_wrapper {
688+
char cs[N];
689+
690+
constexpr cstring_wrapper(const char (&s)[N]) noexcept {
691+
std::copy(s, s+N, cs);
692+
}
693+
694+
constexpr bool operator==(const std::string_view& sv) const noexcept {
695+
return std::equal(cs, cs+N-1, sv.begin(), sv.end()); // N-1 as sv is not null-terminated
696+
}
697+
};
698+
699+
template< cstring_wrapper value, typename X >
700+
constexpr auto is( X const& x ) -> bool {
701+
if constexpr (std::is_convertible_v<X, std::string_view>)
702+
return value == x;
703+
else
704+
return false;
705+
}
618706

619707
//-------------------------------------------------------------------------------------------------------------
620708
// Built-in as (partial)

0 commit comments

Comments
 (0)