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

Reply via email to