Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
January 20, 2016 How to know if opSlice is defined for a type (including built-in types)? | ||||
---|---|---|---|---|
| ||||
Hi everyone, I was wondering if it was possible to know at compile time if opSlice is defined for a type, including built-in types like "string". Here is the code I have: import std.stdio; struct Test { Test opSlice(size_t i, size_t j) { return this; // We don't care what it returns } } void main () { string s = "Hello"; auto s2 = s[0..2]; static if (is(typeof(&string.opSlice))) writeln("Ok string"); Test t; auto t2 = t[0..2]; static if (is(typeof(&Test.opSlice))) writeln("Ok Test"); } Output: Ok Test How to make it work for "string" too (if possible)? And is there a way to differentiate "opSlice()" from "opSlice(size_t, size_t)" (or "opSlice(T, T)" for any T)? Thank you in advance! |
January 20, 2016 Re: How to know if opSlice is defined for a type (including built-in types)? | ||||
---|---|---|---|---|
| ||||
Posted in reply to chardetm | On 20/01/16 11:41 PM, chardetm wrote:
> Hi everyone,
>
> I was wondering if it was possible to know at compile time if opSlice is
> defined for a type, including built-in types like "string". Here is the
> code I have:
>
>
> import std.stdio;
>
> struct Test {
> Test opSlice(size_t i, size_t j) {
> return this; // We don't care what it returns
> }
> }
>
> void main () {
> string s = "Hello";
> auto s2 = s[0..2];
> static if (is(typeof(&string.opSlice))) writeln("Ok string");
>
> Test t;
> auto t2 = t[0..2];
> static if (is(typeof(&Test.opSlice))) writeln("Ok Test");
> }
>
> Output:
> Ok Test
>
>
> How to make it work for "string" too (if possible)? And is there a way
> to differentiate "opSlice()" from "opSlice(size_t, size_t)" (or
> "opSlice(T, T)" for any T)?
>
> Thank you in advance!
template CanSlice(T) {
enum CanSlice = __traits(compiles, {T t; auto v = t[0 .. 1];}) || __traits(compiles, {T t; auto v = t.opSlice();});
}
Should work.
|
January 20, 2016 Re: How to know if opSlice is defined for a type (including built-in types)? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rikki Cattermole | On Wednesday, 20 January 2016 at 10:44:36 UTC, Rikki Cattermole wrote:
>
> template CanSlice(T) {
> enum CanSlice = __traits(compiles, {T t; auto v = t[0 .. 1];}) || __traits(compiles, {T t; auto v = t.opSlice();});
> }
>
> Should work.
Thanks it works just fine!
|
January 20, 2016 Re: How to know if opSlice is defined for a type (including built-in types)? | ||||
---|---|---|---|---|
| ||||
Posted in reply to chardetm | Anyone who has the same problem: I found std.range.primitives.hasSlicing (https://dlang.org/phobos/std_range_primitives.html#hasSlicing) which does exactly what I want! |
January 20, 2016 Re: How to know if opSlice is defined for a type (including built-in types)? | ||||
---|---|---|---|---|
| ||||
Posted in reply to chardetm | On Wednesday, January 20, 2016 13:06:00 chardetm via Digitalmars-d-learn wrote:
> Anyone who has the same problem: I found std.range.primitives.hasSlicing (https://dlang.org/phobos/std_range_primitives.html#hasSlicing) which does exactly what I want!
Note that because strings are treated as ranges of dchar regardless of what their actual character type is, arrays of char and wchar (so-called "narrow" strings) are not consider to have slicing or random access by the traits in std.range. So, hasSlicing!string is false, though for anything other than an array of char or wchar, it will do what you're looking for, whereas for arrays of char or wchar, you really shouldn't be using the slice operator on them without knowing that they're what you're operating on so that you take the Unicode issues into account correctly.
- Jonathan M Davis
|
January 20, 2016 Re: How to know if opSlice is defined for a type (including built-in types)? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Wednesday, 20 January 2016 at 15:25:10 UTC, Jonathan M Davis wrote:
> On Wednesday, January 20, 2016 13:06:00 chardetm via Digitalmars-d-learn wrote:
>> Anyone who has the same problem: I found std.range.primitives.hasSlicing (https://dlang.org/phobos/std_range_primitives.html#hasSlicing) which does exactly what I want!
>
> Note that because strings are treated as ranges of dchar regardless of what their actual character type is, arrays of char and wchar (so-called "narrow" strings) are not consider to have slicing or random access by the traits in std.range. So, hasSlicing!string is false, though for anything other than an array of char or wchar, it will do what you're looking for, whereas for arrays of char or wchar, you really shouldn't be using the slice operator on them without knowing that they're what you're operating on so that you take the Unicode issues into account correctly.
>
> - Jonathan M Davis
Yes and that was the next step of my problem, it turned out that it was already taken into account by hasSlicing!
Thank you very much!
|
Copyright © 1999-2021 by the D Language Foundation