Skip to content

Commit 921ed9f

Browse files
committed
Add is() specialisations for literals
1 parent 4729ff9 commit 921ed9f

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
@@ -597,6 +597,94 @@ auto is( X const& x ) -> bool {
597597
return x == X();
598598
}
599599

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

601689
//-------------------------------------------------------------------------------------------------------------
602690
// Built-in as (partial)

0 commit comments

Comments
 (0)