@@ -597,6 +597,94 @@ auto is( X const& x ) -> bool {
597
597
return x == X ();
598
598
}
599
599
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
+ }
600
688
601
689
// -------------------------------------------------------------------------------------------------------------
602
690
// Built-in as (partial)
0 commit comments