digitalmars.D.learn - template parameters
- Charles H. (11/11) Aug 29 2021 I've set up a class template (so far untested) thus:
- =?UTF-8?Q?Ali_=c3=87ehreli?= (32/46) Aug 29 2021 variable of T,=20
- Charles Hixson (7/48) Aug 29 2021 Thanks. I going to have to study:
- =?UTF-8?Q?Ali_=c3=87ehreli?= (35/39) Aug 29 2021 Trying to explain with comments:
- Charles Hixson (210/252) Sep 02 2021 I'm going to need to save that for the future. I ran into errors in
- H. S. Teoh (6/9) Sep 02 2021 ROFL! I'm st^Wborrowing this for my quotes file. ;-)
- Charles Hixson (6/6) Sep 03 2021 change:
I've set up a class template (so far untested) thus: class AARL (T, ndx = "ndx") if (isIntegral(T.init.ndx) ) If I'm correct, this should work for ndx an integer variable of T, but I'd really like T to be able to be anything which can be stored both in an array and in an associative array. But I can't figure out how to specify ndx. After all, T might be a float, so it wouldn't have any appropriate attributes. And I'd also like ndx to be able to be a function either a member of the class/struct T or a stand alone function. So how should I set up this template?
Aug 29 2021
On 8/29/21 11:32 AM, Charles H. wrote:I've set up a class template (so far untested) thus: =20 =C2=A0=C2=A0=C2=A0 class=C2=A0=C2=A0=C2=A0 AARL (T, ndx =3D "ndx") =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if =(isIntegral(T.init.ndx) )=20 =C2=A0=C2=A0=C2=A0 If I'm correct, this should work for ndx an integer=variable of T,=20but I'd really like T to be able to be anything which can be stored bot=h=20in an array and in an associative array.=C2=A0 But I can't figure out h=ow to=20specify ndx.=C2=A0 After all, T might be a float, so it wouldn't have a=ny=20appropriate attributes.=C2=A0 And I'd also like ndx to be able to be a =function either a member of the class/struct T or a stand alone functio=n.=20 So how should I set up this template? =20I came up with the following: template supportsCall(T, string func) { import std.format : format; import std.traits : isIntegral; enum expr =3D format!q{ enum supportsCall =3D isIntegral!(typeof(T.init.%s())); }(func); mixin (expr); } class AARL (T, string func =3D "ndx") if (supportsCall!(T, func)) { } int ndx(int i) { return 42; } struct S { long ndx() { return 100; } } void main() { auto a =3D new AARL!int(); auto b =3D new AARL!S(); } Ali
Aug 29 2021
Thanks. I going to have to study: enum supportsCall = isIntegral!(typeof(T.init.%s())); for awhile to make any sense of that, but it looks like just what I was looking for. On 8/29/21 2:41 PM, Ali Çehreli via Digitalmars-d-learn wrote:On 8/29/21 11:32 AM, Charles H. wrote:-- Javascript is what you use to allow third part programs you don't know anything about and doing you know not what to run on your computer.I've set up a class template (so far untested) thus: class AARL (T, ndx = "ndx") if (isIntegral(T.init.ndx) ) If I'm correct, this should work for ndx an integer variable of T, but I'd really like T to be able to be anything which can be stored both in an array and in an associative array. But I can't figure out how to specify ndx. After all, T might be a float, so it wouldn't have any appropriate attributes. And I'd also like ndx to be able to be a function either a member of the class/struct T or a stand alone function. So how should I set up this template?I came up with the following: template supportsCall(T, string func) { import std.format : format; import std.traits : isIntegral; enum expr = format!q{ enum supportsCall = isIntegral!(typeof(T.init.%s())); }(func); mixin (expr); } class AARL (T, string func = "ndx") if (supportsCall!(T, func)) { } int ndx(int i) { return 42; } struct S { long ndx() { return 100; } } void main() { auto a = new AARL!int(); auto b = new AARL!S(); } Ali
Aug 29 2021
On 8/29/21 3:31 PM, Charles Hixson wrote:Thanks. I going to have to study: enum supportsCall = isIntegral!(typeof(T.init.%s())); for awhile to make any sense of that, but it looks like just what I was looking for.Trying to explain with comments: // This is an eponymous template because it contains // a symbol that's the same as the name of this template. // And that symbol is 'supportsCall'. So, this template // will be whatever that symbol is. (In this case, it // will be a compile-time know entity: 'enum bool'.) template supportsCall(T, string func) { import std.format : format; import std.traits : isIntegral; // This is a string expression we will mix-in below. enum expr = format!q{ enum supportsCall = isIntegral!(typeof(T.init.%s())); }(func); // The above expression will be the following e.g. // for 'int' and for "ndx": // // enum supportsCall = isIntegral!(typeof(int.init.ndx())); // // So, it's determining whether the typeof the expression // int.init.ndx() is an integral. // // 'supportsCall' is a bool, which I could have made explicit: // // enum bool supportsCall = [...] // // You can prove it for yourself by "printing" the expression // at compile time: pragma(msg, expr); // Here is where we mix-in the expression into this template's // definition. mixin (expr); } Then the whole template can be used as a compile-time bool value. Ali
Aug 29 2021
Thanks. See below for what I did. On 8/29/21 5:05 PM, Ali Çehreli via Digitalmars-d-learn wrote:On 8/29/21 3:31 PM, Charles Hixson wrote:I'm going to need to save that for the future. I ran into errors in other sections. I suspect that a general form would require static if tests in numerous routines. Anyway, if you're interested this is what I ended up with. (I think it's error free, but not all paths have been tested.) import std.algorithm : remove; import std.exception; import std.stdio; import std.traits : isIntegral; import utils; // this is for my randomized integer code based on time: rndT /** An Associative Array with some Randomization and Linear features. * Note: This is done in a simplified and not too generalized fashion so that I don't need to * figure out template parameters at the moment. It should be redone later, when my mastery * is better. The current version should work for classes and structs that have a function * int T.ndx() that returns a unique id. That id (called the key) is used as an AA index * to find the instance, with duplicates not being allowed. */ class AARL2 (T) { /** The associative array of cells, with the index as the key. */ T[int] aa; /** A linear array of cell key values. This is ordered by the order in which they were * inserted rather than by value. */ int[] rl; /** Create an AARL from an array of cells. The array must have no entries with duplicate * key values (i.e. cell.ndx). Currently this throws an exception. Consider how it could * be handled more gracefully. */ this (T[] inp) { foreach (T c; inp) { int key = c.ndx; enforce (key !in aa, "Attempt to insert a key already present."); aa[key] = c; rl ~= key; } } this () {} /** Access members by serial position of key. (Not the value of the key!) */ T at (int i) in { assert (i >= 0 && i < rl.length, "Index outside bounds"); } body { int key = rl[i]; return aa[key]; } /** This is a read-only count of number of entries. */ long length() { return aa.length; } bool opBinaryRight(string op)(int key) const if (op == "in") { return cast (bool)(key in aa); } bool opBinaryRight(string op)(T c) const if (op == "in") { return cast (bool)(c.ndx in aa); } /** Allow the [] operator to retrieve instances by key value. */ T opIndex(int key) { if (key in aa) return aa[key]; return null; } /** "append" an instance of T. */ void opOpAssign (string op)(T c) // if (op == "~=" && isIntegral!(typeof(T.init.ndx()) if (op == "~") { append (c); } /** "append" an instance of T. * Note: I need a better response to an attempt to add duplicates. */ void append (T c) { if (c is null) { stderr.writeln ("Attempt to add a null T to the AARL rejected."); return; } int key = c.ndx; if (key in aa) { aa[key] = c; } else { aa[key] = c; rl ~= key; } return; } /** Pop the most recently added T off the table. */ T pop () { if (rl.length < 1) return null; T c = aa[rl[cast(int)rl.length - 1]]; aa.remove (c.ndx); rl.length -= 1; return c; } /** Pop a random cell off the table. */ T popR() { int which = rndT(cast(int)rl.length); int key = rl[which]; assert (key in aa, "AARL popR Logic error..1..but where?"); T c = aa[key]; remove(c); return c; } /** Pop the most recently added Cells off the table until the key is found. No value is returned. * Note: The key value is left in the AARL. */ void popUntil (T c) in { assert (c.ndx in aa, "Trying to pop until a value is reached which isn't in the table."); } body { while (c.ndx != rl[rl.length - 1]) { pop(); } } /** Push a cell onto the table. * Returns: True if the push was successful. False if either the item was null or one with * the same key value was already in the table. */ bool push (T c) { if (c is null) return false; if (c.ndx in aa) return false; aa[c.ndx] = c; rl ~= c.ndx; return true; } /** Read the most recently pushed cell of the table. * WARNING: No valid return value exists when the AARL is empty and T is not a class. * Consider throwing an exception in that case. Currently that case is not handled. */ T read() { int key = rl[rl.length - 1]; assert (key in aa, "AARL read Logic error...but where?"); return aa[key]; } /** Read a random cell of the table. * WARNING: No valid return value exists when the AARL is empty and T is not a class. * Consider throwing an exception in that case. Currently that case is not handled. */ T readR() { int which = rndT(cast(int)rl.length); int key = rl[which]; assert (key in aa, "AARL readR Logic error...but where?"); return aa[key]; } /** Remove a T from the table. * Returns: True if successful, otherwise false. */ bool remove (T c) { if (c is null) return false; return removeKey (c.ndx); } /** Remove the T whose key matches the given key from the table. * Returns: True if successful, otherwise flase. */ bool removeKey (int key) { if (key !in aa) return false; int i = 0; while (i < rl.length) { if (rl[i] == key) { rl.remove(i); aa.remove(key); return true; } i++; } assert (false, "Logic Error: never come here"); } } unittest { class AARLTest1 { int ndx_; this () { ndx_ = -1; } this (int val) { ndx_ = val; } int ndx() { return ndx_; } } // some to test with a simple class AARLTest1[] t1; for (int i = 0; i < 10; i++) t1 ~= new AARLTest1(i); // t1t and instance of AARL2!AARLTest1 to run the tests on, i.e., "t1 tests" auto t1t = new AARL2!AARLTest1 (t1); assert (t1t.length == 10, "t1t.length != 10"); t1t.push (new AARLTest1(11)); assert (t1t.length == 11, "t1t.length != 11"); // t1ta the first auxillary variable for the testing. auto t1ta = t1t.pop (); assert (t1t.length == 10, "t1t.length != 10"); assert (t1ta.ndx() == 11, "t1ta.ndx() != 11"); assert (t1ta !in t1t, "Oop1! t1ta in t1t"); // t1tb the second auxillary variable for the testing. auto t1tb = t1t.popR (); assert (t1t.length == 9, "t1t.length != 9"); assert (t1tb !in t1t, "Oop2! t1tb in t1t"); t1ta = t1t.readR(); assert (t1t.length == 9, "t1t.length != 9"); assert (t1ta in t1t, "Oop3! t1ta !in t1t"); // t1t.append (t1tb); t1t ~= t1tb; assert (t1t.length == 10, "t1t.length != 10"); assert (t1tb in t1t, "Oop4! t1tb !in t1t"); t1t.removeKey(t1tb.ndx); assert (t1tb !in t1t, "Oop5! removeKey failed."); t1t.remove (t1ta); assert (t1ta !in t1t, "Oop6! remove failed."); } -- Javascript is what you use to allow third part programs you don't know anything about and doing you know not what to run on your computer.Thanks. I going to have to study: enum supportsCall = isIntegral!(typeof(T.init.%s())); for awhile to make any sense of that, but it looks like just what I was looking for.Trying to explain with comments: // This is an eponymous template because it contains // a symbol that's the same as the name of this template. // And that symbol is 'supportsCall'. So, this template // will be whatever that symbol is. (In this case, it // will be a compile-time know entity: 'enum bool'.) template supportsCall(T, string func) { import std.format : format; import std.traits : isIntegral; // This is a string expression we will mix-in below. enum expr = format!q{ enum supportsCall = isIntegral!(typeof(T.init.%s())); }(func); // The above expression will be the following e.g. // for 'int' and for "ndx": // // enum supportsCall = isIntegral!(typeof(int.init.ndx())); // // So, it's determining whether the typeof the expression // int.init.ndx() is an integral. // // 'supportsCall' is a bool, which I could have made explicit: // // enum bool supportsCall = [...] // // You can prove it for yourself by "printing" the expression // at compile time: pragma(msg, expr); // Here is where we mix-in the expression into this template's // definition. mixin (expr); } Then the whole template can be used as a compile-time bool value. Ali
Sep 02 2021
On Thu, Sep 02, 2021 at 02:28:23PM -0700, Charles Hixson via Digitalmars-d-learn wrote: [...]-- Javascript is what you use to allow third part programs you don't know anything about and doing you know not what to run on your computer.ROFL! I'm st^Wborrowing this for my quotes file. ;-) T -- "How are you doing?" "Doing what?"
Sep 02 2021
change: { rl.remove(i); to: { rl = rl.remove(i); -- Javascript is what you use to allow third party programs you don't know anything about and doing you know not what to run on your computer.
Sep 03 2021