Compare int to all entries in an enum

I have the following enum:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
enum WeaponClassID {
	CAK47 = 1,
	CDEagle = 46,
	CDecoyGrenade = 47,
	CFlashbang = 77,
	CHEGrenade = 96,
	CIncendiaryGrenade = 99,
	CItem_Healthshot = 104,
	CItemCash = 105,
	CKnife = 107,
	CKnifeGG = 108,
	CMolotovGrenade = 112,
	CSCAR17 = 149,
	CSensorGrenade = 151,
	CSmokeGrenade = 155,
	CSnowball = 158,
	CTablet = 171,
	CWeaponAug = 231,
	CWeaponAWP = 232,
	CWeaponBizon = 234,
	CWeaponElite = 238,
	CWeaponFamas = 239,
	CWeaponFiveSeven = 240,
	CWeaponG3SG1 = 241,
	CWeaponGalil = 242,
	CWeaponGalilAR = 243,
	CWeaponGlock = 244,
	CWeaponHKP2000 = 245,
	CWeaponM249 = 246,
	CWeaponM3 = 247,
	CWeaponM4A1 = 248,
	CWeaponMAC10 = 249,
	CWeaponMag7 = 250,
	CWeaponMP5Navy = 251,
	CWeaponMP7 = 252,
	CWeaponMP9 = 253,
	CWeaponNegev = 254,
	CWeaponNOVA = 255,
	CWeaponP228 = 256,
	CWeaponP250 = 257,
	CWeaponP90 = 258,
	CWeaponSawedoff = 259,
	CWeaponSCAR20 = 260,
	CWeaponScout = 261,
	CWeaponSG550 = 262,
	CWeaponSG552 = 263,
	CWeaponSG556 = 264,
	CWeaponShield = 265,
	CWeaponSSG08 = 266,
	CWeaponTaser = 267,
	CWeaponTec9 = 268,
	CWeaponTMP = 269,
	CWeaponUMP45 = 270,
	CWeaponUSP = 271,
	CWeaponXM1014 = 272
}

I also have an if statement where I compare a variable of type int to basically every entry in the enum.
if (classid == 1 || classid == 46 || classid == 104 || classid == 107 || classid == 108 || classid == 149 || classid == 231 || classid == 232 || classid == 234 || classid == 238 || classid == 239 || classid == 240 || classid == 241 || classid == 242 || classid == 243 || classid == 244 || classid == 245 || classid == 246 || classid == 247 || classid == 248 || classid == 250 || classid == 251 || classid == 252 || classid == 253 || classid == 254 || classid == 255 || classid == 256 || classid == 257 || classid == 258 || classid == 260 || classid == 261 || classid == 262 || classid == 263 || classid == 264 || classid == 265 || classid == 266 || classid == 267 || classid == 268 || classid == 269 || classid == 270 || classid == 271 || classid == 272)
Is there a better way of doing this?
For c# there's Enum.IsDefined, is there a c++ alternative?
Last edited on
No. If the enum values are not sequential, you'll have to compare them one by one, or use a code generation step to do that for you.
What helps is the Enum Macro Trick: make the preprocessor do work for you.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// Declare your names and values with ODR

#define WEAPON_CLASS_ID  \
  F( AK47,           1 ) \
  F( DEagle,        46 ) \
  ...                    \
  F( WeaponUSP,    271 ) \
  F( WeaponXM1014, 272 )

// Instantiate the enumeration

#define F( name, value ) C ## name = value,
enum WeaponClassID { WEAPON_CLASS_ID(F) };
#undef F

// Compute the number of items in the enum

#define F( name, value ) + 1
const int NumWeaponClassIDs = WEAPON_CLASS_ID(F);
#undef F

// A set of WeaponClassIDs (I presume you are using C++)

#define F( name, value ) C ## name ,
std::unordered_set <enum WeaponClassID> WeaponClassIDs
{
  WEAPON_CLASS_ID(F)
};
#undef F

// Enum.IsDefined equivalent in C++

bool IsWeaponClassID( enum WeaponClassID wcid )
{
  return WeaponClassIDs.count( wcid ) != 0;
}

Etc.

Hope this helps.
Last edited on
That's pretty cool. I had to change a couple of details to get it to work. Another possibility would be a map mapping the id to a Weapon class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>
#include <unordered_set>

// Declare your names and values with ODR

#define WEAPON_CLASS_ID  \
  F( AK47,           1 ) \
  F( DEagle,        46 ) \
  F( WeaponUSP,    271 ) \
  F( WeaponXM1014, 272 )

// Instantiate the enumeration

#define F( name, value ) C ## name = value,
enum WeaponClassID { WEAPON_CLASS_ID };
#undef F

// Compute the number of items in the enum

#define F( name, value ) + 1
const int NumWeaponClassIDs = WEAPON_CLASS_ID;
#undef F

// A set of WeaponClassIDs (I presume you are using C++)

#define F( name, value ) C ## name ,
std::unordered_set <int> WeaponClassIDs
{
  WEAPON_CLASS_ID
};
#undef F

// Enum.IsDefined equivalent in C++

bool IsWeaponClassID( WeaponClassID wcid )
{
  return WeaponClassIDs.count( wcid ) != 0;
}

void Action_AK47()         { std::cout << "Action_AK47\n"; }
void Action_DEagle()       { std::cout << "Action_DEagle\n"; }
void Action_WeaponUSP()    { std::cout << "Action_WeaponUSP\n"; }
void Action_WeaponXM1014() { std::cout << "Action_WeaponXM1014\n"; }

int main() {
    WeaponClassID wcid = CWeaponUSP;
    if ( IsWeaponClassID( wcid ) )
        std::cout << "found\n";

    switch ( wcid )
    {
    #define F( name, value ) case C ## name : Action_ ## name(); break;
    WEAPON_CLASS_ID
    #undef F
    }
}

I've always heard this referred to as the "X macro" trick. More:
https://en.wikipedia.org/wiki/X_Macro
dutch, your IsWeaponClassID method is elegant and fits my use quite well. Thanks everyone for all the solutions!
Topic archived. No new replies allowed.