[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

random_access_set.hxx VIGRA

1 /************************************************************************/
2 /* */
3 /* Copyright 2014 by Thorsten Beier and Ullrich Koethe */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35 
36 
37 //! @cond Doxygen_Suppress
38 #pragma once
39 #ifndef VIGRA_RANDOM_ACCESS_SET_HXX
40 #define VIGRA_RANDOM_ACCESS_SET_HXX
41 
42 #include <vector>
43 #include <algorithm>
44 #include <utility>
45 
46 namespace vigra {
47 
48 /// set with O(n) insert and O(1) access
49 ///
50 /// \tparam Key key and value type of the set
51 /// \tparam Alloc allocator of the set
52 /// RandomAccessSet has the same interface as std::set.
53 /// In addition, there is operator[].
54 /// \warning Values in set must not be changend through the mutable iterator
55 /// because doing so would potentially change the order of the values
56 /// \\ingroup datastructures
57 template<class Key,class Compare=std::less<Key>,class Alloc=std::allocator<Key> >
58 class RandomAccessSet {
59 private:
60  /// type of the underlying vector
61  typedef std::vector<Key,Alloc> VectorType;
62 
63 public:
64  // typedefs
65  /// key type of the set
66  typedef Key key_type;
67  /// value type of the set
68  typedef Key ValueType;
69  /// value type of the set
70  typedef Key value_type;
71  /// comperator
72  typedef Compare key_compare;
73  /// value comperator
74  typedef Compare value_compare;
75  /// acclocator
76  typedef Alloc allocator_type;
77  /// const reference type
78  typedef typename Alloc::const_reference const_reference;
79  /// iterator type
80  typedef typename VectorType::iterator iterator;
81  /// const iterator type
82  typedef typename VectorType::const_iterator const_iterator;
83  /// size type
84  typedef typename VectorType::size_type size_type;
85  /// difference type
86  typedef typename VectorType::difference_type difference_type;
87  /// const pointer type
88  typedef typename VectorType::const_pointer const_pointer;
89  /// const reverse iterator
90  typedef typename VectorType::const_reverse_iterator const_reverse_iterator;
91 
92  // memeber functions:
93  // constructor
94  RandomAccessSet(const size_t, const Compare& compare=Compare(), const Alloc& alloc=Alloc());
95  RandomAccessSet(const Compare& compare=Compare(), const Alloc& alloc=Alloc());
96  template <class InputIterator>
97  RandomAccessSet(InputIterator, InputIterator, const Compare& compare =Compare(), const Alloc & alloc=Alloc());
98  RandomAccessSet(const RandomAccessSet&);
99 
100  // operator=
101  RandomAccessSet& operator=(const RandomAccessSet &);
102  // operator[]
103  const value_type& operator[](const size_type) const;
104  // iterators
105  const_iterator begin() const;
106  const_iterator end() const;
107  const_iterator rbegin() const;
108  const_iterator rend() const;
109 
110  iterator begin();
111  iterator end();
112  iterator rbegin();
113  iterator rend();
114  bool empty() const;
115  size_type size() const;
116  size_type max_size() const;
117  std::pair< const_iterator,bool> insert(const value_type&);
118  template <class InputIterator>
119  void insert(InputIterator, InputIterator);
120  const_iterator insert(const_iterator , const value_type&);
121  void erase(iterator position);
122  size_type erase(const key_type& );
123  void erase( const_iterator, const_iterator);
124  void swap(RandomAccessSet&);
125  void clear();
126  key_compare key_comp() const;
127  value_compare value_comp() const;
128  const_iterator find(const key_type&) const;
129  iterator find(const key_type&);
130  size_type count(const key_type&) const;
131  const_iterator lower_bound(const key_type&) const;
132  const_iterator upper_bound(const key_type&) const;
133  std::pair<const_iterator,const_iterator> equal_range(const key_type&) const;
134  iterator lower_bound(const key_type&) ;
135  iterator upper_bound(const key_type&) ;
136  std::pair<iterator,iterator> equal_range(const key_type&) ;
137  allocator_type get_allocator() const;
138 
139  // std vector functions
140  void reserve(const size_t size){
141  vector_.reserve(size);
142  }
143  size_t capacity()const{
144  return vector_.capacity();
145  }
146 
147  template<class SET>
148  void assignFromSet(const SET & set){
149  vector_.assign(set.begin(),set.end());
150  }
151 
152 private:
153  std::vector<Key> vector_;
154  Compare compare_;
155 };
156 
157 /// constructor
158 /// \param reserveSize reserve /allocate space
159 /// \param compare comperator
160 /// \param alloc allocator
161 template<class Key, class Compare, class Alloc>
162 inline
163 RandomAccessSet<Key,Compare,Alloc>::RandomAccessSet
164 (
165  const size_t reserveSize,
166  const Compare& compare,
167  const Alloc& alloc
168 )
169 : vector_(alloc),
170  compare_(compare) {
171  vector_.reserve(reserveSize);
172 }
173 
174 /// const access values
175 /// \param index index of the value in the set
176 /// \return value / key at the position index
177 template<class Key, class Compare, class Alloc>
178 inline const typename RandomAccessSet<Key,Compare,Alloc>::value_type&
179 RandomAccessSet<Key,Compare,Alloc>::operator[]
180 (
181  const typename RandomAccessSet<Key,Compare,Alloc>::size_type index
182 ) const
183 {
184  return vector_[index];
185 }
186 
187 /// constructor
188 /// \param compare comperator
189 /// \allloc allocator
190 template<class Key, class Compare, class Alloc>
191 inline
192 RandomAccessSet<Key,Compare,Alloc>::RandomAccessSet
193 (
194  const Compare& compare,
195  const Alloc& alloc
196 )
197 : vector_(alloc),
198  compare_(compare)
199 {}
200 
201 /// constructor
202 /// \tparam InputIterator (key/value) input iterator
203 /// \param beginInput
204 /// \param endInput
205 template<class Key, class Compare, class Alloc>
206 template <class InputIterator>
207 inline
208 RandomAccessSet<Key,Compare,Alloc>::RandomAccessSet
209 (
210  InputIterator beginInput,
211  InputIterator endInput,
212  const Compare& compare,
213  const Alloc& alloc
214 )
215 : vector_(alloc),
216  compare_(compare)
217 {
218  while(beginInput!=endInput) {
219  this->insert(*beginInput);
220  ++beginInput;
221  }
222 }
223 
224 /// copy constructor
225 /// \param src other random access set
226 template<class Key, class Compare, class Alloc>
227 inline
228 RandomAccessSet<Key,Compare,Alloc>::RandomAccessSet
229 (
230  const RandomAccessSet<Key,Compare,Alloc>& src
231 )
232 : vector_(src.vector_),
233  compare_(src.compare_) {
234 }
235 
236 /// assignment operator
237 /// \param src other random access set
238 template<class Key, class Compare, class Alloc>
239 inline RandomAccessSet<Key,Compare,Alloc>&
240 RandomAccessSet<Key,Compare,Alloc>::operator=
241 (
242  const RandomAccessSet<Key,Compare,Alloc> & src
243 )
244 {
245  if(this!=&src) {
246  vector_=src.vector_;
247  compare_=src.compare_;
248  }
249  return *this;
250 }
251 
252 /// const begin iterator
253 /// \returns begin iterator
254 template<class Key, class Compare, class Alloc>
255 inline typename RandomAccessSet<Key,Compare,Alloc>::const_iterator
256 RandomAccessSet<Key,Compare,Alloc>::begin() const
257 {
258  return vector_.begin();
259 }
260 
261 /// const end iterator
262 /// \returns end iterator
263 template<class Key, class Compare, class Alloc>
264 inline typename RandomAccessSet<Key,Compare,Alloc>::const_iterator
265 RandomAccessSet<Key,Compare,Alloc>::end() const
266 {
267  return vector_.end();
268 }
269 /// reverse const begin iterator
270 /// \returns reverse begin iterator
271 template<class Key, class Compare, class Alloc>
272 inline typename RandomAccessSet<Key,Compare,Alloc>::const_iterator
273 RandomAccessSet<Key,Compare,Alloc>::rbegin() const
274 {
275  return vector_.rbegin();
276 }
277 
278 /// reverse const end iterator
279 /// \param reverse end iterator
280 template<class Key, class Compare, class Alloc>
281 inline typename RandomAccessSet<Key,Compare,Alloc>::const_iterator
282 RandomAccessSet<Key,Compare,Alloc>::rend() const
283 {
284  return vector_.rend();
285 }
286 
287 /// begin iterator
288 /// \param begin iterator
289 template<class Key, class Compare, class Alloc>
290 inline typename RandomAccessSet<Key,Compare,Alloc>::iterator
291 RandomAccessSet<Key,Compare,Alloc>::begin()
292 {
293  return vector_.begin();
294 }
295 
296 /// end iterator
297 /// \param end iterator
298 template<class Key, class Compare, class Alloc>
299 inline typename RandomAccessSet<Key,Compare,Alloc>::iterator
300 RandomAccessSet<Key,Compare,Alloc>::end()
301 {
302  return vector_.end();
303 }
304 
305 /// reverse begin iterator
306 /// \param reverse begin iterator
307 template<class Key, class Compare, class Alloc>
308 inline typename RandomAccessSet<Key,Compare,Alloc>::iterator
309 RandomAccessSet<Key,Compare,Alloc>::rbegin()
310 {
311  return vector_.rbegin();
312 }
313 
314 /// reverse end iterator
315 /// \param reverse end iterator
316 template<class Key, class Compare, class Alloc>
317 inline typename RandomAccessSet<Key,Compare,Alloc>::iterator
318 RandomAccessSet<Key,Compare,Alloc>::rend()
319 {
320  return vector_.rend();
321 }
322 
323 /// query if the set is empty
324 /// \return true if empty
325 template<class Key, class Compare, class Alloc>
326 inline bool
327 RandomAccessSet<Key,Compare,Alloc>::empty() const
328 {
329  return vector_.empty();
330 }
331 
332 /// number of elements of the set
333 /// \returns number of elements in the set
334 template<class Key, class Compare, class Alloc>
335 inline typename RandomAccessSet<Key,Compare,Alloc>::size_type
336 RandomAccessSet<Key,Compare,Alloc>::size() const
337 {
338  return vector_.size();
339 }
340 
341 /// maximum size of the underlying container
342 /// \return the maximum size
343 template<class Key, class Compare, class Alloc>
344 inline typename RandomAccessSet<Key,Compare,Alloc>::size_type
345 RandomAccessSet<Key,Compare,Alloc>::max_size() const
346 {
347  return vector_.max_size();
348 }
349 
350 // modifiers
351 /// insert an element into the set
352 ///
353 /// \param value element to insert
354 /// \return pair in which the first entry is an iterator pointing to inserted
355 /// value and the second entry is true iff the value had not already been in the
356 /// set
357 template<class Key, class Compare, class Alloc>
358 inline std::pair<typename RandomAccessSet<Key,Compare,Alloc>::const_iterator,bool>
359 RandomAccessSet<Key,Compare,Alloc>::insert
360 (
361  const typename RandomAccessSet<Key,Compare,Alloc>::value_type& value
362 ) {
363  bool found(true);
364  iterator i(lower_bound(static_cast<Key>(value)));
365  if(i == end() || compare_(static_cast<Key>(value), *i)) {
366  i = vector_.insert(i, static_cast<Key>(value));
367  found = false;
368  }
369  return std::make_pair(i, !found);
370 }
371 
372 /// insert a sequence of elements
373 ///
374 /// \param first iterator to the first element
375 /// \param last iterator to the last element
376 template<class Key, class Compare, class Alloc>
377 template <class InputIterator>
378 inline void
379 RandomAccessSet<Key,Compare,Alloc>::insert
380 (
381  InputIterator first,
382  InputIterator last
383 )
384 {
385  while(first!=last) {
386  this->insert(*first);
387  ++first;
388  }
389 }
390 
391 /// insert a sequence of elements with a hint for the position
392 ///
393 /// \param position iterator to the position
394 /// \param value element to insert
395 template<class Key, class Compare, class Alloc>
396 inline typename RandomAccessSet<Key,Compare,Alloc>::const_iterator
397 RandomAccessSet<Key,Compare,Alloc>::insert
398 (
399  typename RandomAccessSet<Key,Compare,Alloc>::const_iterator position,
400  const typename RandomAccessSet<Key,Compare,Alloc>::value_type& value
401 )
402 {
403  if((position == begin() || this->operator()(*(position-1),value))
404  && (position == end() || this->operator()(value, *position))) {
405  return vector_.insert(position, value);
406  }
407  return insert(value).first;
408 }
409 
410 /// erase an element
411 /// \param position iterator to the position
412 template<class Key, class Compare, class Alloc>
413 inline void
414 RandomAccessSet<Key,Compare,Alloc>::erase
415 (
416  typename RandomAccessSet<Key,Compare,Alloc>::iterator position
417 )
418 {
419  vector_.erase(position);
420 }
421 
422 /// erease and element
423 /// \param x element
424 template<class Key, class Compare, class Alloc>
425 inline typename RandomAccessSet<Key,Compare,Alloc>::size_type
426 RandomAccessSet<Key,Compare,Alloc>::erase
427 (
428  const typename RandomAccessSet<Key,Compare,Alloc>::key_type& x
429 )
430 {
431  iterator i =find(x);
432  if(i!=vector_.end())
433  {
434  erase(i);
435  return 1;
436  }
437  return 0;
438 }
439 
440 /// erase a sequence of elements
441 /// \param first iterator to the beginning of the sequence to erase
442 /// \param last iterator to the end of the sequence to erase
443 template<class Key, class Compare, class Alloc>
444 inline void
445 RandomAccessSet<Key,Compare,Alloc>::erase
446 (
447  const typename RandomAccessSet<Key,Compare,Alloc>::const_iterator first,
448  const typename RandomAccessSet<Key,Compare,Alloc>::const_iterator last
449 )
450 {
451  vector_.erase(first,last);
452 }
453 
454 /// swap random access sets
455 /// \param rhs set to swap with
456 template<class Key, class Compare, class Alloc>
457 inline void
458 RandomAccessSet<Key,Compare,Alloc>::swap
459 (
460  RandomAccessSet<Key,Compare,Alloc>& rhs
461 )
462 {
463  vector_.swap(rhs.vector_);
464  std::swap(compare_, rhs.compare_);
465 }
466 
467 /// clear the set
468 ///
469 /// erases all elements
470 template<class Key, class Compare, class Alloc>
471 inline void
472 RandomAccessSet<Key,Compare,Alloc>::clear()
473 {
474  vector_.clear();
475 }
476 
477 /// key comparator
478 /// \return key comparator
479 template<class Key, class Compare, class Alloc>
480 inline typename RandomAccessSet<Key,Compare,Alloc>::key_compare
481 RandomAccessSet<Key,Compare,Alloc>::key_comp() const
482 {
483  return compare_;
484 }
485 
486 /// value comparator
487 /// \return value comparator
488 template<class Key, class Compare, class Alloc>
489 inline typename RandomAccessSet<Key,Compare,Alloc>::value_compare
490 RandomAccessSet<Key,Compare,Alloc>::value_comp() const
491 {
492  return compare_;
493 }
494 
495 /// find an element
496 /// \param value element
497 /// \return const_iterator to the position where element was found or end
498 /// iterator if the element was not found
499 template<class Key, class Compare, class Alloc>
500 inline typename RandomAccessSet<Key,Compare,Alloc>::const_iterator
501 RandomAccessSet<Key,Compare,Alloc>::find
502 (
503  const typename RandomAccessSet<Key,Compare,Alloc>::key_type& value
504 ) const
505 {
506  const_iterator i(lower_bound(value));
507  if (i != end() && compare_(value, *i))
508  {
509  i = end();
510  }
511  return i;
512 }
513 
514 /// find an element
515 /// \param value element
516 /// \return iterator to the position where the element was found or end
517 /// iterator if the element was not found
518 template<class Key, class Compare, class Alloc>
519 inline typename RandomAccessSet<Key,Compare,Alloc>::iterator
520 RandomAccessSet<Key,Compare,Alloc>::find
521 (
522  const typename RandomAccessSet<Key,Compare,Alloc>::key_type& value
523 )
524 {
525  iterator i(lower_bound(value));
526  if (i != end() && compare_(value, *i))
527  {
528  i = end();
529  }
530  return i;
531 }
532 
533 /// count elements
534 /// \param element
535 /// \return zero or one
536 template<class Key, class Compare, class Alloc>
537 inline typename RandomAccessSet<Key,Compare,Alloc>::size_type
538 RandomAccessSet<Key,Compare,Alloc>::count
539 (
540  const typename RandomAccessSet<Key,Compare,Alloc>::key_type& value
541 ) const
542 {
543  return find(value) != end() ? 1 : 0;
544 }
545 
546 /// lower bound
547 /// \param value
548 /// \return iterator to lower bound
549 template<class Key, class Compare, class Alloc>
550 inline typename RandomAccessSet<Key,Compare,Alloc>::const_iterator
551 RandomAccessSet<Key,Compare,Alloc>::lower_bound
552 (
553  const typename RandomAccessSet<Key,Compare,Alloc>::key_type& value
554 ) const
555 {
556  return std::lower_bound(vector_.begin(), vector_.end(), value, compare_);
557 }
558 
559 /// lower bound
560 /// \param value
561 /// \return iterator to lower bound
562 template<class Key, class Compare, class Alloc>
563 inline typename RandomAccessSet<Key,Compare,Alloc>::iterator
564 RandomAccessSet<Key,Compare,Alloc>::lower_bound
565 (
566  const typename RandomAccessSet<Key,Compare,Alloc>::key_type& value
567 )
568 {
569  return std::lower_bound(vector_.begin(), vector_.end(), value, compare_);
570 }
571 
572 /// upper bound
573 /// \param value
574 /// \return iterator to upper bound
575 template<class Key, class Compare, class Alloc>
576 inline typename RandomAccessSet<Key,Compare,Alloc>::const_iterator
577 RandomAccessSet<Key,Compare,Alloc>::upper_bound
578 (
579  const typename RandomAccessSet<Key,Compare,Alloc>::key_type& value
580 ) const
581 {
582  return std::upper_bound(vector_.begin(), vector_.end(), value, compare_);
583 }
584 
585 /// upper bound
586 /// \param value
587 /// \return iterator to upper bound
588 template<class Key, class Compare, class Alloc>
589 inline typename RandomAccessSet<Key,Compare,Alloc>::iterator
590 RandomAccessSet<Key,Compare,Alloc>::upper_bound
591 (
592  const typename RandomAccessSet<Key,Compare,Alloc>::key_type& value
593 )
594 {
595  return std::upper_bound(vector_.begin(), vector_.end(), value, compare_);
596 }
597 
598 /// equal range
599 /// \param value
600 /// \return iterator pair to lower equal range
601 template<class Key, class Compare, class Alloc>
602 inline std::pair<typename RandomAccessSet<Key,Compare,Alloc>::const_iterator,typename RandomAccessSet<Key,Compare,Alloc>::const_iterator>
603 RandomAccessSet<Key,Compare,Alloc>::equal_range
604 (
605  const typename RandomAccessSet<Key,Compare,Alloc>::key_type& value
606 ) const
607 {
608  return std::equal_range(vector_.begin(), vector_.end(), value, compare_);
609 }
610 
611 /// equal range
612 /// \param value
613 /// \return iterator pair to lower equal range
614 template<class Key, class Compare, class Alloc>
615 inline std::pair<typename RandomAccessSet<Key,Compare,Alloc>::iterator,typename RandomAccessSet<Key,Compare,Alloc>::iterator>
616 RandomAccessSet<Key,Compare,Alloc>::equal_range
617 (
618  const typename RandomAccessSet<Key,Compare,Alloc>::key_type& value
619 )
620 {
621  return std::equal_range(vector_.begin(), vector_.end(), value, compare_);
622 }
623 /// allocators
624 /// \return allocator
625 template<class Key, class Compare, class Alloc>
626 inline typename RandomAccessSet<Key,Compare,Alloc>::allocator_type
627 RandomAccessSet<Key,Compare,Alloc>::get_allocator() const
628 {
629  return vector_.get_allocator();
630 }
631 
632 } // namespace vigra
633 
634 #endif // VIGRA_RANDOM_ACCESS_SET_HXX
635 //! @endcond

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.11.1 (Fri May 19 2017)