Proposal: Multidimensional opSlice solution

Norbert Nemec Norbert at Nemec-online.de
Mon Mar 8 04:24:25 PST 2010


Hi there,

in implementing multi-dimensional arrays, the current way of overloading 
the slicing operator does not scale up.

Currently, there is opIndex working for an arbitrary number of indices, 
but opSlice works only for one dimension. Ultimately, it should be 
possible to allow slicing for more than one dimension, and mixing it 
with indexing for e.g.:
	A[4,7..8,7,2..5]
So far, no clean solution for overloading this has been suggested.

Looking at Python, there is a range operator a:b or a:b:c that takes two 
or three integer and returns a 'slice' object. I.e. a builtin type. The 
__getitem__ method (Python's equivalent to opIndex) then simply receives 
either integers or 'slice' object for each dimension. The range operator 
only exists within indexing expressions.

The more D-ish equivalent of this solution is another opXXX method. How 
about the following:

----------------

* The slicing operation obj[] is overloaded by
	obj.opIndex()

* The slicing operation obj[a..b] is overloaded by
	obj.opIndex(obj.opRange(a,b))

* Within an indexing expression on an object 'obj', an expression of the 
form 'a..b' is transformed into a call
	obj.opRange(a,b)
furthermore, an expression of the form 'a..b:c' is transformed into
	obj.opRange(a,b,c)
to where 'c' is the stride.

* Alternatively, template functions of the form
	obj.opRange(int N)(a,b)
	obj.opRange(int N)(a,b,c)
are tried, with N set to the dimension number within the indexing 
expression. It is an error for both opRange(a,b,c) and
opRange(int N)(a,b,c) to exist in the same user defined type.
For example
	obj[a..b,d..e:f]
would become
	obj.opIndex(obj.opRange!(0)(a,b),obj.opRange!(1)(d,e,f))

* The opRange function may return an object of arbitrary type with is 
passed on to opIndex (or opOpIndex or opIndexAssign) to perform the 
actual slicing on the object. Proper overloading of these functions 
allows arbitrary mixing of slicing and indexing within the same expression.

* All op*Slice* operators become obsolete.

----------------

I am not sure whether opRange is the best name, as it clashes with the 
range concept in the libraries. I would have liked to reuse the name 
opSlice which would become unused by this change. However - the 
transition to this completely different meaning would be rather painful. 
Alternative name suggestions are welcome.

Greetings,
Norbert



More information about the Digitalmars-d mailing list