@@ -389,7 +389,7 @@ struct Match<checkp, std::tuple<P ...>, mp::int_list<I ...>>
389389#pragma GCC diagnostic warning "-Warray-bounds"
390390 dim_t ls = len (k);
391391#pragma GCC diagnostic pop
392- if (((k<ra::rank (std:: get<I>(t)) && ls!=choose_len (std:: get<I>(t).len (k), ls)) || ...)) {
392+ if (((k<ra::rank (get<I>(t)) && ls!=choose_len (get<I>(t).len (k), ls)) || ...)) {
393393 return false ;
394394 }
395395 }
@@ -419,7 +419,7 @@ struct Match<checkp, std::tuple<P ...>, mp::int_list<I ...>>
419419 rank () const requires (ANY==rs)
420420 {
421421 rank_t r = BAD;
422- ((r = choose_rank (r, ra::rank (std:: get<I>(t)))), ...);
422+ ((r = choose_rank (r, ra::rank (get<I>(t)))), ...);
423423 assert (ANY!=r); // not at runtime
424424 return r;
425425 }
@@ -445,34 +445,34 @@ struct Match<checkp, std::tuple<P ...>, mp::int_list<I ...>>
445445 auto f = [&k](dim_t s, auto const & a) {
446446 return k<ra::rank (a) ? choose_len (s, a.len (k)) : s;
447447 };
448- dim_t s = BAD; ((s>=0 ? s : s = f (s, std:: get<I>(t))), ...);
448+ dim_t s = BAD; ((s>=0 ? s : s = f (s, get<I>(t))), ...);
449449 assert (ANY!=s); // not at runtime
450450 return s;
451451 }
452452// could preserve static, but ply doesn't use it atm.
453453 constexpr auto
454454 step (int i) const
455455 {
456- return std::make_tuple (std:: get<I>(t).step (i) ...);
456+ return std::make_tuple (get<I>(t).step (i) ...);
457457 }
458458 constexpr void
459459 adv (rank_t k, dim_t d)
460460 {
461- (std:: get<I>(t).adv (k, d), ...);
461+ (get<I>(t).adv (k, d), ...);
462462 }
463463 constexpr bool
464464 keep (dim_t st, int z, int j) const requires (!(requires { P::keep (st, z, j); } && ...))
465465 {
466- return (std:: get<I>(t).keep (st, z, j) && ...);
466+ return (get<I>(t).keep (st, z, j) && ...);
467467 }
468468 constexpr static bool
469469 keep (dim_t st, int z, int j) requires (requires { P::keep (st, z, j); } && ...)
470470 {
471471 return (std::decay_t <P>::keep (st, z, j) && ...);
472472 }
473- constexpr auto save () const { return std::make_tuple (std:: get<I>(t).save () ...); }
474- constexpr void load (auto const & pp) { ((std:: get<I>(t).load (std:: get<I>(pp))), ...); }
475- constexpr void mov (auto const & s) { ((std:: get<I>(t).mov (std:: get<I>(s))), ...); }
473+ constexpr auto save () const { return std::make_tuple (get<I>(t).save () ...); }
474+ constexpr void load (auto const & pp) { ((get<I>(t).load (get<I>(pp))), ...); }
475+ constexpr void mov (auto const & s) { ((get<I>(t).mov (get<I>(s))), ...); }
476476};
477477
478478
@@ -633,12 +633,17 @@ struct Framematch_def<V, std::tuple<Ti ...>, std::tuple<Ri ...>, skip>
633633// explicit agreement checks
634634// ---------------
635635
636+ template <bool checkp, class ... P>
637+ constexpr auto
638+ match (P && ... p) { return Match<checkp, std::tuple<P ...>> { RA_FWD (p) ... }; }
639+
640+ template <class ... P>
636641constexpr bool
637- agree (auto && ... p) { return agree_ (ra::start (RA_FWD (p)) ...); }
642+ agree (P && ... p) { return match< false > (ra::start (RA_FWD (p)) ...). check ( ); }
638643
639- // 0: fail, 1: rt, 2: pass
644+ template < class ... P>
640645constexpr int
641- agree_s (auto && ... p) { return agree_s_ ( ra::start (RA_FWD (p)) ...); }
646+ agree_s (P && ... p) { return decltype (match< false >( ra::start (RA_FWD (p)) ...)):: check_s ( ); }
642647
643648template <class Op , class ... P> requires (is_verb<Op>)
644649constexpr bool
@@ -648,14 +653,6 @@ template <class Op, class ... P> requires (!is_verb<Op>)
648653constexpr bool
649654agree_op(Op && op, P && ... p) { return agree (RA_FWD (p) ...); }
650655
651- template <class ... P>
652- constexpr bool
653- agree_ (P && ... p) { return (Match<false , std::tuple<P ...>> { RA_FWD (p) ... }).check (); }
654-
655- template <class ... P>
656- constexpr int
657- agree_s_ (P && ... p) { return Match<false , std::tuple<P ...>>::check_s (); }
658-
659656template <class V , class ... T, int ... i>
660657constexpr bool
661658agree_verb (mp::int_list<i ...>, V && v, T && ... t)
@@ -672,89 +669,82 @@ agree_verb(mp::int_list<i ...>, V && v, T && ... t)
672669template <class E >
673670decltype (auto ) to_scalar(E && e)
674671{
675- if constexpr (1 !=size_s (e)) {
672+ if constexpr (constexpr dim_t s=size_s (e); 1 !=s) {
673+ static_assert (ANY==s, " Bad scalar conversion from shape." );
676674 RA_CHECK (1 ==size (e), " Bad scalar conversion from shape [" , fmt (nstyle, ra::shape (e)), " ]." );
677675 }
678676 return *e;
679677}
680678
681- template <class Op , class T , class K =mp::iota<mp::len<T>>> struct Expr ;
679+ template <class Op , class T , class K =mp::iota<mp::len<T>>> struct Map ;
682680template <class Op , IteratorConcept ... P, int ... I>
683- struct Expr <Op, std::tuple<P ...>, mp::int_list<I ...>>: public Match<true , std::tuple<P ...>>
681+ struct Map <Op, std::tuple<P ...>, mp::int_list<I ...>>: public Match<true , std::tuple<P ...>>
684682{
685683 using Match_ = Match<true , std::tuple<P ...>>;
686684 using Match_::t;
687685 Op op;
688686
689- constexpr Expr (Op op_, P ... p_): Match_(p_ ...), op(op_) {} // [ra1]
690- RA_ASSIGNOPS_SELF (Expr )
687+ constexpr Map (Op op_, P ... p_): Match_(p_ ...), op(op_) {} // [ra1]
688+ RA_ASSIGNOPS_SELF (Map )
691689 RA_ASSIGNOPS_DEFAULT_SET
692- constexpr decltype (auto ) at(auto const & j) const { return std::invoke (op, std:: get<I>(t).at (j) ...); }
693- constexpr decltype (auto ) operator*() const { return std::invoke (op, *std:: get<I>(t) ...); }
694- constexpr operator decltype (std::invoke(op, *std:: get<I>(t) ...)) () const { return to_scalar (*this ); }
690+ constexpr decltype (auto ) at(auto const & j) const { return std::invoke (op, get<I>(t).at (j) ...); }
691+ constexpr decltype (auto ) operator*() const { return std::invoke (op, *get<I>(t) ...); }
692+ constexpr operator decltype (std::invoke(op, *get<I>(t) ...)) () const { return to_scalar (*this ); }
695693};
696694
697695template <class Op , IteratorConcept ... P>
698- constexpr bool is_special_def<Expr <Op, std::tuple<P ...>>> = (is_special<P> || ...);
696+ constexpr bool is_special_def<Map <Op, std::tuple<P ...>>> = (is_special<P> || ...);
699697
700- template <class V , class ... T , int ... i>
698+ template <class Op , class ... P , int ... i>
701699constexpr auto
702- expr_verb (mp::int_list<i ...>, V && v, T && ... t )
700+ map_verb (mp::int_list<i ...>, Op && op, P && ... p )
703701{
704- using FM = Framematch<V , std::tuple<T ...>>;
705- return expr (FM::op (RA_FWD (v )), reframe<mp::ref<typename FM::R, i>>(RA_FWD (t )) ...);
702+ using FM = Framematch<Op , std::tuple<P ...>>;
703+ return map_ (FM::op (RA_FWD (op )), reframe<mp::ref<typename FM::R, i>>(RA_FWD (p )) ...);
706704}
707705
708706template <class Op , class ... P>
709707constexpr auto
710- expr (Op && op, P && ... p)
708+ map_ (Op && op, P && ... p)
711709{
712710 if constexpr (is_verb<Op>) {
713- return expr_verb (mp::iota<sizeof ...(P)> {}, RA_FWD (op), RA_FWD (p) ...);
711+ return map_verb (mp::iota<sizeof ...(P)> {}, RA_FWD (op), RA_FWD (p) ...);
714712 } else {
715- return Expr <Op, std::tuple<P ...>> { RA_FWD (op), RA_FWD (p) ... };
713+ return Map <Op, std::tuple<P ...>> { RA_FWD (op), RA_FWD (p) ... };
716714 }
717715}
718716
719717constexpr auto
720- map (auto && op, auto && ... a) { return expr (RA_FWD (op), start (RA_FWD (a)) ...); }
718+ map (auto && op, auto && ... a) { return map_ (RA_FWD (op), start (RA_FWD (a)) ...); }
721719
722720
723721// ---------------------------
724722// pick expression
725723// ---------------------------
726724
727- template <class T , class J > struct pick_at_type ;
728- template <class ... P, class J > struct pick_at_type <std::tuple<P ...>, J>
729- {
730- using type = std::common_reference_t <decltype (std::declval<P>().at(std::declval<J>())) ...>;
731- };
725+ template <class J > struct type_at { template <class P > using type = decltype (std::declval<P>().at(std::declval<J>())); };
732726
733727template <std::size_t I, class T , class J >
734- constexpr pick_at_type< mp::drop1<std::decay_t <T>>, J>::type
728+ constexpr mp::apply<std:: common_reference_t , mp::map<type_at<J>:: template type, mp:: drop1<std::decay_t <T>>>>
735729pick_at (std::size_t p0, T && t, J const & j)
736730{
737731 constexpr std::size_t N = mp::len<std::decay_t <T>> - 1 ;
738732 if constexpr (I < N) {
739- return (p0==I) ? std:: get<I+1 >(t).at (j) : pick_at<I+1 >(p0, t, j);
733+ return (p0==I) ? get<I+1 >(t).at (j) : pick_at<I+1 >(p0, t, j);
740734 } else {
741735 RA_CHECK (p0 < N, " Bad pick " , p0, " with " , N, " arguments." ); std::abort ();
742736 }
743737}
744738
745- template <class T > struct pick_star_type ;
746- template <class ... P> struct pick_star_type <std::tuple<P ...>>
747- {
748- using type = std::common_reference_t <decltype (*std::declval<P>()) ...>;
749- };
739+ template <class P > using type_star = decltype (*std::declval<P>());
750740
751741template <std::size_t I, class T >
752- constexpr pick_star_type< mp::drop1<std::decay_t <T>>>::type
742+ constexpr mp::apply<std:: common_reference_t , mp::map<type_star, mp:: drop1<std::decay_t <T>>>>
753743pick_star (std::size_t p0, T && t)
754744{
755745 constexpr std::size_t N = mp::len<std::decay_t <T>> - 1 ;
756746 if constexpr (I < N) {
757- return (p0==I) ? *(std:: get<I+1 >(t)) : pick_star<I+1 >(p0, t);
747+ return (p0==I) ? *(get<I+1 >(t)) : pick_star<I+1 >(p0, t);
758748 } else {
759749 RA_CHECK (p0 < N, " Bad pick " , p0, " with " , N, " arguments." ); std::abort ();
760750 }
@@ -771,9 +761,9 @@ struct Pick<std::tuple<P ...>, mp::int_list<I ...>>: public Match<true, std::tup
771761 constexpr Pick (P ... p_): Match_(p_ ...) {} // [ra1]
772762 RA_ASSIGNOPS_SELF (Pick)
773763 RA_ASSIGNOPS_DEFAULT_SET
774- constexpr decltype (auto ) at(auto const & j) const { return pick_at<0 >(std:: get<0 >(t).at (j), t, j); }
775- constexpr decltype (auto ) operator*() const { return pick_star<0 >(*std:: get<0 >(t), t); }
776- constexpr operator decltype (pick_star<0 >(*std:: get<0 >(t), t)) () const { return to_scalar (*this ); }
764+ constexpr decltype (auto ) at(auto const & j) const { return pick_at<0 >(get<0 >(t).at (j), t, j); }
765+ constexpr decltype (auto ) operator*() const { return pick_star<0 >(*get<0 >(t), t); }
766+ constexpr operator decltype (pick_star<0 >(*get<0 >(t), t)) () const { return to_scalar (*this ); }
777767};
778768
779769template <IteratorConcept ... P>
0 commit comments