AMRange  201909
String localization library
AMRange.h
Go to the documentation of this file.
1 
8 #ifndef AMCORE_AMRANGE_H
9 #define AMCORE_AMRANGE_H
10 
11 #include <set>
12 #include <algorithm>
13 
19 namespace AMCore {
20 
33  template<typename T>
34  class AMRange
35  {
36  public:
40  T from;
44  T to;
45 
51  AMRange();
52 
60  AMRange(T _from, T _to);
61 
68  inline bool operator<(const AMRange &right) const;
69 
78  inline AMRange &operator-=(const AMRange &right);
79 
88  inline AMRange &operator+=(const AMRange &right);
89 
96  inline bool operator==(const AMRange &right) const;
97 
104  inline bool operator!=(const AMRange &right) const;
105 
113  inline AMRange &intersect(const AMRange &right);
114 
120  inline bool valid() const;
121 
127  inline bool nonEmpty() const;
128 
135  inline bool in(T num) const;
136 
143  inline bool in(const AMRange &rng) const;
144 
150  inline bool empty() const;
151  };
152 
161  template<typename T>
162  inline AMRange<T> intersect(const AMRange<T> &left, const AMRange<T> &right);
172  template<typename T>
173  inline AMRange<T> operator+(const AMRange<T> &left, const AMRange<T> &right);
183  template<typename T>
184  inline AMRange<T> operator-(const AMRange<T> &left, const AMRange<T> &right);
185 
194  template<typename T>
195  bool isPacked(const std::set<AMRange<T> > &s);
202  template<typename T>
203  bool valid(const std::set<AMRange<T> > &s);
212  template<typename T>
213  std::set<AMRange<T> > pack(const std::set<AMRange<T> > &s);
214  template<typename T>
224  std::set<AMRange<T> > operator+(const std::set<AMRange<T> > &left, const std::set<AMRange<T> > &right);
234  template<typename T>
235  std::set<AMRange<T> > operator-(const std::set<AMRange<T> > &left, const std::set<AMRange<T> > &right);
245  template<typename T>
246  std::set<AMRange<T> > operator+(const AMRange<T> &left, const std::set<AMRange<T> > &right);
256  template<typename T>
257  std::set<AMRange<T> > operator-(const AMRange<T> &left, const std::set<AMRange<T> > &right);
267  template<typename T>
268  std::set<AMRange<T> > operator+(const std::set<AMRange<T> > &left, const AMRange<T> &right);
278  template<typename T>
279  std::set<AMRange<T> > operator-(const std::set<AMRange<T> > &left, const AMRange<T> &right);
280 
281 
282  template<typename T>
284  : from(),
285  to()
286  {
287  };
288 
289  template<typename T>
290  AMRange<T>::AMRange(T _from, T _to)
291  : from(_from),
292  to(_to)
293  {
294  };
295 
296  template<typename T>
297  inline bool AMRange<T>::operator<(const AMRange<T> &right) const
298  {
299  if (from < right.from) {
300  return true;
301  } else if (from == right.from) {
302  return to < right.to;
303  }
304  return false;
305  }
306 
307  template<typename T>
309  {
310  if (!valid()) {
311  return *this;
312  }
313  if (!right.valid()) {
314  from = right.from;
315  to = right.to;
316  return *this;
317  }
318  if (from < right.from) {
319  if (to > right.to) {
320  T t = to;
321  to = from;
322  from = t;
323  }else if (to > right.from) {
324  to = right.from;
325  }
326  } else {
327  if (to < right.to) {
328  to = from;
329  } else if (from < right.to) {
330  from = right.to;
331  }
332  }
333  return *this;
334  }
335 
336  template<typename T>
338  {
339  if (from < right.from) {
340  from = right.from;
341  }
342  if (to > right.to) {
343  to = right.to;
344  }
345  if (to < from) {
346  to = from;
347  }
348  return *this;
349  }
350 
351  template<typename T>
353  {
354  if (!valid()) {
355  return *this;
356  }
357  if (!right.valid()) {
358  from = right.from;
359  to = right.to;
360  return *this;
361  }
362  if (to < right.from || from > right.to) {
363  if (from == to) {
364  from = right.from;
365  to = right.to;
366  } else {
367  T t = to;
368  to = from;
369  from = t;
370  }
371  } else {
372  if (to < right.to) {
373  to = right.to;
374  }
375  if (from > right.from) {
376  from = right.from;
377  }
378  }
379  return *this;
380  }
381 
382  template<typename T>
383  inline bool AMRange<T>::operator==(const AMRange<T> &right) const
384  {
385  return (from == right.from && to == right.to);
386  }
387 
388  template<typename T>
389  inline bool AMRange<T>::operator!=(const AMRange<T> &right) const
390  {
391  return (from != right.from || to != right.to);
392  }
393 
394 
395  template<typename T>
396  inline bool AMRange<T>::valid() const
397  {
398  return (to >= from);
399  }
400 
401  template<typename T>
402  inline bool AMRange<T>::in(T num) const
403  {
404  return ((num >= from) && (num < to));
405  }
406 
407  template<typename T>
408  inline bool AMRange<T>::empty() const
409  {
410  return to == from;
411  }
412 
413  template<typename T>
414  inline bool AMRange<T>::nonEmpty() const
415  {
416  return to > from;
417  }
418 
419  template<typename T>
420  inline bool AMRange<T>::in(const AMRange<T> &_rng) const
421  {
422  return ((_rng.from >= from) && (_rng.to <= to) && (_rng.from < _rng.to));
423  }
424 
425  template<typename T>
426  inline AMRange<T> operator+(const AMRange<T> &left, const AMRange<T> &right)
427  {
428  AMRange<T> r = left;
429  r += right;
430  return r;
431  }
432 
433  template<typename T>
434  inline AMRange<T> operator-(const AMRange<T> &left, const AMRange<T> &right)
435  {
436  AMRange<T> r = left;
437  r -= right;
438  return r;
439  }
440 
441  template<typename T>
442  inline AMRange<T> intersect(const AMRange<T> &left, const AMRange<T> &right)
443  {
444  AMRange<T> r = left;
445  r.intersect(right);
446  return r;
447  }
448 
449  template<typename T>
450  bool isPacked(const std::set<AMRange<T> > &s)
451  {
452  typename std::set<AMRange<T> >::iterator it = s.begin();
453  if (it == s.end()) {
454  return true;
455  }
456  typename std::set<AMRange<T> >::iterator itn = it;
457  if (!itn->valid()) {
458  return false;
459  }
460  itn++;
461  while (itn != s.end()) {
462  if (itn->from > it->to) {
463  if (!itn->valid()) {
464  return false;
465  }
466  it = itn;
467  itn++;
468  continue;
469  }
470  return false;
471  }
472  return true;
473  }
474 
475  template<typename T>
476  bool valid(const std::set<AMRange<T> > &s)
477  {
478  for(typename std::set<AMRange<T> >::iterator it = s.begin(); it != s.end(); it++) {
479  if (!it->valid()) {
480  return false;
481  }
482  }
483  return true;
484  }
485 
486  template<typename T>
487  std::set<AMRange<T> > pack(const std::set<AMRange<T> > &s)
488  {
489  AMRange<T> r;
490  std::set<AMRange<T> > result;
491  bool start = true;
492  typename std::set<AMRange<T> >::iterator it = s.begin();
493 
494  do {
495  do {
496  if (it == s.end()) {
497  if (!start) {
498  result.insert(r);
499  }
500  return result;
501  }
502  if (it->valid()) {
503  break;
504  }
505  it++;
506  } while (1);
507 
508  if (start) {
509  r = *it;
510  start = false;
511  continue;
512  }
513  AMRange<T> rx = r + *it;
514  if (rx.valid()) {
515  r = rx;
516  } else {
517  result.insert(r);
518  r = *it;
519  }
520  it++;
521  } while(1);
522  }
523 
524  template<typename T>
525  std::set<AMRange<T> > operator+(const std::set<AMRange<T> > &left, const std::set<AMRange<T> > &right)
526  {
527  std::set<AMRange<T> > result = left;
528  std::merge(left.begin(), left.end(),
529  right.begin(), right.end(),
530  std::inserter(result, result.begin()));
531  result = pack(result);
532  return result;
533  }
534 
535  template<typename T>
536  std::set<AMRange<T> > operator-(const std::set<AMRange<T> > &left, const std::set<AMRange<T> > &right)
537  {
538  if (left.size() == 0) {
539  return std::set<AMRange<T> >();
540  }
541  if (right.size() == 0) {
542  return left;
543  }
544  std::set<AMRange<T> > ls = pack(left);
545  std::set<AMRange<T> > rs = pack(right);
546  std::set<AMRange<T> > result;
547  typename std::set<AMRange<T> >::iterator lit = ls.begin();
548  typename std::set<AMRange<T> >::iterator rit = rs.begin();
549  AMRange<int> r = *lit;
550  while (1) {
551  if (lit != ls.end()) {
552  if (rit != rs.end()) {
553  AMRange<T> tr = r - *rit;
554  if (!tr.valid()) {
555  AMRange ir(r.from, rit->from);
556  if (ir.nonEmpty()) {
557  result.insert(ir);
558  }
559  r.from = rit->to;
560  } else {
561  r = tr;
562  }
563  if (lit->to > rit->to) {
564  rit++;
565  } else {
566  lit++;
567  if (lit != ls.end()) {
568  if (r.nonEmpty()) {
569  result.insert(r);
570  }
571  r = *lit;
572  }
573  }
574  } else {
575  lit++;
576  if (lit != ls.end()) {
577  if (r.nonEmpty()) {
578  result.insert(r);
579  }
580  r = *lit;
581  }
582  }
583  } else {
584  if (rit != rs.end()) {
585  rit++;
586  } else {
587  break;
588  }
589  }
590  }
591  if (r.nonEmpty()) {
592  result.insert(r);
593  }
594  return result;
595  }
596 
597  template<typename T>
598  std::set<AMRange<T> > operator+(const AMRange<T> &left, const std::set<AMRange<T> > &right)
599  {
600  std::set<AMRange<T> > result = right;
601  result.insert(left);
602  result = pack(result);
603  return result;
604  }
605  template<typename T>
606  std::set<AMRange<T> > operator-(const AMRange<T> &left, const std::set<AMRange<T> > &right)
607  {
608  std::set<AMRange<T> > ls = {left};
609  return ls - right;
610  }
611  template<typename T>
612  std::set<AMRange<T> > operator+(const std::set<AMRange<T> > &left, const AMRange<T> &right)
613  {
614  std::set<AMRange<T> > result = left;
615  result.insert(right);
616  result = pack(result);
617  return result;
618  }
619  template<typename T>
620  std::set<AMRange<T> > operator-(const std::set<AMRange<T> > &left, const AMRange<T> &right)
621  {
622  std::set<AMRange<T> > rs = {right};
623  return left - rs;
624  }
625 }
626 
629 #endif //AMCORE_AMRANGE_H
AMCore::AMRange::operator==
bool operator==(const AMRange &right) const
comparison operator Tests both bounds for equality.
Definition: AMRange.h:383
AMCore::operator+
AMRange< T > operator+(const AMRange< T > &left, const AMRange< T > &right)
plus operator Cut part of range by intersect with right operand. If right range is inside left,...
Definition: AMRange.h:426
AMCore::AMRange::operator+=
AMRange & operator+=(const AMRange &right)
plus operator Cut part of range by intersect with right operand. If right range is inside left,...
Definition: AMRange.h:352
AMCore::AMRange::operator!=
bool operator!=(const AMRange &right) const
comparison operator If at least one bound not equalt to rught bound.
Definition: AMRange.h:389
AMCore::AMRange
Range and set of range operations.
Definition: AMRange.h:34
AMCore::intersect
AMRange< T > intersect(const AMRange< T > &left, const AMRange< T > &right)
intersect Intersection with right interval If ranges are in disjunction, returnned rage is empty
Definition: AMRange.h:442
AMCore::operator-
AMRange< T > operator-(const AMRange< T > &left, const AMRange< T > &right)
minus operator Cut part of range by intersect with right operand. If ranges are in disjunction,...
Definition: AMRange.h:434
AMCore::AMRange::operator-=
AMRange & operator-=(const AMRange &right)
minus operator Cut part of range by intersect with right operand. If ranges are in disjunction,...
Definition: AMRange.h:308
AMCore::AMRange::to
T to
right bound
Definition: AMRange.h:44
AMCore::AMRange::from
T from
left bound
Definition: AMRange.h:40
AMCore::AMRange::nonEmpty
bool nonEmpty() const
test for validity and empty Simply checks that from bound > to bound
Definition: AMRange.h:414
AMCore::AMRange::valid
bool valid() const
test for validity Simply checks that from bound >= to bound
Definition: AMRange.h:396
AMCore::AMRange::AMRange
AMRange()
empty constructor Uses T() for init bounds.
Definition: AMRange.h:283
AMCore::AMRange::operator<
bool operator<(const AMRange &right) const
less operator Used namely for std::set container
Definition: AMRange.h:297
AMCore::valid
bool valid(const std::set< AMRange< T > > &s)
valid test Set of ranges is valid when all range in are valid
Definition: AMRange.h:476
AMCore::AMRange::in
bool in(T num) const
check that number is inside Remember that interval is open from right, so if num == to,...
Definition: AMRange.h:402
AMCore::AMRange::intersect
AMRange & intersect(const AMRange &right)
intersect Intersection with right interval If ranges are in disjunction, range become empty
Definition: AMRange.h:337
AMCore::pack
std::set< AMRange< T > > pack(const std::set< AMRange< T > > &s)
pack a set of ranges Set of ranges is packed when, ranges has not intersections. E....
Definition: AMRange.h:487
AMCore::isPacked
bool isPacked(const std::set< AMRange< T > > &s)
packed test Set of ranges is packed when, ranges has not intersections. E.q. Second range starts abov...
Definition: AMRange.h:450
AMCore::AMRange::empty
bool empty() const
test for empty Simply checks that from bound == to bound
Definition: AMRange.h:408