| |
| Posted by dunecourser | PermalinkReply |
|
dunecourser
| Yorumları İngilizce yazdığıma bakmayın, Türkçeleştirmeye üşendim.
Diğer üşenenler için özet:
a. Bu basit bir kod. Yalnızca çok üyeli objelerin olabildiğince basit set ve get metotlarını tanımlama zahmetinden kurtulmak için yazıldı. (static foreach'in her döngüsünde typeid(typeof(member)) mevcut üyenin türünü de verebiliyor, yani metotlara typeof(%s) üzerinden member yollamak yerine direkt türü yollayabilirdim. Gelgelelim typeid() derleme zamanında çalışan bir olanak değilmiş, gerekçesini merak ettim.)
b. set ve get tek başlarına kullanıldıklarında, biri mixin edilip diğeri edilmediğinde çalışıyor. setget olarak yeni bir template'te birleştirildiğinde de çalışıyor.
c. set ve get yanyana mixin edildiğinde yerleştirilme sıralarına göre farklı hatalar veriyor.
--------------------------
mixin template set(S)
{
import std.format : format;
import std.string : capitalize;
static foreach (member; __traits(allMembers, S))
mixin(format!"public void set%s(typeof(%s) value) { %s = value; }"(
capitalize(member), member, member));
}
mixin template get(S)
{
import std.format : format;
import std.string : capitalize;
static foreach (member; __traits(allMembers, S))
mixin(format!"public typeof(%s) get%s() const { return %s; }"(
member, capitalize(member), member));
}
mixin template setget(S)
{
import std.format : format;
import std.string : capitalize;
static foreach (member; __traits(allMembers, S))
{
// setter
mixin(format!"public void set%s(typeof(%s) value) { %s = value; }"(
capitalize(member), member, member));
// getter
mixin(format!"public typeof(%s) get%s() const { return %s; }"(
member, capitalize(member), member));
}
}
unittest // working nicely
{
struct Man
{
private:
bool married;
bool childed;
public:
mixin setget!Man;
}
auto man = Man();
assert(man.getMarried() == false);
assert(man.getChilded() == false);
man.setMarried(true);
man.setChilded(true);
assert(man.getMarried() == true);
assert(man.getChilded() == true);
}
unittest // not working nicely
{
struct Man
{
private:
bool married;
bool childed;
public:
// mixin get!Man;
// mixin set!Man;
// cannot have parameter of function type `const`
// mixin set!Man;
// mixin get!Man;
// functions cannot return a function
// NOTE: these template mixins are singly usable
}
// auto man = Man();
// assert(man.getMarried() == false);
// assert(man.getChilded() == false);
// man.setMarried(true);
// man.setChilded(true);
// assert(man.getMarried() == true);
// assert(man.getChilded() == true);
}
|