ModErn Text Analysis
META Enumerates Textual Applications
identifiers.h
Go to the documentation of this file.
1 
12 #ifndef META_NUMERIC_IDENTIFIER_H_
13 #define META_NUMERIC_IDENTIFIER_H_
14 
15 #include <functional> // for std::hash
16 #include "util/comparable.h"
17 
18 namespace meta
19 {
20 namespace util
21 {
22 
26 struct numeric
27 {
28 };
29 
34 template <template <class> class Wrapped>
35 struct hash_wrapper : public Wrapped<hash_wrapper<Wrapped>>
36 {
37  using Wrapped<hash_wrapper>::Wrapped;
38  using Wrapped<hash_wrapper>::operator=;
39 
40  hash_wrapper() = default;
41  hash_wrapper(const hash_wrapper&) = default;
42  hash_wrapper(hash_wrapper&&) = default;
43  hash_wrapper& operator=(const hash_wrapper&) = default;
44  hash_wrapper& operator=(hash_wrapper&&) = default;
45 };
46 
52 template <class Derived, class T>
53 struct identifier : public comparable<identifier<Derived, T>>
54 {
58  T id_;
59 
66  explicit identifier(const T& t) : id_{t}
67  {
68  }
69 
73  identifier() = default;
74 
78  identifier(const identifier&) = default;
79 
83  identifier(identifier&&) = default;
84 
88  identifier& operator=(const identifier&) = default;
89 
93  identifier& operator=(identifier&&) = default;
94 
110  identifier& operator=(const T& t)
111  {
112  id_ = t;
113  return *this;
114  }
115 
122  operator const T&() const
123  {
124  return id_;
125  }
126 
133  operator T&()
134  {
135  return id_;
136  }
137 
146  inline friend bool operator<(const identifier& lhs, const identifier& rhs)
147  {
148  return static_cast<T>(lhs) < static_cast<T>(rhs);
149  }
150 
157  inline friend std::ostream& operator<<(std::ostream& stream,
158  const identifier& ident)
159  {
160  return stream << static_cast<T>(ident);
161  }
162 
169  inline friend std::istream& operator>>(std::istream& stream,
170  identifier& ident)
171  {
172  return stream >> ident.id_;
173  }
174 };
175 
181 template <class Derived, class T>
182 struct numerical_identifier : public identifier<Derived, T>, numeric
183 {
187 
192  Derived& operator++()
193  {
194  ++id_;
195  return *derived();
196  }
197 
202  Derived operator++(int)
203  {
204  Derived t = *derived();
205  ++(*this);
206  return t;
207  }
208 
213  Derived& operator--()
214  {
215  --id_;
216  return *derived();
217  }
218 
223  Derived operator--(int)
224  {
225  Derived t = *derived();
226  --(*this);
227  return t;
228  }
229 
234  Derived& operator+=(const T& step)
235  {
236  id_ += step;
237  return *derived();
238  }
239 
244  Derived& operator-=(const T& step)
245  {
246  id_ -= step;
247  return *derived();
248  }
249 
256  friend inline Derived operator+(Derived lhs, const Derived& rhs)
257  {
258  lhs += static_cast<T>(rhs);
259  return lhs;
260  }
261 
268  friend inline Derived operator-(Derived lhs, const Derived& rhs)
269  {
270  lhs -= static_cast<T>(rhs);
271  return lhs;
272  }
273 
274  private:
279  Derived* derived()
280  {
281  return static_cast<Derived*>(this);
282  }
283 };
284 }
285 }
286 
287 namespace std
288 {
289 
294 template <template <class> class Wrapped>
295 struct hash<meta::util::hash_wrapper<Wrapped>>
296 {
302  template <class T>
303  size_t operator()(
305  T>& to_hash) const
306  {
307  return hash<T>{}(static_cast<T>(to_hash));
308  }
309 };
310 }
311 
312 #define MAKE_USER_DEFINED_LITERAL(ident_name, base_type, suffix) \
313  inline ident_name operator"" suffix(const char* str, std::size_t len) \
314  { \
315  return ident_name{base_type{str, len}}; \
316  }
317 
318 #define MAKE_USER_DEFINED_NUMERIC_LITERAL(ident_name, base_type, suffix) \
319  inline ident_name operator"" suffix(unsigned long long int val) \
320  { \
321  return ident_name{base_type(val)}; \
322  }
323 
324 #define MAKE_OPAQUE_IDENTIFIER(ident_name, base_type) \
325  template <class Wrapper> \
326  struct ident_name##_dummy \
327  : public meta::util::identifier<Wrapper, base_type> \
328  { \
329  using meta::util::identifier<Wrapper, base_type>::identifier; \
330  using meta::util::identifier<Wrapper, base_type>::operator=; \
331  }; \
332  using ident_name = meta::util::hash_wrapper<ident_name##_dummy>;
333 
334 #define MAKE_OPAQUE_NUMERIC_IDENTIFIER(ident_name, base_type) \
335  template <class Wrapper> \
336  struct ident_name##_dummy \
337  : public meta::util::numerical_identifier<Wrapper, base_type> \
338  { \
339  using meta::util::numerical_identifier<Wrapper, base_type>:: \
340  numerical_identifier; \
341  using meta::util::numerical_identifier<Wrapper, base_type>::operator=; \
342  }; \
343  using ident_name = meta::util::hash_wrapper<ident_name##_dummy>;
344 
345 #if !defined NDEBUG && !defined NUSE_OPAQUE_IDENTIFIERS
346 #define MAKE_IDENTIFIER(ident_name, base_type) \
347  MAKE_OPAQUE_IDENTIFIER(ident_name, base_type)
348 #else
349 #define MAKE_IDENTIFIER(ident_name, base_type) using ident_name = base_type;
350 #endif
351 
352 #if !defined NDEBUG && !defined NUSE_OPAQUE_IDENTIFIERS
353 #define MAKE_NUMERIC_IDENTIFIER(ident_name, base_type) \
354  MAKE_OPAQUE_NUMERIC_IDENTIFIER(ident_name, base_type)
355 #else
356 #define MAKE_NUMERIC_IDENTIFIER(ident_name, base_type) \
357  using ident_name = base_type;
358 #endif
359 
360 #if !defined NDEBUG && !defined NUSE_OPAQUE_IDENTIFIERS
361 #define MAKE_IDENTIFIER_UDL(ident_name, base_type, suffix) \
362  MAKE_OPAQUE_IDENTIFIER(ident_name, base_type) \
363  MAKE_USER_DEFINED_LITERAL(ident_name, base_type, suffix)
364 #else
365 #define MAKE_IDENTIFIER_UDL(ident_name, base_type, suffix) \
366  using ident_name = base_type; \
367  MAKE_USER_DEFINED_LITERAL(ident_name, base_type, suffix)
368 #endif
369 
370 #if !defined NDEBUG && !defined NUSE_OPAQUE_IDENTIFIERS
371 #define MAKE_NUMERIC_IDENTIFIER_UDL(ident_name, base_type, suffix) \
372  MAKE_OPAQUE_NUMERIC_IDENTIFIER(ident_name, base_type) \
373  MAKE_USER_DEFINED_NUMERIC_LITERAL(ident_name, base_type, suffix)
374 #else
375 #define MAKE_NUMERIC_IDENTIFIER_UDL(ident_name, base_type, suffix) \
376  using ident_name = base_type; \
377  MAKE_USER_DEFINED_NUMERIC_LITERAL(ident_name, base_type, suffix)
378 #endif
379 
380 #endif
identifier & operator=(const identifier &)=default
identifiers may be copy assigned.
friend bool operator<(const identifier &lhs, const identifier &rhs)
identifiers are comparable by their base types.
Definition: identifiers.h:146
A CRTP template base that adds numeric functionality to the identifier type.
Definition: identifiers.h:182
Helper class that allows the wrapped type to be hashed into standard library containers such as unord...
Definition: identifiers.h:35
size_t operator()(const meta::util::identifier< meta::util::hash_wrapper< Wrapped >, T > &to_hash) const
Definition: identifiers.h:303
Derived & operator--()
Prefix-decrement.
Definition: identifiers.h:213
STL namespace.
Derived & operator++()
Prefix-increment.
Definition: identifiers.h:192
identifier(const T &t)
identifiers must be explicitly constructed from their base type—they cannot be implicitly converted ...
Definition: identifiers.h:66
Empty helper class to denote that something is numeric.
Definition: identifiers.h:26
friend std::istream & operator>>(std::istream &stream, identifier &ident)
identifiers may be read from input streams.
Definition: identifiers.h:169
Derived & operator+=(const T &step)
Definition: identifiers.h:234
Derived operator++(int)
Postifx-increment.
Definition: identifiers.h:202
identifier & operator=(const T &t)
identifiers may be assigned into from their base type, provided they have already been constructed...
Definition: identifiers.h:110
friend std::ostream & operator<<(std::ostream &stream, const identifier &ident)
identifiers may be printed to output streams.
Definition: identifiers.h:157
friend Derived operator+(Derived lhs, const Derived &rhs)
Definition: identifiers.h:256
The ModErn Text Analysis toolkit is a suite of natural language processing, classification, information retreival, data mining, and other applications of text processing.
Definition: analyzer.h:24
T id_
The underlying id for the identifier.
Definition: identifiers.h:58
Derived & operator-=(const T &step)
Definition: identifiers.h:244
friend Derived operator-(Derived lhs, const Derived &rhs)
Definition: identifiers.h:268
CRTP base template that denotes an identifier.
Definition: identifiers.h:53
Derived * derived()
Reinterprets the current numerical_identifier as is underlying Derived type.
Definition: identifiers.h:279
Derived operator--(int)
Postfix-decrement.
Definition: identifiers.h:223
A CRTP base class that allows for inheritance of all comparator operators given that the derived clas...
Definition: comparable.h:26
identifier()=default
identifier has a default constructor.