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