SmartEnum.h
1/* Distributed under the Apache License, Version 2.0.
2 See accompanying NOTICE file for details.*/
3
4#pragma once
5
6#include <iostream>
7#include <sstream>
8#include <string>
9#include <algorithm>
10#include <vector>
11#include <iterator>
12
13// Not sure why I have such a facination with enums, but..
14// This is a bit of a pet project, I have been curious to see how one can make
15// and enum that both, has string mappings and is iterable
16// It would really be nice to have unbound wildcard templates in C++ some how...
17// I really want to be able to have a compartment manager be populated with
18// a set of compartments defined in a custom enum definition
19// and have the compartment manager getCompartment method take in the custom type
20// And allow for support of multiple custom types..
21// At anyrate, I am only using this in unit testing
22// Found these articles that helped come up with this junk
23// http://www.cprogramming.com/c++11/c++11-nullptr-strongly-typed-enum-class.html
24// http://www.cprogramming.com/tutorial/template_specialization.html
25// http://codereview.stackexchange.com/questions/57626/iterable-enum-class-in-c11
26// http://codereview.stackexchange.com/questions/14309/conversion-between-enum-and-string-in-c-class-header?rq=1
27// http://stackoverflow.com/questions/6288812/template-in-c
28
29// This is the type that will hold all the strings.
30// Each enumerate type will declare its own specialization.
31// Any enum that does not have a specialization will generate a compiler error
32// indicating that there is no definition of this variable (as there should be
33// be no definition of a generic version).
34template<typename T>
36{
37 static char const* values[];
38};
39
40// Here is a base class that works via an index and string
42{
43 virtual int index() const = 0;
44 virtual const std::string& string() const = 0;
45};
46
47// Here are is a macro to fill out the contents of a SmartEnum struct
48// You only need to provide the struct, the enum associated (and how many)
49// and the strings mapped to those enums
50
51#define SMART_ENUM(Clazz, Type, Length) \
52 static constexpr std::size_t _size = Length; \
53\
54 Clazz() : _idx(0) {} \
55 Clazz(Type t) { _idx = static_cast<Type>(t); } \
56 virtual ~Clazz() {} \
57\
58 int index() const { return _idx; } \
59 Type value() const { return Type(_idx); } \
60 const char* string() const { return Clazz::Value(_idx); } \
61 void set(const Type& t) { _idx = static_cast<int>(t); } \
62\
63 Type operator++() { if (_idx != (_size - 1)) _idx++; return Type(_idx); } \
64 Type operator++(int) { if (_idx != (_size - 1)) _idx++; return Type(_idx); } \
65 bool operator==(Clazz const& rhs) { return _idx == rhs._idx; } \
66 bool operator!=(Clazz const& rhs) { return _idx != rhs._idx; } \
67protected: \
68 int _idx; \
69public:
70
71// Here is an example (You don't need to derive from SmartEnum if you don't want to)
72//struct ExampleEnum : public SmartEnum
73//{
74// // NOTE, THESE ENUMS MUST BE OF THE DEFAULT INDEXING (You can't say enum Type {A=10, B=30 }
75// enum Type { A, B, C };
76// SMART_ENUM(ExampleEnum, Type, 3);
77// static char const* Value(size_t idx);
78//};// Length of enum and values[] must be the same, and reflected in the input to SMART_ENUM
79// Put this in your cpp file
80//template<> char const* enumStrings<ExampleEnum>::values[] = { "Alpha", "Bravo", "Charlie" };
81//char const* ExampleEnum::Value(size_t idx)
82//{
83// return enumStrings<ExampleEnum>::values[idx];
84//}
85//NOTE: You can also templitize this class with the enum type if you want, but how to you set the size?
86//I will figure that out when/if I need it
87
Definition: SmartEnum.h:42
virtual int index() const =0
virtual const std::string & string() const =0
Definition: SmartEnum.h:36
static char const * values[]
Definition: SmartEnum.h:37

Distributed under the Apache License, Version 2.0.

See accompanying NOTICE file for details.