Indexing with an arbitrary type

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Aug 1 08:51:58 PDT 2016


On Monday, August 01, 2016 15:25:59 Alex via Digitalmars-d-learn wrote:
> On Monday, 1 August 2016 at 15:06:54 UTC, Jonathan M Davis wrote:
> > If you want a template constraint that checks that a type works
> > with the index operator on a type, and you're not restricting
> > it to something like size_t, then you're just going to have to
> > check whether the expression is going to compile. Also, that is
> > incompatible with random access ranges. Random access ranges
> > are expected to work with size_t, and while isRandomAccessRange
> > isn't currently quite that restrictive, it does check that r[1]
> > compiles, so the index operator is going to have to accept
> > integers at minimum. If you want a completely generic index
> > operator, and you want a template constraint for it, you're
> > pretty much going to have to test that it compiles. e.g.
> >
> > auto fun(I, T)(I index, T obj)
> >     if(__traits(compiles, obj[index]))
> > {
> >     return obj[index];
> > }
> >
> > or if you want a reusable template, you can do something like
> >
> > template isIndexable(I, T)
> > {
> >     enum isIndexable = __traits(compiles, T.init[I.init]);
> > }
> >
> > auto fun(I, T)(I index, T obj)
> >
> >     if(isIndexable!(I, T))
> > {
> >     return obj[index];
> > }
> >
> > Personally, I think that having code that accepts any type that
> > can be indexable with any type isn't a particularly good idea,
> > because odds are, it won't actually work, because those
> >
> > different types will work quite differently (e.g. associative
> > arrays are indexable with stuff other than size_t, but they're
> > really not interchangeable with dynamic arrays or static
> > arrays, which use size_t). And anything that wants to be
> > interchangeable with a dynamic array or be usable as a random
> > access range should be using size_t to index. But if you
>
> This is exactly what my question is about. I don't think, that it
> doesn't make sense (and isn't a good idea) to index with an
> arbitrary type, too.

The issue is that the semantics have to be sufficiently similar across the
types that the code will work. And if your code is doing much beyond
indexing, it probably won't. But if it does in your case, then great.

> So, how I can define/design a type, which is not an int/size_t,
> but has one to be able to index with it?
>
> And if the __compiles trait is the way to go with... well then
> that's just how it is...

You're pretty much going to have to go with some form of
__traits(compiles, ...) to test the code that the code that you want to code
compiles. That's ultimately what a lot of traits do. And if what you're
looking to test is that obj[index] works where obj and index are arbitrary
types, what else would you be testing for anyway? You'd only need to test
for more beyond that if you were trying to further restrict the types
involved and/or to require that some other set of operations compiled in
addition to indexing.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list