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).
34 template<typename T>
36 {
37  static char const* values[];
38 };
39 
40 // Here is a base class that works via an index and string
41 struct SmartEnum
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  const 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; } \
67 protected: \
68  int _idx; \
69 public:
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:35
Definition: SmartEnum.h:41
char const * values[]
Definition: SECircuitCalculator.cpp:8