phdMesh  Version of the Day
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Groups
Setv.hpp
1 /*------------------------------------------------------------------------*/
2 /* phdMesh : Parallel Heterogneous Dynamic unstructured Mesh */
3 /* Copyright (2007) Sandia Corporation */
4 /* */
5 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */
6 /* license for use of this work by or on behalf of the U.S. Government. */
7 /* */
8 /* This library is free software; you can redistribute it and/or modify */
9 /* it under the terms of the GNU Lesser General Public License as */
10 /* published by the Free Software Foundation; either version 2.1 of the */
11 /* License, or (at your option) any later version. */
12 /* */
13 /* This library is distributed in the hope that it will be useful, */
14 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
15 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
16 /* Lesser General Public License for more details. */
17 /* */
18 /* You should have received a copy of the GNU Lesser General Public */
19 /* License along with this library; if not, write to the Free Software */
20 /* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 */
21 /* USA */
22 /*------------------------------------------------------------------------*/
23 
24 #ifndef util_Setv_hpp
25 #define util_Setv_hpp
26 
27 #include <utility>
28 #include <iterator>
29 #include <functional>
30 
31 namespace phdmesh {
32 
83 // ---------------------------------------------------------------------
84 // ---------------------------------------------------------------------
85 
86 #ifndef DOXYGEN_COMPILE
87 
88 template < typename KeyType > class SetvMember ;
89 
90 template < class ValueType , bool Forward > class SetvIter ;
91 
92 template < class ValueType, class KeyCompare, class Allocator > class Setv ;
93 
94 // ---------------------------------------------------------------------
95 
96 template<>
97 class SetvMember<void> {
98 public:
99  ~SetvMember(); // Destructor removes member from its container
100  SetvMember();
101 
102  enum { black = 0 , red = 1 };
103 
104  SetvMember<void> * parent ; // Binary tree node
105  SetvMember<void> * left ; // Binary tree node
106  SetvMember<void> * right ; // Binary tree node
107  unsigned color ; // Red-black color
108 
109 private:
110  SetvMember<void>( const SetvMember<void> & );
111  SetvMember<void> & operator = ( const SetvMember<void> & );
112 };
113 
114 template<bool Forward>
115 SetvMember<void> * setv_iterate( const SetvMember<void> * );
116 
117 template<>
118 SetvMember<void> * setv_iterate<true>( const SetvMember<void> * );
119 
120 template<>
121 SetvMember<void> * setv_iterate<false>( const SetvMember<void> * );
122 
123 #endif /* DOXYGEN_COMPILE */
124 
125 // ---------------------------------------------------------------------
126 // ---------------------------------------------------------------------
137 template < typename KeyType >
138 class SetvMember : private SetvMember<void> {
139 public:
141  typedef KeyType key_type ;
142 
144  const key_type & key() const { return m_key ; }
145 
148 
150  SetvMember() : SetvMember<void>() {}
151 
154  : SetvMember<void>(), m_key( rhs.m_key ) {}
155 
157  explicit SetvMember( const KeyType & k )
158  : SetvMember<void>(), m_key( k ) {}
159 
160 private:
161 
163  SetvMember<key_type> & operator = ( const SetvMember<key_type> & m );
164 
165  key_type m_key ;
166 
167  template< class T , class C , class A > friend class Setv ;
168  template< class T , bool F > friend class SetvIter ;
169 };
170 
171 //----------------------------------------------------------------------
178 template < class Type , bool Forward>
179 class SetvIter : public std::iterator<std::bidirectional_iterator_tag,Type>
180 {
181 private:
182 
183  Type * n ;
184 
185  SetvIter( Type * x ) : n(x) {}
186 
187  template < class T , bool F > friend class SetvIter ;
188  template < class T , class C , class A > friend class Setv ;
189 
190 public:
191 
193  operator bool () const { return n && n->parent ; }
194 
196  SetvIter() : n(NULL) {}
197 
201  template<class T,bool F> SetvIter( const SetvIter<T,F> & x ) : n(x.n) {}
202 
206  template<class T,bool F>
208  { n = x.n ; return *this ; }
209 
211  template<class T,bool F>
212  bool operator == ( const SetvIter<T,F> & y ) const { return n == y.n ; }
213 
215  template<class T,bool F>
216  bool operator != ( const SetvIter<T,F> & y ) const { return n != y.n ; }
217 
219  Type & operator * () const
220  { return *(operator bool() ? n : reinterpret_cast<Type*>(NULL) ); }
221 
223  Type * operator ->() const
224  { return (operator bool() ? n : reinterpret_cast<Type*>(NULL) ); }
225 
228  { n = static_cast<Type*>( setv_iterate<Forward>(n) ); return *this ; }
229 
232  { n = static_cast<Type*>( setv_iterate<!Forward>(n) ); return *this ; }
233 
236  {
237  Type * const t = n ;
238  n = static_cast<Type*>( setv_iterate<Forward>(n) );
239  return SetvIter<Type,Forward>(t);
240  }
241 
244  {
245  Type * const t = n ;
246  n = static_cast<Type*>( setv_iterate<!Forward>(n) );
247  return SetvIter<Type,Forward>(t);
248  }
249 };
250 
251 //----------------------------------------------------------------------
252 
253 #ifndef DOXYGEN_COMPILE
254 
255 template<>
256 class Setv<void,void,void> : private SetvMember<void> {
257 protected:
258  friend class SetvMember<void> ; // For destructor to remove
259 
260  Setv();
261  ~Setv();
262 
263  size_t size() const { return m_size ; }
264 
265  SetvMember<void> * nRoot() const { return m_header.parent ; }
266 
267  SetvMember<void> * nEnd() const
268  { return const_cast<SetvMember<void>*>( & m_right_end ); }
269 
270  SetvMember<void> * nREnd() const
271  { return const_cast<SetvMember<void>*>( & m_left_end ); }
272 
273  SetvMember<void> * nBegin() const
274  { return ( m_left_end.right != nREnd() ) ? m_left_end.right : nEnd(); }
275 
276  SetvMember<void> * nRBegin() const
277  { return ( m_right_end.left != nEnd() ) ? m_right_end.left : nREnd(); }
278 
279  void initialize();
280 
281  void insert( SetvMember<void> * y , SetvMember<void> * z , bool z_lt_y );
282 
283  void remove( SetvMember<void> * );
284 
285  SetvMember<void> * unbalancing_removal( SetvMember<void> ** n );
286 
287  static Setv<void,void,void> * container( const SetvMember<void> * );
288 
289 private:
290 
291  SetvMember<void> & m_header ; // head node is this
292  SetvMember<void> m_left_end ; // 'rend()' node
293  SetvMember<void> m_right_end ; // 'end()' node
294  size_t m_size ;
295 
296  // root == m_header.parent
297  // leftmost == m_left_end.right
298  // rightmost == m_right_end.left
299 };
300 
301 #endif /* DOXYGEN_COMPILE */
302 
303 //----------------------------------------------------------------------
317 template < class ValueType ,
318  class KeyCompare = std::less<typename ValueType::key_type> ,
319  class Allocator = std::allocator<ValueType> >
320 class Setv : private Setv<void,void,void> {
321 public:
323  typedef typename ValueType::key_type key_type ;
324 
326  typedef ValueType value_type ;
327 
329  typedef KeyCompare key_compare ;
330 
332  typedef Allocator allocator_type ;
333 
334 #ifndef DOXYGEN_COMPILE
335 
336  typedef typename allocator_type::reference reference ;
337  typedef typename allocator_type::const_reference const_reference ;
338  typedef typename allocator_type::pointer pointer ;
339  typedef typename allocator_type::const_pointer const_pointer ;
340  typedef typename allocator_type::size_type size_type ;
341  typedef typename allocator_type::difference_type difference_type ;
342 
343  typedef SetvIter< value_type,true> iterator ;
344  typedef SetvIter<const value_type,true> const_iterator ;
345  typedef SetvIter< value_type,false> reverse_iterator ;
346  typedef SetvIter<const value_type,false> const_reverse_iterator ;
347 
348  struct value_compare : public std::binary_function<value_type,value_type,bool>
349  {
350  protected:
351  key_compare comp ;
352  public:
353  bool operator()(const value_type& x, const value_type& y) const {
354  return comp( x.SetvMember<key_type>::key() ,
355  y.SetvMember<key_type>::key() );
356  }
357  };
358 
359 #endif /* DOXYGEN_COMPILE */
360 
361  ~Setv();
362 
364  Setv( const key_compare & arg_compare = key_compare(),
365  const allocator_type & arg_alloc = allocator_type() )
366  : Setv<void,void,void>(),
367  alloc(arg_alloc), key_less(arg_compare), value_less() {}
368 
371 
375 
377  allocator_type get_allocator() const { return alloc ; }
378 
382  iterator begin() const
383  { return iterator(
384  static_cast<value_type*>( Setv<void,void,void>::nBegin() ) ); }
385 
386  iterator end() const
387  { return iterator(
388  static_cast<value_type*>( Setv<void,void,void>::nEnd() ) ); }
389 
390  reverse_iterator rbegin() const
391  { return reverse_iterator(
392  static_cast<value_type*>( Setv<void,void,void>::nRBegin() ) ); }
393 
394  reverse_iterator rend() const
395  { return reverse_iterator(
396  static_cast<value_type*>( Setv<void,void,void>::nREnd() ) ); }
397 
418  std::pair<iterator,bool>
419  insert( const key_type & key , value_type * value = NULL );
420 
422  std::pair<iterator,bool> insert( value_type * );
423 
425  void erase( iterator position );
426 
428  void erase( value_type * );
429 
431  size_type erase( const key_type & );
432 
436  void remove( value_type & v )
438 
440  void clear();
444  bool empty() const { return Setv<void,void,void>::size() == 0 ; }
445 
447  size_type size() const { return Setv<void,void,void>::size() ; }
448 
450  size_type max_size() const { return alloc.max_size(); }
451 
453  key_compare key_comp() const { return key_less ; }
454 
456  value_compare value_comp() const { return value_less ; }
457 
459  value_type & operator[]( const key_type & key );
460 
462  iterator find( const key_type & ) const ;
463 
465  size_type count( const key_type & ) const ;
466 
468  iterator lower_bound( const key_type & ) const ;
469 
471  iterator upper_bound( const key_type & ) const ;
472 
474  bool verify_ordering() const ;
475 
477  static
479 
480 private:
481 
482  typedef SetvMember<key_type> MemberType ;
483 
484  allocator_type alloc ;
485  key_compare key_less ;
486  value_compare value_less ;
487 };
488 
489 } // namespace phdmesh
490 
491 // ---------------------------------------------------------------------
492 // ---------------------------------------------------------------------
493 // Implementation from here forward
494 
495 #ifndef DOXYGEN_COMPILE
496 
497 namespace phdmesh {
498 
499 //----------------------------------------------------------------------
500 
501 template<class T,class C,class M>
502 inline
503 Setv<T,C,M>::~Setv()
504 { clear(); }
505 
506 template<class T,class C,class M>
507 inline
508 std::pair<typename Setv<T,C,M>::iterator,bool>
509 Setv<T,C,M>::insert( typename Setv<T,C,M>::value_type * v )
510 {
511  bool flag = false ;
512 
513  if ( v != NULL ) {
514  const typename Setv<T,C,M>::key_type & k = v->key();
515 
516  phdmesh::SetvMember<void> * y = nEnd();
517  phdmesh::SetvMember<void> * x = nRoot();
518 
519  flag = true ;
520 
521  while ( x ) {
522  y = x ;
523  x = ( flag = key_less( k , static_cast<MemberType*>(x)->key() ) )
524  ? x->left : x->right ;
525  }
526 
527  /* flag = k < y , check previous value if exists */
528 
529  const bool k_lt_y = flag ;
530 
531  x = flag && y != nBegin() ? ( flag = false , setv_iterate<false>(y) ) : y ;
532 
533  if ( flag || ( flag = key_less(static_cast<MemberType*>(x)->key(),k) ) ) {
534  x = v ;
535  Setv<void,void,void>::insert( y , x , k_lt_y );
536  }
537  else {
538  v = static_cast<typename Setv<T,C,M>::value_type*>( x );
539  }
540  }
541  return std::pair<typename Setv<T,C,M>::iterator,bool>( iterator(v), flag );
542 }
543 
544 template<class T,class C,class M>
545 inline
546 std::pair<typename Setv<T,C,M>::iterator,bool>
547 Setv<T,C,M>::insert( const typename Setv<T,C,M>::key_type & k ,
548  typename Setv<T,C,M>::value_type * v )
549 {
550  phdmesh::SetvMember<void> * y = nEnd();
551  phdmesh::SetvMember<void> * x = nRoot();
552 
553  bool flag = true ;
554 
555  while ( x ) {
556  y = x ;
557  x = ( flag = key_less( k , static_cast<MemberType*>(x)->key() ) )
558  ? x->left : x->right ;
559  }
560 
561  /* flag = k < y , check previous value if exists */
562 
563  const bool k_lt_y = flag ;
564 
565  x = flag && y != nBegin() ? ( flag = false , setv_iterate<false>(y) ) : y ;
566 
567  if ( flag || ( flag = key_less(static_cast<MemberType*>(x)->key(),k) ) ) {
568  if ( v == NULL ) {
569  v = alloc.allocate(1);
570  new(v) value_type();
571  }
572  v->SetvMember<key_type>::m_key = k ;
573  x = v ;
574  Setv<void,void,void>::insert( y , x , k_lt_y );
575  }
576  else {
577  v = static_cast<typename Setv<T,C,M>::value_type*>( x );
578  }
579  return std::pair<typename Setv<T,C,M>::iterator,bool>( iterator(v), flag );
580 }
581 
582 template<class T,class C,class M>
583 inline
584 typename Setv<T,C,M>::value_type &
585 Setv<T,C,M>::operator[]( const key_type & k )
586 {
587  std::pair<typename Setv<T,C,M>::iterator,bool> result = insert(k);
588  return *result.second ;
589 }
590 
591 template<class T,class C,class M>
592 inline
593 void Setv<T,C,M>::erase( typename Setv<T,C,M>::value_type * p )
594 {
596  alloc.destroy( p );
597  alloc.deallocate( p , 1 );
598 }
599 
600 template<class T,class C,class M>
601 inline
602 void Setv<T,C,M>::erase( typename Setv<T,C,M>::iterator p )
603 {
604  if ( p.operator bool() ) { erase( p.n ); }
605 }
606 
607 template<class T,class C,class M>
608 inline
609 typename Setv<T,C,M>::size_type
610 Setv<T,C,M>::erase( const typename Setv<T,C,M>::key_type & k )
611 {
612  iterator i = find(k);
613  return i != end() ? ( erase( i ) , 1 ) : 0 ;
614 }
615 
616 template<class T,class C,class M>
617 void Setv<T,C,M>::clear()
618 {
619  if ( Setv<void,void,void>::size() ) {
620  phdmesh::SetvMember<void> * n = nBegin();
622  while ( ( t = Setv<void,void,void>::unbalancing_removal( &n ) ) ) {
623  alloc.destroy( static_cast<value_type*>(t) );
624  alloc.deallocate( static_cast<value_type*>(t) , 1 );
625  }
626  }
627  Setv<void,void,void>::initialize();
628 }
629 
630 template<class T,class C,class M>
631 inline
632 typename Setv<T,C,M>::iterator
633 Setv<T,C,M>::lower_bound( const typename Setv<T,C,M>::key_type & k ) const
634 {
635  phdmesh::SetvMember<void> * y = nEnd();
636  phdmesh::SetvMember<void> * x = nRoot();
637  while ( x ) x = key_less(static_cast<MemberType*>(x)->key(),k)
638  ? x->right : ( y = x )->left ;
639  return iterator( static_cast<value_type*>(y) );
640 }
641 
642 template<class T,class C,class M>
643 inline
644 typename Setv<T,C,M>::iterator
645 Setv<T,C,M>::upper_bound( const typename Setv<T,C,M>::key_type & k ) const
646 {
647  phdmesh::SetvMember<void> * y = nEnd();
648  phdmesh::SetvMember<void> * x = nRoot();
649  while ( x ) x = key_less(k,static_cast<MemberType*>(x)->key())
650  ? ( y = x )->left : x->right ;
651  return iterator( static_cast<value_type*>(y) );
652 }
653 
654 template<class T,class C,class M>
655 inline
656 typename Setv<T,C,M>::iterator
657 Setv<T,C,M>::find( const typename Setv<T,C,M>::key_type & k ) const
658 {
659  typename Setv<T,C,M>::iterator i = lower_bound(k); // k <= i->key();
660 
661  // If 'end()' or k < y->key() then not found
662  if ( i != end() && key_less(k,(*i).MemberType::key()) ) i = end();
663 
664  return i ;
665 }
666 
667 template<class T,class C,class M>
668 inline
669 typename Setv<T,C,M>::size_type
670 Setv<T,C,M>::count( const typename Setv<T,C,M>::key_type & k ) const
671 {
672  typename Setv<T,C,M>::iterator i = lower_bound(k); // k <= i->key();
673  return i == end() || key_less(k,(*i).SetvMember<T>::key()) ? 0 : 1 ;
674 }
675 
676 template<class T,class C,class M>
677 inline
678 Setv<T,C,M>::Setv( const Setv<T,C,M> & V )
679  : Setv<void,void,void>()
680 {
681  for ( const_iterator i = V.begin() ; i != V.end() ; ++i ) {
682  pointer a = alloc.allocate(1);
683  alloc.construct(a,*i);
684  insert( i->SetvMember<key_type>::key() , a );
685  }
686 }
687 
688 template<class T,class C,class M>
689 inline
690 Setv<T,C,M> &
691 Setv<T,C,M>::operator = ( const Setv<T,C,M> & V )
692 {
693  clear();
694  for ( const_iterator i = V.begin() ; i != V.end() ; ++i ) {
695  pointer a = alloc.allocate(1);
696  alloc.construct(a,*i);
697  insert( i->SetvMember<key_type>::key() , a );
698  }
699 }
700 
702 template<class T,class C,class M>
703 inline
704 Setv<T,C,M> *
705 Setv<T,C,M>::container( const typename Setv<T,C,M>::value_type & v )
706 {
707  Setv<void,void,void> * const c = Setv<void,void,void>::container(&v);
708  return c ? static_cast<Setv<T,C,M>*>( c ) :
709  reinterpret_cast<Setv<T,C,M>*>( NULL );
710 }
711 
712 template<class T,class C,class M>
713 inline
714 bool Setv<T,C,M>::verify_ordering() const
715 {
716  size_type count = 0 ;
717  iterator i = begin();
718  iterator j ;
719 
720  while ( i != end() &&
721  ( ++(j=i) == end() || key_less( i->MemberType::key() ,
722  j->MemberType::key() ) )
723  && --j == i )
724  { ++i ; ++count ; }
725 
726  return ( i == end() && count == size() );
727 }
728 
729 // ---------------------------------------------------------------------
730 
731 } // namespace phdmesh
732 
733 #endif /* DOXYGEN_COMPILE */
734 
735 #endif /* util_Setv_hpp */
value_type & operator[](const key_type &key)
Retrieve or create a value with the given key.
bool operator!=(const SetvIter< T, F > &y) const
Return if not pointing to the same entity.
Definition: Setv.hpp:216
bool empty() const
Query if container is empty.
Definition: Setv.hpp:444
const key_type & key() const
Definition: Setv.hpp:144
size_type max_size() const
Query capacity.
Definition: Setv.hpp:450
Type * operator->() const
Pointer to a valid entity, null otherwise.
Definition: Setv.hpp:223
bool operator==(const SetvIter< T, F > &y) const
Return if pointing to the same entity.
Definition: Setv.hpp:212
value_compare value_comp() const
Comparison operator for key type via the value type.
Definition: Setv.hpp:456
SetvIter()
Default constructor to NULL entity.
Definition: Setv.hpp:196
std::pair< iterator, bool > insert(const key_type &key, value_type *value=NULL)
Inserts the given entity with key() == key.
allocator_type get_allocator() const
Allocator.
Definition: Setv.hpp:377
bool verify_ordering() const
Verify that iteration of the container is properly ordered.
SetvIter< Type, Forward > & operator--()
Decrement to the previous entity.
Definition: Setv.hpp:231
key_compare key_comp() const
Comparison operator for key type.
Definition: Setv.hpp:453
static Setv< value_type, key_compare, allocator_type > * container(const value_type &)
Query the container for a given member.
SetvIter(const SetvIter< T, F > &x)
Copy from other similar iterators. Compilation will fail when assigning non-const to const...
Definition: Setv.hpp:201
void erase(iterator position)
Destroys the member referenced by the iterator.
SetvIter< Type, Forward > & operator=(const SetvIter< T, F > &x)
Assign from other similar iterators. Compilation will fail when assigning non-const to const...
Definition: Setv.hpp:207
iterator find(const key_type &) const
Find a member with a given key.
SetvIter< Type, Forward > operator++(int)
Return this iterator and then increment to the next entity.
Definition: Setv.hpp:235
iterator lower_bound(const key_type &) const
First member with key equal to or greater than the given key.
SetvMember(const KeyType &k)
Definition: Setv.hpp:157
size_type size() const
Query number of members.
Definition: Setv.hpp:447
ValueType::key_type key_type
Type of the comparison keys, obtained from the member class.
Definition: Setv.hpp:323
KeyCompare key_compare
Key comparison operator.
Definition: Setv.hpp:329
Template class for the Setv bidirectional iterators.
Definition: Setv.hpp:179
ValueType value_type
Type of the members.
Definition: Setv.hpp:326
Setv< value_type, key_compare, allocator_type > & operator=(const Setv< value_type, key_compare, allocator_type > &)
Assignment.
SetvIter< Type, Forward > & operator++()
Increment to the next entity.
Definition: Setv.hpp:227
Associative container of explictly managed entities.
Definition: Setv.hpp:320
Type & operator*() const
Reference to a valid entity, null otherwise.
Definition: Setv.hpp:219
SetvIter< Type, Forward > operator--(int)
Return this iterator and then decrement to the previous entity.
Definition: Setv.hpp:243
Allocator allocator_type
Allocator class.
Definition: Setv.hpp:332
Base class for Setv members.Objects stored in a Setv container must be derived from this template bas...
Definition: Setv.hpp:138
KeyType key_type
Definition: Setv.hpp:141
void clear()
Destroys all members.
iterator upper_bound(const key_type &) const
Last member with key greater than or equal to the given key.
Setv(const key_compare &arg_compare=key_compare(), const allocator_type &arg_alloc=allocator_type())
Construct with comparison and allocator.
Definition: Setv.hpp:364
size_type count(const key_type &) const
Count number of members with a given key, zero or one.
SetvMember(const SetvMember< key_type > &rhs)
Definition: Setv.hpp:153
void remove(value_type &v)
Removes the member from container but does not destroy it. The caller assumes responsibility for the ...
Definition: Setv.hpp:436