// This is example code used in an article about X-Macros at
// http://op.closedformodification.com/2006/06/18/x-macros/
// This software is in the public domain. You can do what you want with it.
// This software is provided as is. No claim is made about any kind
// of usefulness in any area.

#include <string>
#include <iostream>

namespace
{


int gErrorCount = 0;
    
template<class T, class U>
void _assertEquals(int line, T exp1, U exp2)
{
    if (exp1!=exp2)
    {
        std::cout << "Error: Line " << line << "; " << exp1 << "!="  << exp2 << std::endl;
        gErrorCount++;
    }
}

}

#define assertEquals(exp1, exp2) _assertEquals(__LINE__, exp1, exp2);
namespace
{

#define GENERATE_IDS    \
    X(ID0, "ID 0")      \
    X(ID1, "ID 1")      \
    X(ID2, "ID 2")
    
#define X(id, idString) id,
    enum IDs
    {
        // To be on the safe side, force ID's to start at 0
        ID_LOWERBOUND = -1,
        GENERATE_IDS
        NUM_IDS
    };
#undef X

#define X(id, idString) idString,
    const char* iDStrings[] = 
    {
        GENERATE_IDS
        NULL
    };
#undef X

} // unnamed namespace


int main()
{
    std::cout << "Running X-Macros enum example test..." << std::endl;

#define X(id, idString) assertEquals(std::string(iDStrings[id]), idString);
    GENERATE_IDS
#undef X    

    if (!gErrorCount)
    {
        std::cout << "All tests passed" << std::endl;
    }

    return gErrorCount;
}

