Skip to content

Instantly share code, notes, and snippets.

@crazymonkyyy
Last active October 12, 2022 16:58
Show Gist options
  • Save crazymonkyyy/f6a1219758558ff2f4fd68433f0f08ea to your computer and use it in GitHub Desktop.
Save crazymonkyyy/f6a1219758558ff2f4fd68433f0f08ea to your computer and use it in GitHub Desktop.
enum stuff
struct catigoryenum(T,I=ubyte){
T t; //alias t this;
I i;
auto opBinary(string s)(int j){
assert(j==1);
return typeof(this)(t,cast(I)(i+1));
}
bool opEquals(T s){
return s==t;
}
bool opEquals(typeof(this) a){
return a.t==t && a.i==i;}
enum min=typeof(this)(T.init,I.min);
enum max=typeof(this)(T.init,I.max);
}
unittest{
import std;
alias T=typeof(catigoryenum!float(0.0));
enum foo{a=T(4.20),b,c,d=T(6.9),e,f}
foreach(bar;EnumMembers!foo){
(bar==6.9).writeln;
}
}
unittest{
alias T=catigoryenum!string;
enum foo{a=T("a"),b,c,d=T("d")}
}
struct flagenum(I=ubyte){
I i=1; alias i this;
auto opBinary(string s)(int j){
assert(j==1);
return typeof(this)(cast(I)(i*2));
}
//AA key type `flagenum` does not have `bool opEquals(ref const flagenum) const blah blah blah
auto opEquals(ref const typeof(this) a) const{
return (a.i&i)!=0;
}
auto opEquals(I a){
return false;
}
auto opBinary(string s:"+")(typeof(this) a){
return typeof(this)(a.i|i);
}
auto opOpAssign(string s:"+")(typeof(this) a){
i=a.i|i;
return this;
}
auto opBinary(string s:"-")(typeof(this) a){
return typeof(this)(a.i^i);
}
auto opOpAssign(string s:"-")(typeof(this) a){
i=a.i^i;
return this;
}
auto opOpAssign(string s:"&",S)(S){
static assert(false,"causes a infite loop otherwise");
}
auto opAssign(int j){
i=j;
}
//AA key type `flagenum` should have `extern (D) size_t toHash() const nothrow @safe` if `opEquals` defined
size_t toHash() const nothrow @safe{
return size_t(i);}
}
unittest{
import std;
//alias flag=flagenum!();
enum foo{a=flagenum!()(),b,c,d}
foo bar;
foreach(a;EnumMembers!foo){
bar+=a;
bar.i.writeln;
foreach(b;EnumMembers!foo){
write(b.stringof);//https://issues.dlang.org/show_bug.cgi?id=23400
writeln(":",bar==b);
}
}
foreach(a;EnumMembers!foo){
bar-=a;
bar.i.writeln;
foreach(b;EnumMembers!foo){
write(b.stringof);
writeln(":",bar==b);
}
}
}
template combineenums(E...){
import std;
alias A=catigoryenum!string;
template T(int n){enum A T=A(E[n].stringof);}
string[] enums(){
string[] o;
foreach(n,e;E){
foreach(i,e_;__traits(allMembers,e)){
enum uglymagic="=T!("~n.to!string~")";
o~=e_~(i==0?uglymagic:"");
}
}
return o;
}
mixin("enum combineenums{"~enums.join(',').array~"}");
}
unittest{
enum A{a,b,c}
enum B{d,e,f}
alias C=combineenums!(A,B);
import std;
foreach(s;EnumMembers!C){
(s.stringof).writeln(" ,",s=="A"," ",s.i);
}
}
auto toenum(T,S)(S a){
import std;
//switch(a){
// foreach(t;__traits(allMembers,T)){
// mixin("case S."~t~": return T."~t~";");
// }
// default:
// assert(0);
//}
foreach(t;__traits(allMembers,T)){
mixin("if(a==S."~t~"){return T."~t~";}");
}
assert(0);
}
unittest{
enum A{a,b,c}
enum B{d,e,f}
alias C=combineenums!(A,B);
//enum C{a,b,c,d,e,f}
A[] a;
foreach(c;[C.a,C.b,C.c]){
a~=c.toenum!A;
}
import std;
a.writeln;
}
string flagstostring(T,S)(S a){
string o;
foreach(b;__traits(allMembers,T)){
mixin("enum b_=T."~b~";");
if(a==b_){o~=b;}
}
return o;
}
unittest{
import std;
enum foo{a=flagenum!()(),b,c,d,e,f,g}
(foo.a+foo.c+foo.e+foo.f).flagstostring!foo.writeln;
}
unittest{
import std;
enum A{a=flagenum!(ushort)(),b,c,d,e,f,g,h,i,j,k}
enum B{z=flagenum!()(),y,x}
alias C=combineenums!(A,B);
typeof(A.init) a;
typeof(B.init) b;
foreach(c;EnumMembers!C){
if(c=="A"){a+=c.toenum!A;}
if(c=="B"){b+=c.toenum!B;}
}
flagstostring!A(a).writeln;//why does ufcs fail here
flagstostring!B(b).writeln;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment