Lumiera  0.pre.03
»edit your freedom«
util.hpp
Go to the documentation of this file.
1 /*
2  UTIL.hpp - collection of small helper functions used "everywhere"
3 
4  Copyright (C)
5  2008, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 */
13 
14 
27 #ifndef LIB_UTIL_H
28 #define LIB_UTIL_H
29 
30 #include "include/limits.hpp"
31 #include "lib/hash-standard.hpp"
32 
33 #include <string>
34 
35 namespace std {// forward declarations to avoid pervasive includes
36 
37  template<typename T>
38  class allocator;
39  template<typename K, typename CMP, class ALLO>
40  class set;
41 
42  template<typename IT, typename V>
43  IT find (IT, IT, V const&);
44  template<typename IT, typename V>
45  IT remove (IT, IT, V const&);
46 }
47 
48 
49 const char* cStr (std::string const&);
50 
51 
52 
53 namespace util {
54 
55  using std::string;
56  using CStr = const char*;
57 
58 
59  template <class NUM>
60  inline int constexpr
61  sgn (NUM n)
62  {
63  return (n==0)? 0 :((n<0)? -1:+1 );
64  }
65 
66  template <class N1, class N2>
67  inline N1 constexpr
68  min (N1 n1, N2 n2)
69  {
70  return n2 < n1? N1(n2) : n1;
71  }
72 
73  template <class N1, class N2>
74  inline N1 constexpr
75  max (N1 n1, N2 n2)
76  {
77  return n1 < n2? N1(n2) : n1;
78  }
79 
81  template <typename NUM>
82  inline NUM constexpr
83  noneg (NUM val)
84  {
85  return (0<val? val : 0);
86  }
87 
89  template <typename NUM, typename NB>
90  inline NUM constexpr
91  limited (NB lowerBound, NUM val, NB upperBound)
92  {
93  return min ( max (val, lowerBound)
94  , upperBound);
95  }
96 
97  template <typename NUM, typename NB>
98  inline bool constexpr
99  isLimited (NB lowerBound, NUM val, NB upperBound)
100  {
101  return lowerBound <= val
102  and val <= upperBound;
103  }
104 
105  template <typename UN, typename N2>
106  inline UN constexpr
107  positiveDiff (N2 newVal, UN refVal)
108  {
109  return UN(newVal) > refVal? UN(newVal) - refVal
110  : UN(0);
111  }
112 
116  inline uint
117  uNum (CStr charPtr)
118  {
119  if (!charPtr) return 0;
120  int parsedNumber (std::atoi (charPtr));
121  return limited (0, parsedNumber, LUMIERA_MAX_ORDINAL_NUMBER);
122  }
123 
124  inline int
125  sNum (CStr charPtr)
126  {
127  if (!charPtr) return 0;
128  int parsedNumber (std::atoi (charPtr));
129  return limited (-LUMIERA_MAX_ORDINAL_NUMBER, parsedNumber, LUMIERA_MAX_ORDINAL_NUMBER);
130  }
131 
132  template<class OBJ>
133  inline uint
134  uNum (OBJ const& spec)
135  {
136  return uNum (cStr(spec));
137  }
138 
139  template<class OBJ>
140  inline int
141  sNum (OBJ const& spec)
142  {
143  return sNum (cStr(spec));
144  }
145 
146 
147 
148  /* ======== generic empty check ========= */
149 
152  template <class CONT>
153  inline bool
154  isnil (const CONT& container)
155  {
156  return container.empty();
157  }
158 
159  template <class CONT>
160  inline bool
161  isnil (const CONT* pContainer)
162  {
163  return !pContainer or pContainer->empty();
164  }
165 
166  template <class CONT>
167  inline bool
168  isnil (CONT* pContainer)
169  {
170  return !pContainer or pContainer->empty();
171  }
172 
173  inline bool
174  isnil (CStr charPtr)
175  {
176  return !charPtr or !(*charPtr);
177  }
178 
179 
180 
181  /* ======== string and containment ========= */
182 
184  inline bool
185  startsWith (string const& str, string const& prefix)
186  {
187  return 0 == str.rfind (prefix, 0);
188  }
189 
190  inline bool
191  startsWith (string const& str, CStr prefix)
192  {
193  return 0 == str.rfind (prefix, 0);
194  }
195 
197  inline bool
198  endsWith (string const& str, string const& suffix)
199  {
200  size_t l = suffix.length();
201  if (l > str.length()) return false;
202  size_t pos = str.length() - l;
203  return pos == str.find (suffix, pos);
204  }
205 
206  inline bool
207  endsWith (string const& str, CStr suffix)
208  {
209  return endsWith (str, string(suffix));
210  }
211 
212  inline void
213  removePrefix (string& str, string const& prefix)
214  {
215  if (not startsWith (str,prefix)) return;
216  str = str.substr (prefix.length());
217  }
218 
219  inline void
220  removeSuffix (string& str, string const& suffix)
221  {
222  if (not endsWith (str,suffix)) return;
223  str.resize(str.length() - suffix.length());
224  }
225 
226 
228  template <typename MAP>
229  inline bool
230  contains (MAP& map, typename MAP::key_type const& key)
231  {
232  return map.find(key) != map.end();
233  }
234 
236  template <typename T, class CMP, class ALO>
237  inline bool
238  contains (std::set<T,CMP,ALO> const& set, T const& val)
239  {
240  return set.end() != set.find (val);
241  }
242 
244  template <typename T>
245  inline bool
246  contains (std::string const& str, const T& val)
247  {
248  return str.find (val) != std::string::npos;
249  }
250 
253  template <typename SEQ>
254  inline bool
255  contains (SEQ const& cont, typename SEQ::const_reference val)
256  {
257  typename SEQ::const_iterator begin = cont.begin();
258  typename SEQ::const_iterator end = cont.end();
259 
260  return end != std::find(begin,end, val);
261  }
262 
264  template <class IT>
265  inline bool
266  linearSearch (IT iter, typename IT::value_type const& val)
267  {
268  IT end{};
269  return end != std::find (std::move (iter), end, val);
270  }
271 
273  template <typename MAP>
274  inline typename MAP::mapped_type
275  getValue_or_default (MAP& map, typename MAP::key_type const& key
276  , typename MAP::mapped_type defaultVal)
277  {
278  typename MAP::const_iterator pos = map.find (key);
279  if (pos != map.end())
280  return pos->second;
281  else
282  return defaultVal;
283  }
284 
290  template <typename MAP>
291  inline typename MAP::mapped_type const &
292  access_or_default (MAP& map, typename MAP::key_type const& key
293  , typename MAP::mapped_type const& refDefault)
294  {
295  typename MAP::const_iterator pos = map.find (key);
296  if (pos != map.end())
297  return pos->second;
298  else
299  return refDefault;
300  }
301 
304  template <typename SEQ>
305  inline typename SEQ::iterator
306  removeall (SEQ& coll, typename SEQ::value_type const& val)
307  {
308  typename SEQ::iterator collEnd = coll.end();
309  return coll.erase (std::remove (coll.begin(), collEnd, val),
310  collEnd
311  );
312  }
313 
314 
318  template<class SET, typename FUN>
319  bool remove_if (SET& set, FUN test)
320  {
321  typedef typename SET::iterator Itor;
322  bool found = false;
323  Itor end = set.end();
324  Itor begin = set.begin();
325  Itor pos = begin;
326  while (pos!=end)
327  {
328  if (not test(*pos))
329  ++pos;
330  else
331  {
332  found = true;
333  if (pos==begin)
334  {
335  set.erase(pos);
336  pos = begin = set.begin();
337  }
338  else
339  {
340  set.erase(pos--);
341  ++pos;
342  }
343  end = set.end();
344  } }
345  return found;
346  }
347 
348 
349 
350 
356  template<class OBJ>
357  inline OBJ*
358  unConst (const OBJ* o)
359  {
360  return const_cast<OBJ*> (o);
361  }
362 
363  template<class OBJ>
364  inline OBJ&
365  unConst (OBJ const& ro)
366  {
367  return const_cast<OBJ&> (ro);
368  }
369 
370 
371 
372  /* ======== address and identity ========= */
373 
375  template<class X>
376  inline const void*
377  getAdr (X& x)
378  {
379  return static_cast<const void*> (std::addressof(x));
380  }
381  template<class X>
382  inline const void*
383  getAdr (X* x)
384  {
385  return static_cast<const void*> (x);
386  }
387 
389  template<class X>
390  inline size_t
391  addrID (X const& x)
392  {
393  return size_t(getAdr (x));
394  }
395 
396 
398  template<typename X>
399  inline size_t
400  slotNr (X const& x)
401  {
402  return addrID(x) / sizeof(size_t);
403  }
404 
405 
409  template<class A, class B>
410  inline bool
411  isSameAdr (A const& a, B const& b)
412  {
413  return getAdr(a) == getAdr(b);
414  }
415 
419  template<class A, class B>
420  inline bool
421  isSameObject (A const& a, B const& b)
422  {
423  return static_cast<const void*> (std::addressof(a))
424  == static_cast<const void*> (std::addressof(b));
425  }
426 
432  template<typename A, typename B>
433  inline bool
434  isCloseBy (A&& a, B&& b, size_t consideredNearby =50)
435  {
436  size_t loc1 = slotNr (std::forward<A> (a));
437  size_t loc2 = slotNr (std::forward<B> (b));
438  size_t dist = loc2 > loc1? loc2-loc1:loc1-loc2;
439  return dist < consideredNearby;
440  }
441 
442 
443 
444 
464  string sanitise (string const& org);
465 
466 
470  string trim (string const& org);
471 
472 
480  bool boolVal (string const&);
481 
482 
487  bool isYes (string const&) noexcept;
488 
493  bool isNo (string const&) noexcept;
494 
495 } // namespace util
496 
497 
498 
499 
500  /* === some common macro definitions === */
501 
505 #define SIDEEFFECT __attribute__ ((unused));
506 
508 #define STRINGIFY(TOKEN) __STRNGFY(TOKEN)
509 #define __STRNGFY(TOKEN) #TOKEN
510 
514 #define INSTANCEOF(CLASS, EXPR) (dynamic_cast<const CLASS*> (EXPR))
515 
517 #ifndef MAX // this is present to make this definition play nice with GLib
518 #define MAX(A,B) ((A < B) ? (B) : (A))
519 #endif
520 
521 #endif /*UTIL_HPP_*/
OBJ * unConst(const OBJ *)
shortcut to save some typing when having to define const and non-const variants of member functions ...
Definition: util.hpp:358
const char * cStr(std::string const &)
convenience shortcut: forced conversion to c-String via string.
Definition: symbol.hpp:59
bool isYes(string const &textForm) noexcept
check the given text if it can be interpreted as affirmative answer (bool true).
Definition: util.cpp:107
bool startsWith(string const &str, string const &prefix)
check if string starts with a given prefix
Definition: util.hpp:185
Definition: run.hpp:40
const void * getAdr(X &x)
extract address but strip any type info
Definition: util.hpp:377
STL namespace.
bool isCloseBy(A &&a, B &&b, size_t consideredNearby=50)
determine heuristically if two objects are located „close to each other“ in memory.
Definition: util.hpp:434
std::string sanitise(std::string const &)
produce an identifier based on the given string.
Definition: util.cpp:56
hard wired safety limits.
bool boolVal(string const &textForm)
interpret text representation of a boolean value.
Definition: util.cpp:98
NUM constexpr noneg(NUM val)
cut a numeric value to be >=0
Definition: util.hpp:83
bool linearSearch(IT iter, typename IT::value_type const &val)
use (and exhaust) a »Lumiera Forward Iterator« for linear search
Definition: util.hpp:266
size_t slotNr(X const &x)
the addressable memory »slot« — platform dependent.
Definition: util.hpp:400
bool contains(MAP &map, typename MAP::key_type const &key)
shortcut for containment test on a map
Definition: util.hpp:230
uint uNum(CStr charPtr)
positive integral number from textual representation
Definition: util.hpp:117
bool isNo(string const &textForm) noexcept
check if the given text is empty or can be interpreted as rejection (bool false)- ...
Definition: util.cpp:114
size_t addrID(X const &x)
generate an unique numeric ID based on the referred entity
Definition: util.hpp:391
MAP::mapped_type const & access_or_default(MAP &map, typename MAP::key_type const &key, typename MAP::mapped_type const &refDefault)
expose a reference to a map entry, with fall-back to some default object
Definition: util.hpp:292
Helper to use a single extension point for specialised hash functions.
bool remove_if(SET &set, FUN test)
remove all elements fulfilling a given predicate from a (sorted) set.
Definition: util.hpp:319
string trim(string const &org)
remove leading and trailing whitespace
Definition: util.cpp:84
MAP::mapped_type getValue_or_default(MAP &map, typename MAP::key_type const &key, typename MAP::mapped_type defaultVal)
fetch value from a Map, or return a default if not found
Definition: util.hpp:275
NUM constexpr limited(NB lowerBound, NUM val, NB upperBound)
force a numeric to be within bounds, inclusively
Definition: util.hpp:91
bool endsWith(string const &str, string const &suffix)
check if string ends with the given suffix
Definition: util.hpp:198
SEQ::iterator removeall(SEQ &coll, typename SEQ::value_type const &val)
shortcut for removing all copies of an Element in any sequential collection
Definition: util.hpp:306
bool isSameAdr(A const &a, B const &b)
compare plain object address identity, disregarding type.
Definition: util.hpp:411
bool isSameObject(A const &a, B const &b)
compare plain object identity, based directly on the referee&#39;s memory identities. ...
Definition: util.hpp:421