www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - CT-String as a Symbol

reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
At

https://github.com/nordlow/justd/blob/master/typecons_ex.d#L143

I can't figure out how to make the call to

     mixin genOps!I;

expand to, for instance,

     mixin genOps!Index

in the case when I = "Index".

Help please.
Apr 15 2015
next sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 04/15/2015 09:21 AM, "Nordlöw" wrote:
 At

 https://github.com/nordlow/justd/blob/master/typecons_ex.d#L143

 I can't figure out how to make the call to

      mixin genOps!I;

 expand to, for instance,

      mixin genOps!Index
This seems to work: mixin genOps!(mixin(I));
 in the case when I = "Index".

 Help please.
Ali
Apr 15 2015
parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Wednesday, 15 April 2015 at 17:03:36 UTC, Ali Çehreli wrote:
 This seems to work:

     mixin genOps!(mixin(I));
I'm afraid not: mixin genOps!(mixin(I)); errors typecons_ex.d(135,5): Error: mixin typecons_ex.IndexedBy!(int[3], "I").IndexedBy.genOps!"I" does not match template declaration genOps(T) typecons_ex.d(152,12): Error: template instance typecons_ex.IndexedBy!(int[3], "I") error instantiating typecons_ex.d(185,20): instantiated from here: indexedBy!("I", int[3]) typecons_ex.d(202,9): Error: static assert (!true) is false
Apr 15 2015
parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Wednesday, 15 April 2015 at 19:15:36 UTC, Nordlöw wrote:
 errors

 typecons_ex.d(135,5): Error: mixin 
 typecons_ex.IndexedBy!(int[3], "I").IndexedBy.genOps!"I" does 
 not match template declaration genOps(T)
 typecons_ex.d(152,12): Error: template instance 
 typecons_ex.IndexedBy!(int[3], "I") error instantiating
 typecons_ex.d(185,20):        instantiated from here: 
 indexedBy!("I", int[3])
 typecons_ex.d(202,9): Error: static assert  (!true) is false
Correction. This error is triggered if I put at the top of the defintion of IndexedBy(R, string I = "Index") mixin genOps!(mixin(I)); If I place after the definition of index struct I get another error typecons_ex.d(143,19): Error: argument to mixin must be a string type, not I typecons_ex.d(152,12): Error: template instance typecons_ex.IndexedBy!(int[3], "I") error instantiating typecons_ex.d(185,20): instantiated from here: indexedBy!("I", int[3]) typecons_ex.d(202,9): Error: static assert (!true) is false How is this possible?
Apr 15 2015
parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
I'm using DMD 2.067.
Apr 15 2015
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 04/15/2015 12:19 PM, "Nordlöw" wrote:
 I'm using DMD 2.067.
Mee too. The following is the minimum amount of code I used, which compiles: import std.traits; import std.range; struct Index(T = size_t) if (isUnsigned!T) { this(T ix) { this._ix = ix; } T opCast(U : T)() const { return _ix; } private T _ix = 0; } mixin template genOps(T) { auto ref opIndex(T i) inout { return _r[cast(size_t)i]; } auto ref opIndexAssign(V)(V value, T i) { return _r[cast(size_t)i] = value; } static if (hasSlicing!R) { auto ref opSlice(T i, T j) inout { return _r[cast(size_t)i .. cast(size_t)j]; } auto ref opSliceAssign(V)(V value, T i, T j) { return _r[cast(size_t)i .. cast(size_t)j] = value; } } } struct IndexedBy(R, string I = "Index") if (isArray!R) { mixin(q{ struct } ~ I ~ q{ { alias T = size_t; this(T ix) { this._ix = ix; } T opCast(U : T)() const { return _ix; } private T _ix = 0; } }); mixin genOps!(mixin(I)); R _r; alias _r this; // TODO Use opDispatch instead; to override only opSlice and opIndex } void main() { auto i = IndexedBy!(int[])(); } Ali
Apr 15 2015
parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Wednesday, 15 April 2015 at 20:12:27 UTC, Ali Çehreli wrote:
 Ali
I cracked it: Reason: I hade a failing unittest using it as auto xs = x.indexedBy!"I"; which I changed to auto xs = x.indexedBy!"Ix"; For some reason the mixin magic becomes confused when I equals "I". Do you have any clues as to why? Should we restrict IndexedBy to not allow I to equal "I"? :) Thx anyway.
Apr 15 2015
next sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 4/15/15 6:42 PM, "Nordlöw" wrote:
 On Wednesday, 15 April 2015 at 20:12:27 UTC, Ali Çehreli wrote:
 Ali
I cracked it: Reason: I hade a failing unittest using it as auto xs = x.indexedBy!"I"; which I changed to auto xs = x.indexedBy!"Ix"; For some reason the mixin magic becomes confused when I equals "I". Do you have any clues as to why? Should we restrict IndexedBy to not allow I to equal "I"? :) Thx anyway.
Hm.. from that link you sent, look up a bit, you see this interesting tidbit: struct IndexedBy(R, string I_ = "Index") if (isArray!R && I_ != "I_") // prevent strange bug from occurring That comment seems to be similar to what you are talking about... Later, there's this: auto indexedBy(string I, R)(R range) if (isArray!R && I != "I_") // prevent strange bug from occurring Should that be change to "string I_" also? -Steve
Apr 15 2015
prev sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 04/15/2015 03:42 PM, "Nordlöw" wrote:

 On Wednesday, 15 April 2015 at 20:12:27 UTC, Ali Çehreli wrote:
 Ali
I cracked it: Reason: I hade a failing unittest using it as auto xs = x.indexedBy!"I"; which I changed to auto xs = x.indexedBy!"Ix"; For some reason the mixin magic becomes confused when I equals "I". Do you have any clues as to why?
That is because you have a nested struct named I inside IndexedBy. :) I print it with pragma(msg) below. So, mixin(I) is not happy because it thinks you mean 'struct I' :) struct IndexedBy(R, string I = "Index") if (isArray!R) { enum toMixin = q{ struct } ~ I ~ q{ { alias T = size_t; this(T ix) { this._ix = ix; } T opCast(U : T)() const { return _ix; } private T _ix = 0; } }; pragma(msg, toMixin); mixin(toMixin); mixin genOps!(mixin(I)); R _r; alias _r this; // TODO Use opDispatch instead; to override only opSlice and opIndex } void main() { auto i = IndexedBy!(int[], "I")(); } The output: struct I { alias T = size_t; this(T ix) { this._ix = ix; } T opCast(U : T)() const { return _ix; } private T _ix = 0; }
 Should we restrict IndexedBy to not allow I to equal "I"?
I don't think there is a general solution but you can always disallow as a template constraint or as a static assert: struct IndexedBy(R, string I = "Index") if (isArray!R && I != "I") // <-- ADDED { // ... }
 :)

 Thx anyway.
Ali
Apr 15 2015
parent reply "Per =?UTF-8?B?Tm9yZGzDtnci?= <per.nordlow gmail.com> writes:
On Wednesday, 15 April 2015 at 23:02:32 UTC, Ali Çehreli wrote:
  struct I {
                   alias T = size_t;
                   this(T ix) { this._ix = ix; }
                   T opCast(U : T)() const { return _ix; }
                   private T _ix = 0;
               }
How is this possible? Shouldn't it CT-evaluate to struct Index { ... } !?
Apr 16 2015
parent "Per =?UTF-8?B?Tm9yZGzDtnci?= <per.nordlow gmail.com> writes:
On Thursday, 16 April 2015 at 10:24:05 UTC, Per Nordlöw wrote:
 How is this possible? Shouldn't it CT-evaluate to

     struct Index { ... }

 !?
Ahh, in the case when I is "I". Ok I get it. That's the reason. Thx
Apr 16 2015
prev sibling parent reply "Per =?UTF-8?B?Tm9yZGzDtnci?= <per.nordlow gmail.com> writes:
On Wednesday, 15 April 2015 at 16:21:59 UTC, Nordlöw wrote:
 Help please.
I'm quite satisfied with the current state now. Is anybody interested in having this in typecons.d in Phobos?
Apr 16 2015
parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Thursday, 16 April 2015 at 10:27:20 UTC, Per Nordlöw wrote:
 On Wednesday, 15 April 2015 at 16:21:59 UTC, Nordlöw wrote:
 Help please.
I'm quite satisfied with the current state now. Is anybody interested in having this in typecons.d in Phobos?
I would be, yes. Have you considered what happens if you apply it to a type that uses the new opIndex/opSlice semantics?
Apr 16 2015
parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Thursday, 16 April 2015 at 10:46:25 UTC, John Colvin wrote:
 On Thursday, 16 April 2015 at 10:27:20 UTC, Per Nordlöw wrote:
 On Wednesday, 15 April 2015 at 16:21:59 UTC, Nordlöw wrote:
 Help please.
I'm quite satisfied with the current state now. Is anybody interested in having this in typecons.d in Phobos?
I would be, yes. Have you considered what happens if you apply it to a type that uses the new opIndex/opSlice semantics?
I guess you mean Kenjis multidim array indexing and slicing. If so, I haven't thought of that. I'm very open to suggestions. Is there a way to CT-query the arity of all opIndex and opSlice overloads?
Apr 16 2015
next sibling parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Thursday, 16 April 2015 at 18:12:35 UTC, Nordlöw wrote:
 Is there a way to CT-query the arity of all opIndex and opSlice 
 overloads?
Ping.
Apr 20 2015
parent ketmar <ketmar ketmar.no-ip.org> writes:
On Mon, 20 Apr 2015 13:31:03 +0000, Nordl=C3=B6w wrote:

 On Thursday, 16 April 2015 at 18:12:35 UTC, Nordl=C3=B6w wrote:
 Is there a way to CT-query the arity of all opIndex and opSlice
 overloads?
=20 Ping.
as long as they aren't templates, you can use any function traits on 'em.=20 like `ParameterTypeTuple!(A.opIndex).length` for example. with templated opXXX i believe that there is no simply way to get=20 argument tuple.=
Apr 20 2015
prev sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Thursday, 16 April 2015 at 18:12:35 UTC, Nordlöw wrote:
 Is there a way to CT-query the arity of all opIndex and opSlice 
 overloads?
Ideally you don't want to have to do that. You'd have to consider alias this and inheritance.
Apr 20 2015
parent reply "Per =?UTF-8?B?Tm9yZGzDtnci?= <per.nordlow gmail.com> writes:
On Monday, 20 April 2015 at 13:49:41 UTC, John Colvin wrote:
 On Thursday, 16 April 2015 at 18:12:35 UTC, Nordlöw wrote:
 Is there a way to CT-query the arity of all opIndex and 
 opSlice overloads?
Ideally you don't want to have to do that. You'd have to consider alias this and inheritance.
How do you plan on overriding the behaviour of opIndex and opSlice with alias this and inheritance? We don't want to limit this classes only. Fixed-dimensional matrices (in 2D/3D graphics) is a typically example of where we want to use structs instead. Typical use case is a Matrix class having index dimension RowIndex and ColumnIndex.
Apr 20 2015
parent reply "Per =?UTF-8?B?Tm9yZGzDtnci?= <per.nordlow gmail.com> writes:
On Tuesday, 21 April 2015 at 06:56:33 UTC, Per Nordlöw wrote:
 On Monday, 20 April 2015 at 13:49:41 UTC, John Colvin wrote:
 On Thursday, 16 April 2015 at 18:12:35 UTC, Nordlöw wrote:
 Is there a way to CT-query the arity of all opIndex and 
 opSlice overloads?
Further, this is slightly related to a way to query the dimensions of a data-type. If possible I would like to have a type trait for this. This type-trait could then be used both for this challenge but also for figuring out how to create randomized instances of multi-dimensional structures. This can be used for automatic generation of data instances of parameters in algorithm testing and benchmarking.
Apr 21 2015
parent reply "Vlad Levenfeld" <vlevenfeld gmail.com> writes:
On Tuesday, 21 April 2015 at 07:01:27 UTC, Per Nordlöw wrote:
 On Tuesday, 21 April 2015 at 06:56:33 UTC, Per Nordlöw wrote:
 On Monday, 20 April 2015 at 13:49:41 UTC, John Colvin wrote:
 On Thursday, 16 April 2015 at 18:12:35 UTC, Nordlöw wrote:
 Is there a way to CT-query the arity of all opIndex and 
 opSlice overloads?
Further, this is slightly related to a way to query the dimensions of a data-type. If possible I would like to have a type trait for this. This type-trait could then be used both for this challenge but also for figuring out how to create randomized instances of multi-dimensional structures. This can be used for automatic generation of data instances of parameters in algorithm testing and benchmarking.
template dimensionality (S) { template count_dim (uint i = 0) { static if (is (typeof(S.init.opSlice!i (0,0)))) enum count_dim = count_dim!(i+1); else enum count_dim = i; } alias dimensionality = count_dim!(); } Then you throw in some more stuff to detect 1-dimensional cases.
Apr 21 2015
next sibling parent reply "Per =?UTF-8?B?Tm9yZGzDtnci?= <per.nordlow gmail.com> writes:
On Tuesday, 21 April 2015 at 07:46:03 UTC, Vlad Levenfeld wrote:
 template dimensionality (S) {
   template count_dim (uint i = 0) {
     static if (is (typeof(S.init.opSlice!i (0,0))))
       enum count_dim = count_dim!(i+1);
     else enum count_dim = i;
   }

   alias dimensionality = count_dim!();
 }

 Then you throw in some more stuff to detect 1-dimensional cases.
Great! I guess a template restriction on opSlice would be in Place aswell. One thing: Why aren't you using opIndex instead? If there are types that have opIndex but not opSlice defined then dimensionality() could cover more types, right?
Apr 21 2015
next sibling parent "Vlad Levenfeld" <vlevenfeld gmail.com> writes:
On Tuesday, 21 April 2015 at 08:09:38 UTC, Per Nordlöw wrote:
 On Tuesday, 21 April 2015 at 07:46:03 UTC, Vlad Levenfeld wrote:
 template dimensionality (S) {
  template count_dim (uint i = 0) {
    static if (is (typeof(S.init.opSlice!i (0,0))))
      enum count_dim = count_dim!(i+1);
    else enum count_dim = i;
  }

  alias dimensionality = count_dim!();
 }

 Then you throw in some more stuff to detect 1-dimensional 
 cases.
Great! I guess a template restriction on opSlice would be in Place aswell. One thing: Why aren't you using opIndex instead? If there are types that have opIndex but not opSlice defined then dimensionality() could cover more types, right?
So, if the type is multidimensional, that means its using the new opIndex/opSlice syntax that was designed for multidimensional structures. So I know that, if dim > 1, opSlice!i must be defined, and (assuming we are only working with integral indices here) I can instantiate it with opSlice!i (0,0). For other types, you would throw in a test for a length member, or for front, and know that you have a 1-dimensional type. Alternatively, if we're assuming only integral indices, a recursive attempt to get the typeof(opIndex (Repeat!(i, 0))) would probably handle all the opIndex-but-not-opSlice cases (but you still need to handle non-indexed ranges and D arrays specially).
Apr 21 2015
prev sibling parent "Vlad Levenfeld" <vlevenfeld gmail.com> writes:
As an aside, I've put a bit of work into the generic 
multidimensional containers problem lately and have an interface 
generating library as a result.

https://github.com/evenex/autodata

It's still in the nascent stages but contains a lot of tools for 
working with multidimensional structures.

You can take a look at the definition in the spaces/ and 
topology/ folder (and the unittests in operators/) to get an idea 
of how it works - basically generates all the opIndex/opSlice 
stuff (with safety checks) under a unified system; end result 
being that you just write the business logic for your types, 
mixin the operators, and they will all interoperate with uniform 
semantics.

The definitions for the types themselves tend to be very short 
and to-the-point as a result. I've taken old containers of mine 
whose defs were pushing 300 lines and reimplemented them in ~50 
using the autodata operators.

A full set of traits and multidim range compositions (map, zip, 
take, cycle, repeat) are present as well. A lot of them are full 
or partial reimplementations of Phobos stuff.

It's pretty poorly documented (for now) but I'm happy to answer 
questions (and make documentation based on that) if you decide to 
check it out.
Apr 21 2015
prev sibling parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Tuesday, 21 April 2015 at 07:46:03 UTC, Vlad Levenfeld wrote:
 Then you throw in some more stuff to detect 1-dimensional cases.
Could you please elaborate a bit?
Apr 21 2015
parent reply "Vlad Levenfeld" <vlevenfeld gmail.com> writes:
On Tuesday, 21 April 2015 at 19:46:03 UTC, Nordlöw wrote:
 On Tuesday, 21 April 2015 at 07:46:03 UTC, Vlad Levenfeld wrote:
 Then you throw in some more stuff to detect 1-dimensional 
 cases.
Could you please elaborate a bit?
Well assuming the type is not multidimensional (does not define opSlice!i) then testing for input range primitives or opIndex(0) is probably enough to conclude that a type is 1d.
Apr 21 2015
parent reply "Vlad Levenfeld" <vlevenfeld gmail.com> writes:
template dimensionality (S) {
   template count_dim (uint i = 0) {
     static if (is (typeof(S.init.opSlice!i (0,0))))
       enum count_dim = count_dim!(i+1);
     else static if (i == 0 && (isInputRange!S || is 
(typeof(S.init[0])))
       enum count_dim = 1;
     else enum count_dim = i;
   }

   alias dimensionality = count_dim!();
}

Should work for any case I can think of (assuming integral 
indices).
Apr 21 2015
parent =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Tuesday, 21 April 2015 at 20:30:00 UTC, Vlad Levenfeld wrote:
 Should work for any case I can think of (assuming integral 
 indices).
Thanks.
Apr 21 2015