Search code examples
c++dependenciespimpl-idiom

Remove dependancy constants from enum definition


I am trying to safely remove a dependency from my project by using opaque structures and forward declarations but like most I am still stuck on my enums.

The header file dependency I am trying to remove from my header files has defined constants that I want to set my enumeration's values to. Something like this

// depends header
#define DEP_TYPE_ONE   1
#define DEP_TYPE_TWO   2
#define DEP_TYPE_THREE 3

// My header
enum TYPES
{
    T_ONE     = DEP_TYPE_ONE,
    T_TWO     = DEP_TYPE_TWO,
    T_THREE   = DEP_TYPE_THREE
}

I am trying to figure out a way to not have to include the depends header in my header.

Odds are the answer is probably simply 'you can't do that' but I just want to ask because a solution would make my life infinity easier.


Solution

  • How about removing the include of the depends header, hard code the values, and comment the dependency:

    // my_header.h
    
    // NOTE: Enumerands must be in sync with symbols defined in depends.h
    enum TYPES
    {
        T_ONE     = 1, // DEP_TYPE_ONE
        T_TWO     = 2, // DEP_TYPE_TWO
        T_THREE   = 3  // DEP_TYPE_THREE
    };
    

    To allay fears about the values getting out of sync, you can have another header or source file (one that users of your class or API don't get) that contains one or more compile-time asserts:

    // Some non-distributed file
    
    #include <depends.h>
    #include "my_header.h"
    
    // Compile-time assertion macro
    #define compile_time_assert(cond, msg) \
        typedef char msg[(cond) ? 1 : -1]
    
    // Check assumptions at compile time...
    compile_time_assert(T_ONE==DEP_TYPE_ONE, ValueOutOfSync1);
    compile_time_assert(T_TWO==DEP_TYPE_TWO, ValueOutOfSync2);
        .
        .
        .
    

    This would give you a compile time error if the values ever get out of sync.

    For more info on the compile_time_assert macro, see: http://www.embedded.com/columns/programmingpointers/164900888?_requestid=379501