Suggestion: type-safe flags

hey Ollie/Alex, just got back to working with iPlug2, excellent work.

one tip - you use integers for enum-ed flag values. there’s a nice type-safe way of doing that (also helps with Intellisense):

#define _USE_ENUM_AS_FLAGS(_enum, func_prefix) \
	func_prefix inline		 _enum  operator |  (const _enum a, const _enum b)	 { return (_enum)((DWORD)a | (DWORD)b); } \
	func_prefix inline		 _enum  operator &  (const _enum a, const _enum b)	 { return (_enum)((DWORD)a & (DWORD)b); } \
	func_prefix inline		 _enum  operator ^  (const _enum a, const _enum b)	 { return (_enum)((DWORD)a ^ (DWORD)b); } \
	func_prefix inline		 _enum  operator ~  (const _enum a)					 { return (_enum)(~(DWORD)a); } \
	func_prefix inline const _enum& operator |= (_enum &a, const _enum b) { a = a | b; return a; } \
	func_prefix inline const _enum& operator &= (_enum &a, const _enum b) { a = a & b; return a; } \
	func_prefix inline const _enum& operator ^= (_enum &a, const _enum b) { a = a ^ b; return a; }

// use this for global enums:
#define USE_ENUM_AS_FLAGS(_enum)			_USE_ENUM_AS_FLAGS(_enum, )

// and this for class/struct enum members:
#define USE_MEMBER_ENUM_AS_FLAGS(_enum)		_USE_ENUM_AS_FLAGS(_enum, friend)

Usage:

enum options
	{
	OPTION_A = 1<<0,
	OPTION_B = 1<<1,
	OPTION_C = 1<<2,
	};
 USE_ENUM_AS_FLAGS(options)

void DoSomething(options flags);

DoSomething(OPTION_A | OPTION_C);

So all the binary stuff works as usual, but now it’s type-safe + you can’t pass incorrect flags in, and they are easy to look up from the function declaration.

Thanks, I’ll try this out and see how it feels

1 Like