@@ -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+ 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+ 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+ 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+ 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+ 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+ 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