@@ -552,6 +552,94 @@ auto is( X const& x ) -> bool {
552
552
return x == X ();
553
553
}
554
554
555
+ // -------------------------------------------------------------------------------------------------------------
556
+ // Built-in is (literals)
557
+ //
558
+
559
+ template < auto value, typename X, typename V = CPP2_TYPEOF(value)>
560
+ // This requires are needed for gcc compiler to avoid ambiguity when value is double
561
+ requires (
562
+ (std::floating_point<V> && !std::floating_point<X>) ||
563
+ (std::integral<V> && !std::integral<X>) ||
564
+ (std::is_enum_v<V> && !std::is_same_v<V, X> )
565
+ )
566
+ constexpr auto is ( X const & x ) -> bool {
567
+ return false ;
568
+ }
569
+
570
+ template < auto value, typename X >
571
+ requires (std::is_enum_v<CPP2_TYPEOF(value)> && std::is_same_v<X,CPP2_TYPEOF(value)>)
572
+ constexpr auto is ( X const & x ) -> bool {
573
+ return x == value;
574
+ }
575
+
576
+ template < auto value, typename X >
577
+ requires std::integral<CPP2_TYPEOF(value)> && std::integral<X>
578
+ constexpr auto is ( X const & x ) -> bool {
579
+ return x == value;
580
+ }
581
+
582
+ // Workaroud for lack of support for floating point template argument by clang and MSVC
583
+ struct double_wrapper {
584
+ double value = {};
585
+
586
+ template <typename T>
587
+ requires std::is_floating_point_v<T>
588
+ constexpr double_wrapper (T d) : value(d) {}
589
+
590
+ operator double () const {
591
+ return value;
592
+ }
593
+
594
+ template <typename T>
595
+ bool operator ==(T rhs) const {
596
+ return value == rhs;
597
+ }
598
+ };
599
+
600
+ // This is needed to solve some issue with clang - probably clang bug.
601
+ // Without it clang is not able to match with default specialisation:
602
+ // template< auto value, typename X > auto is( X const& x ) -> bool;
603
+ #if defined(__clang__)
604
+
605
+ template < double_wrapper value, typename X >
606
+ constexpr auto is ( X const & x ) -> bool {
607
+ if constexpr (std::is_floating_point_v<X>)
608
+ return x == value;
609
+ else
610
+ return false ;
611
+ }
612
+
613
+ #else
614
+
615
+ template < double_wrapper value, typename X >
616
+ requires std::is_floating_point_v<X>
617
+ constexpr auto is ( X const & x ) -> bool {
618
+ return x == value;
619
+ }
620
+
621
+ #endif
622
+
623
+ template <auto N>
624
+ struct cstring_wrapper {
625
+ char cs[N];
626
+
627
+ constexpr cstring_wrapper (const char (&s)[N]) noexcept {
628
+ std::copy (s, s+N, cs);
629
+ }
630
+
631
+ constexpr bool operator ==(const std::string_view& sv) const noexcept {
632
+ return std::equal (cs, cs+N-1 , sv.begin (), sv.end ()); // N-1 as sv is not null-terminated
633
+ }
634
+ };
635
+
636
+ template < cstring_wrapper value, typename X >
637
+ constexpr auto is ( X const & x ) -> bool {
638
+ if constexpr (std::is_convertible_v<X, std::string_view>)
639
+ return value == x;
640
+ else
641
+ return false ;
642
+ }
555
643
556
644
// -------------------------------------------------------------------------------------------------------------
557
645
// Built-in as (partial)
0 commit comments