Function-like Macros
(From Marius Bancila's Blog)
These are macros that look like functions. The macro name is followed by none, one, or more arguments in paranthesis. Most of the times these can be replaced with regular functions or function templates. Let us get back to the previous example with the permission bigflag macros and introduce a couple function-like macros for setting and testing bit flag values.
#define PERMISSION_NONE 0 #define PERMISSION_READ 1 #define PERMISSION_WRITE 2 #define PERMISSION_ADD 4 #define PERMISSION_DELETE 8 #define SETBIT(fFlag, lValue, lBits) (fFlag ? (lValue) | (lBits) : (lValue) & (~lBits)) #define TESTBIT(lValue, lBits) (((lValue) & (lBits)) == (lBits)) void show_permissions(int const p) { if (TESTBIT(p, PERMISSION_READ)) std::cout << "can read" << std::endl; if (TESTBIT(p, PERMISSION_WRITE)) std::cout << "can write" << std::endl; if (TESTBIT(p, PERMISSION_ADD)) std::cout << "can add" << std::endl; if (TESTBIT(p, PERMISSION_DELETE)) std::cout << "can delete" << std::endl; } int main() { int flags = PERMISSION_READ | PERMISSION_WRITE; show_permissions(flags); flags = SETBIT(true, flags, PERMISSION_DELETE); flags = SETBIT(true, flags, PERMISSION_ADD); flags = SETBIT(false, flags, PERMISSION_WRITE); show_permissions(flags); }
The SETBIT
and TESTBIT
macros can be replaced with inline functions (SETBIT
being replaced by two functions, one that sets a bit and one that resets a bit). For the following example, I assume the permissions scoped enum and the overloaded operators are defined as above.
inline int set_bit(int const v, permissions const p) { return v | p; } inline int reset_bit(int const v, permissions const p) { return v & ~p; } inline bool test_bit(int const v, permissions const p) { return (v & p) == p; } void show_permissions(int const p) { if(test_bit(p, permissions::read)) std::cout << "can read" << std::endl; if (test_bit(p, permissions::write)) std::cout << "can write" << std::endl; if (test_bit(p, permissions::add)) std::cout << "can add" << std::endl; if (test_bit(p, permissions::del)) std::cout << "can delete" << std::endl; } int main() { int flags = permissions::read | permissions::write; show_permissions(flags); flags= set_bit(flags, permissions::del); flags = set_bit(flags, permissions::add); flags = reset_bit(flags, permissions::write); show_permissions(flags); }