]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libstdc++-v3/testsuite/util/testsuite_iterators.h
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / util / testsuite_iterators.h
index a1c71a23cdd84605355def5e1b71f4a4726353c7..e01d7daea5da1adbca87befdc5a005f659ab2637 100644 (file)
@@ -1,7 +1,7 @@
 // -*- C++ -*-
 // Iterator Wrappers for the C++ library testsuite.
 //
-// Copyright (C) 2004-2016 Free Software Foundation, Inc.
+// Copyright (C) 2004-2020 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
@@ -56,8 +56,11 @@ namespace __gnu_test
     {
       T* first;
       T* last;
+
       BoundsContainer(T* _first, T* _last) : first(_first), last(_last)
       { }
+
+      std::size_t size() const { return last - first; }
     };
 
   // Simple container for holding state of a set of output iterators.
@@ -66,13 +69,11 @@ namespace __gnu_test
     {
       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[i] = false;
-      }
+      : BoundsContainer<T>(_first, _last), incrementedto(_first),
+       writtento(new bool[this->size()]())
+      { }
 
       ~OutputContainer()
       { delete[] writtento; }
@@ -86,14 +87,15 @@ namespace __gnu_test
 
     public:
       OutputContainer<T>* SharedInfo;
-      WritableObject(T* ptr_in,OutputContainer<T>* SharedInfo_in):
+
+      WritableObject(T* ptr_in, OutputContainer<T>* SharedInfo_in):
        ptr(ptr_in), SharedInfo(SharedInfo_in)
       { }
 
 #if __cplusplus >= 201103L
       template<class U>
-      void
-      operator=(U&& new_val)
+      typename std::enable_if<std::is_assignable<T&, U>::value>::type
+      operator=(U&& new_val) const
       {
        ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == 0);
        SharedInfo->writtento[ptr - SharedInfo->first] = 1;
@@ -132,9 +134,14 @@ namespace __gnu_test
       ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last);
     }
 
-    output_iterator_wrapper(const output_iterator_wrapper& in)
-    : ptr(in.ptr), SharedInfo(in.SharedInfo)
-    { }
+#if __cplusplus >= 201103L
+    output_iterator_wrapper() = delete;
+
+    output_iterator_wrapper(const output_iterator_wrapper&) = default;
+
+    output_iterator_wrapper&
+    operator=(const output_iterator_wrapper&) = default;
+#endif
 
     WritableObject<T>
     operator*() const
@@ -144,14 +151,6 @@ namespace __gnu_test
       return WritableObject<T>(ptr, SharedInfo);
     }
 
-    output_iterator_wrapper&
-    operator=(const output_iterator_wrapper& in)
-    {
-      ptr = in.ptr;
-      SharedInfo = in.SharedInfo;
-      return *this;
-    }
-
     output_iterator_wrapper&
     operator++()
     {
@@ -180,6 +179,20 @@ namespace __gnu_test
 #endif
   };
 
+#if __cplusplus >= 201103L
+  template<typename T, typename U>
+    void operator,(const T&, const output_iterator_wrapper<U>&) = delete;
+#endif
+
+#if __cplusplus >= 201103L
+  using std::remove_cv;
+#else
+  template<typename T> struct remove_cv { typedef T type; };
+  template<typename T> struct remove_cv<const T> { typedef T type; };
+  template<typename T> struct remove_cv<volatile T> { typedef T type; };
+  template<typename T> struct remove_cv<const volatile T> { typedef T type; };
+#endif
+
   /**
    * @brief input_iterator wrapper for pointer
    *
@@ -189,10 +202,11 @@ namespace __gnu_test
    */
   template<class T>
   class input_iterator_wrapper
-  : public std::iterator<std::input_iterator_tag, T, std::ptrdiff_t, T*, T&>
+  : public std::iterator<std::input_iterator_tag, typename remove_cv<T>::type,
+                        std::ptrdiff_t, T*, T&>
   {
   protected:
-    input_iterator_wrapper()
+    input_iterator_wrapper() : ptr(0), SharedInfo(0)
     { }
 
   public:
@@ -204,9 +218,12 @@ namespace __gnu_test
     : 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)
-    { }
+#if __cplusplus >= 201103L
+    input_iterator_wrapper(const input_iterator_wrapper&) = default;
+
+    input_iterator_wrapper&
+    operator=(const input_iterator_wrapper&) = default;
+#endif
 
     bool
     operator==(const input_iterator_wrapper& in) const
@@ -236,14 +253,6 @@ namespace __gnu_test
       return &**this;
     }
 
-    input_iterator_wrapper&
-    operator=(const input_iterator_wrapper& in)
-    {
-      ptr = in.ptr;
-      SharedInfo = in.SharedInfo;
-      return *this;
-    }
-
     input_iterator_wrapper&
     operator++()
     {
@@ -270,6 +279,10 @@ namespace __gnu_test
 #endif
   };
 
+#if __cplusplus >= 201103L
+  template<typename T, typename U>
+    void operator,(const T&, const input_iterator_wrapper<U>&) = delete;
+#endif
 
   /**
    * @brief forward_iterator wrapper for pointer
@@ -283,19 +296,20 @@ namespace __gnu_test
   {
     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()
     { }
 
-    forward_iterator_wrapper()
-    {
-      this->ptr = 0;
-      this->SharedInfo = 0;
-    }
+#if __cplusplus >= 201103L
+    forward_iterator_wrapper(const forward_iterator_wrapper&) = default;
+
+    forward_iterator_wrapper&
+    operator=(const forward_iterator_wrapper&) = default;
+#endif
 
     T&
     operator*() const
@@ -329,7 +343,7 @@ namespace __gnu_test
    * @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
+   * the requirements of a bidirectional_iterator. It should not be
    * instantiated directly, but generated from a test_container
    */
   template<class T>
@@ -337,24 +351,22 @@ namespace __gnu_test
   {
     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(): forward_iterator_wrapper<T>()
-    { }
+#if __cplusplus >= 201103L
+    bidirectional_iterator_wrapper(
+       const bidirectional_iterator_wrapper&) = default;
 
     bidirectional_iterator_wrapper&
-    operator=(const bidirectional_iterator_wrapper& in)
-    {
-      this->ptr = in.ptr;
-      this->SharedInfo = in.SharedInfo;
-      return *this;
-    }
+    operator=(const bidirectional_iterator_wrapper&) = default;
+#endif
 
     bidirectional_iterator_wrapper&
     operator++()
@@ -393,7 +405,7 @@ namespace __gnu_test
    * @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
+   * the requirements of a random_access_iterator. It should not be
    * instantiated directly, but generated from a test_container
    */
   template<class T>
@@ -402,24 +414,22 @@ namespace __gnu_test
   {
     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():bidirectional_iterator_wrapper<T>()
-    { }
+#if __cplusplus >= 201103L
+    random_access_iterator_wrapper(
+       const random_access_iterator_wrapper&) = default;
 
     random_access_iterator_wrapper&
-    operator=(const random_access_iterator_wrapper& in)
-    {
-      this->ptr = in.ptr;
-      this->SharedInfo = in.SharedInfo;
-      return *this;
-    }
+    operator=(const random_access_iterator_wrapper&) = default;
+#endif
 
     random_access_iterator_wrapper&
     operator++()
@@ -539,13 +549,21 @@ namespace __gnu_test
   struct test_container
   {
     typename ItType<T>::ContainerType bounds;
-    test_container(T* _first, T* _last):bounds(_first, _last)
+
+    test_container(T* _first, T* _last) : bounds(_first, _last)
     { }
 
+#if __cplusplus >= 201103L
+    template<std::size_t N>
+      explicit
+      test_container(T (&arr)[N]) : test_container(arr, arr+N)
+      { }
+#endif
+
     ItType<T>
     it(int pos)
     {
-      ITERATOR_VERIFY(pos >= 0 && pos <= (bounds.last - bounds.first));
+      ITERATOR_VERIFY(pos >= 0 && pos <= size());
       return ItType<T>(bounds.first + pos, &bounds);
     }
 
@@ -567,6 +585,184 @@ namespace __gnu_test
     ItType<T>
     end()
     { return it(bounds.last); }
-   };
-}
-#endif
+
+    std::size_t
+    size() const
+    { return bounds.size(); }
+  };
+
+#if __cplusplus > 201703L
+  template<typename T>
+    struct contiguous_iterator_wrapper
+    : random_access_iterator_wrapper<T>
+    {
+      using random_access_iterator_wrapper<T>::random_access_iterator_wrapper;
+
+      using iterator_concept = std::contiguous_iterator_tag;
+
+      contiguous_iterator_wrapper&
+      operator++()
+      {
+       random_access_iterator_wrapper<T>::operator++();
+       return *this;
+      }
+
+      contiguous_iterator_wrapper&
+      operator--()
+      {
+       random_access_iterator_wrapper<T>::operator--();
+       return *this;
+      }
+
+      contiguous_iterator_wrapper
+      operator++(int)
+      {
+       auto tmp = *this;
+       ++*this;
+       return tmp;
+      }
+
+      contiguous_iterator_wrapper
+      operator--(int)
+      {
+       auto tmp = *this;
+       --*this;
+       return tmp;
+      }
+
+      contiguous_iterator_wrapper&
+      operator+=(std::ptrdiff_t n)
+      {
+       random_access_iterator_wrapper<T>::operator+=(n);
+       return *this;
+      }
+
+      friend contiguous_iterator_wrapper
+      operator+(contiguous_iterator_wrapper iter, std::ptrdiff_t n)
+      { return iter += n; }
+
+      friend contiguous_iterator_wrapper
+      operator+(std::ptrdiff_t n, contiguous_iterator_wrapper iter)
+      { return iter += n; }
+
+      contiguous_iterator_wrapper&
+      operator-=(std::ptrdiff_t n)
+      { return *this += -n; }
+
+      friend contiguous_iterator_wrapper
+      operator-(contiguous_iterator_wrapper iter, std::ptrdiff_t n)
+      { return iter -= n; }
+    };
+
+  // A type meeting the minimum std::range requirements
+  template<typename T, template<typename> class Iter>
+    class test_range
+    {
+      // Adds default constructor to Iter<T> if needed
+      struct iterator : Iter<T>
+      {
+       using Iter<T>::Iter;
+
+       iterator() : Iter<T>(nullptr, nullptr) { }
+
+       using Iter<T>::operator++;
+
+       iterator& operator++() { Iter<T>::operator++(); return *this; }
+      };
+
+      template<typename I>
+       struct sentinel
+       {
+         T* end;
+
+         friend bool operator==(const sentinel& s, const I& i)
+         { return s.end == i.ptr; }
+       };
+
+      auto
+      get_iterator(T* p)
+      {
+       if constexpr (std::default_initializable<Iter<T>>)
+         return Iter<T>(p, &bounds);
+       else
+         return iterator(p, &bounds);
+      }
+
+    public:
+      test_range(T* first, T* last) : bounds(first, last)
+      { }
+
+      template<std::size_t N>
+       explicit
+       test_range(T (&arr)[N]) : test_range(arr, arr+N)
+       { }
+
+      auto begin() & { return get_iterator(bounds.first); }
+
+      auto end() &
+      {
+       using I = decltype(get_iterator(bounds.last));
+       if constexpr (std::sentinel_for<I, I>)
+         return get_iterator(bounds.last);
+       else
+         return sentinel<I>{bounds.last};
+      }
+
+      typename Iter<T>::ContainerType bounds;
+    };
+
+  template<typename T>
+    using test_contiguous_range
+      = test_range<T, contiguous_iterator_wrapper>;
+  template<typename T>
+    using test_random_access_range
+      = test_range<T, random_access_iterator_wrapper>;
+  template<typename T>
+    using test_bidirectional_range
+      = test_range<T, bidirectional_iterator_wrapper>;
+  template<typename T>
+    using test_forward_range
+      = test_range<T, forward_iterator_wrapper>;
+  template<typename T>
+    using test_input_range
+      = test_range<T, input_iterator_wrapper>;
+  template<typename T>
+    using test_output_range
+      = test_range<T, output_iterator_wrapper>;
+
+  // A type meeting the minimum std::sized_range requirements
+  template<typename T, template<typename> class Iter>
+    struct test_sized_range : test_range<T, Iter>
+    {
+      using test_range<T, Iter>::test_range;
+
+      std::size_t size() const noexcept
+      { return this->bounds.size(); }
+    };
+
+  template<typename T>
+    using test_contiguous_sized_range
+      = test_sized_range<T, contiguous_iterator_wrapper>;
+  template<typename T>
+    using test_random_access_sized_range
+      = test_sized_range<T, random_access_iterator_wrapper>;
+  template<typename T>
+    using test_bidirectional_sized_range
+      = test_sized_range<T, bidirectional_iterator_wrapper>;
+  template<typename T>
+    using test_forward_sized_range
+      = test_sized_range<T, forward_iterator_wrapper>;
+  template<typename T>
+    using test_input_sized_range
+      = test_sized_range<T, input_iterator_wrapper>;
+  template<typename T>
+    using test_output_sized_range
+      = test_sized_range<T, output_iterator_wrapper>;
+
+// test_container, test_range and test_sized_range do not own their elements,
+// so they all model std::ranges::safe_range. This file does not define
+// specializations of std::ranges::enable_safe_range, so that individual
+// test can decide whether or not to do so.
+#endif // C++20
+} // namespace __gnu_test
+#endif // _TESTSUITE_ITERATORS