SimulationCraft
SimulationCraft is a tool to explore combat mechanics in the popular MMO RPG World of Warcraft (tm).
type.hpp
1 #ifndef CPP_SEMVER_TYPE_HPP
2 #define CPP_SEMVER_TYPE_HPP
3 
4 #include <string>
5 #include <vector>
6 
7 namespace semver
8 {
9  // ------------ exception types ------------------------------------ //
10 
11  struct semver_error : public std::runtime_error
12  {
13  semver_error(const std::string& msg) : std::runtime_error(msg) {}
14  };
15 
16  // ------------ syntax types ------------------------------------ //
17 
18  struct syntax
19  {
20  /*
21  * original NPM semver syntax grammar: https://docs.npmjs.com/misc/Syntax#range-grammar
22  *
23  * range-set ::= range ( logical-or range ) *
24  * logical-or ::= ( ' ' ) * '||' ( ' ' ) *
25  * range ::= hyphen | simple ( ' ' simple ) * | ''
26  * hyphen ::= partial ' - ' partial
27  * simple ::= primitive | partial | tilde | caret
28  * primitive ::= ( '<' | '>' | '>=' | '<=' | '=' | ) partial
29  * partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )?
30  * xr ::= 'x' | 'X' | '*' | nr
31  * nr ::= '0' | ['1'-'9'] ( ['0'-'9'] ) *
32  * tilde ::= '~' partial
33  * caret ::= '^' partial
34  * qualifier ::= ( '-' pre )? ( '+' build )?
35  * pre ::= parts
36  * build ::= parts
37  * parts ::= part ( '.' part ) *
38  * part ::= nr | [-0-9A-Za-z]+
39  */
40 
41  enum class comparator
42  {
43  eq, lt, lte, gt, gte, tilde, caret
44  };
45 
47  struct xnumber
48  {
50  explicit xnumber(const int& val) : is_wildcard(false), value(val) {}
51 
53  xnumber() : is_wildcard(true), value(0) {}
54 
55  bool is_wildcard;
56  int value;
57  };
58 
61  struct simple
62  {
63  xnumber major;
64  xnumber minor;
65  xnumber patch;
66 
67  std::string pre = "";
68  std::string build = "";
69 
70  comparator cmp = comparator::eq;
71  };
72 
75  struct range
76  {
77  bool as_hyphon = false; // hint to interpret the range as hyphon if possible
78  std::vector< simple > and_set;
79  };
80 
82  struct range_set
83  {
84  std::vector< range > or_set;
85  };
86  };
87 
88  // ------------ semantic types ------------------------------------ //
89 
90  struct semantic
91  {
92  struct boundary
93  {
94  int major = 0;
95  int minor = 0;
96  int patch = 0;
97  std::string pre = "";
98  bool is_max = false;
99 
101  static boundary min()
102  {
103  return {};
104  }
105 
107  static boundary max()
108  {
109  boundary b;
110  b.is_max = true;
111  return b;
112  }
113  };
114 
116  struct interval
117  {
118  bool from_inclusive = true;
119  bool to_inclusive = true;
120  boundary from = boundary::min();
121  boundary to = boundary::max();
122  };
123 
126  {
127  std::vector< interval > or_set;
128  };
129  };
130 
131  inline bool operator ==(const semantic::boundary& lhs, const semantic::boundary& rhs)
132  {
133  return (lhs.major == rhs.major) &&
134  (lhs.minor == rhs.minor) &&
135  (lhs.patch == rhs.patch) &&
136  (lhs.pre == rhs.pre) &&
137  (lhs.is_max == rhs.is_max);
138  }
139 
140  inline bool operator !=(const semantic::boundary& lhs, const semantic::boundary& rhs)
141  {
142  return !(lhs == rhs);
143  }
144 
145  inline bool operator <(const semantic::boundary& lhs, const semantic::boundary& rhs)
146  {
147  // TODO: improve the performance of comparison
148 
149  // XXX: is_max case
150  if (lhs.is_max || rhs.is_max)
151  return !lhs.is_max && rhs.is_max; // 1.2.3 < max
152 
153  if (lhs.major < rhs.major) // 1.* < 2.*
154  return true;
155 
156  if ((lhs.major == rhs.major) && // 1.2.* < 1.3.*
157  (lhs.minor < rhs.minor))
158  return true;
159 
160  if ((lhs.major == rhs.major) && // 1.2.3 < 1.2.4
161  (lhs.minor == rhs.minor) &&
162  (lhs.patch < rhs.patch))
163  return true;
164 
165  // XXX: pre-release case
166  if ((lhs.major == rhs.major) && // 1.2.3-alpha < 1.2.3
167  (lhs.minor == rhs.minor) &&
168  (lhs.patch == rhs.patch) &&
169  (!lhs.pre.empty() && rhs.pre.empty()))
170  return true;
171 
172  // XXX: pre-release case
173  if ((lhs.major == rhs.major) && // 1.2.3-alpha < 1.2.3-beta
174  (lhs.minor == rhs.minor) &&
175  (lhs.patch == rhs.patch) &&
176  (!lhs.pre.empty() && !rhs.pre.empty()) &&
177  (lhs.pre < rhs.pre))
178  return true;
179 
180  return false;
181  }
182 
183  inline bool operator >(const semantic::boundary& lhs, const semantic::boundary& rhs)
184  {
185  return (lhs != rhs) && !(lhs < rhs);
186  }
187 
188  inline bool operator <=(const semantic::boundary& lhs, const semantic::boundary& rhs)
189  {
190  return (lhs < rhs) || (lhs == rhs);
191  }
192 
193  inline bool operator >=(const semantic::boundary& lhs, const semantic::boundary& rhs)
194  {
195  return (lhs > rhs) || (lhs == rhs);
196  }
197 
198  inline bool operator ==(const semantic::interval& lhs, const semantic::interval& rhs)
199  {
200  return (lhs.from_inclusive == rhs.from_inclusive) &&
201  (lhs.to_inclusive == rhs.to_inclusive) &&
202  (lhs.from == rhs.from) &&
203  (lhs.to == rhs.to);
204  }
205 
206  inline bool operator !=(const semantic::interval& lhs, const semantic::interval& rhs)
207  {
208  return !(lhs == rhs);
209  }
210 
211  inline bool operator <(const semantic::interval& lhs, const semantic::interval& rhs)
212  {
213  if (lhs.to < rhs.from ||
214  (lhs.to == rhs.from && (!lhs.to_inclusive || !rhs.from_inclusive)))
215  return true;
216  return false;
217  }
218 
219  inline bool operator <=(const semantic::interval& lhs, const semantic::interval& rhs)
220  {
221  return (lhs < rhs) || (lhs == rhs);
222  }
223 
224  inline bool operator >(const semantic::interval& lhs, const semantic::interval& rhs)
225  {
226  return (lhs != rhs) && !(lhs < rhs);
227  }
228 
229  inline bool operator >=(const semantic::interval& lhs, const semantic::interval& rhs)
230  {
231  return (lhs > rhs) || (lhs == rhs);
232  }
233 }
234 
235 #endif
Definition: type.hpp:18
union set (i.e. OR conjunction )
Definition: type.hpp:82
xnumber()
represents &#39;*&#39;
Definition: type.hpp:53
Definition: generic.hpp:135
static boundary max()
Represent a maximal version boundary.
Definition: type.hpp:107
Definition: type.hpp:90
xnumber(const int &val)
represents an integer
Definition: type.hpp:50
static boundary min()
Represent a minimal version boundary.
Definition: type.hpp:101
interval set (i.e. OR conjunction )
Definition: type.hpp:125
Definition: type.hpp:92
Definition: type.hpp:11
default interval is *.*.* := [min, max]
Definition: type.hpp:116
Definition: core.h:1208
represents any type of &#39;simple&#39;, &#39;primitive&#39;, &#39;partial&#39;, &#39;tilde&#39; or &#39;caret&#39; from the grammar...
Definition: type.hpp:61
an integer or wildcard
Definition: type.hpp:47
Definition: type.hpp:7