@@ -548,6 +548,94 @@ auto is( X const& x ) -> bool {
548
548
return x == X ();
549
549
}
550
550
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
+ constexpr 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
+ constexpr 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
+ constexpr 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
+ constexpr 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
+ constexpr 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
+ constexpr 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
+ }
551
639
552
640
// -------------------------------------------------------------------------------------------------------------
553
641
// Built-in as (partial)
0 commit comments