[multiple changes]

2004-06-25  Dan Nicolaescu  <dann@ics.uci.edu>
	    Paolo Carlini  <pcarlini@suse.de>

	* include/bits/stl_algobase.h (__fill, __fill_n): New helpers
	for fill and fill_n, respectively: when copying is cheap, use a
	temporary to avoid a memory read in each iteration.

2004-06-25  Paolo Carlini  <pcarlini@suse.de>

	* testsuite/25_algorithms/fill/1.cc: New.
	* testsuite/25_algorithms/fill/2.cc: Likewise.

From-SVN: r83645
This commit is contained in:
Paolo Carlini 2004-06-25 09:25:57 +00:00
parent c19d6c9f9f
commit 6e539e2396
4 changed files with 229 additions and 26 deletions

View File

@ -1,3 +1,15 @@
2004-06-25 Dan Nicolaescu <dann@ics.uci.edu>
Paolo Carlini <pcarlini@suse.de>
* include/bits/stl_algobase.h (__fill, __fill_n): New helpers
for fill and fill_n, respectively: when copying is cheap, use a
temporary to avoid a memory read in each iteration.
2004-06-25 Paolo Carlini <pcarlini@suse.de>
* testsuite/25_algorithms/fill/1.cc: New.
* testsuite/25_algorithms/fill/2.cc: Likewise.
2004-06-25 Benjamin Kosnik <bkoz@redhat.com>
* include/debug/formatter.h (__gnu_debug::_Error_formatter):

View File

@ -499,6 +499,32 @@ namespace std
__result, __Normal());
}
template<typename>
struct __fill
{
template<typename _ForwardIterator, typename _Tp>
static void
fill(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __value)
{
for (; __first != __last; ++__first)
*__first = __value;
}
};
template<>
struct __fill<__true_type>
{
template<typename _ForwardIterator, typename _Tp>
static void
fill(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __value)
{
const _Tp __tmp = __value;
for (; __first != __last; ++__first)
*__first = __tmp;
}
};
/**
* @brief Fills the range [first,last) with copies of value.
@ -520,31 +546,9 @@ namespace std
_ForwardIterator>)
__glibcxx_requires_valid_range(__first, __last);
for ( ; __first != __last; ++__first)
*__first = __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 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)
{
// concept requirements
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,_Tp>)
for ( ; __n > 0; --__n, ++__first)
*__first = __value;
return __first;
typedef typename __type_traits<_Tp>::has_trivial_copy_constructor
_Trivial;
std::__fill<_Trivial>::fill(__first, __last, __value);
}
// Specialization: for one-byte types we can use memset.
@ -572,6 +576,56 @@ namespace std
std::memset(__first, static_cast<unsigned char>(__tmp), __last - __first);
}
template<typename>
struct __fill_n
{
template<typename _OutputIterator, typename _Size, typename _Tp>
static _OutputIterator
fill_n(_OutputIterator __first, _Size __n, const _Tp& __value)
{
for (; __n > 0; --__n, ++__first)
*__first = __value;
return __first;
}
};
template<>
struct __fill_n<__true_type>
{
template<typename _OutputIterator, typename _Size, typename _Tp>
static _OutputIterator
fill_n(_OutputIterator __first, _Size __n, const _Tp& __value)
{
const _Tp __tmp = __value;
for (; __n > 0; --__n, ++__first)
*__first = __tmp;
return __first;
}
};
/**
* @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)
{
// concept requirements
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _Tp>)
typedef typename __type_traits<_Tp>::has_trivial_copy_constructor
_Trivial;
return std::__fill_n<_Trivial>::fill_n(__first, __n, __value);
}
template<typename _Size>
inline unsigned char*
fill_n(unsigned char* __first, _Size __n, const unsigned char& __c)
@ -596,7 +650,6 @@ namespace std
return __first + __n;
}
/**
* @brief Finds the places in ranges which don't match.
* @param first1 An input iterator.

View File

@ -0,0 +1,69 @@
// 2004-06-25 Paolo Carlini <pcarlini@suse.de>
// 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.2.5 [lib.alg.fill] Fill
#include <list>
#include <algorithm>
#include <testsuite_hooks.h>
class num
{
int stored;
public:
num(int init = 0)
: stored(init)
{ }
operator int() const
{ return stored; }
};
// fill
void test01()
{
bool test __attribute__((unused)) = true;
using namespace std;
const int val = 1;
const int V[] = { val, val, val, val, val, val, val };
const list<int>::size_type N = sizeof(V) / sizeof(int);
list<int> coll(N);
fill(coll.begin(), coll.end(), val);
VERIFY( equal(coll.begin(), coll.end(), V) );
list<num> coll2(N);
fill(coll2.begin(), coll2.end(), val);
VERIFY( equal(coll2.begin(), coll2.end(), V) );
}
#if !__GXX_WEAK__ && _MT_ALLOCATOR_H
// Explicitly instantiate for systems with no COMDAT or weak support.
template class __gnu_cxx::__mt_alloc<std::_List_node<int> >;
#endif
int main()
{
test01();
return 0;
}

View File

@ -0,0 +1,69 @@
// 2004-06-25 Paolo Carlini <pcarlini@suse.de>
// 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.2.5 [lib.alg.fill] Fill
#include <list>
#include <algorithm>
#include <testsuite_hooks.h>
class num
{
int stored;
public:
num(int init = 0)
: stored(init)
{ }
operator int() const
{ return stored; }
};
// fill_n
void test01()
{
bool test __attribute__((unused)) = true;
using namespace std;
const int val = 3;
const int V[] = { val, val, val, val, val, val, val, val, val };
const list<int>::size_type N = sizeof(V) / sizeof(int);
list<int> coll(N);
fill_n(coll.begin(), coll.size(), val);
VERIFY( equal(coll.begin(), coll.end(), V) );
list<num> coll2(N);
fill_n(coll2.begin(), coll2.size(), val);
VERIFY( equal(coll2.begin(), coll2.end(), V) );
}
#if !__GXX_WEAK__ && _MT_ALLOCATOR_H
// Explicitly instantiate for systems with no COMDAT or weak support.
template class __gnu_cxx::__mt_alloc<std::_List_node<int> >;
#endif
int main()
{
test01();
return 0;
}