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