MeVisLab Toolbox Reference
mlStringSwitch.h
Go to the documentation of this file.
1 /*************************************************************************************
2 **
3 ** Copyright 2013, MeVis Medical Solutions AG
4 **
5 ** The user may use this file in accordance with the license agreement provided with
6 ** the Software or, alternatively, in accordance with the terms contained in a
7 ** written agreement between the user and MeVis Medical Solutions AG.
8 **
9 ** For further information use the contact form at https://www.mevislab.de/contact
10 **
11 **************************************************************************************/
12 
13 #ifndef ML_STRING_SWITCH_H
14 #define ML_STRING_SWITCH_H
15 
16 #include "mlTypeDefs.h"
17 
18 #include <stdexcept>
19 #include <exception>
20 #include <string>
21 #include <cstring>
22 
48 ML_START_NAMESPACE
49 
50 template<typename T, typename R = T>
52 {
53 public:
54  explicit StringSwitch(const std::string& s)
55  : _string(s)
56  , _result(nullptr)
57  {}
58 
59  explicit StringSwitch(const char* s)
60  : _string(s)
61  , _result(nullptr)
62  {}
63 
64  template<unsigned N>
65  StringSwitch& Case(const char (&s)[N], const T& Value)
66  {
67  if (!_result
68  && N-1 == _string.size()
69  && (std::memcmp(s, _string.c_str(), N-1) == 0))
70  {
71  _result = &Value;
72  }
73 
74  return *this;
75  }
76 
77  StringSwitch& Case(const std::string& s, const T& Value)
78  {
79  if (!_result && s == _string)
80  {
81  _result = &Value;
82  }
83 
84  return *this;
85  }
86 
87 
88  template<unsigned N>
89  StringSwitch& EndsWith(const char (&s)[N], const T &Value)
90  {
91  if (!_result
92  && _string.size() >= N-1
93  && std::memcmp(s, _string.c_str() + _string.size() + 1 - N, N-1) == 0)
94  {
95  _result = &Value;
96  }
97 
98  return *this;
99  }
100 
101  template<unsigned N>
102  StringSwitch& StartsWith(const char (&s)[N], const T &Value)
103  {
104  if (!_result
105  && _string.size() >= N-1
106  && std::memcmp(s, _string.c_str(), N-1) == 0)
107  {
108  _result = &Value;
109  }
110 
111  return *this;
112  }
113 
114  template<unsigned N0, unsigned N1>
115  StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1], const T& Value)
116  {
117  return Case(S0, Value).Case(S1, Value);
118  }
119 
120  template<unsigned N0, unsigned N1, unsigned N2>
121  StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1], const char (&S2)[N2], const T& Value)
122  {
123  return Case(S0, Value).Case(S1, Value).Case(S2, Value);
124  }
125 
126  template<unsigned N0, unsigned N1, unsigned N2, unsigned N3>
127  StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1], const char (&S2)[N2], const char (&S3)[N3], const T& Value)
128  {
129  return Case(S0, Value).Case(S1, Value).Case(S2, Value).Case(S3, Value);
130  }
131 
132  template<unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4>
133  StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1], const char (&S2)[N2], const char (&S3)[N3], const char (&S4)[N4], const T& Value)
134  {
135  return Case(S0, Value).Case(S1, Value).Case(S2, Value).Case(S3, Value).Case(S4, Value);
136  }
137 
138  R Default(const T& Value) const
139  {
140  if (_result)
141  {
142  return *_result;
143  }
144  return Value;
145  }
146 
147  template<typename Ex, typename ExP1>
148  R Throw(const ExP1& p1) const
149  {
150  if (_result)
151  {
152  return *_result;
153  }
154  throw Ex(p1);
155  }
156 
157  template<typename Ex, typename ExP1, typename ExP2>
158  R Throw(const ExP1& p1, const ExP2& p2) const
159  {
160  if (_result)
161  {
162  return *_result;
163  }
164  throw Ex(p1, p2);
165  }
166 
167  template<typename Ex, typename ExP1, typename ExP2, typename ExP3>
168  R Throw(const ExP1& p1, const ExP2& p2, const ExP3& p3) const
169  {
170  if (_result)
171  {
172  return *_result;
173  }
174  throw Ex(p1, p2, p3);
175  }
176 
177  operator R() const
178  {
179  if (!_result)
180  {
181  throw std::domain_error("Fell off the end of the string switch");
182  }
183  return *_result;
184  }
185 
186 private:
187  const std::string _string;
188 
189  const T *_result;
190 };
191 
192 ML_END_NAMESPACE
193 
194 #endif
@ R
Definition: SoKeyGrabber.h:69
@ T
Definition: SoKeyGrabber.h:71
@ N
Definition: SoKeyGrabber.h:65
StringSwitch(const std::string &s)
StringSwitch(const char *s)
StringSwitch & Case(const std::string &s, const T &Value)
StringSwitch & EndsWith(const char(&s)[N], const T &Value)
StringSwitch & Cases(const char(&S0)[N0], const char(&S1)[N1], const char(&S2)[N2], const char(&S3)[N3], const T &Value)
StringSwitch & Case(const char(&s)[N], const T &Value)
StringSwitch & StartsWith(const char(&s)[N], const T &Value)
R Throw(const ExP1 &p1, const ExP2 &p2) const
R Default(const T &Value) const
StringSwitch & Cases(const char(&S0)[N0], const char(&S1)[N1], const T &Value)
StringSwitch & Cases(const char(&S0)[N0], const char(&S1)[N1], const char(&S2)[N2], const T &Value)
StringSwitch & Cases(const char(&S0)[N0], const char(&S1)[N1], const char(&S2)[N2], const char(&S3)[N3], const char(&S4)[N4], const T &Value)
R Throw(const ExP1 &p1) const
R Throw(const ExP1 &p1, const ExP2 &p2, const ExP3 &p3) const