www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to know if opSlice is defined for a type (including built-in

reply chardetm <chardetm gmail.com> writes:
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!
Jan 20
next sibling parent reply Rikki Cattermole <alphaglosined gmail.com> writes:
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.
Jan 20
parent chardetm <chardetm gmail.com> writes:
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!
Jan 20
prev sibling parent reply chardetm <chardetm gmail.com> writes:
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!
Jan 20
parent reply Jonathan M Davis via Digitalmars-d-learn writes:
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
Jan 20
parent chardetm <chardetm gmail.com> writes:
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!
Jan 20