Whether or not to recurse into aggregate members.
Reference to a struct or class whose members to iterate over.
What value to look for in members, be it a string or an integer or whatever; anything that can be compared to.
What to assign matched values. Defaults to the .init of the matched type.
1 struct Bar 2 { 3 string s = "content"; 4 } 5 6 struct Foo 7 { 8 Bar b; 9 string s = "more content"; 10 } 11 12 Foo foo1, foo2; 13 foo1.replaceMembers("-"); 14 assert(foo1 == foo2); 15 16 foo2.s = "-"; 17 foo2.replaceMembers("-"); 18 assert(!foo2.s.length); 19 foo2.b.s = "-"; 20 foo2.replaceMembers!(Yes.recurse)("-", "herblp"); 21 assert((foo2.b.s == "herblp"), foo2.b.s); 22 23 Foo foo3; 24 foo3.s = "---"; 25 foo3.b.s = "---"; 26 foo3.replaceMembers!(No.recurse)("---"); 27 assert(!foo3.s.length); 28 assert((foo3.b.s == "---"), foo3.b.s); 29 foo3.replaceMembers!(Yes.recurse)("---"); 30 assert(!foo3.b.s.length); 31 32 class Baz 33 { 34 string barS = "init"; 35 string barT = "*"; 36 Foo f; 37 } 38 39 Baz b1 = new Baz; 40 Baz b2 = new Baz; 41 42 b1.replaceMembers("-"); 43 assert((b1.barS == b2.barS), b1.barS); 44 assert((b1.barT == b2.barT), b1.barT); 45 46 b1.replaceMembers("*"); 47 assert(b1.barS.length, b1.barS); 48 assert(!b1.barT.length, b1.barT); 49 assert(b1.f.s.length, b1.f.s); 50 51 b1.replaceMembers!(Yes.recurse)("more content"); 52 assert(!b1.f.s.length, b1.f.s); 53 54 import std.conv : to; 55 56 struct Qux 57 { 58 int i = 42; 59 } 60 61 Qux q; 62 63 q.replaceMembers("*"); 64 assert(q.i == 42); 65 66 q.replaceMembers(43); 67 assert(q.i == 42); 68 69 q.replaceMembers(42, 99); 70 assert((q.i == 99), q.i.to!string); 71 72 struct Flerp 73 { 74 string[] arr; 75 } 76 77 Flerp flerp; 78 flerp.arr = [ "-" ]; 79 assert(flerp.arr.length == 1); 80 flerp.replaceMembers("-"); 81 assert(!flerp.arr.length);
Inspects a passed struct or class for members whose values match that of the passed token. Matches members are set to a replacement value, which is an optional parameter that defaults to the .init value of the token's type.