]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Mostly implement iterators for block vectors. Some parts still missing though.
authorwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Thu, 27 Sep 2001 15:35:50 +0000 (15:35 +0000)
committerwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Thu, 27 Sep 2001 15:35:50 +0000 (15:35 +0000)
git-svn-id: https://svn.dealii.org/trunk@5112 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/lac/include/lac/block_vector.h
deal.II/lac/include/lac/block_vector.templates.h

index 20c75c26cf8511971f6c57527006cd55c3f5e3c5..0d0f39a05719bfe370964a040fbda9e45b42a4ca 100644 (file)
 template <typename Number>
 class BlockVector
 {
+    template <typename Pointee>
+    class Iterator
+    {
+      public:
+                                        /**
+                                         * Construct an iterator from
+                                         * a vector to which we point
+                                         * and the global index of
+                                         * the element pointed to.
+                                         */
+       Iterator (BlockVector<Number> &parent,
+                 const unsigned       global_index);
+       
+                                        /**
+                                         * Copy constructor.
+                                         */
+       Iterator (const Iterator &c);
+
+                                        /**
+                                         * Copy operator.
+                                         */
+       Iterator & operator = (const Iterator &c);
+
+                                        /**
+                                         * Dereferencing operator. If
+                                         * the template argument
+                                         * @p{Pointee} has a
+                                         * @p{const} specification,
+                                         * then no writing to the
+                                         * result is possible, making
+                                         * this a @p{const_iterator}.
+                                         */
+       Pointee & operator * () const;
+
+                                        /**
+                                         * Prefix @p{++} operator:
+                                         * @p{++i}. This operator
+                                         * advances the iterator to
+                                         * the next element and
+                                         * returns a reference to
+                                         * @p{*this}.
+                                         */
+       Iterator & operator ++ ();
+
+                                        /**
+                                         * Postfix @p{++} operator:
+                                         * @p{i++}. This operator
+                                         * advances the iterator to
+                                         * the next element and
+                                         * returns a copy of the old
+                                         * value of this iterator.
+                                         */
+       Iterator operator ++ (int);
+
+                                        /**
+                                         * Prefix @p{--} operator:
+                                         * @p{--i}. This operator
+                                         * retracts the iterator to
+                                         * the previous element and
+                                         * returns a reference to
+                                         * @p{*this}.
+                                         */
+       Iterator & operator -- ();
+
+                                        /**
+                                         * Postfix @p{--} operator:
+                                         * @p{i--}. This operator
+                                         * retracts the iterator to
+                                         * the previous element and
+                                         * returns a copy of the old
+                                         * value of this iterator.
+                                         */
+       Iterator operator -- (int);
+
+                                        /**
+                                         * Compare for equality of
+                                         * iterators. This operator
+                                         * checks whether the vectors
+                                         * pointed to are the same,
+                                         * and if not it throws an
+                                         * exception.                                   
+                                         */
+       bool operator == (const Iterator &i) const;
+
+                                        /**
+                                         * Compare for inequality of
+                                         * iterators. This operator
+                                         * checks whether the vectors
+                                         * pointed to are the same,
+                                         * and if not it throws an
+                                         * exception.                                   
+                                         */
+       bool operator != (const Iterator &i) const;
+
+                                        /**
+                                         * Check whether this
+                                         * iterators points to an
+                                         * element previous to the
+                                         * one pointed to by the
+                                         * given argument. This
+                                         * operator checks whether
+                                         * the vectors pointed to are
+                                         * the same, and if not it
+                                         * throws an exception.
+                                         */
+       bool operator < (const Iterator &i) const;
+
+                                        /**
+                                         * Comparison operator alike
+                                         * to the one above.
+                                         */
+       bool operator <= (const Iterator &i) const;
+
+                                        /**
+                                         * Comparison operator alike
+                                         * to the one above.
+                                         */
+       bool operator > (const Iterator &i) const;
+
+                                        /**
+                                         * Comparison operator alike
+                                         * to the one above.
+                                         */
+       bool operator >= (const Iterator &i) const;
+       
+                                        /**
+                                         * Exception.
+                                         */
+       DeclException0 (ExcPointerToDifferentVectors);
+
+       
+      private:
+                                        /**
+                                         * Pointer to the block
+                                         * vector object to which
+                                         * this iterator points.
+                                         */
+       BlockVector<Number> *parent;
+
+                                        /**
+                                         * Global index of the
+                                         * element to which we
+                                         * presently point.
+                                         */
+       unsigned int         global_index;
+
+                                        /**
+                                         * Current block and index
+                                         * within this block of the
+                                         * element presently pointed
+                                         * to.
+                                         */
+       unsigned int current_block;
+       unsigned int index_within_block;
+
+                                        /**
+                                         * Indices of the global
+                                         * element address at which
+                                         * we have to move on to
+                                         * another block when moving
+                                         * forward and
+                                         * backward. These indices
+                                         * are kept as a cache since
+                                         * this is much more
+                                         * efficient than always
+                                         * asking the parent object.
+                                         */
+       unsigned int next_break_forward;
+       unsigned int next_break_backward;
+
+                                        /**
+                                         * Move forward one element.
+                                         */
+       void move_forward ();
+
+                                        /**
+                                         * Move backward one element.
+                                         */
+       void move_backward ();
+    };
+    
   public:
                                     /**
                                      * Declare standard types used in
@@ -63,12 +244,14 @@ class BlockVector
                                      * implemented that cycle through
                                      * the individual sub-vectors.
                                      */
-    typedef Number value_type;
-    typedef value_type* pointer;
-    typedef const value_type* const_pointer;
-    typedef value_type& reference;
-    typedef const value_type& const_reference;
-    typedef size_t size_type;
+    typedef Number                  value_type;
+    typedef value_type             *pointer;
+    typedef const value_type       *const_pointer;
+    typedef Iterator<Number>        iterator;
+    typedef Iterator<const Number>  const_iterator;
+    typedef value_type             &reference;
+    typedef const value_type       &const_reference;
+    typedef size_t                  size_type;
 
                                     /**
                                      *  Constructor. There are three
@@ -355,6 +538,20 @@ class BlockVector
                                      * as a writeable reference.
                                      */
     Number& operator() (const unsigned int i);
+
+                                    /**
+                                     * Return an iterator pointing to
+                                     * the first element.
+                                     */
+    iterator begin ();
+
+                                    /**
+                                     * Return an iterator pointing to
+                                     * the first element of a
+                                     * constant block vector.
+                                     */
+    const_iterator begin () const;
+    
                                     //@}
 
 
@@ -546,6 +743,12 @@ class BlockVector
                                      * here for convenience.
                                      */
     unsigned int num_blocks;
+
+                                    /**
+                                     * Make the iterator class a
+                                     * friend.
+                                     */
+    template <typename Pointee> friend class Iterator;
 };
 
 
index 68af1979dbd06f55acf9fb4bb1bd6d2cc4b4d547..d151449c5ba19306464be9ac43042e22f151254e 100644 (file)
@@ -150,6 +150,7 @@ bool BlockVector<Number>::all_zero () const
 }
 
 
+
 template <typename Number>
 Number BlockVector<Number>::operator * (const BlockVector<Number>& v) const
 {
@@ -165,6 +166,24 @@ Number BlockVector<Number>::operator * (const BlockVector<Number>& v) const
 }
 
 
+template <typename Number>
+typename BlockVector<Number>::iterator
+BlockVector<Number>::begin()
+{
+  return iterator(*this, 0U);
+};
+
+
+
+template <typename Number>
+typename BlockVector<Number>::const_iterator
+BlockVector<Number>::begin() const
+{
+  Assert (false, ExcNotImplemented());
+  return const_iterator(*const_cast<BlockVector*>(this), 0U);
+};
+
+
 template <typename Number>
 Number BlockVector<Number>::norm_sqr () const
 {
@@ -507,6 +526,268 @@ BlockVector<Number>::memory_consumption () const
 
 
 
+template <typename Number>
+template <typename Pointee>
+BlockVector<Number>::Iterator<Pointee>::
+Iterator (BlockVector<Number> &parent,
+         const unsigned       global_index)
+               :
+               parent (&parent),
+               global_index (global_index)
+{
+                                  // find which block we are in
+  const std::pair<unsigned int, unsigned int>
+    indices = parent.block_indices.global_to_local(global_index);
+  current_block      = indices.first;
+  index_within_block = indices.second;
+  
+  next_break_backward = parent.block_indices.local_to_global (current_block, 0);
+  next_break_forward
+    = parent.block_indices.local_to_global (current_block,
+                                           next_break_backward + 
+                                           parent.block_indices
+                                           .block_size(current_block)-1);
+};
+
+
+
+
+template <typename Number>
+template <typename Pointee>
+BlockVector<Number>::Iterator<Pointee>::
+Iterator (const Iterator &c)
+               :
+               parent (c.parent),
+               global_index (c.global_index),
+               current_block (c.current_block),
+               index_within_block (c.index_within_block),
+               next_break_forward (c.next_break_forward),
+               next_break_backward (c.next_break_backward)
+{};
+
+
+
+template <typename Number>
+template <typename Pointee>
+typename BlockVector<Number>::Iterator<Pointee> &
+BlockVector<Number>::Iterator<Pointee>::
+operator = (const Iterator &c)
+{
+  parent              = c.parent;
+  global_index        = c.global_index;
+  index_within_block  = c.index_within_block;
+  current_block       = c.current_block;
+  next_break_forward  = c.next_break_forward;
+  next_break_backward = c.next_break_backward;
+
+  return *this;
+};
+
+
+
+template <typename Number>
+template <typename Pointee>
+void
+BlockVector<Number>::Iterator<Pointee>::move_forward ()
+{
+  if (global_index != next_break_forward)
+    ++index_within_block;
+  else
+    {
+                                      // ok, we traverse a boundary
+                                      // between blocks:
+      index_within_block = 0;
+      ++current_block;
+
+                                      // break backwards is now old
+                                      // break forward
+      next_break_backward = next_break_forward+1;
+
+                                      // compute new break forward
+      if (current_block < parent->block_indices.size())
+       next_break_forward
+         = parent->block_indices.local_to_global (current_block,
+                                                  next_break_backward + 
+                                                  parent->block_indices
+                                                  .block_size(current_block)-1);
+      else
+                                        // if we are beyond the end,
+                                        // then move the next
+                                        // boundary arbitrarily far
+                                        // away
+       next_break_forward = static_cast<unsigned int>(-1);
+    };
+  
+  ++global_index;
+};
+
+
+
+template <typename Number>
+template <typename Pointee>
+void
+BlockVector<Number>::Iterator<Pointee>::move_backward ()
+{
+  if (global_index != next_break_backward)
+    --index_within_block;
+  else
+    if (current_block != 0)
+      {
+                                        // ok, we traverse a boundary
+                                        // between blocks:
+       --current_block;
+       index_within_block = parent->block_indices.block_size(current_block)-1;
+       
+                                        // break forwards is now old
+                                        // break backward
+       next_break_forward = next_break_backward-1;
+       
+                                        // compute new break forward
+       next_break_backward
+         = parent->block_indices.local_to_global (current_block, 0);
+      }
+    else
+                                      // current block was 0, we now
+                                      // get into unspecified terrain
+      {
+       --current_block;
+       index_within_block = static_cast<unsigned int>(-1);
+       next_break_forward = 0;
+       next_break_backward = 0;
+      };
+  
+  --global_index;
+};
+
+
+
+template <typename Number>
+template <typename Pointee>
+Pointee &
+BlockVector<Number>::Iterator<Pointee>::operator * () const
+{
+  return parent->block(current_block)(index_within_block);
+};
+
+
+
+template <typename Number>
+template <typename Pointee>
+typename BlockVector<Number>::Iterator<Pointee> &
+BlockVector<Number>::Iterator<Pointee>::operator ++ ()
+{
+  move_forward ();
+  return *this;
+};
+
+
+
+template <typename Number>
+template <typename Pointee>
+typename BlockVector<Number>::Iterator<Pointee>
+BlockVector<Number>::Iterator<Pointee>::operator ++ (int)
+{
+  const Iterator old_value = *this;
+  move_forward ();
+  return old_value;
+};
+
+
+
+template <typename Number>
+template <typename Pointee>
+typename BlockVector<Number>::Iterator<Pointee> &
+BlockVector<Number>::Iterator<Pointee>::operator -- ()
+{
+  move_backward ();
+  return *this;
+};
+
+
+
+template <typename Number>
+template <typename Pointee>
+typename BlockVector<Number>::Iterator<Pointee>
+BlockVector<Number>::Iterator<Pointee>::operator -- (int)
+{
+  const Iterator old_value = *this;
+  move_backward ();
+  return old_value;
+};
+
+
+
+template <typename Number>
+template <typename Pointee>
+bool
+BlockVector<Number>::Iterator<Pointee>::operator == (const Iterator &i) const
+{
+  Assert (parent == i.parent, ExcPointerToDifferentVectors());
+
+  return (global_index == i.global_index);
+};
+
+
+
+template <typename Number>
+template <typename Pointee>
+bool
+BlockVector<Number>::Iterator<Pointee>::operator != (const Iterator &i) const
+{
+  Assert (parent == i.parent, ExcPointerToDifferentVectors());
+
+  return (global_index != i.global_index);
+};
+
+
+
+template <typename Number>
+template <typename Pointee>
+bool
+BlockVector<Number>::Iterator<Pointee>::operator < (const Iterator &i) const
+{
+  Assert (parent == i.parent, ExcPointerToDifferentVectors());
+
+  return (global_index < i.global_index);
+};
+
+
+
+template <typename Number>
+template <typename Pointee>
+bool
+BlockVector<Number>::Iterator<Pointee>::operator <= (const Iterator &i) const
+{
+  Assert (parent == i.parent, ExcPointerToDifferentVectors());
+
+  return (global_index <= i.global_index);
+};
+
+
+
+template <typename Number>
+template <typename Pointee>
+bool
+BlockVector<Number>::Iterator<Pointee>::operator > (const Iterator &i) const
+{
+  Assert (parent == i.parent, ExcPointerToDifferentVectors());
+
+  return (global_index > i.global_index);
+};
+
+
+
+template <typename Number>
+template <typename Pointee>
+bool
+BlockVector<Number>::Iterator<Pointee>::operator >= (const Iterator &i) const
+{
+  Assert (parent == i.parent, ExcPointerToDifferentVectors());
+
+  return (global_index >= i.global_index);
+};
+
+
 
 
 #endif

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.