@@ -67,7 +67,7 @@ struct ViewBig
6767
6868 constexpr ViewBig (): cp() {} // FIXME used by Container constructors
6969 constexpr ViewBig (Dimv const & dimv_, P cp_): dimv(dimv_), cp(cp_) {} // [ra36]
70- constexpr ViewBig (auto & & s, P cp_): cp(cp_)
70+ constexpr ViewBig (auto const & s, P cp_): cp(cp_)
7171 {
7272 ra::resize (dimv, ra::size (s)); // [ra37]
7373 if constexpr (std::is_convertible_v<value_t <decltype (s)>, Dim>) {
@@ -77,22 +77,8 @@ struct ViewBig
7777 }
7878 }
7979 constexpr ViewBig (std::initializer_list<dim_t > s, P cp_): ViewBig(start(s), cp_) {}
80- // cf RA_ASSIGNOPS_SELF [ra38] [ra34]
81- ViewBig const & operator =(ViewBig const & x) const { start (*this ) = x; return *this ; }
82- constexpr ViewBig (ViewBig const &) = default;
83-
84- template <class X > requires (!std::is_same_v<std::decay_t <X>, T>)
85- constexpr ViewBig const & operator=(X && x) const { start (*this ) = x; return *this ; }
86- #define ASSIGNOPS (OP ) \
87- constexpr ViewBig const & operator OP (auto && x) const { start (*this ) OP x; return *this ; }
88- FOR_EACH (ASSIGNOPS, *=, +=, -=, /=)
89- #undef ASSIGNOPS
90- // if T isn't is_scalar [ra44]
91- constexpr ViewBig const &
92- operator =(T const & t) const
93- {
94- start (*this ) = ra::scalar (t); return *this ;
95- }
80+ // T not is_scalar [ra44]
81+ constexpr ViewBig const & operator =(T const & t) const { start (*this ) = ra::scalar (t); return *this ; }
9682// row-major ravel braces
9783 constexpr ViewBig const &
9884 operator =(std::initializer_list<T> const x) const requires (1 !=RANK)
@@ -114,6 +100,13 @@ struct ViewBig
114100 }
115101 FOR_EACH (RA_BRACES_ANY, 2 , 3 , 4 );
116102#undef RA_BRACES_ANY
103+ constexpr ViewBig (ViewBig const &) = default;
104+ // cf RA_ASSIGNOPS_SELF [ra38] [ra34]
105+ ViewBig const & operator =(ViewBig const & x) const { start (*this ) = x; return *this ; }
106+ #define ASSIGNOPS (OP ) \
107+ constexpr ViewBig const & operator OP (auto const & x) const { start (*this ) OP x; return *this ; }
108+ FOR_EACH (ASSIGNOPS, =, *=, +=, -=, /=)
109+ #undef ASSIGNOPS
117110
118111 constexpr dim_t
119112 select (Dim * dim, int k, dim_t i) const
@@ -188,14 +181,14 @@ struct ViewBig
188181 operator[](this auto && self, auto && ... i) { return RA_FW (self)(RA_FW (i) ...); }
189182
190183 constexpr decltype (auto )
191- at(auto & & i) const
184+ at(auto const & i) const
192185 {
193186// can't say 'frame rank 0' so -size wouldn't work. FIXME What about ra::len
194187 constexpr rank_t crank = rank_diff (RANK, ra::size_s (i));
195188 if constexpr (ANY==crank) {
196- return iter (rank ()-ra::size (i)).at (RA_FW (i) );
189+ return iter (rank ()-ra::size (i)).at (i );
197190 } else {
198- return iter<crank>().at (RA_FW (i) );
191+ return iter<crank>().at (i );
199192 }
200193 }
201194
@@ -266,59 +259,43 @@ template <class Store, rank_t RANK>
266259struct Container : public ViewBig <typename storage_traits<Store>::T *, RANK>
267260{
268261 Store store;
262+ constexpr auto data (this auto && self) { return self.view ().data (); }
269263 using T = typename storage_traits<Store>::T;
270264 using View = ViewBig<T *, RANK>;
271265 using ViewConst = ViewBig<T const *, RANK>;
272266 constexpr ViewConst const & view () const { return *this ; }
273267 constexpr View & view () { return *this ; }
274268 using View::size, View::rank, View::dimv, View::cp;
275269
276- // Needed to set cp. FIXME Remove duplication as in SmallArray.
277- Container (Container && w): store(std::move(w.store))
270+ // A(shape 2 3) = A-type [1 2 3] initializes, so it doesn't behave as A(shape 2 3) = not-A-type [1 2 3] which uses View::operator=. This is used by operator>>(std::istream &, Container &). See test/ownership.cc [ra20].
271+ // TODO don't require copyable T in constructors, see fill1. That requires operator= to initialize, not update.
272+ constexpr Container & operator =(Container && w)
278273 {
274+ store = std::move (w.store );
279275 dimv = std::move (w.dimv );
280276 cp = storage_traits<Store>::data (store);
277+ return *this ;
281278 }
282- Container (Container const & w): store(w.store )
279+ constexpr Container & operator = (Container const & w)
283280 {
281+ store = w.store ;
284282 dimv = w.dimv ;
285283 cp = storage_traits<Store>::data (store);
284+ return *this ;
286285 }
287- Container (Container & w): Container(std::as_const(w)) {}
288-
289- // A(shape 2 3) = A-type [1 2 3] initializes, so it doesn't behave as A(shape 2 3) = not-A-type [1 2 3] which uses View::operator=. This is used by operator>>(std::istream &, Container &). See test/ownership.cc [ra20].
290- // TODO don't require copyable T in constructors, see fill1. That requires operator= to initialize, not update.
291- Container & operator =(Container && w)
286+ constexpr Container (Container && w): store(std::move(w.store))
292287 {
293- store = std::move (w.store );
294288 dimv = std::move (w.dimv );
295289 cp = storage_traits<Store>::data (store);
296- return *this ;
297290 }
298- Container & operator = (Container const & w)
291+ constexpr Container (Container const & w): store(w.store )
299292 {
300- store = w.store ;
301293 dimv = w.dimv ;
302294 cp = storage_traits<Store>::data (store);
303- return *this ;
304295 }
305- Container & operator =(Container & w) { return *this = std::as_const (w); }
306-
307- constexpr decltype (auto ) back(this auto && self) { return RA_FW (self).view ().back (); }
308- constexpr auto data (this auto && self) { return self.view ().data (); }
309- constexpr decltype (auto ) operator()(this auto && self, auto && ... a) { return RA_FW (self).view ()(RA_FW (a) ...); }
310- constexpr decltype (auto ) operator[](this auto && self, auto && ... a) { return RA_FW (self).view ()(RA_FW (a) ...); }
311- constexpr decltype (auto ) at(this auto && self, auto && i) { return RA_FW (self).view ().at (RA_FW (i)); }
312- // always compact/row-major, so STL-like iterators can be raw pointers.
313- constexpr auto begin (this auto && self) { assert (is_c_order (self.view ())); return self.view ().data (); }
314- constexpr auto end (this auto && self) { return self.view ().data ()+self.size (); }
315- template <rank_t c=0 > constexpr auto iter (this auto && self) { if constexpr (1 ==RANK && 0 ==c) { return ptr (self.data (), self.size ()); } else { return RA_FW (self).view ().template iter <c>(); } }
316- constexpr operator T & () { return view (); }
317- constexpr operator T const & () const { return view (); }
318-
319- // these need repeating bc of various reasons; constness, no TAD for initializer_list, or constructor overriding.
296+ // repeated bc of constness re. ViewBig
320297#define ASSIGNOPS (OP ) \
321- constexpr Container & operator OP (auto & & x) { view () OP x; return *this ; }
298+ constexpr Container & operator OP (auto const & x) { view () OP x; return *this ; }
322299 FOR_EACH (ASSIGNOPS, =, *=, +=, -=, /=)
323300#undef ASSIGNOPS
324301 constexpr Container & operator =(std::initializer_list<T> const x) requires (1 !=RANK) { view () = x; return *this ; }
@@ -329,7 +306,7 @@ struct Container: public ViewBig<typename storage_traits<Store>::T *, RANK>
329306#undef RA_BRACES_ANY
330307
331308 void
332- init (auto & & s) requires (1 ==rank_s(s) || ANY==rank_s(s))
309+ init (auto const & s) requires (1 ==rank_s(s) || ANY==rank_s(s))
333310 {
334311 static_assert (!std::is_convertible_v<value_t <decltype (s)>, Dim>);
335312 RA_CK (1 ==ra::rank (s), " Rank mismatch for init shape." );
@@ -340,18 +317,18 @@ struct Container: public ViewBig<typename storage_traits<Store>::T *, RANK>
340317 }
341318 void init (dim_t s) { init (std::array {s}); } // scalar allowed as shape if rank is 1.
342319
343- // provided so that {} calls shape_arg constructor below.
320+ // provided so that {} calls sharg constructor below.
344321 Container () requires (ANY==RANK): View({ Dim {0 , 1 } }, nullptr ) {}
345322 Container () requires (ANY!=RANK && 0 !=RANK): View(typename View::Dimv (Dim {0 , 1 }), nullptr) {}
346323 Container () requires (0 ==RANK): Container({}, none) {}
347324
348- using shape_arg = decltype (shape(std::declval<View>().iter()));
349- // shape_arg overloads handle {...} arguments. Size check is at conversion if shape_arg is Small.
350- Container (shape_arg const & s, none_t ) { init (s); }
351- Container (shape_arg const & s, auto && x): Container(s, none) { view () = x; }
352- Container (shape_arg const & s, braces<T, RANK> x) requires (1 ==RANK): Container(s, none) { view () = x; }
325+ using sharg = decltype (shape(std::declval<View>().iter()));
326+ // sharg overloads handle {...} arguments. Size check is at conversion if sharg is Small.
327+ Container (sharg const & s, none_t ) { init (s); }
328+ Container (sharg const & s, auto && x): Container(s, none) { view () = x; }
329+ Container (sharg const & s, braces<T, RANK> x) requires (1 ==RANK): Container(s, none) { view () = x; }
353330
354- Container (auto & & x): Container(ra::shape(x), none) { view () = x; }
331+ Container (auto const & x): Container(ra::shape(x), none) { view () = x; }
355332 Container (braces<T, RANK> x) requires (RANK!=ANY): Container(braces_shape<T, RANK>(x), none) { view () = x; }
356333#define RA_BRACES_ANY (N ) \
357334 Container (braces<T, N> x) requires (RANK==ANY): Container(braces_shape<T, N>(x), none) { view () = x; }
@@ -369,19 +346,14 @@ struct Container: public ViewBig<typename storage_traits<Store>::T *, RANK>
369346// shape + row-major ravel.
370347// FIXME explicit it-is-ravel mark. Also iter<n> initializers.
371348// FIXME regular (no need for fill1) for ANY if rank is 1.
372- Container (shape_arg const & s, std::initializer_list<T> x) requires (1 !=RANK)
373- : Container(s, none) { fill1 (x.begin (), x.size ()); }
374- // FIXME remove
375- Container (shape_arg const & s, auto * p)
376- : Container(s, none) { fill1 (p, size ()); } // FIXME fake check
377- // FIXME remove
378- Container (shape_arg const & s, auto && pbegin, dim_t psize)
379- : Container(s, none) { fill1 (RA_FW (pbegin), psize); }
380-
381- // for shape arguments that doesn't convert implicitly to shape_arg
382- Container (auto && s, none_t ) { init (RA_FW (s)); }
383- Container (auto && s, auto && x): Container(RA_FW(s), none) { view () = x; }
384- Container (auto && s, std::initializer_list<T> x): Container(RA_FW(s), none) { fill1 (x.begin (), x.size ()); }
349+ Container (sharg const & s, std::initializer_list<T> x) requires (1 !=RANK): Container(s, none) { fill1 (x.begin (), x.size ()); }
350+ // FIXME remove these two
351+ Container (sharg const & s, auto * p): Container(s, none) { fill1 (p, size ()); } // FIXME fake check
352+ Container (sharg const & s, auto && pbegin, dim_t psize): Container(s, none) { fill1 (RA_FW (pbegin), psize); }
353+ // for shape arguments that doesn't convert implicitly to sharg
354+ Container (auto const & s, none_t ) { init (s); }
355+ Container (auto const & s, auto const & x): Container(s, none) { view () = x; }
356+ Container (auto const & s, std::initializer_list<T> x): Container(s, none) { fill1 (x.begin (), x.size ()); }
385357
386358// resize first axis or full shape. Only for some kinds of store.
387359 void resize (dim_t const s)
@@ -433,6 +405,16 @@ struct Container: public ViewBig<typename storage_traits<Store>::T *, RANK>
433405 --dimv[0 ].len ;
434406 store.pop_back ();
435407 }
408+ constexpr decltype (auto ) back(this auto && self) { return RA_FW (self).view ().back (); }
409+ constexpr decltype (auto ) operator()(this auto && self, auto && ... a) { return RA_FW (self).view ()(RA_FW (a) ...); }
410+ constexpr decltype (auto ) operator[](this auto && self, auto && ... a) { return RA_FW (self).view ()(RA_FW (a) ...); }
411+ constexpr decltype (auto ) at(this auto && self, auto const & i) { return RA_FW (self).view ().at (i); }
412+ // always compact/row-major, so STL-like iterators can be raw pointers.
413+ constexpr auto begin (this auto && self) { assert (is_c_order (self.view ())); return self.view ().data (); }
414+ constexpr auto end (this auto && self) { return self.view ().data ()+self.size (); }
415+ template <rank_t c=0 > constexpr auto iter (this auto && self) { if constexpr (1 ==RANK && 0 ==c) { return ptr (self.data (), self.size ()); } else { return RA_FW (self).view ().template iter <c>(); } }
416+ constexpr operator T & () { return view (); }
417+ constexpr operator T const & () const { return view (); }
436418};
437419
438420// rely on std::swap; else ambiguous
0 commit comments