Click here to Skip to main content
15,885,216 members
Articles / Programming Languages / Visual C++ 9.0

.NET-like Reflection Support for Enums in C++

Rate me:
Please Sign up or sign in to vote.
4.08/5 (8 votes)
27 Sep 2010CPOL6 min read 34.7K   150   15  
This article provides a macro + template solution to support .NET-like Reflection for enums such as ToString, IsDefined, Parse, GetValues, GetNames.
#include <iostream>
#include <string>

// Compile:
// vcvars32.bat
// cl /W4 /WX /EHsc Reflect4CppEnum_demo.cpp
using namespace std;

#include "Reflection4CppEnum.hpp"
#include "Reflection4CppEnum_demo.h"

DEF_ENUM_2(, WeekDay, ALL_THE_WEEK);

void demo2()
{
    // Name and How many enumerators defined for WeekDay:
    // .NET equivlent: typeof(WeekDay).Name       Enum.GetNames(typeof(WeekDay)).Length
    printf("%d enumerators defined for Enum [%s]\n", EnumHelper<WeekDay>::count(), 
	    EnumHelper<WeekDay>::get_type_name() );

    // Iterate all the names and corresponding Values
    // .NET equivlent:
    //      foreach(string s in Enum.GetNames(typeof(WeekDay))) Console.WriteLine( s );
    //      foreach(object o in Enum.GetValues(typeof(WeekDay))) Console.WriteLine( o );
    EnumHelper<WeekDay>::const_str_iterator it_str = EnumHelper<WeekDay>::str_begin();
    EnumHelper<WeekDay>::const_value_iterator it_val = EnumHelper<WeekDay>::value_begin();

    for(; it_str != EnumHelper<WeekDay>::str_end() && it_val != EnumHelper<WeekDay>::value_end();
	    ++it_str, ++it_val)
    {
	printf("Enum str: [%20s],  value: %d\n", *it_str, *it_val);
    }

    // Determine whether an integer value is a defined enumerator:
    // .NET equivlent:
    //     Console.WriteLine(  Enum.IsDefined(typeof(WeekDay), 0) );
    int test_enum_val = 0;
    printf("Is %d a defined enumerator for %s: %s\n", test_enum_val,  EnumHelper<WeekDay>::get_type_name(),
	    EnumHelper<WeekDay>::is_defined(test_enum_val)? "True" : "False" );

    // Determine whether a string value is a defined enumerator:
    // .NET equivlent:
    //     Console.WriteLine(  Enum.IsDefined(typeof(WeekDay), "Sunday" ) );
    const char * test_enum_str = "Sunday";
    printf("Is %s a defined enumerator for %s: %s(case-sensitive)\n", test_enum_str,
	    EnumHelper<WeekDay>::get_type_name(), 
	    EnumHelper<WeekDay>::is_defined(test_enum_str) ? "True": "False" );

    // Support case-insenstive is_defined
    // .NET equivlent: No
    test_enum_str = "sunday";
    printf("Is %s a defined enumerator for %s: %s(case-insensitive)\n", test_enum_str,
	    EnumHelper<WeekDay>::get_type_name(), 
	    EnumHelper<WeekDay>::is_defined(test_enum_str, true) ? "True": "False" );

    // From enumerator to string
    // .NET equivlent: 
    //     WeekDay day = Sunday; Console.WriteLine( day.ToString() );
    printf("enum string for %d is %s\n",  test_enum_val, EnumHelper<WeekDay>::to_string(
		static_cast<WeekDay>(test_enum_val)) );
    printf("enum string for %d is %s\n",  Sunday, EnumHelper<WeekDay>::to_string( Sunday ) );
    //     for a non-exist item, get NULL
    printf("enum string for %d is %s\n",  104, EnumHelper<WeekDay>::to_string( 
		static_cast<WeekDay>(104) ) );

    // From string to enumerator:
    // .NET equivlent: 
    //     WeekDay day = Enum.Parse( typeof(WeekDay), "Sunday");
    printf("enum value for %s is %d(case-insensitive)\n",  test_enum_str,
	    EnumHelper<WeekDay>::parse( test_enum_str, true ) );
    try {
	EnumHelper<WeekDay>::parse( test_enum_str, false );
    } catch( runtime_error & e)
    {
	fprintf(stderr, "exception: %s\n", e.what() );
    }
    test_enum_str = "Sunday";
    printf("enum value for %s is %d(case-sensitive)\n",  test_enum_str,
	    EnumHelper<WeekDay>::parse( test_enum_str) );

    // Find the index for an enumerator value
    // .NET equivlent: No
    printf("enum value %d is the %d-th item in the declaration order\n", 0, EnumHelper<WeekDay>::index_of(0) );
    //     return -1 for the non exist value
    printf("enum value %d is the %d-th item in the declaration order\n", 104, EnumHelper<WeekDay>::index_of(104) );

    // Find the index for an enumerator string
    // .NET equivlent: No
    printf("enum string [%s] is the %d-th item in the declaration order\n", test_enum_str,
	    EnumHelper<WeekDay>::index_of(test_enum_str) );
    //     return -1 for the non exist strings:
    test_enum_str = "not exist";
    printf("enum string [%s] is the %d-th item in the declaration order\n", test_enum_str,
	    EnumHelper<WeekDay>::index_of(test_enum_str) );

	ColorSpace::Image::print_colors();
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
China China
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions