FEDEM Solver  R8.0
Source code of the dynamics solver
FFaEnum.H
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2023 SAP SE
2 //
3 // SPDX-License-Identifier: Apache-2.0
4 //
5 // This file is part of FEDEM - https://openfedem.org
7 
13 #ifndef FFA_ENUM_H
14 #define FFA_ENUM_H
15 
16 #include <vector>
17 #include <utility>
18 #include <cstring>
19 #include <cstdlib>
20 #include <cstdio>
21 #include <iostream>
22 
23 
86 template<class EnumType, class ETMapping> class FFaEnum
87 {
88 public:
90  FFaEnum(EnumType val = EnumType(0)) : myValue(val) {}
92  FFaEnum(const char* val) { *this = val; }
93 
96  {
97  if (this != &val)
98  this->myValue = val.myValue;
99  return *this;
100  }
101 
104  {
105  this->myValue = val;
106  return *this;
107  }
108 
111  {
112  this->myValue = EnumType(val);
113  return *this;
114  }
115 
118  {
119  if (!text || strlen(text) < 1)
120  return *this; // Empty string, don't touch the value
121 
122  // Ignore leading and trailing whitespace, if any
123  size_t istart = 0, iend = strlen(text)-1;
124  while (isspace(text[istart]))
125  if (++istart > iend)
126  {
127  // Blank string, treat as zero
128  this->myValue = EnumType(0);
129  return *this;
130  }
131 
132  while (iend > istart && isspace(text[iend]))
133  --iend;
134 
135  for (const std::pair<EnumType,const char*>& ep : ETMapping::map())
136  if (strncmp(ep.second,text+istart,iend-istart+1) == 0)
137  {
138  // Found a matching string value
139  this->myValue = ep.first;
140  return *this;
141  }
142 
143  // No match, check if the string is some integer value
144  for (size_t i = istart; i <= iend; i++)
145  if (!isdigit(text[i]))
146  return *this;
147 
148  // Try to convert the integer value to the enum value
149  this->myValue = EnumType(atoi(text+istart));
150  return *this;
151  }
152 
154  operator EnumType() const { return this->myValue; }
155 
157  const char* getText() const
158  {
159  for (const std::pair<EnumType,const char*>& ep : ETMapping::map())
160  if (ep.first == this->myValue)
161  return ep.second;
162 
163  // Fall-back in case of an enum value without matching string value
164  static char text[16];
165  snprintf(text,16,"%d",this->myValue);
166  return text;
167  }
168 
170  bool operator==(const FFaEnum<EnumType,ETMapping>& e) const { return this->myValue == e.myValue; }
172  bool operator==(const EnumType& e) const { return this->myValue == e; }
173 
175  bool operator!=(const FFaEnum<EnumType,ETMapping>& e) const { return this->myValue != e.myValue; }
177  bool operator!=(const EnumType& e) const { return this->myValue != e; }
178 
179 private:
180  EnumType myValue;
181 };
182 
183 
185 template<class EnumType, class ETMapping>
186 std::ostream& operator<<(std::ostream& s, const FFaEnum<EnumType,ETMapping>& e)
187 {
188  return s << e.getText();
189 }
190 
192 template<class EnumType, class ETMapping>
193 std::istream& operator>>(std::istream& s, FFaEnum<EnumType,ETMapping>& e)
194 {
195  char enumText[128];
196  size_t iend = 0;
197  while (iend < 127 && s.get(enumText[iend]))
198  if (!isspace(enumText[iend]))
199  ++iend;
200  else if (iend > 0)
201  break;
202 
203  if (iend == 0)
204  return s; // Empty string, don't touch anything
205  else if (enumText[0] == '"' && enumText[iend-1])
206  {
207  if (iend < 3) return s; // Empty string, don't touch anything
208  // Remove the embedding '"'-characters
209  enumText[0] = ' ';
210  --iend;
211  }
212 
213  enumText[iend] = '\0';
214  e = enumText;
215  s.clear();
216  return s;
217 }
218 
219 
221 #define FFaEnumMapping(EnumType) \
222  class EnumType##Mapping; \
223  typedef FFaEnum<EnumType,EnumType##Mapping> EnumType##Enum; \
224  class EnumType##Mapping \
225  { \
226  typedef std::pair<EnumType,const char*> EnumType##Pair; \
227  public: \
228  static const std::vector<EnumType##Pair> map() \
229  { \
230  std::vector<EnumType##Pair> enumMap; \
231  if (enumMap.empty())
232 
234 #define FFaEnumEntry(EnumValue,EnumText) \
235  enumMap.push_back(std::make_pair(EnumValue,EnumText));
236 
238 #define FFaEnumEntryEnd \
239  } return enumMap; }
240 
241 #endif
std::ostream & operator<<(std::ostream &s, const FFaEnum< EnumType, ETMapping > &e)
Global output stream operator.
Definition: FFaEnum.H:186
std::istream & operator>>(std::istream &s, FFaEnum< EnumType, ETMapping > &e)
Global input stream operator.
Definition: FFaEnum.H:193
Class to be used as a enum variable with text representations.
Definition: FFaEnum.H:87
FFaEnum< EnumType, ETMapping > & operator=(const EnumType &val)
Overloaded assignment operator.
Definition: FFaEnum.H:103
bool operator!=(const FFaEnum< EnumType, ETMapping > &e) const
Unequality operator.
Definition: FFaEnum.H:175
bool operator==(const FFaEnum< EnumType, ETMapping > &e) const
Equality operator.
Definition: FFaEnum.H:170
EnumType myValue
The actual enum value.
Definition: FFaEnum.H:180
FFaEnum< EnumType, ETMapping > & operator=(const FFaEnum< EnumType, ETMapping > &val)
Assignment operator.
Definition: FFaEnum.H:95
FFaEnum(EnumType val=EnumType(0))
Default constructor.
Definition: FFaEnum.H:90
bool operator==(const EnumType &e) const
Overloaded equality operator.
Definition: FFaEnum.H:172
FFaEnum(const char *val)
Constructor obtaining its value from a string.
Definition: FFaEnum.H:92
const char * getText() const
Returns the text representation of the enum value.
Definition: FFaEnum.H:157
FFaEnum< EnumType, ETMapping > & operator=(const int &val)
Overloaded assignment operator.
Definition: FFaEnum.H:110
bool operator!=(const EnumType &e) const
Overloaded unequality operator.
Definition: FFaEnum.H:177
FFaEnum< EnumType, ETMapping > & operator=(const char *text)
Overloaded assignment operator.
Definition: FFaEnum.H:117
integer(ptr), save, private ep
Definition: extCtrlSysRoutinesModule.f90:16