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









Charles Hixson <charleshixsn earthlink.net> 