Index: libcfa/src/collections/array.hfa
===================================================================
--- libcfa/src/collections/array.hfa	(revision e6e250dd2e3aad6c341b64a30dc67e27608341a2)
+++ libcfa/src/collections/array.hfa	(revision 1abcec9b6adf2ed1d9f833ccc39e3e9f529c3d52)
@@ -1,4 +1,3 @@
 #pragma once
-
 
 
@@ -176,4 +175,46 @@
 }
 
+// RAII for copying interacts poorly with CFA RAII's default (quasi-mandate) to take
+// 'src' parameters by value; note doc/proposals/autogen.md suggests changing this pattern.
+// If Timmed offers a by-value copy-ctor, then
+//  - the array copy-ctor will make lots of memcpys of them
+//  - the array assignment operator will make temporaries (and call their RAII, implying
+//    the above memcpys) of them
+//  - the array assignment operator will scale poorly to higher dimensionality due to #226
+// Furthermore, enabling this experimental flag breaks some multidimensional behaviour,
+// as illustraed by a test failure in array-md-sbscr-cases, which has not been investigated.
+// These limitations kick in upon calling the copy operation, not upon including the definitions.
+// Design choice here:
+//  - FIX ME: deal with `const &` on params
+#ifdef EXPERIMENTAL_ARRAY_ALLOW_COPY_RAII
+	// call copy ctor on elements
+	//   array(float, 5) y;     // given
+	//   array(float, 5) x = y; // <- do
+	forall( [N], S & | sized(S), Timmed *, Tbase & | { void ?{}( Timmed &, Timmed & ); } )
+	static inline void ?{}( arpk( N, S, Timmed, Tbase ) & this, arpk( N, S, Timmed, Tbase ) & src ) {
+		?{}( this, delay_init );
+		for (i; N) ?{}( (Timmed &)this.strides[i], src[i] );
+	}
+	forall( [N], S & | sized(S), Timmed *, Tbase & | { void ?{}( Timmed &, const Timmed & ); } )
+	static inline void ?{}( arpk( N, S, Timmed, Tbase ) & this, arpk( N, S, Timmed, Tbase ) & src  ) {
+		?{}( this, delay_init );
+		for (i; N) ?{}( (Timmed &)this.strides[i], src[i] );
+	}
+
+	// call assignment on elements
+	//   array(float, 5) x, y;  // given
+	//   x = y;                 // <- do
+	forall( [N], S & | sized(S), Timmed & | is_value(Timmed), Tbase & )
+	static inline void ?=?( arpk( N, S, Timmed, Tbase ) & this, arpk( N, S, Timmed, Tbase ) & src ) {
+		for (i; N) this[i] = src[i];
+		return src;
+	}
+	forall( [N], S & | sized(S), Timmed &, Tbase & | { void ?=?( Timmed &, const Timmed & ); } )
+	static inline void ?=?( arpk( N, S, Timmed, Tbase ) & this, arpk( N, S, Timmed, Tbase ) & src  ) {
+		for (i; N) this[i] = src[i];
+		return src;
+	}
+#endif // EXPERIMENTAL_ARRAY_ALLOW_COPY_RAII
+
 
 //
Index: libcfa/src/collections/string.cfa
===================================================================
--- libcfa/src/collections/string.cfa	(revision e6e250dd2e3aad6c341b64a30dc67e27608341a2)
+++ libcfa/src/collections/string.cfa	(revision 1abcec9b6adf2ed1d9f833ccc39e3e9f529c3d52)
@@ -244,8 +244,9 @@
 
 string ?()( string & s, ssize_t start, ssize_t len ) {
-	if ( start < 0 ) start += len( s );
-	if ( len < 0 ) { len = -len; start -= len - 1; }
-	if ( start < 0 || start >= len( s ) ) return (string){ "" };
-	if ( start + len > len( s ) ) len = len( s ) - start;
+	// if ( start < 0 ) start += len( s );
+	// if ( len < 0 ) { len = -len; start -= len - 1; }
+	// if ( start < 0 ) start = 0;
+	// if ( start > len( s ) ) start = len( s );
+	// if ( start + len > len( s ) ) len = len( s ) - start;
 	string ret = { *s.inner, start, len };
 	return ret`share;
