www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Passing anonymous enums as function parameters

reply kerdemdemir <kerdemdemir gmail.com> writes:
I have an enum statement :

enum : string
{
     KErdem
     Ali
     Zafer
     Salih
     //etc...
}


I don't want to give a name to my enum class since I am accessing 
this variables very often.

But I also have a function like:

double ReturnCoolNess( /* Is there any way? */ enumVal )
{
   switch (enumVal)
   {
	case KErdem:
	{
		return 0.0
	}
	case Ali:
	{
		return 100.0;	
	}
	case Salih:
	{
		return 100.0;	
	}
         // etc..
   }
}

Is there any way I still keep my enum anonymous and be able to 
call functions with different enumarations. Or is there any other 
way to call named enums without type name ?
Dec 17 2017
next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Sunday, December 17, 2017 11:49:58 kerdemdemir via Digitalmars-d-learn 
wrote:
 I have an enum statement :

 enum : string
 {
      KErdem
      Ali
      Zafer
      Salih
      //etc...
 }


 I don't want to give a name to my enum class since I am accessing
 this variables very often.

 But I also have a function like:

 double ReturnCoolNess( /* Is there any way? */ enumVal )
 {
    switch (enumVal)
    {
   case KErdem:
   {
       return 0.0
   }
   case Ali:
   {
       return 100.0;
   }
   case Salih:
   {
       return 100.0;
   }
          // etc..
    }
 }

 Is there any way I still keep my enum anonymous and be able to
 call functions with different enumarations. Or is there any other
 way to call named enums without type name ?
D does not have anonymous enums. Either you're declaring an enum which creates a new type and therefore has a name and a base type, or you're just creating manifest constants that don't create a new type. e.g. enum MyEnum : string { a = "hello", b = "foo", c = "dog", d = "cat" } vs enum string a = "hello"; enum string b = "foo"; enum string c = "dog"; enum string d = "cat"; or enum a = "hello"; enum b = "foo"; enum c = "dog"; enum d = "cat"; If you want a function to accept values that aren't tied to a specific enum, then just have the function take the base type. Now, within sections of code, you can use the with statement to reduce how often you have to use the enum type's name, e.g. with(MyEnum) switch(enumVal) { case a: { .. } case b: { .. } case c: { .. } case d: { .. } } but you can't have an enum without a name or just choose not to use an enum's name. With how enums work in D, there's really no point in having them if you're not going to treat them as their own type or refer to them via the enum type's name. If that's what you want to do, then just create a bunch of manifest constants. - Jonathan M Davis
Dec 17 2017
parent reply kerdemdemir <kerdemdemir gmail.com> writes:
What I meant with anonymous enums was:
https://dlang.org/spec/enum.html#anonymous_enums. Maybe I 
couldn't explain well but I believe D have anonymous enums. I am 
sorry I have forgotten to remove " :string" in my example from 
the "enum : string". Please stretch out ": string" part my 
problem is not related with that.

I am not sure if it is a good one but I found a solution for my 
problem

double ReturnCoolNess(U)( U enumVal )
{
   switch (enumVal)
   {
	case KErdem:
	{
		return 0.0
	}
	case Ali:
	{
		return 100.0;	
	}
	case Salih:
	{
		return 100.0;	
	}
         // etc..
   }
}

ReturnCoolNess(KErdem); ---> Compiles


 D does not have anonymous enums. Either you're declaring an 
 enum which creates a new type and therefore has a name and a 
 base type, or you're just creating manifest constants that 
 don't create a new type. e.g.

 enum MyEnum : string
 {
     a = "hello",
     b = "foo",
     c = "dog",
     d = "cat"
 }

 vs

 enum string a = "hello";
 enum string b = "foo";
 enum string c = "dog";
 enum string d = "cat";

 or

 enum a = "hello";
 enum b = "foo";
 enum c = "dog";
 enum d = "cat";

 If you want a function to accept values that aren't tied to a 
 specific enum, then just have the function take the base type.

 Now, within sections of code, you can use the with statement to 
 reduce how often you have to use the enum type's name, e.g.

 with(MyEnum) switch(enumVal)
 {
     case a: { .. }
     case b: { .. }
     case c: { .. }
     case d: { .. }
 }

 but you can't have an enum without a name or just choose not to 
 use an enum's name. With how enums work in D, there's really no 
 point in having them if you're not going to treat them as their 
 own type or refer to them via the enum type's name. If that's 
 what you want to do, then just create a bunch of manifest 
 constants.

 - Jonathan M Davis
Dec 17 2017
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Sunday, December 17, 2017 12:47:26 kerdemdemir via Digitalmars-d-learn 
wrote:
 What I meant with anonymous enums was:
 https://dlang.org/spec/enum.html#anonymous_enums. Maybe I
 couldn't explain well but I believe D have anonymous enums. I am
 sorry I have forgotten to remove " :string" in my example from
 the "enum : string". Please stretch out ": string" part my
 problem is not related with that.
That's pretty much just declaring manifest constants with braces so that you don't repeat the keyword enum a bunch of times. enum { a = "foo", b = "bar", c = "baz"; } is identical to enum a = "foo"; enum b = "bar"; enum c = "baz"; and it will even let you mix types, e.g. enum { a = "foo", b = 42 } which you can't do with actual enums. You're not declaring a new type. You're just declaring a bunch of constants. They're really not enums in the classic sense, and for the most part, folks around here aren't going to call them enums. If anything, a number of folks complain that the keyword enum was reused for manifest constants. I don't know why the documentation has a section for "anonymous enums" separate from manifest constants, since they're really not a different thing, and AFAIK, pretty much no one calls them that - though at least they're right next to the documentation for manifest constants. - Jonathan M Davis
Dec 17 2017
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2017-12-17 20:45, Jonathan M Davis wrote:

 That's pretty much just declaring manifest constants with braces so that you
 don't repeat the keyword enum a bunch of times.
Anonymous enum is what the spec calls it and was available before manifest constants. -- /Jacob Carlborg
Dec 18 2017
prev sibling parent kerdemdemir <kerdemdemir hotmail.com> writes:
 enum
 {
     a = "foo",
     b = "bar",
     c = "baz";
 }

 is identical to

 enum a = "foo";
 enum b = "bar";
 enum c = "baz";
Thanks Jonathan I think that changes my point of perspective. And Jacob Carlborg I like the third option a lot with aliases good to know that enum Foo : string { KErdem Ali Zafer Salih //etc... } alias KErdem = Foo.KErdem alias Ali = Foo.Ali // etc... Erdem
Dec 20 2017
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2017-12-17 12:49, kerdemdemir wrote:
 I have an enum statement :
 
 enum : string
 {
      KErdem
      Ali
      Zafer
      Salih
      //etc...
 }
 
 
 I don't want to give a name to my enum class since I am accessing this 
 variables very often.
 
 But I also have a function like:
 
 double ReturnCoolNess( /* Is there any way? */ enumVal )
 {
    switch (enumVal)
    {
      case KErdem:
      {
          return 0.0
      }
      case Ali:
      {
          return 100.0;
      }
      case Salih:
      {
          return 100.0;
      }
          // etc..
    }
 }
 
 Is there any way I still keep my enum anonymous and be able to call 
 functions with different enumarations. Or is there any other way to call 
 named enums without type name ?
You have three options: * Specify "string" as the type of the parameter for the ReturnCoolNess function. Note that this will allow any string to be passed to this function * Use the "with" statement to avoid having to specify the enum name. This needs to be used in every place you want to access the enum members enum Foo : string { KErdem Ali Zafer Salih //etc... } double ReturnCoolNess(Foo enumVal ) { with(Foo) switch (enumVal) { case KErdem: { return 0.0 } case Ali: { return 100.0; } case Salih: { return 100.0; } // etc.. } } * Use "alias" to make the enum members available without having to specify the enum name: enum Foo : string { KErdem Ali Zafer Salih //etc... } alias KErdem = Foo.KErdem alias Ali = Foo.Ali // etc... Now you can access the enum members through the aliases. Specify "Foo" as the type of the parameter in the ReturnCoolNess function. Generating these alias can be automated with some metaprogramming and string mixins. -- /Jacob Carlborg
Dec 17 2017