@@ -24,8 +24,7 @@ inline std::ostream &
2424operator <<(std::ostream & o, Dim const & dim) { return (o << " [Dim " << dim.len << " " << dim.step << " ]" ); }
2525
2626template <auto v, int n>
27- constexpr auto vdrop = []
28- {
27+ constexpr auto vdrop = []{
2928 std::array<Dim, ssize (v)-n> r;
3029 for (int i=0 ; i<int (r.size ()); ++i) { r[i] = v[n+i]; }
3130 return r;
@@ -314,8 +313,7 @@ struct filterdims<prev, I0, I ...>
314313 constexpr static int dst = stretch ? (ssize (prev) - (0 + ... + beatable<I>.src )) : beatable<I0>.dst ;
315314 constexpr static int src = stretch ? (ssize (prev) - (0 + ... + beatable<I>.src )) : beatable<I0>.src ;
316315 constexpr static auto next = filterdims<vdrop<prev, src>, I ...>::dimv;
317- constexpr static auto dimv = []
318- {
316+ constexpr static auto dimv = []{
319317 std::array<Dim, dst+ssize (next)> r;
320318 for (int i=0 ; i<dst; ++i) { r[i] = prev[i]; }
321319 for (int i=0 ; i<ssize (next); ++i) { r[dst+i] = next[i]; }
@@ -328,8 +326,7 @@ struct filterdims<prev, I0, I ...>
328326{
329327 constexpr static int src = beatable<I0>.src ;
330328 constexpr static auto next = filterdims<vdrop<prev, src>, I ...>::dimv;
331- constexpr static auto dimv = []
332- {
329+ constexpr static auto dimv = []{
333330 std::array<Dim, 1 +ssize (next)> r;
334331 r[0 ] = Dim { I0::nn, prev[0 ].step * I0::gets () };
335332 for (int i=0 ; i<ssize (next); ++i) { r[1 +i] = next[i]; }
@@ -373,25 +370,13 @@ struct ViewSmall
373370 consteval static dim_t size () { return std::apply ([](auto ... i) { return (i.len * ... * 1 ); }, dimv); }
374371
375372 P cp;
373+ constexpr ViewSmall const & view () const { return *this ; }
374+ constexpr P data () const { return cp; }
375+ constexpr explicit ViewSmall (P cp_): cp(cp_) {}
376376// exclude all T and sub constructors by making T & sub noarg
377377 constexpr static bool have_braces = std::is_reference_v<decltype (*cp)>;
378378 using T = std::conditional_t <have_braces, std::remove_reference_t <decltype (*cp)>, noarg>;
379379 using sub = typename nested_arg<T, Dimv>::sub;
380-
381- constexpr ViewSmall const & view () const { return *this ; }
382- constexpr P data () const { return cp; }
383-
384- constexpr explicit ViewSmall (P cp_): cp(cp_) {}
385- // cf RA_ASSIGNOPS_SELF [ra38] [ra34]
386- ViewSmall const & operator =(ViewSmall const & x) const { start (*this ) = x; return *this ; }
387- constexpr ViewSmall (ViewSmall const & s) = default;
388-
389- template <class X > requires (!std::is_same_v<std::decay_t <X>, T>)
390- constexpr ViewSmall const & operator=(X && x) const { start (*this ) = x; return *this ; }
391- #define ASSIGNOPS (OP ) \
392- constexpr ViewSmall const & operator OP (auto && x) const { start (*this ) OP x; return *this ; }
393- FOR_EACH (ASSIGNOPS, *=, +=, -=, /=)
394- #undef ASSIGNOPS
395380// if T isn't is_scalar [ra44]
396381 constexpr ViewSmall const &
397382 operator =(T const & t) const
@@ -412,6 +397,15 @@ struct ViewSmall
412397 {
413398 ra::iter<-1 >(*this ) = x; return *this ;
414399 }
400+ // cf RA_ASSIGNOPS_SELF [ra38] [ra34]
401+ ViewSmall const & operator =(ViewSmall const & x) const { start (*this ) = x; return *this ; }
402+ constexpr ViewSmall (ViewSmall const & s) = default;
403+ template <class X > requires (!std::is_same_v<std::decay_t <X>, T>)
404+ constexpr ViewSmall const & operator=(X && x) const { start (*this ) = x; return *this ; }
405+ #define ASSIGNOPS (OP ) \
406+ constexpr ViewSmall const & operator OP (auto && x) const { start (*this ) OP x; return *this ; }
407+ FOR_EACH (ASSIGNOPS, *=, +=, -=, /=)
408+ #undef ASSIGNOPS
415409
416410 template <int k>
417411 constexpr static dim_t
@@ -597,6 +591,21 @@ transpose_dims(auto const & s, auto const & src, auto & dst)
597591
598592RA_IS_DEF (cv_viewsmall, (std::is_convertible_v<A, ViewSmall<decltype (std::declval<A>().data()), ic_t <A::dimv>>>));
599593
594+ template <class K =ic_t <0 >>
595+ constexpr auto
596+ reverse (cv_viewsmall auto && a_, K k = K {})
597+ {
598+ decltype (auto ) a = a_.view ();
599+ using A = std::decay_t <decltype (a)>;
600+ constexpr auto rdimv = [&]{
601+ std::remove_const_t <decltype (A::dimv)> rdimv = A::dimv;
602+ RA_CHECK (inside (k, ssize (rdimv)), " Bad axis " , K::value, " for rank " , ssize (rdimv), " ." );
603+ rdimv[k].step *= -1 ;
604+ return rdimv;
605+ }();
606+ return ViewSmall<decltype (a.cp ), ic_t <rdimv>>(0 ==rdimv[k].len ? a.cp : a.cp + rdimv[k].step *(1 -rdimv[k].len ));
607+ }
608+
600609template <int ... Iarg>
601610constexpr auto
602611transpose (cv_viewsmall auto && a_, ilist_t <Iarg ...>)
@@ -607,7 +616,7 @@ transpose(cv_viewsmall auto && a_, ilist_t<Iarg ...>)
607616 constexpr static auto src = A::dimv;
608617 static_assert (ra::size (src)==ra::size (s), " Bad size for transposed axes list." );
609618 constexpr static rank_t dstrank = (0 ==ra::size (s)) ? 0 : 1 + std::ranges::max (s);
610- constexpr static auto dst = [&]() { std::array<Dim, dstrank> dst; transpose_dims (s, src, dst); return dst; }();
619+ constexpr static auto dst = [&]{ std::array<Dim, dstrank> dst; transpose_dims (s, src, dst); return dst; }();
611620 return ViewSmall<decltype (a.cp ), ic_t <dst>>(a.data ());
612621}
613622
@@ -641,8 +650,7 @@ constexpr auto
641650explode (cv_viewsmall auto && a)
642651{
643652 constexpr static rank_t ru = sizeof (value_t <sup_t >)==sizeof (value_t <decltype (a)>) ? 0 : 1 ;
644- constexpr static auto bdimv = [&a]()
645- {
653+ constexpr static auto bdimv = [&a]{
646654 std::array<Dim, ra::rank_s (a)-rank_s<sup_t >()-ru> bdimv;
647655 explode_dims<sup_t , value_t <decltype (a)>>(a.dimv , bdimv);
648656 return bdimv;
0 commit comments