testsuite_iterators.h: New.
authorChris Jefferson <chris@bubblescope.net>
Wed, 24 Nov 2004 06:24:10 +0000 (06:24 +0000)
committerBenjamin Kosnik <bkoz@gcc.gnu.org>
Wed, 24 Nov 2004 06:24:10 +0000 (06:24 +0000)
2004-11-23  Chris Jefferson  <chris@bubblescope.net>

        * testsuite/testsuite_iterators.h: New.
        * testsuite/25_algorithms/search_n/iterator.cc: New.
        * testsuite/performance/25_algorithms/search_n.cc: New.

From-SVN: r91139

libstdc++-v3/ChangeLog
libstdc++-v3/testsuite/25_algorithms/search_n/iterator.cc [new file with mode: 0644]
libstdc++-v3/testsuite/performance/25_algorithms/search_n.cc [new file with mode: 0644]
libstdc++-v3/testsuite/testsuite_iterators.h [new file with mode: 0644]

index 2a182b5..75fd077 100644 (file)
@@ -1,3 +1,9 @@
+2004-11-23  Chris Jefferson  <chris@bubblescope.net>
+
+       * testsuite/testsuite_iterators.h: New.
+        * testsuite/25_algorithms/search_n/iterator.cc: New.
+        * testsuite/performance/25_algorithms/search_n.cc: New.
+
 2004-11-23  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 
        * testsuite/lib/libstdc++.exp: Use new procs in target-libpath.exp.
diff --git a/libstdc++-v3/testsuite/25_algorithms/search_n/iterator.cc b/libstdc++-v3/testsuite/25_algorithms/search_n/iterator.cc
new file mode 100644 (file)
index 0000000..f822745
--- /dev/null
@@ -0,0 +1,103 @@
+// Copyright (C) 2004 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 25 algorithms, search_n
+
+#include <algorithm>
+#include <functional>
+#include <testsuite_hooks.h>
+#include <testsuite_iterators.h>
+
+#define TEST_DEPTH 14
+int array1[11] = {0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0};
+int array2[TEST_DEPTH];
+
+bool 
+pred(int i, int j)
+{
+  return i == j;
+}
+
+bool
+lexstep(int* start, int length) 
+{
+  int i = 0;
+  int carry = 1;
+  while(i < length && carry) 
+    {
+      if(start[i] == 1)
+       start[i] = 0;
+      else 
+       {
+         start[i] = 1;
+         carry = 0;
+       }
+      i++;
+    }
+  return !carry;
+}
+
+using __gnu_test::test_container;
+using __gnu_test::random_access_iterator_wrapper;
+using __gnu_test::bidirectional_iterator_wrapper;
+using __gnu_test::forward_iterator_wrapper;
+
+int main() {
+  test_container<int,forward_iterator_wrapper> con(array1,array1 + 10);
+  VERIFY(search_n(con.end(), con.end(), 0, 1) == con.end());
+  VERIFY(search_n(con.end(), con.end(), 1, 1) == con.end());
+  VERIFY(search_n(con.begin(), con.end(), 1, 1).ptr == array1 + 1);
+  VERIFY(search_n(con.begin(), con.end(), 2, 1).ptr == array1 + 4);
+  VERIFY(search_n(con.begin(), con.end(), 3, 1).ptr == array1 + 7);
+  VERIFY(search_n(con.begin(), con.end(), 3, 0) == con.end());
+
+  // Now do a brute-force comparison of the different types
+  for(int i = 0; i < TEST_DEPTH; i++) 
+    {
+      for(int j = 0; j < i; j++)
+       array2[i] = 0;
+      do {
+       for(int j = 0; j < i; j++)
+         {
+           test_container<int, forward_iterator_wrapper>
+             forwardcon(array2, array2 + i);
+           test_container<int, bidirectional_iterator_wrapper>
+             randomcon(array2, array2 + i);
+           test_container<int, bidirectional_iterator_wrapper>
+             bidircon(array2, array2 + i);
+
+           int* t1 = search_n(forwardcon.begin(),
+                              forwardcon.end(), j, 1).ptr;
+           int* t2 = search_n(forwardcon.begin(),
+                              forwardcon.end(), j, 1, pred).ptr;
+           int* t3 = search_n(bidircon.begin(),
+                              bidircon.end(), j, 1).ptr;
+           int* t4 = search_n(bidircon.begin(),
+                              bidircon.end(), j, 1, pred).ptr;
+           int* t5 = search_n(randomcon.begin(),
+                              randomcon.end(), j, 1).ptr;
+           int* t6 = search_n(randomcon.begin(),
+                              randomcon.end(), j, 1, pred).ptr;
+           VERIFY((t1 == t2) && (t2 == t3) && (t3 == t4) &&
+                  (t4 == t5) && (t5 == t6));
+         }
+      } 
+      while(lexstep(array2, i));
+    }
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/performance/25_algorithms/search_n.cc b/libstdc++-v3/testsuite/performance/25_algorithms/search_n.cc
new file mode 100644 (file)
index 0000000..6ffa0a9
--- /dev/null
@@ -0,0 +1,72 @@
+// Copyright (C) 2004 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#define DISABLE_ITERATOR_DEBUG 1
+
+#include<cstdlib>
+#include<vector>
+#include<algorithm>
+
+#include<sstream>
+#include<testsuite_performance.h>
+#include<testsuite_iterators.h>
+
+using namespace std;
+using namespace __gnu_test;
+
+const int length = 10000000;
+const int match_length = 3;
+int array[length];
+
+int
+main(void)
+{
+  time_counter time;
+  resource_counter resource;
+  int match = rand() % (match_length - 1);
+  for(int i = 0; i < length; i++)
+    {
+      array[i] = (match != 0) ? 1 : 0;
+      if(--match < 0) match = rand() % (match_length - 1);
+    }
+  test_container<int, forward_iterator_wrapper> fcon(array, array + length);
+  start_counters(time, resource);
+  for(int i = 0; i < 100; i++)
+    search_n(fcon.begin(), fcon.end(), 10, 1);
+  stop_counters(time, resource);
+  report_performance(__FILE__, "forward iterator", time, resource);
+  clear_counters(time, resource);
+
+  test_container<int, random_access_iterator_wrapper> rcon(array, array + length);
+  start_counters(time, resource);
+  for(int i = 0; i < 100; i++)
+    search_n(rcon.begin(), rcon.end(), 10, 1);
+  stop_counters(time, resource);
+  report_performance(__FILE__, "random acess iterator", time, resource);
+  clear_counters(time, resource);
+}
+
diff --git a/libstdc++-v3/testsuite/testsuite_iterators.h b/libstdc++-v3/testsuite/testsuite_iterators.h
new file mode 100644 (file)
index 0000000..435bb1d
--- /dev/null
@@ -0,0 +1,539 @@
+// -*- C++ -*-
+// Iterator Wrappers for the C++ library testsuite. 
+//
+// Copyright (C) 2004 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+//
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// This file provides the following:
+//
+// input_iterator_wrapper, output_iterator_wrapper
+// forward_iterator_wrapper, bidirectional_iterator_wrapper and
+// random_access_wrapper, which attempt to exactly perform the requirements
+// of these types of iterators. These are constructed from the class
+// test_container, which is given two pointers to T and an iterator type.
+
+#include <testsuite_hooks.h>
+#include <iterator>
+
+#ifndef _TESTSUITE_ITERATORS
+#define _TESTSUITE_ITERATORS
+
+#ifdef DISABLE_ITERATOR_DEBUG
+#define ITERATOR_VERIFY(x)
+#else
+#define ITERATOR_VERIFY(x) VERIFY(x)
+#endif
+
+namespace __gnu_test
+{
+  /**
+   * @brief Simple container for holding two pointers.
+   *
+   * Note that input_iterator_wrapper changes first to denote
+   * how the valid range of == , ++, etc. change as the iterators are used.
+   */
+  template<typename T>
+    struct BoundsContainer
+    {
+      T* first;
+      T* last;
+      BoundsContainer(T* _first, T* _last)
+       : first(_first), last(_last)
+      { }
+    };
+
+  // Simple container for holding state of a set of output iterators.
+  template<typename T>
+    struct OutputContainer : public BoundsContainer<T>
+    {
+      T* incrementedto;
+      bool* writtento;
+      OutputContainer(T* _first, T* _last)
+       : BoundsContainer<T>(_first, _last), incrementedto(_first)
+      {
+       writtento = new bool[this->last - this->first];
+       for(int i = 0; i < this->last - this->first; i++)
+         writtento = false;
+      }
+
+      ~OutputContainer()
+      { delete[] writtento; }
+    };
+
+  // Produced by output_iterator to allow limited writing to pointer
+  template<class T>
+    class WritableObject
+    {
+      T* ptr;
+
+    public:
+      OutputContainer<T>* SharedInfo;
+      WritableObject(T* ptr_in,OutputContainer<T>* SharedInfo_in):
+       ptr(ptr_in), SharedInfo(SharedInfo_in)
+      { }
+
+      void
+      operator=(T& new_val)
+      {
+       ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == 0);
+       SharedInfo->writtento[ptr - SharedInfo->first] = 1;
+       ptr = new_val;
+      }
+    };
+
+  /**
+   * @brief output_iterator wrapper for pointer
+   * 
+   * This class takes a pointer and wraps it to provide exactly
+   * the requirements of a output_iterator. It should not be
+   * instansiated directly, but generated from a test_container
+   */
+  template<class T>
+  struct output_iterator_wrapper: public std::iterator
+  <std::output_iterator_tag, T, ptrdiff_t, T*, T&>
+  {
+    typedef OutputContainer<T> ContainerType;
+    T* ptr;
+    ContainerType* SharedInfo;
+
+    output_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
+      :ptr(_ptr), SharedInfo(SharedInfo_in)
+    {
+      ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last);
+    }
+    
+    output_iterator_wrapper(const output_iterator_wrapper& in)
+      :ptr(in.ptr), SharedInfo(in.SharedInfo)
+    { }
+
+    WritableObject<T>
+    operator*() const
+    {
+      ITERATOR_VERIFY(ptr < SharedInfo->last);
+      ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == false);
+      return WritableObject<T>(ptr, SharedInfo);
+    }
+    
+    output_iterator_wrapper&
+    operator=(const output_iterator_wrapper& in) 
+    {
+      ptr = in.ptr;
+      SharedInfo = in.SharedInfo;
+    }
+
+    output_iterator_wrapper&
+    operator++()
+    {
+      ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
+      ITERATOR_VERIFY(ptr>=SharedInfo->first);
+      ptr++;
+      SharedInfo->first=ptr;
+      return *this;
+    }
+
+    output_iterator_wrapper
+    operator++(int)
+    {
+      output_iterator_wrapper<T> tmp = *this;
+      ++*this;
+      return tmp;
+    }
+
+  };
+
+  /**
+   * @brief input_iterator wrapper for pointer
+   * 
+   * This class takes a pointer and wraps it to provide exactly
+   * the requirements of a input_iterator. It should not be
+   * instansiated directly, but generated from a test_container
+   */
+  template<class T>
+  class input_iterator_wrapper:public std::iterator
+  <std::input_iterator_tag, T, ptrdiff_t, T*, T&>
+  {
+  protected:
+    input_iterator_wrapper()
+    { }
+
+  public:
+    typedef BoundsContainer<T> ContainerType;
+    T* ptr;
+    ContainerType* SharedInfo;
+
+    input_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
+      : ptr(_ptr), SharedInfo(SharedInfo_in)
+    { ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last); }
+    
+    input_iterator_wrapper(const input_iterator_wrapper& in)
+      : ptr(in.ptr), SharedInfo(in.SharedInfo)
+    { }
+
+    bool
+    operator==(const input_iterator_wrapper& in) const
+    {
+      ITERATOR_VERIFY(SharedInfo != NULL && SharedInfo == in.SharedInfo);
+      ITERATOR_VERIFY(ptr>=SharedInfo->first && in.ptr>=SharedInfo->first);
+      return ptr == in.ptr;
+    }
+
+    bool
+    operator!=(const input_iterator_wrapper& in) const
+    {
+      return !(*this == in);
+    }
+
+    T&
+    operator*() const
+    {
+      ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
+      ITERATOR_VERIFY(ptr >= SharedInfo->first);
+      return *ptr;
+    }
+
+    T*
+    operator->() const
+    {
+      return &**this;
+    }
+
+    input_iterator_wrapper&
+    operator=(const input_iterator_wrapper& in)
+    {
+      ptr = in.ptr;
+      SharedInfo = in.SharedInfo;
+      return *this;
+    }
+
+    input_iterator_wrapper&
+    operator++()
+    {
+      ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
+      ITERATOR_VERIFY(ptr>=SharedInfo->first);
+      ptr++;
+      SharedInfo->first=ptr;
+      return *this;
+    }
+
+    void
+    operator++(int)
+    {
+      ++*this;
+    }
+  };
+
+
+  /**
+   * @brief forward_iterator wrapper for pointer
+   * 
+   * This class takes a pointer and wraps it to provide exactly
+   * the requirements of a forward_iterator. It should not be
+   * instansiated directly, but generated from a test_container
+   */
+  template<class T>
+  struct forward_iterator_wrapper:public input_iterator_wrapper<T>
+  {
+    typedef BoundsContainer<T> ContainerType;
+    typedef std::forward_iterator_tag iterator_category;
+    forward_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
+      :input_iterator_wrapper<T>(_ptr, SharedInfo_in)
+    { }
+    
+    forward_iterator_wrapper(const forward_iterator_wrapper& in)
+      :input_iterator_wrapper<T>(in)
+    { }
+
+    forward_iterator_wrapper()
+    {
+      this->ptr = NULL;
+      this->SharedInfo = NULL;
+    }
+
+    T&
+    operator*() const
+    {
+      ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
+      return *(this->ptr);
+    }
+
+    T*
+    operator->() const
+    { return &**this; }
+
+    forward_iterator_wrapper&
+    operator++()
+    {
+      ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
+      this->ptr++;
+      return *this;
+    }
+
+    forward_iterator_wrapper
+    operator++(int)
+    {
+      forward_iterator_wrapper<T> tmp = *this;
+      ++*this;
+      return tmp;
+    }
+   };
+
+  /**
+   * @brief bidirectional_iterator wrapper for pointer
+   * 
+   * This class takes a pointer and wraps it to provide exactly
+   * the requirements of a forward_iterator. It should not be
+   * instansiated directly, but generated from a test_container
+   */
+  template<class T>
+  struct bidirectional_iterator_wrapper:public forward_iterator_wrapper<T>
+  {
+    typedef BoundsContainer<T> ContainerType;
+    typedef std::bidirectional_iterator_tag iterator_category;
+    bidirectional_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
+      :forward_iterator_wrapper<T>(_ptr, SharedInfo_in)
+    { }
+
+    bidirectional_iterator_wrapper(const bidirectional_iterator_wrapper& in)
+      :forward_iterator_wrapper<T>(in)
+    { }
+
+    bidirectional_iterator_wrapper(): forward_iterator_wrapper<T>()
+    { }
+
+    bidirectional_iterator_wrapper&
+    operator=(const bidirectional_iterator_wrapper& in)
+    {
+      this->ptr = in.ptr;
+      this->SharedInfo = in.SharedInfo;
+      return *this;
+    }
+   
+    bidirectional_iterator_wrapper&
+    operator++()
+    {
+      ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
+      this->ptr++;
+      return *this;
+    }
+
+    bidirectional_iterator_wrapper
+    operator++(int)
+    {
+      bidirectional_iterator_wrapper<T> tmp = *this;
+      ++*this;
+      return tmp;
+    }
+
+    bidirectional_iterator_wrapper& 
+    operator--()
+    {
+      ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first);
+      this->ptr--;
+      return *this;
+    }
+
+    bidirectional_iterator_wrapper
+    operator--(int)
+    { 
+      bidirectional_iterator_wrapper<T> tmp = *this;
+      --*this;
+      return tmp;
+    }
+   };
+
+  /**
+   * @brief random_access_iterator wrapper for pointer
+   * 
+   * This class takes a pointer and wraps it to provide exactly
+   * the requirements of a forward_iterator. It should not be
+   * instansiated directly, but generated from a test_container
+   */
+  template<class T>
+  struct random_access_iterator_wrapper:public bidirectional_iterator_wrapper<T>
+  {
+    typedef BoundsContainer<T> ContainerType;
+    typedef std::random_access_iterator_tag iterator_category;
+    random_access_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
+      : bidirectional_iterator_wrapper<T>(_ptr, SharedInfo_in)
+    { }
+
+    random_access_iterator_wrapper(const random_access_iterator_wrapper<T>& in)
+      : bidirectional_iterator_wrapper<T>(in)
+    { }
+
+    random_access_iterator_wrapper():bidirectional_iterator_wrapper<T>()
+    { }
+
+    random_access_iterator_wrapper&
+    operator=(const random_access_iterator_wrapper& in)
+    {
+      this->ptr = in.ptr;
+      this->SharedInfo = in.SharedInfo;
+    }
+
+    random_access_iterator_wrapper&
+    operator++()
+    {
+      ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
+      this->ptr++;
+      return *this;
+    }
+
+    random_access_iterator_wrapper
+    operator++(int)
+    {
+      random_access_iterator_wrapper<T> tmp = *this;
+      ++*this;
+      return tmp;
+    }
+
+    random_access_iterator_wrapper&
+    operator--()
+    {
+      ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first);
+      this->ptr--;
+      return *this;
+    }
+
+    random_access_iterator_wrapper
+    operator--(int)
+    {
+      random_access_iterator_wrapper<T> tmp = *this;
+      ++*this;
+      return tmp;
+    }
+
+    random_access_iterator_wrapper&
+    operator+=(ptrdiff_t n)
+    {
+      if(n > 0)
+       {
+         ITERATOR_VERIFY(n <= this->SharedInfo->last - this->ptr);
+         this->ptr += n;
+       }
+      else
+       {
+         ITERATOR_VERIFY(n <= this->ptr - this->SharedInfo->first);
+         this->ptr += n;
+       }
+      return *this;
+    }
+
+    random_access_iterator_wrapper
+    operator+(ptrdiff_t n)
+    {
+      random_access_iterator_wrapper<T> tmp = *this;
+      return tmp += n;
+    }
+
+    random_access_iterator_wrapper&
+    operator-=(ptrdiff_t n)
+    { return *this += -n; }
+
+    random_access_iterator_wrapper
+    operator-(ptrdiff_t n)
+    {
+      random_access_iterator_wrapper<T> tmp = *this;
+      return tmp -= n;
+    }
+
+    ptrdiff_t
+    operator-(const random_access_iterator_wrapper<T>& in)
+    {
+      ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo);
+      return this->ptr - in.ptr;
+    }
+
+    T&
+    operator[](ptrdiff_t n)
+    { return *(this + n); }
+
+    bool
+    operator<(const random_access_iterator_wrapper<T>& in) const
+    {
+      ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo);
+      return this->ptr < in.ptr;
+    }
+
+    bool
+    operator>(const random_access_iterator_wrapper<T>& in) const
+    {
+      return in < *this;
+    }
+
+    bool
+    operator>=(const random_access_iterator_wrapper<T>& in) const
+    {
+      return !(*this < in);
+    }
+
+    bool 
+    operator<=(const random_access_iterator_wrapper<T>& in) const
+    {
+      return !(*this > in);
+    }
+   };
+
+
+  /** 
+   * @brief A container-type class for holding iterator wrappers
+   * test_container takes two parameters, a class T and an iterator
+   * wrapper templated by T (for example forward_iterator_wrapper<T>.
+   * It takes two pointers representing a range and presents them as 
+   * a container of iterators.
+   */
+  template <class T, template<class T> class ItType>
+  struct test_container
+  {
+    typename ItType<T>::ContainerType bounds;
+    test_container(T* _first, T* _last):bounds(_first, _last)
+    { }
+
+    ItType<T>
+    it(int pos)
+    {
+      ITERATOR_VERIFY(pos >= 0 && pos <= (bounds.last - bounds.first));
+      return ItType<T>(bounds.first + pos, &bounds);
+    }
+
+    ItType<T>
+    it(T* pos)
+    {
+      ITERATOR_VERIFY(pos >= bounds.first && pos <= bounds.last);
+      return ItType<T>(pos, &bounds);
+    }
+
+    ItType<T>
+    begin()
+    { return it(bounds.first); }
+
+    ItType<T>
+    end()
+    { return it(bounds.last); }
+   };
+}
+#endif