@@ -615,6 +615,94 @@ auto is( X const& x ) -> bool {
615
615
return x == X ();
616
616
}
617
617
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
+ }
618
706
619
707
// -------------------------------------------------------------------------------------------------------------
620
708
// Built-in as (partial)
0 commit comments