TPIE

2362a60
tiny.h
1 // -*- mode: c++; tab-width: 4; indent-tabs-mode: t; eval: (progn (c-set-style "stroustrup") (c-set-offset 'innamespace 0)); -*-
2 // vi:set ts=4 sts=4 sw=4 noet :
3 // Copyright 2015, The TPIE development team
4 //
5 // This file is part of TPIE.
6 //
7 // TPIE is free software: you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License as published by the
9 // Free Software Foundation, either version 3 of the License, or (at your
10 // option) any later version.
11 //
12 // TPIE is distributed in the hope that it will be useful, but WITHOUT ANY
13 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 // License for more details.
16 //
17 // You should have received a copy of the GNU Lesser General Public License
18 // along with TPIE. If not, see <http://www.gnu.org/licenses/>
19 #ifndef __TPIE_TINY_H__
20 #define __TPIE_TINY_H__
21 
22 #include <algorithm>
23 #include <stdexcept>
24 #include <tpie/config.h>
25 
26 namespace tpie {
27 namespace tiny {
28 
35 template <typename T, typename Comp>
36 void sort(T start, T end, Comp comp=Comp()) {
37  for (T i = start; i != end; ++i)
38  std::rotate(std::upper_bound(start, i, *i, comp), i, std::next(i));
39 }
40 
47 template <typename T>
48 void sort(T start, T end) {
49  for (T i = start; i != end; ++i)
50  std::rotate(std::upper_bound(start, i, *i), i, std::next(i));
51 }
52 
53 namespace bits {
58 public:
59  template <typename T>
60  const T & operator()(const T & x) const {return x;}
61 };
62 
66 template <typename A, typename B>
67 class PairExtract {
68 public:
69  template <typename T>
70  const T & operator()(const T & x) const {return x;}
71  const A & operator()(const std::pair<A, B> & x) const {return x.first;}
72 };
73 
78  template <typename Inner>
79  struct type {
80  static const bool multi=false;
81  typedef typename Inner::iterator iterator;
82  typedef std::pair<iterator, bool> result;
83 
84  template <typename Comp>
85  static result handle(Inner & inner, const Comp & comp) {
86  iterator fend=std::prev(inner.end());
87  iterator i=std::lower_bound(inner.begin(), fend, *fend, comp);
88  if (i != fend && !comp(*fend, *i)) {
89  inner.pop_back();
90  return std::make_pair(i, false);
91  }
92  std::rotate(i, fend, std::next(fend));
93  return std::make_pair(i, true);
94  }
95  };
96 };
97 
102  template <typename Inner>
103  struct type {
104  static const bool multi=true;
105  typedef typename Inner::iterator iterator;
106  typedef iterator result;
107 
108  template <typename Comp>
109  static result handle(Inner & inner, const Comp &) {
110  iterator y=std::upper_bound(inner.begin(), inner.end()-1, inner.back());
111  std::rotate(y, inner.end()-1, inner.end());
112  return y;
113  }
114  };
115 };
116 
117 } //namespace bits
131 template <typename T,
132  typename Key,
133  typename KeyExtract,
134  typename Comp,
135  typename Alloc,
136  typename InsertHelp>
137 class set_impl {
138 protected:
139  typedef std::vector<T, Alloc> Inner;
140  typedef typename InsertHelp::template type<Inner> IH;
141 public:
142  typedef T value_type;
143  typedef Key key_type;
144  typedef typename Inner::iterator iterator;
145  typedef typename Inner::const_iterator const_iterator;
146  typedef typename Inner::reverse_iterator reverse_iterator;
147  typedef typename Inner::const_reverse_iterator const_reverse_iterator;
148  typedef Comp key_compare;
149  typedef Alloc allocator_type;
150  typedef typename IH::result insert_result;
151 
152  struct value_compare {
153  template <typename L, typename R>
154  bool operator()(const L & l, const R & r) const {
155  return comp(extract(l), extract(r));
156  }
157  Comp comp;
158  KeyExtract extract;
159  value_compare(Comp comp): comp(comp) {}
160  };
161 
165  set_impl(): comp(Comp()) {}
166 
170  explicit set_impl(const Comp & comp, const Alloc & alloc=Alloc()): comp(comp), inner(alloc) {}
171 
175  explicit set_impl(const Alloc & alloc): inner(alloc) {}
176 
180  set_impl(const set_impl & other): comp(other.comp), inner(other.inner) {}
181 
185  set_impl(const set_impl & other, const Alloc & alloc): comp(other.comp), inner(other.inner, alloc) {}
186 
190  set_impl(set_impl && other): comp(std::move(other.comp)), inner(std::move(other.inner)) {}
191 
195  set_impl(set_impl && other, const Alloc & alloc): comp(std::move(other.comp)), inner(std::move(other.inner), alloc) {}
196 
200  template< class InputIterator >
201  set_impl(InputIterator first, InputIterator last,
202  const Comp& comp = Comp(),
203  const Alloc& alloc = Alloc()): comp(comp), inner(alloc) {
204  insert(first, last);
205  }
206 
210  set_impl( std::initializer_list<value_type> init,
211  const Comp& comp = Comp(),
212  const Alloc& alloc = Alloc() ): comp(comp), inner(alloc) {
213  insert(init);
214  }
215 
219  iterator begin() noexcept {return inner.begin();}
220 
224  const_iterator begin() const noexcept {return inner.cbegin();}
225 
229  const_iterator cbegin() const noexcept {return inner.cbegin();}
230 
234  reverse_iterator rbegin() noexcept {return inner.rbegin();}
235 
239  const_reverse_iterator rbegin() const noexcept {return inner.rbegin();}
240 
244  const_reverse_iterator crbegin() const noexcept {return inner.rbegin();}
245 
249  iterator end() noexcept {return inner.end();}
250 
254  const_iterator end() const noexcept {return inner.cend();}
255 
259  const_iterator cend() const noexcept {return inner.cend();}
260 
265  reverse_iterator rend() noexcept {return inner.rend();}
266 
271  const_reverse_iterator rend() const noexcept {return inner.rend();}
272 
277  const_reverse_iterator crend() const noexcept {return inner.rend();}
278 
283  bool empty() const noexcept {return inner.empty();}
284 
288  size_t size() const noexcept {return inner.size();}
289 
295  size_t max_size() const noexcept {return inner.max_size();}
296 
300  void clear() {inner.clear(); }
301 
306  iterator erase(iterator pos) {
307  std::rotate(pos, std::next(pos), inner.end());
308  inner.pop_back();
309  return pos;
310  }
311 
317  iterator erase(iterator first, iterator last) {
318  std::rotate(first, last, inner.end());
319  inner.resize(size() - (last-first));
320  return begin();
321  }
322 
327  size_t erase(const Key & key) {
328  auto x=equal_range(key);
329  erase(x.first, x.second);
330  return x.second - x.first;
331  }
332 
338  void swap(set_impl & o) {
339  std::swap(comp, o.comp);
340  std::swap(inner, o.inner);
341  }
342 
347  iterator find(const Key & key) noexcept {
348  iterator x=lower_bound(key);
349  if (x == end() || comp(key, *x)) return end();
350  return x;
351  }
352 
357  const_iterator find(const Key & key) const noexcept {
358  const_iterator x=lower_bound(key);
359  if (x == end() || comp(key, *x)) return end();
360  return x;
361  }
362 
369  std::pair<iterator, iterator> equal_range(const Key & key) noexcept {
370  return std::equal_range(inner.begin(), inner.end(), key, comp);
371  }
372 
379  std::pair<const_iterator, const_iterator> equal_range(const Key & key) const noexcept {
380  return std::equal_range(inner.begin(), inner.end(), key, comp);
381  }
382 
387  iterator lower_bound(const Key & key) noexcept {
388  return std::lower_bound(inner.begin(), inner.end(), key, comp);
389  }
390 
395  const_iterator lower_bound(const Key & key) const noexcept {
396  return std::lower_bound(inner.begin(), inner.end(), key, comp);
397  }
398 
403  iterator upper_bound(const Key & key) noexcept {
404  return std::upper_bound(inner.begin(), inner.end(), key, comp);
405  }
406 
411  const_iterator upper_bound(const Key & key) const noexcept {
412  return std::upper_bound(inner.begin(), inner.end(), key, comp);
413  }
414 
419  key_compare key_comp() const noexcept {
420  return comp.comp;
421  }
422 
428  value_compare value_comp() const noexcept {
429  return comp;
430  }
431 
435  allocator_type get_allocator() const {
436  return inner.get_allocator();
437  }
438 
442  set_impl & operator=(const set_impl& other ) {
443  inner = other.inner;
444  comp = other.comp;
445  return *this;
446  }
447 
454  inner = std::move(other.inner);
455  comp = std::move(other.comp);
456  return *this;
457  }
458 
462  set_impl& operator=(std::initializer_list<value_type> ilist) {
463  clear();
464  insert(ilist);
465  return *this;
466  }
467 
471  friend bool operator==(const set_impl & lhs, const set_impl & rhs) {
472  return lhs.inner == rhs.inner;
473  }
474 
478  friend bool operator!=(const set_impl & lhs, const set_impl & rhs) {
479  return lhs.inner != rhs.inner;
480  }
481 
486  friend bool operator<(const set_impl & lhs, const set_impl & rhs) {
487  return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), lhs.comp);
488  }
489 
494  friend bool operator<=(const set_impl & lhs, const set_impl & rhs) {
495  return !std::lexicographical_compare(rhs.begin(), rhs.end(), lhs.begin(), lhs.end());
496 
497  }
498 
503  friend bool operator>(const set_impl & lhs, const set_impl & rhs) {
504  return std::lexicographical_compare(rhs.begin(), rhs.end(), lhs.begin(), lhs.end());
505  }
506 
511  friend bool operator>=(const set_impl & lhs, const set_impl & rhs) {
512  return !std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), lhs.comp);
513  }
514 
519  friend void swap(set_impl & lhs, set_impl & rhs) {lhs.swap(rhs);}
520 
521 
525  size_t count(const Key k) const noexcept {
526  if (IH::multi) {
527  auto x=equal_range(k);
528  return x.second - x.first;
529  } else {
530  auto x=lower_bound(k);
531  if (x == end() || comp(k, *x)) return 0;
532  return 1;
533  }
534  }
535 
545  insert_result insert(const T & t) {
546  inner.push_back(t);
547  return IH::handle(inner, comp);
548  }
549 
559  template <typename TT>
560  insert_result insert(TT && t) {
561  return emplace(std::forward<TT>(t));
562  }
563 
567  insert_result insert(const_iterator /*hint*/, const T & t) {
568  return insert(t);
569  }
570 
574  template <typename TT>
575  insert_result insert(const_iterator /*hint*/, TT && t) {
576  return insert(std::forward<TT>(t));
577  }
578 
582  template <class InputIt>
583  void insert(InputIt first, InputIt last) {
584  inner.reserve(size() + last-first);
585  for (InputIt i=first; i != last; ++i)
586  insert(*i);
587  }
588 
592  void insert(std::initializer_list<value_type> list) {
593  insert(list.begin(), list.end());
594  }
595 
606  template <class... Args>
607  insert_result emplace(Args &&... args) {
608  inner.emplace_back(std::forward<Args>(args)...);
609  return IH::handle(inner, comp);
610  }
611 
615  template <class... Args>
616  insert_result emplace_hint(const_iterator /*hint*/, Args &&... args) {
617  return emplace(std::forward<Args>(args)...);
618  }
619 
626  void reserve(size_t new_cap) {inner.reserve(new_cap);}
627 
631  void shrink_to_fit() {inner.shrink_to_fit();}
632 
637  size_t capacity() const noexcept {return inner.capacity();}
638 protected:
639  value_compare comp;
640  std::vector<value_type, Alloc> inner;
641 };
642 
646 template <typename T,
647  typename Comp=std::less<T>,
648  typename Alloc=std::allocator<T> >
649 using set = set_impl<T, T, bits::IdentityExtract, Comp, Alloc, bits::SingleInsertHelp>;
650 
654 template <typename T,
655  typename Comp=std::less<T>,
656  typename Alloc=std::allocator<T> >
657 using multiset = set_impl<T, T, bits::IdentityExtract, Comp, Alloc, bits::MultiInsertHelp>;
658 
662 template <typename Key,
663  typename T,
664  typename Comp=std::less<Key>,
665  typename Alloc=std::allocator<std::pair<Key, T> > >
666 using multimap = set_impl<std::pair<Key, T>, T, bits::PairExtract<Key, T>, Comp, Alloc, bits::MultiInsertHelp>;
667 
671 template <typename Key,
672  typename T,
673  typename Comp=std::less<Key>,
674  typename Alloc=std::allocator<std::pair<Key, T> >
675  > class map: public set_impl<std::pair<Key, T>, T, bits::PairExtract<Key, T>, Comp, Alloc, bits::SingleInsertHelp> {
676 private:
678 public:
679 
680  map() {}
681  explicit map(const Comp & comp, const Alloc & alloc = Alloc()) : P(comp, alloc) {}
682  explicit map(const Alloc & alloc) : P(alloc) {}
683  map(const map & other) : P(other) {}
684  map(const map & other, const Alloc & alloc) : P(other, alloc) {}
685  map(map && other) : P(other) {}
686  map(map && other, const Alloc & alloc) : P(std::move(other), alloc) {}
687  template< class InputIterator >
688  map(InputIterator first, InputIterator last,
689  const Comp& comp = Comp(),
690  const Alloc& alloc = Alloc()) : P(first, last, comp, alloc) {}
691  map(std::initializer_list<typename P::value_type> init,
692  const Comp& comp = Comp(),
693  const Alloc& alloc = Alloc()) : P(init, comp, alloc) {}
694 
695  //using P::P; we must explicity copy the constructors until VS supports this
696 
702  T & operator[](const Key & key) {
703  return this->emplace(key, T()).first->second;
704  }
705 
711  T & operator[](Key && key) {
712  return this->emplace(std::move(key), T()).first->second;
713  }
714 
720  T& at( const Key& key ) {
721  typename P::iterator x=P::lower_bound(key);
722  if (x == P::end() || P::comp(key, *x)) throw std::out_of_range("tiny::map::at");
723  return x->second;
724  }
725 
731  const T& at( const Key& key ) const {
732  typename P::const_iterator x=P::lower_bound(key);
733  if (x == P::end() || P::comp(key, *x)) throw std::out_of_range("tiny::map::at");
734  return x->second;
735  }
736 };
737 
738 } //namespace tiny
739 } //namespace tpie;
740 
741 #endif //__TPIE_TINY_H__
void sort(uncompressed_stream< T > &instream, uncompressed_stream< T > &outstream, Compare comp, progress_indicator_base &indicator)
Sort elements of a stream using the given STL-style comparator object.
Definition: sort.h:141
friend void swap(set_impl &lhs, set_impl &rhs)
Specializes the std::swap algorithm using adl.
Definition: tiny.h:519
size_t capacity() const noexcept
Returns the number of elements that the container has currently allocated space for.
Definition: tiny.h:637
friend bool operator<=(const set_impl &lhs, const set_impl &rhs)
true if the contents of the lhs are lexicographically less than or equal the contents of rhs...
Definition: tiny.h:494
friend bool operator>=(const set_impl &lhs, const set_impl &rhs)
true if the contents of the lhs are lexicographically greater than or equal the contents of rhs...
Definition: tiny.h:511
void shrink_to_fit()
Requests the removal of unused capacity.
Definition: tiny.h:631
void reserve(size_t new_cap)
Increase the capacity of the container to a value that's greater or equal to new_cap.
Definition: tiny.h:626
friend bool operator==(const set_impl &lhs, const set_impl &rhs)
true if the contents of the containers are equal, false otherwise.
Definition: tiny.h:471
set_impl & operator=(set_impl &&other)
Move assignment operator.
Definition: tiny.h:453
A std::map compatible map, useful when we do not have many elements (less then 512) ...
Definition: tiny.h:675
set_impl(std::initializer_list< value_type > init, const Comp &comp=Comp(), const Alloc &alloc=Alloc())
Constructs the container with the contents of the initializer list init.
Definition: tiny.h:210
const_reverse_iterator rbegin() const noexcept
Returns a reverse iterator to the first element of the reversed container.
Definition: tiny.h:239
const_reverse_iterator crend() const noexcept
Returns a reverse iterator to the element following the last element of the reversed container...
Definition: tiny.h:277
size_t erase(const Key &key)
Removes all elements with the key value key.
Definition: tiny.h:327
iterator find(const Key &key) noexcept
Finds an element with key equivalent to key.
Definition: tiny.h:347
set_impl & operator=(const set_impl &other)
Copy assignment operator.
Definition: tiny.h:442
iterator begin() noexcept
Returns an iterator to the first element of the container.
Definition: tiny.h:219
value_compare value_comp() const noexcept
Returns a function object that compares objects of type std::map::value_type (key-value pairs) by usi...
Definition: tiny.h:428
const_iterator find(const Key &key) const noexcept
Finds an element with key equivalent to key.
Definition: tiny.h:357
set_impl(const Comp &comp, const Alloc &alloc=Alloc())
Default constructor.
Definition: tiny.h:170
reverse_iterator rbegin() noexcept
Returns a reverse iterator to the first element of the reversed container.
Definition: tiny.h:234
size_t size() const noexcept
Returns the number of elements in the container, i.e.
Definition: tiny.h:288
const_iterator end() const noexcept
Returns an iterator to the element following the last element of the container.
Definition: tiny.h:254
Use the identity function on elements to extract the key.
Definition: tiny.h:57
set_impl(set_impl &&other, const Alloc &alloc)
Move constructor.
Definition: tiny.h:195
const_reverse_iterator crbegin() const noexcept
Returns a reverse iterator to the first element of the reversed container.
Definition: tiny.h:244
T & at(const Key &key)
Returns a reference to the mapped value of the element with key equivalent to key.
Definition: tiny.h:720
allocator_type get_allocator() const
Returns the allocator associated with the container.
Definition: tiny.h:435
const_iterator lower_bound(const Key &key) const noexcept
Returns an iterator pointing to the first element that is not less than key.
Definition: tiny.h:395
set_impl(const set_impl &other, const Alloc &alloc)
Copy constructor.
Definition: tiny.h:185
bool empty() const noexcept
Checks if the container has no elements, i.e.
Definition: tiny.h:283
friend bool operator!=(const set_impl &lhs, const set_impl &rhs)
true if the contents of the containers are not equal, false otherwise.
Definition: tiny.h:478
T & operator[](Key &&key)
Returns a reference to the value that is mapped to a key equivalent to key, performing an insertion i...
Definition: tiny.h:711
reverse_iterator rend() noexcept
Returns a reverse iterator to the element following the last element of the reversed container...
Definition: tiny.h:265
std::pair< iterator, iterator > equal_range(const Key &key) noexcept
Returns a range containing all elements with the given key in the container.
Definition: tiny.h:369
iterator erase(iterator first, iterator last)
Removes the elements in the range [first; last), which must be a valid range in *this.
Definition: tiny.h:317
const_iterator cbegin() const noexcept
Returns an iterator to the first element of the container.
Definition: tiny.h:229
iterator end() noexcept
Returns an iterator to the element following the last element of the container.
Definition: tiny.h:249
When inserting do not allow elements with equivalest keys.
Definition: tiny.h:77
set_impl(InputIterator first, InputIterator last, const Comp &comp=Comp(), const Alloc &alloc=Alloc())
Constructs the container with the contents of the range [first, last).
Definition: tiny.h:201
class implementing a tiny::set, tiny::multiset, and tiny::multimap.
Definition: tiny.h:137
const_iterator upper_bound(const Key &key) const noexcept
Returns an iterator pointing to the first element that is greater than key.
Definition: tiny.h:411
const_iterator begin() const noexcept
Returns an iterator to the first element of the container.
Definition: tiny.h:224
void clear()
Removes all elements from the container.
Definition: tiny.h:300
Extract the first element of a pair as the key.
Definition: tiny.h:67
std::pair< const_iterator, const_iterator > equal_range(const Key &key) const noexcept
Returns a range containing all elements with the given key in the container.
Definition: tiny.h:379
set_impl & operator=(std::initializer_list< value_type > ilist)
Replaces the contents with those identified by initializer list ilist.
Definition: tiny.h:462
insert_result emplace_hint(const_iterator, Args &&...args)
Do the same as emplace, and ignore the hint.
Definition: tiny.h:616
set_impl()
Default constructor.
Definition: tiny.h:165
insert_result insert(const_iterator, TT &&t)
Does the same as normal insert, we ignore the hint.
Definition: tiny.h:575
set_impl(set_impl &&other)
Move constructor.
Definition: tiny.h:190
When inserting allow elements with equivalest keys.
Definition: tiny.h:101
friend bool operator<(const set_impl &lhs, const set_impl &rhs)
true if the contents of the lhs are lexicographically less than the contents of rhs, false otherwise.
Definition: tiny.h:486
key_compare key_comp() const noexcept
Returns the function object that compares the keys, which is a copy of this container's constructor a...
Definition: tiny.h:419
set_impl(const Alloc &alloc)
Default constructor.
Definition: tiny.h:175
iterator upper_bound(const Key &key) noexcept
Returns an iterator pointing to the first element that is greater than key.
Definition: tiny.h:403
void swap(set_impl &o)
Exchanges the contents of the container with those of other.
Definition: tiny.h:338
T & operator[](const Key &key)
Returns a reference to the value that is mapped to a key equivalent to key, performing an insertion i...
Definition: tiny.h:702
insert_result insert(TT &&t)
Inserts element(s) into the container, if the container doesn't already contain an element with an eq...
Definition: tiny.h:560
insert_result emplace(Args &&...args)
Inserts a new element into the container by constructing it in-place with the given args if there is ...
Definition: tiny.h:607
insert_result insert(const T &t)
Inserts element(s) into the container, if the container doesn't already contain an element with an eq...
Definition: tiny.h:545
set_impl(const set_impl &other)
Copy constructor.
Definition: tiny.h:180
void insert(InputIt first, InputIt last)
Inserts elements from range [first, last).
Definition: tiny.h:583
const_iterator cend() const noexcept
Returns an iterator to the element following the last element of the container.
Definition: tiny.h:259
void insert(std::initializer_list< value_type > list)
Inserts elements from initializer list ilist.
Definition: tiny.h:592
size_t count(const Key k) const noexcept
Returns the number of elements with key k.
Definition: tiny.h:525
iterator erase(iterator pos)
Removes the element at pos.
Definition: tiny.h:306
insert_result insert(const_iterator, const T &t)
Does the same as normal insert, we ignore the hint.
Definition: tiny.h:567
const T & at(const Key &key) const
Returns a reference to the mapped value of the element with key equivalent to key.
Definition: tiny.h:731
size_t max_size() const noexcept
Returns the maximum number of elements the container is able to hold due to system or library impleme...
Definition: tiny.h:295
friend bool operator>(const set_impl &lhs, const set_impl &rhs)
true if the contents of the lhs are lexicographically greater than the contents of rhs...
Definition: tiny.h:503
iterator lower_bound(const Key &key) noexcept
Returns an iterator pointing to the first element that is not less than key.
Definition: tiny.h:387
const_reverse_iterator rend() const noexcept
Returns a reverse iterator to the element following the last element of the reversed container...
Definition: tiny.h:271