]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
BlockVectors now have iterators.
authorwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Fri, 28 Sep 2001 17:49:28 +0000 (17:49 +0000)
committerwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Fri, 28 Sep 2001 17:49:28 +0000 (17:49 +0000)
git-svn-id: https://svn.dealii.org/trunk@5120 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/doc/news/2001/c-3-2.html
deal.II/lac/include/lac/block_vector.h
deal.II/lac/include/lac/block_vector.templates.h
deal.II/lac/source/block_vector.cc
tests/lac/Makefile
tests/lac/block_vector_iterator.cc [new file with mode: 0644]
tests/lac/block_vector_iterator.checked [new file with mode: 0644]

index b8b45241e1bb6978e8ba869b9eeab9b3b82311cc..9848e739f747e29c2153e25851024981dc4b346d 100644 (file)
@@ -44,6 +44,14 @@ documentation, etc</a>.
 <h3>lac</h3>
 
 <ol>
+  <li> <p>
+       New: The <code class="class">BlockVector</code> now has a
+       full-fledged random access iterator type, working in exactly
+       the same way as the iterators of the C++ standard containers.
+       <br>
+       (WB 2001/09/28)
+       </p>
+
   <li> <p>
        New: <code class="member">Vector::operator *</code> is now
        templatized, allowing for scalar products of vectors with
index 0d0f39a05719bfe370964a040fbda9e45b42a4ca..7a4a8651c0d86d11b540106e20c6ba6556dad754 100644 (file)
 #include <base/exceptions.h>
 #include <cstdio>
 #include <vector>
+#include <iterator>
+
+
+// forward declaration
+template <typename Number>
+class BlockVector;
+
+
+/**
+ * Namespace in which iterators in block vectors are implemented.
+ *
+ * @author Wolfgang Bangerth, 2001
+ */
+namespace BlockVectorIterators
+{
+                                  /**
+                                   * Declaration of the general
+                                   * template of a structure which is
+                                   * used to determine some types
+                                   * based on the template arguments
+                                   * of other classes.
+                                   */
+  template <typename number, bool constness>
+  struct Types
+  {};
+
+
+  
+                                  /**
+                                   * Declaration of a specialized
+                                   * template of a structure which is
+                                   * used to determine some types
+                                   * based on the template arguments
+                                   * of other classes.
+                                   *
+                                   * This is for the use of non-const
+                                   * iterators.
+                                   */
+  template <typename number>
+  struct Types<number,false>
+  {
+                                      /**
+                                       * Type of the vector
+                                       * underlying the block vector
+                                       * used in non-const
+                                       * iterators. There, the
+                                       * vector must not be constant.
+                                       */
+      typedef Vector<number>      Vector;
+
+                                      /**
+                                       * Type of the block vector
+                                       * used in non-const
+                                       * iterators. There, the block
+                                       * vector must not be constant.
+                                       */
+      typedef BlockVector<number> BlockVector;
+
+                                      /**
+                                       * Type of the numbers we point
+                                       * to. Here, they are not
+                                       * constant.
+                                       */
+      typedef number              NumberType;
+  };
+
+
+  
+                                  /**
+                                   * Declaration of a specialized
+                                   * template of a structure which is
+                                   * used to determine some types
+                                   * based on the template arguments
+                                   * of other classes.
+                                   *
+                                   * This is for the use of
+                                   * @p{const_iterator}s.
+                                   */
+  template <typename number>
+  struct Types<number,true>
+  {
+                                      /**
+                                       * Type of the vector
+                                       * underlying the block vector
+                                       * used in
+                                       * @p{const_iterators}. There,
+                                       * the vector must be
+                                       * constant.
+                                       */
+      typedef const Vector<number>      Vector;
+
+                                      /**
+                                       * Type of the block vector
+                                       * used in
+                                       * @p{const_iterator}s. There,
+                                       * the block vector must be
+                                       * constant.
+                                       */
+      typedef const BlockVector<number> BlockVector;
+
+                                      /**
+                                       * Type of the numbers we point
+                                       * to. Here, they are constant
+                                       * since the block vector we
+                                       * use is constant.
+                                       */
+      typedef const number              NumberType;
+  };
+
+
+                                  /**
+                                   * General random-access iterator
+                                   * class for block vectors. Since
+                                   * we do not want to have two
+                                   * classes for non-const
+                                   * @p{iterator}s and
+                                   * @p{const_iterator}s, we take a
+                                   * second template argument which
+                                   * denotes whether the vector we
+                                   * point into is a constant object
+                                   * or not. The first template
+                                   * argument is always the number
+                                   * type of the block vector in use.
+                                   *
+                                   * This class satisfies all
+                                   * requirements of random access
+                                   * iterators defined in the C++
+                                   * standard. Operations on these
+                                   * iterators are constant in the
+                                   * number of elements in the block
+                                   * vector. However, they are
+                                   * sometimes linear in the number
+                                   * of blocks in the vector, but
+                                   * since that does rarely change
+                                   * dynamically within an
+                                   * application, this is a constant
+                                   * and we again have that the
+                                   * iterator satisfies the
+                                   * requirements of a random access
+                                   * iterator.
+                                   *
+                                   * The implementation of this class
+                                   * has to work around some problems
+                                   * in compilers and standard
+                                   * libraries. One of these requires
+                                   * us to write all comparison
+                                   * operators twice, once comparison
+                                   * with iterators of the same type
+                                   * and once with iterators pointing
+                                   * to numbers of opposite constness
+                                   * specification. The reason is
+                                   * that if we would have written
+                                   * the comparison operators as a
+                                   * template on the constness of the
+                                   * right hand side, then gcc2.95
+                                   * signals an error that these
+                                   * operators ambiguate operators
+                                   * declared somewhere within the
+                                   * standard library. Likewise, we
+                                   * have to work around some
+                                   * problems with granting other
+                                   * iterators friendship. This makes
+                                   * the implementation somewhat
+                                   * non-optimal at places, but at
+                                   * least everything works.
+                                   *
+                                   * @author Wolfgang Bangerth, 2001
+                                   */
+  template <typename number, bool constness>
+  class Iterator :
+#ifdef HAVE_STD_ITERATOR_CLASS  
+               public std::iterator<std::random_access_iterator_tag,
+                                   typename Types<number,constness>::NumberType>
+#else
+               random_access_iterator<typename Types<number,constness>::NumberType,int>
+#endif      
+  {
+    private:
+                                      /**
+                                       * Typedef an iterator with
+                                       * opposite constness
+                                       * requirements on the elements
+                                       * it points to.
+                                       */
+      typedef Iterator<number,!constness> InverseConstnessIterator;
+
+    public:
+                                      /**
+                                       * Declare some typedefs which
+                                       * are standard for iterators
+                                       * and are used by algorithms
+                                       * to enquire about the
+                                       * specifics of the iterators
+                                       * they work on.
+                                       */
+      typedef std::random_access_iterator_tag               iterator_type;
+      typedef typename Types<number,constness>::NumberType  value_type;
+      typedef ptrdiff_t                                     difference_type;
+      typedef value_type                                   &reference;
+      typedef value_type                                   *pointer;
+      
+                                      /**
+                                       * Typedef the type of the
+                                       * block vector (which differs
+                                       * in constness, depending on
+                                       * the second template
+                                       * parameter).
+                                       */
+      typedef typename Types<number,constness>::BlockVector BlockVectorType;
+
+                                      /**
+                                       * Type of the number this
+                                       * iterator points
+                                       * to. Depending on the value
+                                       * of the second template
+                                       * parameter, this is either a
+                                       * constant or non-const
+                                       * number.
+                                       */
+      typedef typename Types<number,constness>::NumberType NumberType;
+       
+                                      /**
+                                       * Construct an iterator from
+                                       * a vector to which we point
+                                       * and the global index of
+                                       * the element pointed to.
+                                       *
+                                       * Depending on the value of
+                                       * the @p{constness} template
+                                       * argument of this class,
+                                       * the first argument of this
+                                       * constructor is either is a
+                                       * @p{const} or non-@p{const}
+                                       * reference.
+                                       */
+      Iterator (BlockVectorType    &parent,
+               const unsigned int  global_index);
+       
+                                      /**
+                                       * Copy constructor.
+                                       */
+      Iterator (const Iterator<number,constness> &c);
+
+                                      /**
+                                       * Copy constructor for
+                                       * conversion between iterators
+                                       * with different constness
+                                       * requirements. This
+                                       * constructor throws an error
+                                       * if an attempt is made at
+                                       * converting a constant to a
+                                       * non-constant iterator.
+                                       */
+      template <bool constness2>
+      Iterator (const Iterator<number,constness2> &c);
+
+    private:
+                                      /**
+                                       * Constructor used internally
+                                       * in this class. The arguments
+                                       * match exactly the values of
+                                       * the respective member
+                                       * variables.
+                                       */
+      Iterator (BlockVectorType    &parent,
+               const unsigned int  global_index,
+               const unsigned int  current_block,
+               const unsigned int  index_within_block,
+               const unsigned int  next_break_forward,
+               const unsigned int  next_break_backward);
+      
+    public:
+      
+                                      /**
+                                       * Copy operator.
+                                       */
+      Iterator & operator = (const Iterator &c);
+
+                                      /**
+                                       * Dereferencing operator. If
+                                       * the template argument
+                                       * @p{constness} is @p{true},
+                                       * then no writing to the
+                                       * result is possible, making
+                                       * this a @p{const_iterator}.
+                                       */
+      reference operator * () const;
+
+                                      /**
+                                       * Dereferencing operator. If
+                                       * the template argument
+                                       * @p{constness} is @p{true},
+                                       * then no writing to the
+                                       * result is possible, making
+                                       * this a @p{const_iterator}.
+                                       */ 
+      pointer operator -> () const;
+
+                                      /**
+                                       * Random access operator,
+                                       * grant access to arbitrary
+                                       * elements relative to the one
+                                       * presently pointed to.
+                                       */
+      reference operator [] (const difference_type d) 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;
+      
+                                      /**
+                                       * Same, but compare with an
+                                       * iterator of different
+                                       * constness.
+                                       */
+      bool operator == (const InverseConstnessIterator &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;
+
+                                      /**
+                                       * Same, but compare with an
+                                       * iterator of different
+                                       * constness.
+                                       */
+      bool operator != (const InverseConstnessIterator &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;
+
+                                      /**
+                                       * Same, but compare with an
+                                       * iterator of different
+                                       * constness.
+                                       */
+      bool operator < (const InverseConstnessIterator &i) const;      
+
+                                      /**
+                                       * Comparison operator alike
+                                       * to the one above.
+                                       */
+      bool operator <= (const Iterator &i) const;
+
+                                      /**
+                                       * Same, but compare with an
+                                       * iterator of different
+                                       * constness.
+                                       */
+      bool operator <= (const InverseConstnessIterator &i) const;      
+
+                                      /**
+                                       * Comparison operator alike
+                                       * to the one above.
+                                       */
+      bool operator > (const Iterator &i) const;
+
+                                      /**
+                                       * Same, but compare with an
+                                       * iterator of different
+                                       * constness.
+                                       */
+      bool operator > (const InverseConstnessIterator &i) const;      
+
+                                      /**
+                                       * Comparison operator alike
+                                       * to the one above.
+                                       */
+      bool operator >= (const Iterator &i) const;
+
+                                      /**
+                                       * Same, but compare with an
+                                       * iterator of different
+                                       * constness.
+                                       */
+      bool operator >= (const InverseConstnessIterator &i) const;
+
+                                      /**
+                                       * Return the distance between
+                                       * the two iterators, in
+                                       * elements.
+                                       */
+      difference_type operator - (const Iterator &i) const;
+
+                                      /**
+                                       * Same, but for iterators of
+                                       * opposite constness.
+                                       */
+      difference_type operator - (const InverseConstnessIterator &i) const;
+
+                                      /**
+                                       * Return an iterator which is
+                                       * the given number of elements
+                                       * in front of the present one.
+                                       */
+      Iterator operator + (const difference_type &d) const;
+      
+                                      /**
+                                       * Return an iterator which is
+                                       * the given number of elements
+                                       * behind the present one.
+                                       */
+      Iterator operator - (const difference_type &d) const;
+
+                                      /**
+                                       * Move the iterator @p{d}
+                                       * elements forward at once,
+                                       * and return the result.
+                                       */
+      Iterator & operator += (const difference_type &d);
+
+                                      /**
+                                       * Move the iterator @p{d}
+                                       * elements backward at once,
+                                       * and return the result.
+                                       */
+      Iterator & operator -= (const difference_type &d);
+      
+                                      /**
+                                       * Exception.
+                                       */
+      DeclException0 (ExcPointerToDifferentVectors);
+                                      /**
+                                       * Exception.
+                                       */
+      DeclException0 (ExcCastingAwayConstness);
+       
+    private:
+                                      /**
+                                       * Pointer to the block
+                                       * vector object to which
+                                       * this iterator
+                                       * points. Depending on the
+                                       * value of the @p{constness}
+                                       * template argument of this
+                                       * class, this is a @p{const}
+                                       * or non-@p{const} pointer.
+                                       */
+      BlockVectorType *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 ();
+
+      friend class InverseConstnessIterator;
+  };
+};
+
 
 
 /**
- * Several vectors of data. 
+ * A vector composed of several blocks each representing a vector of
+ * its own.
  *
- * The BlockVector is a collection of normal LAC-@p{Vector}s. Each of
+ * The @p{BlockVector} is a collection of normal LAC-@p{Vector}s. Each of
  * the vectors inside can have a different size. The special case of a
  * block vector with constant block size is supported by constructor
  * and reinit functions.
 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
@@ -247,8 +614,8 @@ class BlockVector
     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 BlockVectorIterators::Iterator<Number,false> iterator;
+    typedef BlockVectorIterators::Iterator<Number,true>  const_iterator;
     typedef value_type             &reference;
     typedef const value_type       &const_reference;
     typedef size_t                  size_type;
@@ -428,7 +795,7 @@ class BlockVector
                                     /**
                                      * Access to a single block.
                                      */
-    Vector<Number>& block (const unsigned int i);
+    Vector<Number> & block (const unsigned int i);
     
                                     /**
                                      * Read-only access to a single block.
@@ -552,6 +919,18 @@ class BlockVector
                                      */
     const_iterator begin () const;
     
+                                    /**
+                                     * Return an iterator pointing to
+                                     * the element past the end.
+                                     */
+    iterator end ();
+
+                                    /**
+                                     * Return an iterator pointing to
+                                     * the element past the end of a
+                                     * constant block vector.
+                                     */
+    const_iterator end () const;    
                                     //@}
 
 
@@ -748,7 +1127,8 @@ class BlockVector
                                      * Make the iterator class a
                                      * friend.
                                      */
-    template <typename Pointee> friend class Iterator;
+    friend class iterator;
+    friend class const_iterator;
 };
 
 
@@ -861,6 +1241,464 @@ BlockVector<Number>::get_block_indices () const
 }
 
 
+namespace BlockVectorIterators
+{
+
+  template <typename number, bool constness>
+  inline
+  Iterator<number,constness>::
+  Iterator (const Iterator<number,constness> &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, bool constness>
+  template <bool constness2>
+  inline
+  Iterator<number,constness>::
+  Iterator (const Iterator<number,constness2> &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)
+  {
+    Assert (! ((constness==false) && (constness2==true)),
+           ExcCastingAwayConstness());
+  };
+  
+
+
+  template <typename number, bool constness>
+  inline
+  Iterator<number,constness>::
+  Iterator (BlockVectorType    &parent,
+           const unsigned int  global_index,
+           const unsigned int  current_block,
+           const unsigned int  index_within_block,
+           const unsigned int  next_break_forward,
+           const unsigned int  next_break_backward)
+                 :
+                 parent (&parent),
+                 global_index (global_index),
+                 current_block (current_block),
+                 index_within_block (index_within_block),
+                 next_break_forward (next_break_forward),
+                 next_break_backward (next_break_backward)
+  {
+  };
+  
+
+
+  template <typename number, bool constness>
+  inline
+  Iterator<number,constness> &
+  Iterator<number,constness>::
+  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, bool constness>
+  inline
+  typename Iterator<number,constness>::reference
+  Iterator<number,constness>::operator * () const
+  {
+                                    // we might want to return the
+                                    // following directly, but if we do
+                                    // that we run into a gcc bug where
+                                    // it complains that we return a
+                                    // reference to a temporary
+    const reference p = parent->block(current_block)(index_within_block);
+    return p;
+  };
+
+
+
+  template <typename number, bool constness>
+  inline
+  typename Iterator<number,constness>::pointer
+  Iterator<number,constness>::operator -> () const
+  {
+                                    // we might want to return the
+                                    // following directly, but if we do
+                                    // that we run into a gcc bug where
+                                    // it complains that we return a
+                                    // reference to a temporary
+    const reference p = parent->block(current_block)(index_within_block);
+    return &p;
+  };
+  
+
+
+  template <typename number, bool constness>
+  inline
+  typename Iterator<number,constness>::reference
+  Iterator<number,constness>::operator [] (const difference_type d) const
+  {
+                                    // if the index pointed to is
+                                    // still within the block we
+                                    // currently point into, then we
+                                    // can save the computation of
+                                    // the block
+    if ((global_index+d >= next_break_backward) &&
+       (global_index+d <= next_break_forward))
+      {
+       const reference p = parent->block(current_block)(index_within_block + d);
+       return p;
+      };
+    
+    
+                                    // if the index is not within the
+                                    // block of the block vector into
+                                    // which we presently point, then
+                                    // there is no way: we have to
+                                    // search for the block. this can
+                                    // be done through the parent
+                                    // class as well.
+    const reference p = (*parent)(global_index+d);
+    return p;
+  };
+
+
+
+  template <typename number, bool constness>
+  inline
+  Iterator<number,constness> &
+  Iterator<number,constness>::operator ++ ()
+  {
+    move_forward ();
+    return *this;
+  };
+
+
+
+  template <typename number, bool constness>
+  inline
+  Iterator<number,constness>
+  Iterator<number,constness>::operator ++ (int)
+  {
+    const Iterator old_value = *this;
+    move_forward ();
+    return old_value;
+  };
+
+
+
+  template <typename number, bool constness>
+  inline
+  Iterator<number,constness> &
+  Iterator<number,constness>::operator -- ()
+  {
+    move_backward ();
+    return *this;
+  };
+
+
+
+  template <typename number, bool constness>
+  inline
+  Iterator<number,constness>
+  Iterator<number,constness>::operator -- (int)
+  {
+    const Iterator old_value = *this;
+    move_backward ();
+    return old_value;
+  };
+
+
+
+  template <typename number, bool constness>
+  inline
+  bool
+  Iterator<number,constness>::operator == (const Iterator &i) const
+  {
+    Assert (parent == i.parent, ExcPointerToDifferentVectors());
+
+    return (global_index == i.global_index);
+  };
+
+
+
+  template <typename number, bool constness>
+  inline
+  bool
+  Iterator<number,constness>::operator == (const InverseConstnessIterator &i) const
+  {
+    Assert (parent == i.parent, ExcPointerToDifferentVectors());
+
+    return (global_index == i.global_index);
+  };
+  
+
+
+  template <typename number, bool constness>
+  inline
+  bool
+  Iterator<number,constness>::operator != (const Iterator &i) const
+  {
+    Assert (parent == i.parent, ExcPointerToDifferentVectors());
+
+    return (global_index != i.global_index);
+  };
+
+
+
+  template <typename number, bool constness>
+  inline
+  bool
+  Iterator<number,constness>::operator != (const InverseConstnessIterator &i) const
+  {
+    Assert (parent == i.parent, ExcPointerToDifferentVectors());
+
+    return (global_index != i.global_index);
+  };
+  
+
+
+  template <typename number, bool constness>
+  inline
+  bool
+  Iterator<number,constness>::operator < (const Iterator &i) const
+  {
+    Assert (parent == i.parent, ExcPointerToDifferentVectors());
+
+    return (global_index < i.global_index);
+  };
+
+
+
+  template <typename number, bool constness>
+  inline
+  bool
+  Iterator<number,constness>::operator < (const InverseConstnessIterator &i) const
+  {
+    Assert (parent == i.parent, ExcPointerToDifferentVectors());
+
+    return (global_index < i.global_index);
+  };
+
+
+
+  template <typename number, bool constness>
+  inline
+  bool
+  Iterator<number,constness>::operator <= (const Iterator &i) const
+  {
+    Assert (parent == i.parent, ExcPointerToDifferentVectors());
+
+    return (global_index <= i.global_index);
+  };
+
+
+
+  template <typename number, bool constness>
+  inline
+  bool
+  Iterator<number,constness>::operator <= (const InverseConstnessIterator &i) const
+  {
+    Assert (parent == i.parent, ExcPointerToDifferentVectors());
+
+    return (global_index <= i.global_index);
+  };
+
+
+
+  template <typename number, bool constness>
+  inline
+  bool
+  Iterator<number,constness>::operator > (const Iterator &i) const
+  {
+    Assert (parent == i.parent, ExcPointerToDifferentVectors());
+
+    return (global_index > i.global_index);
+  };
+
+
+
+  template <typename number, bool constness>
+  inline
+  bool
+  Iterator<number,constness>::operator > (const InverseConstnessIterator &i) const
+  {
+    Assert (parent == i.parent, ExcPointerToDifferentVectors());
+
+    return (global_index > i.global_index);
+  };
+
+
+
+  template <typename number, bool constness>
+  inline
+  bool
+  Iterator<number,constness>::operator >= (const Iterator &i) const
+  {
+    Assert (parent == i.parent, ExcPointerToDifferentVectors());
+
+    return (global_index >= i.global_index);
+  };  
+
+
+
+  template <typename number, bool constness>
+  inline
+  bool
+  Iterator<number,constness>::operator >= (const InverseConstnessIterator &i) const
+  {
+    Assert (parent == i.parent, ExcPointerToDifferentVectors());
+
+    return (global_index >= i.global_index);
+  };  
+
+
+
+  template <typename number, bool constness>
+  inline
+  typename Iterator<number,constness>::difference_type
+  Iterator<number,constness>::operator - (const Iterator &i) const
+  {
+    Assert (parent == i.parent, ExcPointerToDifferentVectors());
+
+    return (static_cast<signed int>(global_index) -
+           static_cast<signed int>(i.global_index));
+  };  
+
+
+
+  template <typename number, bool constness>
+  inline
+  typename Iterator<number,constness>::difference_type
+  Iterator<number,constness>::operator - (const InverseConstnessIterator &i) const
+  {
+    Assert (parent == i.parent, ExcPointerToDifferentVectors());
+
+    return (static_cast<signed int>(global_index) -
+           static_cast<signed int>(i.global_index));
+  };
+
+
+
+  template <typename number, bool constness>
+  inline
+  Iterator<number,constness>
+  Iterator<number,constness>::operator + (const difference_type &d) const
+  {
+                                    // if the index pointed to is
+                                    // still within the block we
+                                    // currently point into, then we
+                                    // can save the computation of
+                                    // the block
+    if ((global_index+d >= next_break_backward) &&
+       (global_index+d <= next_break_forward))
+      return Iterator (*parent, global_index+d, current_block,
+                      index_within_block+d,
+                      next_break_forward, next_break_backward);
+    else
+                                      // outside present block, so
+                                      // have to seek new block
+                                      // anyway
+      return Iterator (*parent, global_index+d);
+  };
+
+
+
+  template <typename number, bool constness>
+  inline
+  Iterator<number,constness>
+  Iterator<number,constness>::operator - (const difference_type &d) const
+  {
+                                    // if the index pointed to is
+                                    // still within the block we
+                                    // currently point into, then we
+                                    // can save the computation of
+                                    // the block
+    if ((global_index-d >= next_break_backward) &&
+       (global_index-d <= next_break_forward))
+      return Iterator (*parent, global_index-d, current_block,
+                      index_within_block-d,
+                      next_break_forward, next_break_backward);
+    else
+                                      // outside present block, so
+                                      // have to seek new block
+                                      // anyway
+      return Iterator (*parent, global_index-d);
+  };
+
+
+
+  template <typename number, bool constness>
+  inline
+  Iterator<number,constness> &
+  Iterator<number,constness>::operator += (const difference_type &d)
+  {
+                                    // if the index pointed to is
+                                    // still within the block we
+                                    // currently point into, then we
+                                    // can save the computation of
+                                    // the block
+    if ((global_index+d >= next_break_backward) &&
+       (global_index+d <= next_break_forward))
+      {
+       global_index       += d;
+       index_within_block += d;
+      }
+    else
+                                      // outside present block, so
+                                      // have to seek new block
+                                      // anyway
+      *this = Iterator (*parent, global_index+d);
+
+    return *this;
+  };
+
+
+
+  template <typename number, bool constness>
+  inline
+  Iterator<number,constness> &
+  Iterator<number,constness>::operator -= (const difference_type &d)
+  {
+                                    // if the index pointed to is
+                                    // still within the block we
+                                    // currently point into, then we
+                                    // can save the computation of
+                                    // the block
+    if ((global_index-d >= next_break_backward) &&
+       (global_index-d <= next_break_forward))
+      {
+       global_index       -= d;
+       index_within_block -= d;
+      }
+    else
+                                      // outside present block, so
+                                      // have to seek new block
+                                      // anyway
+      *this = Iterator (*parent, global_index-d);
+
+    return *this;
+  };
+  
+};
+
+
 /**
  * Global function @p{swap} which overloads the default implementation
  * of the C++ standard library which uses a temporary object. The
index d151449c5ba19306464be9ac43042e22f151254e..897daf363d9e387d1f0d0de6e5bba91a1eafb127 100644 (file)
@@ -179,11 +179,28 @@ template <typename Number>
 typename BlockVector<Number>::const_iterator
 BlockVector<Number>::begin() const
 {
-  Assert (false, ExcNotImplemented());
-  return const_iterator(*const_cast<BlockVector*>(this), 0U);
+  return const_iterator(*this, 0U);
 };
 
 
+template <typename Number>
+typename BlockVector<Number>::iterator
+BlockVector<Number>::end()
+{
+  return iterator(*this, size());
+};
+
+
+
+template <typename Number>
+typename BlockVector<Number>::const_iterator
+BlockVector<Number>::end() const
+{
+  return const_iterator(*this, size());
+};
+
+
+
 template <typename Number>
 Number BlockVector<Number>::norm_sqr () const
 {
@@ -196,6 +213,7 @@ Number BlockVector<Number>::norm_sqr () const
 };
 
 
+
 template <typename Number>
 Number BlockVector<Number>::mean_value () const
 {
@@ -208,6 +226,7 @@ Number BlockVector<Number>::mean_value () const
 }
 
 
+
 template <typename Number>
 Number BlockVector<Number>::l1_norm () const
 {
@@ -220,6 +239,7 @@ Number BlockVector<Number>::l1_norm () const
 }
 
 
+
 template <typename Number>
 Number BlockVector<Number>::l2_norm () const
 {
@@ -227,6 +247,7 @@ Number BlockVector<Number>::l2_norm () const
 }
 
 
+
 template <typename Number>
 Number BlockVector<Number>::linfty_norm () const
 {
@@ -241,6 +262,7 @@ Number BlockVector<Number>::linfty_norm () const
 }
 
 
+
 template <typename Number>
 BlockVector<Number>&
 BlockVector<Number>::operator += (const BlockVector<Number>& v)
@@ -250,6 +272,7 @@ BlockVector<Number>::operator += (const BlockVector<Number>& v)
 }
 
 
+
 template <typename Number>
 BlockVector<Number>&
 BlockVector<Number>::operator -= (const BlockVector<Number>& v)
@@ -265,6 +288,7 @@ BlockVector<Number>::operator -= (const BlockVector<Number>& v)
 }
 
 
+
 template <typename Number>
 void BlockVector<Number>::add (const Number a)
 {
@@ -275,6 +299,7 @@ void BlockVector<Number>::add (const Number a)
 }
 
 
+
 template <typename Number>
 void BlockVector<Number>::add (const BlockVector<Number>& v)
 {
@@ -288,6 +313,7 @@ void BlockVector<Number>::add (const BlockVector<Number>& v)
 }
 
 
+
 template <typename Number>
 void BlockVector<Number>::add (const Number a,
                               const BlockVector<Number>& v)
@@ -302,6 +328,7 @@ void BlockVector<Number>::add (const Number a,
 }
 
 
+
 template <typename Number>
 void BlockVector<Number>::add (const Number a,
                               const BlockVector<Number>& v,
@@ -321,6 +348,7 @@ void BlockVector<Number>::add (const Number a,
 }
 
 
+
 template <typename Number>
 void BlockVector<Number>::sadd (const Number x,
                                const BlockVector<Number>& v)
@@ -335,6 +363,7 @@ void BlockVector<Number>::sadd (const Number x,
 }
 
 
+
 template <typename Number>
 void BlockVector<Number>::sadd (const Number x, const Number a,
                                const BlockVector<Number>& v)
@@ -349,6 +378,7 @@ void BlockVector<Number>::sadd (const Number x, const Number a,
 }
 
 
+
 template <typename Number>
 void BlockVector<Number>::sadd (const Number x, const Number a,
                                const BlockVector<Number>& v,
@@ -367,6 +397,7 @@ void BlockVector<Number>::sadd (const Number x, const Number a,
 }
 
 
+
 template <typename Number>
 void BlockVector<Number>::sadd (const Number x, const Number a,
                                const BlockVector<Number>& v,
@@ -526,268 +557,120 @@ 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 ()
+namespace BlockVectorIterators
 {
-  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)
+  template <typename number, bool constness>
+  Iterator<number,constness>::
+  Iterator (BlockVectorType &parent,
+           const unsigned   global_index)
+                 :
+                 parent (&parent),
+                 global_index (global_index)
+  {
+                                    // find which block we are
+                                    // in. for this, take into
+                                    // account that it happens at
+                                    // times that people want to
+                                    // initialize iterators
+                                    // past-the-end
+    if (global_index < parent.size())
       {
-                                        // ok, we traverse a boundary
-                                        // between blocks:
-       --current_block;
-       index_within_block = parent->block_indices.block_size(current_block)-1;
+       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;
        
-                                        // 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);
+         = parent.block_indices.local_to_global (current_block, 0);
+       next_break_forward
+         = (parent.block_indices.local_to_global (current_block, 0)
+            +parent.block_indices.block_size(current_block)-1);
       }
     else
-                                      // current block was 0, we now
-                                      // get into unspecified terrain
+                                      // past the end. only have one
+                                      // value for this
       {
-       --current_block;
-       index_within_block = static_cast<unsigned int>(-1);
-       next_break_forward = 0;
-       next_break_backward = 0;
+       this->global_index  = parent.size ();
+       current_block       = parent.n_blocks();
+       index_within_block  = 0;
+       next_break_backward = global_index;
+       next_break_forward  = static_cast<unsigned int>(-1);
       };
-  
-  --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());
+  template <typename number, bool constness>
+  void
+  Iterator<number,constness>::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;
 
-  return (global_index > i.global_index);
-};
+                                        // 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.block_size(current_block);
+       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>
-bool
-BlockVector<Number>::Iterator<Pointee>::operator >= (const Iterator &i) const
-{
-  Assert (parent == i.parent, ExcPointerToDifferentVectors());
 
-  return (global_index >= i.global_index);
+  template <typename number, bool constness>
+  void
+  Iterator<number,constness>::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.block_size (current_block);
+       }
+      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;
+  }; 
 };
 
 
-
-
 #endif
index a085184bb63eeddc975faebe8b982bc0e7e1ca7a..601deb685b513db3b8e968e5255c460a26ee605e 100644 (file)
 // explicit instantiations
 template class BlockVector<double>;
 template class BlockVector<float>;
+
+namespace BlockVectorIterators
+{
+  template class Iterator<double,false>;
+  template class Iterator<double,true>;
+
+  template class Iterator<float,false>;
+  template class Iterator<float,true>;
+};
+
index 03e38372a4a621c6e8c46ced097eb249de3e8220..19ab30819abd20aa97df23822e0eb568f208a57d 100644 (file)
@@ -20,20 +20,21 @@ default: run-tests
 
 ############################################################
 
-block_matrices.exe  : block_matrices.go                          $(libraries)
-block_vector.exe    : block_vector.go     abort.go               $(libraries)
-full_matrix.exe     : full_matrix.go                             $(libraries)
-matrix_out.exe      : matrix_out.go                              $(libraries)
-solver.exe          : solver.go                    testmatrix.go $(libraries)
-sparsity_pattern.exe: sparsity_pattern.go          testmatrix.go $(libraries)
-sparse_ilu.exe      : sparse_ilu.go                testmatrix.go $(libraries)
-vector-vector.exe   : vector-vector.go                           $(libraries)
-#mgbase.exe         : mgbase.go                                  $(libraries)
-#mg.exe             : mg.go                        testmatrix.go $(libraries)
-
-
-tests = block_matrices block_vector full_matrix matrix_out solver \
-       sparsity_pattern sparse_ilu vector-vector
+block_matrices.exe        : block_matrices.go                               $(libraries)
+block_vector.exe          : block_vector.go          abort.go               $(libraries)
+block_vector_iterator.exe : block_vector_iterator.go                        $(libraries)
+full_matrix.exe           : full_matrix.go                                  $(libraries)
+matrix_out.exe            : matrix_out.go                                   $(libraries)
+solver.exe                : solver.go                         testmatrix.go $(libraries)
+sparsity_pattern.exe      : sparsity_pattern.go               testmatrix.go $(libraries)
+sparse_ilu.exe            : sparse_ilu.go                     testmatrix.go $(libraries)
+vector-vector.exe         : vector-vector.go                                $(libraries)
+#mgbase.exe               : mgbase.go                                       $(libraries)
+#mg.exe                   : mg.go                             testmatrix.go $(libraries)
+
+
+tests = block_matrices block_vector block_vector_iterator full_matrix \
+        matrix_out solver sparsity_pattern sparse_ilu vector-vector
 
 ############################################################
 
diff --git a/tests/lac/block_vector_iterator.cc b/tests/lac/block_vector_iterator.cc
new file mode 100644 (file)
index 0000000..4c6c03a
--- /dev/null
@@ -0,0 +1,352 @@
+//--------------------------------------------------------------------
+//    $Id$
+//    Version: $Name$
+//
+//    Copyright (C) 2000, 2001 by the deal.II authors
+//
+//    This file is subject to QPL and may not be  distributed
+//    without copyright and license information. Please refer
+//    to the file deal.II/doc/license.html for the  text  and
+//    further information on this license.
+//
+//--------------------------------------------------------------------
+
+
+#include <base/logstream.h>
+#include <lac/block_vector.h>
+#include <fstream>
+#include <vector>
+#include <algorithm>
+#include <numeric>
+#include <utility>
+
+template <typename number>
+bool operator == (const BlockVector<number> &v1,
+                 const BlockVector<number> &v2)
+{
+  if (v1.size() != v2.size())
+    return false;
+  for (unsigned int i=0; i<v1.size(); ++i)
+    if (v1(i) != v2(i))
+      return false;
+  return true;
+};
+
+
+void test ()
+{
+  std::vector<unsigned int> ivector(4);
+  ivector[0] = 2;
+  ivector[1] = 4;
+  ivector[2] = 3;
+  ivector[3] = 5;
+  
+                                  // Check 1: initialization via
+                                  // iterators
+  if (true)
+    {
+      BlockVector<double> v1(ivector);
+      BlockVector<double> v2(ivector);
+
+                                      // initialize first vector with
+                                      // simple loop
+      for (unsigned int i=0; i<v1.size(); ++i)
+       v1(i) = i;
+                                      // initialize other vector
+                                      // through iterators
+      BlockVector<double>::iterator p2 = v2.begin();
+      for (unsigned int i=0; i<v1.size(); ++i, ++p2)
+       *p2 = i;
+      Assert (p2==v2.end(), ExcInternalError());
+      
+                                      // check that the two vectors are equal
+      deallog << "Check 1: " << (v1==v2 ? "true" : "false") << std::endl;
+    };
+
+                                  // Check 1: initialization via
+                                  // iterators
+  if (true)
+    {
+      BlockVector<double> v1(ivector);
+
+                                      // initialize first vector with
+                                      // simple loop
+      for (unsigned int i=0; i<v1.size(); ++i)
+       v1(i) = i;
+                                      // initialize other vector
+                                      // through iterators into first
+                                      // vector
+      BlockVector<double> v2(ivector, v1.begin(), v1.end());
+                                      // check that the two vectors are equal
+      deallog << "Check 2: " << (v1==v2 ? "true" : "false") << std::endl;
+    };
+
+                                  // Check 3: loop forward and back
+                                  // and check that things are the
+                                  // same
+  if (true)
+    {
+      BlockVector<double> v1(ivector);
+                                      // initialize first vector with
+                                      // simple loop
+      for (unsigned int i=0; i<v1.size(); ++i)
+       v1(i) = i;
+
+      BlockVector<double>::iterator p1 = v1.begin();
+      for (unsigned int i=0; i<v1.size(); ++i, ++p1)
+       Assert (*p1 == i, ExcInternalError());
+
+      Assert (p1 == v1.end(), ExcInternalError());
+      
+                                      // move back into allowable
+                                      // region
+      --p1;
+
+                                      // check backwards
+      for (unsigned int i=0; i<v1.size(); ++i, --p1)
+       Assert (*p1 == v1.size()-i-1, ExcInternalError());
+
+                                      // if we came thus far,
+                                      // everything is alright
+      deallog << "Check 3: true" << std::endl;
+    };
+
+
+                                  // Check 4: same, but this time
+                                  // with const iterators
+  if (true)
+    {
+      BlockVector<double> v1(ivector);
+                                      // initialize first vector with
+                                      // simple loop
+      for (unsigned int i=0; i<v1.size(); ++i)
+       v1(i) = i;
+
+      BlockVector<double>::const_iterator p1 = v1.begin();
+      for (unsigned int i=0; i<v1.size(); ++i, ++p1)
+       Assert (*p1 == i, ExcInternalError());
+
+      Assert (p1 == v1.end(), ExcInternalError());
+
+                                      // move back into allowable
+                                      // region
+      --p1;
+
+                                      // check backwards
+      for (unsigned int i=0; i<v1.size(); ++i, --p1)
+       Assert (*p1 == v1.size()-i-1, ExcInternalError());
+
+                                      // if we came thus far,
+                                      // everything is alright
+      deallog << "Check 4: true" << std::endl;
+    };
+
+                                  // Checks 5-14: use some standard
+                                  // algorithms
+  if (true)
+    {
+      BlockVector<double> v1(ivector);
+                                      // initialize first vector with
+                                      // simple loop
+      for (unsigned int i=0; i<v1.size(); ++i)
+       v1(i) = i;
+
+                                      // check std::distance
+                                      // algorithm
+      deallog << "Check 5: "
+             << (std::distance (v1.begin(), v1.end()) ==
+                 static_cast<signed int>(v1.size()) ?
+                 "true" : "false")
+             << std::endl;
+
+                                      // check std::copy
+      BlockVector<double> v2(ivector);
+      std::copy (v1.begin(), v1.end(), v2.begin());
+      deallog << "Check 6: " << (v1 == v2 ? "true" : "false") << std::endl;
+
+                                      // check std::transform
+      std::transform (v1.begin(), v1.end(), v2.begin(),
+                     std::bind2nd (std::multiplies<double>(),
+                                   2.0));
+      v2.scale (1./2.);
+      deallog << "Check 7: " << (v1 == v2 ? "true" : "false") << std::endl;
+
+
+                                      // check operators +/-, +=/-=
+      deallog << "Check 8: "
+             << (std::distance(v1.begin(), v1.begin()+3) == 3 ?
+                 "true" : "false")
+             << std::endl;
+      deallog << "Check 9: "
+             << (std::distance(v1.end()-6, v1.end()) == 6 ?
+                 "true" : "false")
+             << std::endl;
+      deallog << "Check 10: "
+             << (std::distance(v1.begin(), v1.end()) == (signed)v1.size() ?
+                 "true" : "false")
+             << std::endl;
+      deallog << "Check 11: "
+             << (std::distance(v1.begin(), (v1.begin()+=7)) == 7 ?
+                 "true" : "false")
+             << std::endl;
+      deallog << "Check 12: "
+             << (std::distance((v1.end()-=4), v1.end()) == 4 ?
+                 "true" : "false")
+             << std::endl;
+
+                                      // check advance
+      BlockVector<double>::iterator p2 = v1.begin();
+      std::advance (p2, v1.size());
+      deallog << "Check 13: " << (p2 == v1.end() ? "true" : "false") << std::endl;
+
+      BlockVector<double>::const_iterator p3 = v1.begin();
+      std::advance (p3, v1.size());
+      deallog << "Check 14: " << (p3 == v1.end() ? "true" : "false") << std::endl;
+    };
+
+                                  // Check 15: initialization through
+                                  // iterators
+  if (true)
+    {
+      BlockVector<double> v1(ivector);
+                                      // initialize first vector with
+                                      // simple loop
+      for (unsigned int i=0; i<v1.size(); ++i)
+       v1(i) = i;
+
+                                      // initialize a normal vector
+                                      // from it
+      Vector<double> v2(v1.begin(), v1.end());
+
+                                      // and reverse way
+      BlockVector<double> v3(ivector, v2.begin(), v2.end());
+      deallog << "Check 15: " << (v1==v3 ? "true" : "false") << std::endl;
+    };
+
+                                  // Check 16: initialization through
+                                  // iterators. variant with one
+                                  // constant object
+  if (true)
+    {
+      BlockVector<double> v1(ivector);
+                                      // initialize first vector with
+                                      // simple loop
+      for (unsigned int i=0; i<v1.size(); ++i)
+       v1(i) = i;
+
+                                      // initialize a normal vector
+                                      // from it
+      const Vector<double> v2(v1.begin(), v1.end());
+
+                                      // and reverse way
+      BlockVector<double> v3(ivector, v2.begin(), v2.end());
+      deallog << "Check 16: " << (v1==v3 ? "true" : "false") << std::endl;
+    };
+  
+                                  // Check 17: initialization through
+                                  // iterators. variant with two
+                                  // constant object
+  if (true)
+    {
+      BlockVector<double> v1(ivector);
+                                      // initialize first vector with
+                                      // simple loop
+      for (unsigned int i=0; i<v1.size(); ++i)
+       v1(i) = i;
+
+                                      // initialize a normal vector
+                                      // from it
+      const Vector<double> v2(v1.begin(), v1.end());
+
+                                      // and reverse way
+      const BlockVector<double> v3(ivector, v2.begin(), v2.end());
+      deallog << "Check 17: " << (v1==v3 ? "true" : "false") << std::endl;
+    };
+
+                                  // Check 18: initialization through
+                                  // iterators. variant with three
+                                  // constant object
+  if (true)
+    {
+      BlockVector<double> v0(ivector);
+                                      // initialize first vector with
+                                      // simple loop
+      for (unsigned int i=0; i<v0.size(); ++i)
+       v0(i) = i;
+
+      const BlockVector<double> v1 = v0;
+      
+                                      // initialize a normal vector
+                                      // from it
+      const Vector<double> v2(v1.begin(), v1.end());
+
+                                      // and reverse way
+      const BlockVector<double> v3(ivector, v2.begin(), v2.end());
+      deallog << "Check 18: " << (v1==v3 ? "true" : "false") << std::endl;
+    };
+  
+                                  // Check 19: operator[]
+  if (true)
+    {
+      BlockVector<double> v1(ivector);
+      for (unsigned int i=0; i<v1.size(); ++i)
+       v1(i) = i;
+
+      for (unsigned int i=0; i<v1.size(); ++i)
+       {
+         const BlockVector<double>::iterator p = (v1.begin()+i);
+         for (unsigned int j=0; j<v1.size(); ++j)
+           Assert (p[(signed)j-(signed)i] == j, ExcInternalError());
+       };
+
+                                      // if we came thus far,
+                                      // everything is alright
+      deallog << "Check 19: true" << std::endl;      
+    };
+};
+
+
+
+
+
+int main ()
+{
+  std::ofstream logfile("block_vector_iterator.output");
+  logfile.setf(std::ios::fixed);
+  logfile.precision(3);
+  deallog.attach(logfile);
+  deallog.depth_console(0);
+  
+  try
+    {
+      test ();
+    }
+  catch (std::exception &e)
+    {
+      std::cerr << std::endl << std::endl
+          << "----------------------------------------------------"
+          << std::endl;
+      std::cerr << "Exception on processing: " << e.what() << std::endl
+          << "Aborting!" << std::endl
+          << "----------------------------------------------------"
+          << std::endl;
+                                      // abort
+      return 2;
+    }
+  catch (...) 
+    {
+      std::cerr << std::endl << std::endl
+          << "----------------------------------------------------"
+          << std::endl;
+      std::cerr << "Unknown exception!" << std::endl
+          << "Aborting!" << std::endl
+          << "----------------------------------------------------"
+          << std::endl;
+                                      // abort
+      return 3;
+    };
+  
+  
+  return 0;
+};
+
diff --git a/tests/lac/block_vector_iterator.checked b/tests/lac/block_vector_iterator.checked
new file mode 100644 (file)
index 0000000..ca8a9d5
--- /dev/null
@@ -0,0 +1,20 @@
+
+DEAL::Check 1: true
+DEAL::Check 2: true
+DEAL::Check 3: true
+DEAL::Check 4: true
+DEAL::Check 5: true
+DEAL::Check 6: true
+DEAL::Check 7: true
+DEAL::Check 8: true
+DEAL::Check 9: true
+DEAL::Check 10: true
+DEAL::Check 11: true
+DEAL::Check 12: true
+DEAL::Check 13: true
+DEAL::Check 14: true
+DEAL::Check 15: true
+DEAL::Check 16: true
+DEAL::Check 17: true
+DEAL::Check 18: true
+DEAL::Check 19: true

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.