PR libstdc++/30449 (fill, fill_n)
[gcc.git] / libstdc++-v3 / include / bits / stl_algobase.h
index da93e1588f68e0e33a99b21beeb3b2e72d703177..c0107fc3d9f840fce21054fc9b71b050d62ec907 100644 (file)
@@ -1,6 +1,6 @@
 // Bits and pieces used in algorithms -*- C++ -*-
 
-// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 
 #include <bits/c++config.h>
 #include <cstring>
+#include <cwchar>
 #include <climits>
 #include <cstdlib>
 #include <cstddef>
 #include <iosfwd>
 #include <bits/stl_pair.h>
 #include <bits/cpp_type_traits.h>
+#include <ext/type_traits.h>
 #include <bits/stl_iterator_base_types.h>
 #include <bits/stl_iterator_base_funcs.h>
 #include <bits/stl_iterator.h>
@@ -166,9 +168,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
        iter_swap(__a, __b);
     }
 
-#undef min
-#undef max
-
   /**
    *  @brief This does what you think it does.
    *  @param  a  A thing of arbitrary type.
@@ -319,17 +318,17 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 
   // Helpers for streambuf iterators (either istream or ostream).
   template<typename _CharT>
-    typename __enable_if<ostreambuf_iterator<_CharT>,
-                        __is_char<_CharT>::__value>::__type
+  typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, 
+                                 ostreambuf_iterator<_CharT> >::__type
     __copy_aux(_CharT*, _CharT*, ostreambuf_iterator<_CharT>);
 
   template<typename _CharT>
-    typename __enable_if<ostreambuf_iterator<_CharT>,
-                        __is_char<_CharT>::__value>::__type
+    typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, 
+                                   ostreambuf_iterator<_CharT> >::__type
     __copy_aux(const _CharT*, const _CharT*, ostreambuf_iterator<_CharT>);
 
   template<typename _CharT>
-    typename __enable_if<_CharT*, __is_char<_CharT>::__value>::__type
+  typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, _CharT*>::__type
     __copy_aux(istreambuf_iterator<_CharT>, istreambuf_iterator<_CharT>,
               _CharT*);
 
@@ -405,8 +404,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 
   // Overload for streambuf iterators.
   template<typename _CharT>
-    typename __enable_if<ostreambuf_iterator<_CharT>,
-                        __is_char<_CharT>::__value>::__type
+    typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, 
+                                   ostreambuf_iterator<_CharT> >::__type
     copy(istreambuf_iterator<_CharT>, istreambuf_iterator<_CharT>,
         ostreambuf_iterator<_CharT>);
 
@@ -542,6 +541,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                                                                   __result);
     }
 
+
   template<bool>
     struct __fill
     {
@@ -569,78 +569,90 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
        }
     };
 
-  /**
-   *  @brief Fills the range [first,last) with copies of value.
-   *  @param  first  A forward iterator.
-   *  @param  last   A forward iterator.
-   *  @param  value  A reference-to-const of arbitrary type.
-   *  @return   Nothing.
-   *
-   *  This function fills a range with copies of the same value.  For one-byte
-   *  types filling contiguous areas of memory, this becomes an inline call to
-   *  @c memset.
-  */
   template<typename _ForwardIterator, typename _Tp>
-    void
-    fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
+    inline void
+    __fill_aux(_ForwardIterator __first, _ForwardIterator __last,
+              const _Tp& __value)
     {
-      // concept requirements
-      __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
-                                 _ForwardIterator>)
-      __glibcxx_requires_valid_range(__first, __last);
-
       const bool __scalar = __is_scalar<_Tp>::__value;
       std::__fill<__scalar>::fill(__first, __last, __value);
     }
 
-  // Specialization: for one-byte types we can use memset.
+  // Specialization: for char types we can use memset (wmemset).
   inline void
-  fill(unsigned char* __first, unsigned char* __last, const unsigned char& __c)
+  __fill_aux(unsigned char* __first, unsigned char* __last,
+            const unsigned char& __c)
   {
-    __glibcxx_requires_valid_range(__first, __last);
     const unsigned char __tmp = __c;
     std::memset(__first, __tmp, __last - __first);
   }
 
   inline void
-  fill(signed char* __first, signed char* __last, const signed char& __c)
+  __fill_aux(signed char* __first, signed char* __last,
+            const signed char& __c)
   {
-    __glibcxx_requires_valid_range(__first, __last);
     const signed char __tmp = __c;
     std::memset(__first, static_cast<unsigned char>(__tmp), __last - __first);
   }
 
   inline void
-  fill(char* __first, char* __last, const char& __c)
+  __fill_aux(char* __first, char* __last, const char& __c)
   {
-    __glibcxx_requires_valid_range(__first, __last);
     const char __tmp = __c;
     std::memset(__first, static_cast<unsigned char>(__tmp), __last - __first);
   }
 
-  template<typename _Tp, typename _Ref, typename _Ptr>
-    struct _Deque_iterator;
+#ifdef _GLIBCXX_USE_WCHAR_T
+  inline void
+  __fill_aux(wchar_t* __first, wchar_t* __last, const wchar_t& __c)
+  {
+    const wchar_t __tmp = __c;
+    std::wmemset(__first, __tmp, __last - __first);
+  }
+#endif
 
-  // Overload for deque::iterators, exploiting the "segmented-iterator
-  // optimization".  NB: leave const_iterators alone!
-  template<typename _Tp>
-    void
-    fill(const _Deque_iterator<_Tp, _Tp&, _Tp*>& __first,
-        const _Deque_iterator<_Tp, _Tp&, _Tp*>& __last, const _Tp& __value)
+  template<bool>
+    struct __fill_normal
     {
-      typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self;
+      template<typename _ForwardIterator, typename _Tp>
+        static void
+        __fill_n(_ForwardIterator __first, _ForwardIterator __last,
+                const _Tp& __value)
+        { std::__fill_aux(__first, __last, __value); }
+    };
 
-      for (typename _Self::_Map_pointer __node = __first._M_node + 1;
-           __node < __last._M_node; ++__node)
-       std::fill(*__node, *__node + _Self::_S_buffer_size(), __value);
+  template<>
+    struct __fill_normal<true>
+    {
+      template<typename _ForwardIterator, typename _Tp>
+        static void
+        __fill_n(_ForwardIterator __first, _ForwardIterator __last,
+                const _Tp& __value)
+        { std::__fill_aux(__first.base(), __last.base(), __value); }
+    };
 
-      if (__first._M_node != __last._M_node)
-       {
-         std::fill(__first._M_cur, __first._M_last, __value);
-         std::fill(__last._M_first, __last._M_cur, __value);
-       }
-      else
-       std::fill(__first._M_cur, __last._M_cur, __value);
+  /**
+   *  @brief Fills the range [first,last) with copies of value.
+   *  @param  first  A forward iterator.
+   *  @param  last   A forward iterator.
+   *  @param  value  A reference-to-const of arbitrary type.
+   *  @return   Nothing.
+   *
+   *  This function fills a range with copies of the same value.  For char
+   *  types filling contiguous areas of memory, this becomes an inline call
+   *  to @c memset or @c wmemset.
+  */
+  template<typename _ForwardIterator, typename _Tp>
+    inline void
+    fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
+    {
+      // concept requirements
+      __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
+                                 _ForwardIterator>)
+      __glibcxx_requires_valid_range(__first, __last);
+
+      const bool __fi = __is_normal_iterator<_ForwardIterator>::__value;
+      std::__fill_normal<__fi>::__fill_n(__first, __last, __value);
     }
 
 
@@ -671,51 +683,87 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
        }
     };
 
-  /**
-   *  @brief Fills the range [first,first+n) with copies of value.
-   *  @param  first  An output iterator.
-   *  @param  n      The count of copies to perform.
-   *  @param  value  A reference-to-const of arbitrary type.
-   *  @return   The iterator at first+n.
-   *
-   *  This function fills a range with copies of the same value.  For one-byte
-   *  types filling contiguous areas of memory, this becomes an inline call to
-   *  @c memset.
-  */
   template<typename _OutputIterator, typename _Size, typename _Tp>
-    _OutputIterator
-    fill_n(_OutputIterator __first, _Size __n, const _Tp& __value)
+    inline _OutputIterator
+    __fill_n_aux(_OutputIterator __first, _Size __n, const _Tp& __value)
     {
-      // concept requirements
-      __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _Tp>)
-
       const bool __scalar = __is_scalar<_Tp>::__value;
       return std::__fill_n<__scalar>::fill_n(__first, __n, __value);
     }
 
   template<typename _Size>
     inline unsigned char*
-    fill_n(unsigned char* __first, _Size __n, const unsigned char& __c)
+    __fill_n_aux(unsigned char* __first, _Size __n, const unsigned char& __c)
     {
-      std::fill(__first, __first + __n, __c);
+      std::__fill_aux(__first, __first + __n, __c);
       return __first + __n;
     }
 
   template<typename _Size>
     inline signed char*
-    fill_n(char* __first, _Size __n, const signed char& __c)
+    __fill_n_aux(signed char* __first, _Size __n, const signed char& __c)
     {
-      std::fill(__first, __first + __n, __c);
+      std::__fill_aux(__first, __first + __n, __c);
       return __first + __n;
     }
 
   template<typename _Size>
     inline char*
-    fill_n(char* __first, _Size __n, const char& __c)
+    __fill_n_aux(char* __first, _Size __n, const char& __c)
+    {
+      std::__fill_aux(__first, __first + __n, __c);
+      return __first + __n;
+    }
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+  template<typename _Size>
+    inline wchar_t*
+    __fill_n_aux(wchar_t* __first, _Size __n, const wchar_t& __c)
     {
-      std::fill(__first, __first + __n, __c);
+      std::__fill_aux(__first, __first + __n, __c);
       return __first + __n;
     }
+#endif
+
+  template<bool>
+    struct __fill_n_normal
+    {
+      template<typename _OI, typename _Size, typename _Tp>
+        static _OI
+        __fill_n_n(_OI __first, _Size __n, const _Tp& __value)
+        { return std::__fill_n_aux(__first, __n, __value); }
+    };
+
+  template<>
+    struct __fill_n_normal<true>
+    {
+      template<typename _OI, typename _Size, typename _Tp>
+        static _OI
+        __fill_n_n(_OI __first, _Size __n, const _Tp& __value)
+        { return _OI(std::__fill_n_aux(__first.base(), __n, __value)); }
+    };
+
+  /**
+   *  @brief Fills the range [first,first+n) with copies of value.
+   *  @param  first  An output iterator.
+   *  @param  n      The count of copies to perform.
+   *  @param  value  A reference-to-const of arbitrary type.
+   *  @return   The iterator at first+n.
+   *
+   *  This function fills a range with copies of the same value.  For char
+   *  types filling contiguous areas of memory, this becomes an inline call
+   *  to @c memset or @ wmemset.
+  */
+  template<typename _OutputIterator, typename _Size, typename _Tp>
+    inline _OutputIterator
+    fill_n(_OutputIterator __first, _Size __n, const _Tp& __value)
+    {
+      // concept requirements
+      __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _Tp>)
+
+      const bool __oi = __is_normal_iterator<_OutputIterator>::__value;
+      return std::__fill_n_normal<__oi>::__fill_n_n(__first, __n, __value);
+    }
 
   /**
    *  @brief Finds the places in ranges which don't match.