stl_algo.h (shuffle): Add, per D3056.

2010-03-19  Paolo Carlini  <paolo.carlini@oracle.com>

	* include/bits/stl_algo.h (shuffle): Add, per D3056.
	(random_shuffle): Fix signature in C++0x mode.
	(lower_bound, __lg): Move...
	* include/bits/stl_algobase.h: ... here.
	* include/bits/algorithmfwd.h: Adjust.
	* include/parallel/algorithmfwd.h: Likewise.
	* include/parallel/algo.h: Likewise.
	* include/bits/hashtable_policy.h (__lower_bound): Remove,
	adjust callers.
	* include/tr1/hashtable_policy.h (__lower_bound): Likewise.
	* include/bits/random.tcc (__detail::__transform): Add,
	adjust std::transform callers; don't include <algorithm>.
	* testsuite/25_algorithms/shuffle/1.cc: Add.
	* testsuite/25_algorithms/shuffle/requirements/
	explicit_instantiation/2.cc: Likewise.
	* testsuite/25_algorithms/shuffle/requirements/
	explicit_instantiation/pod.cc: Likewise.

	* include/bits/random.h: Add comments.

From-SVN: r157564
This commit is contained in:
Paolo Carlini 2010-03-19 10:36:57 +00:00 committed by Paolo Carlini
parent 0aeb3cc6c9
commit 247d807571
13 changed files with 494 additions and 245 deletions

View File

@ -1,3 +1,25 @@
2010-03-19 Paolo Carlini <paolo.carlini@oracle.com>
* include/bits/stl_algo.h (shuffle): Add, per D3056.
(random_shuffle): Fix signature in C++0x mode.
(lower_bound, __lg): Move...
* include/bits/stl_algobase.h: ... here.
* include/bits/algorithmfwd.h: Adjust.
* include/parallel/algorithmfwd.h: Likewise.
* include/parallel/algo.h: Likewise.
* include/bits/hashtable_policy.h (__lower_bound): Remove,
adjust callers.
* include/tr1/hashtable_policy.h (__lower_bound): Likewise.
* include/bits/random.tcc (__detail::__transform): Add,
adjust std::transform callers; don't include <algorithm>.
* testsuite/25_algorithms/shuffle/1.cc: Add.
* testsuite/25_algorithms/shuffle/requirements/
explicit_instantiation/2.cc: Likewise.
* testsuite/25_algorithms/shuffle/requirements/
explicit_instantiation/pod.cc: Likewise.
* include/bits/random.h: Add comments.
2010-03-17 Jonathan Wakely <jwakely.gcc@gmail.com>
* doc/xml/manual/debug_mode.xml: Correct debug headers.

View File

@ -1,6 +1,6 @@
// <algorithm> declarations -*- C++ -*-
// Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
// Copyright (C) 2007, 2008, 2009, 2010 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
@ -111,6 +111,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
set_intersection
set_symmetric_difference
set_union
shuffle (C++0x)
sort
sort_heap
stable_partition
@ -517,6 +518,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
// set_symmetric_difference
// set_union
#if defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
template<typename _RAIter, typename _UGenerator>
void
shuffle(_RAIter, _RAIter, _UGenerator&&);
#endif
template<typename _RAIter>
void
sort_heap(_RAIter, _RAIter);
@ -684,7 +691,12 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_P)
template<typename _RAIter, typename _Generator>
void
random_shuffle(_RAIter, _RAIter, _Generator&);
random_shuffle(_RAIter, _RAIter,
#ifdef __GXX_EXPERIMENTAL_CXX0X__
_Generator&&);
#else
_Generator&);
#endif
template<typename _FIter, typename _Tp>
void

View File

@ -56,29 +56,6 @@ namespace __detail
return __distance_fw(__first, __last, _Tag());
}
template<typename _RAIter, typename _Tp>
_RAIter
__lower_bound(_RAIter __first, _RAIter __last, const _Tp& __val)
{
typedef typename std::iterator_traits<_RAIter>::difference_type _DType;
_DType __len = __last - __first;
while (__len > 0)
{
_DType __half = __len >> 1;
_RAIter __middle = __first + __half;
if (*__middle < __val)
{
__first = __middle;
++__first;
__len = __len - __half - 1;
}
else
__len = __half;
}
return __first;
}
// Auxiliary types used for all instantiations of _Hashtable: nodes
// and iterators.
@ -447,8 +424,8 @@ namespace __detail
_Prime_rehash_policy::
_M_next_bkt(std::size_t __n) const
{
const unsigned long* __p = __lower_bound(__prime_list, __prime_list
+ _S_n_primes, __n);
const unsigned long* __p = std::lower_bound(__prime_list, __prime_list
+ _S_n_primes, __n);
_M_next_resize =
static_cast<std::size_t>(__builtin_ceil(*__p * _M_max_load_factor));
return *__p;
@ -461,8 +438,8 @@ namespace __detail
_M_bkt_for_elements(std::size_t __n) const
{
const float __min_bkts = __n / _M_max_load_factor;
const unsigned long* __p = __lower_bound(__prime_list, __prime_list
+ _S_n_primes, __min_bkts);
const unsigned long* __p = std::lower_bound(__prime_list, __prime_list
+ _S_n_primes, __min_bkts);
_M_next_resize =
static_cast<std::size_t>(__builtin_ceil(*__p * _M_max_load_factor));
return *__p;
@ -490,8 +467,8 @@ namespace __detail
{
__min_bkts = std::max(__min_bkts, _M_growth_factor * __n_bkt);
const unsigned long* __p =
__lower_bound(__prime_list, __prime_list + _S_n_primes,
__min_bkts);
std::lower_bound(__prime_list, __prime_list + _S_n_primes,
__min_bkts);
_M_next_resize = static_cast<std::size_t>
(__builtin_ceil(*__p * _M_max_load_factor));
return std::make_pair(true, *__p);

View File

@ -1694,20 +1694,6 @@ namespace std
b() const
{ return _M_param.b(); }
/**
* @brief Returns the inclusive lower bound of the distribution range.
*/
result_type
min() const
{ return this->a(); }
/**
* @brief Returns the inclusive upper bound of the distribution range.
*/
result_type
max() const
{ return this->b(); }
/**
* @brief Returns the parameter set of the distribution.
*/
@ -1724,19 +1710,27 @@ namespace std
{ _M_param = __param; }
/**
* Gets a uniformly distributed random number in the range
* @f$(min, max)@f$.
* @brief Returns the inclusive lower bound of the distribution range.
*/
result_type
min() const
{ return this->a(); }
/**
* @brief Returns the inclusive upper bound of the distribution range.
*/
result_type
max() const
{ return this->b(); }
/**
* @brief Generating functions.
*/
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)
{ return this->operator()(__urng, this->param()); }
/**
* Gets a uniform random number in the range @f$[0, n)@f$.
*
* This function is aimed at use with std::random_shuffle.
*/
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng,
@ -1875,20 +1869,6 @@ namespace std
b() const
{ return _M_param.b(); }
/**
* @brief Returns the inclusive lower bound of the distribution range.
*/
result_type
min() const
{ return this->a(); }
/**
* @brief Returns the inclusive upper bound of the distribution range.
*/
result_type
max() const
{ return this->b(); }
/**
* @brief Returns the parameter set of the distribution.
*/
@ -1904,6 +1884,23 @@ namespace std
param(const param_type& __param)
{ _M_param = __param; }
/**
* @brief Returns the inclusive lower bound of the distribution range.
*/
result_type
min() const
{ return this->a(); }
/**
* @brief Returns the inclusive upper bound of the distribution range.
*/
result_type
max() const
{ return this->b(); }
/**
* @brief Generating functions.
*/
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)
@ -2095,6 +2092,9 @@ namespace std
max() const
{ return std::numeric_limits<result_type>::max(); }
/**
* @brief Generating functions.
*/
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)
@ -2265,6 +2265,9 @@ namespace std
max() const
{ return std::numeric_limits<result_type>::max(); }
/**
* @brief Generating functions.
*/
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)
@ -2456,6 +2459,9 @@ namespace std
max() const
{ return std::numeric_limits<result_type>::max(); }
/**
* @brief Generating functions.
*/
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)
@ -2613,6 +2619,9 @@ namespace std
max() const
{ return std::numeric_limits<result_type>::max(); }
/**
* @brief Generating functions.
*/
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)
@ -2786,6 +2795,9 @@ namespace std
max() const
{ return std::numeric_limits<result_type>::max(); }
/**
* @brief Generating functions.
*/
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)
@ -2959,6 +2971,9 @@ namespace std
max() const
{ return std::numeric_limits<result_type>::max(); }
/**
* @brief Generating functions.
*/
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)
@ -3129,6 +3144,9 @@ namespace std
max() const
{ return std::numeric_limits<result_type>::max(); }
/**
* @brief Generating functions.
*/
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)
@ -3310,7 +3328,7 @@ namespace std
{ return std::numeric_limits<result_type>::max(); }
/**
* @brief Returns the next value in the Bernoullian sequence.
* @brief Generating functions.
*/
template<typename _UniformRandomNumberGenerator>
result_type
@ -3509,6 +3527,19 @@ namespace std
max() const
{ return _M_param.t(); }
/**
* @brief Generating functions.
*/
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)
{ return this->operator()(__urng, this->param()); }
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng,
const param_type& __p);
/**
* @brief Return true if two binomial distributions have
* the same parameters and the sequences that would
@ -3524,16 +3555,6 @@ namespace std
{ return __d1.param() == __d2.param(); }
#endif
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)
{ return this->operator()(__urng, this->param()); }
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng,
const param_type& __p);
/**
* @brief Inserts a %binomial_distribution random number distribution
* @p __x into the output stream @p __os.
@ -3691,6 +3712,9 @@ namespace std
max() const
{ return std::numeric_limits<result_type>::max(); }
/**
* @brief Generating functions.
*/
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)
@ -3860,6 +3884,9 @@ namespace std
max() const
{ return std::numeric_limits<result_type>::max(); }
/**
* @brief Generating functions.
*/
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng);
@ -4040,6 +4067,9 @@ namespace std
max() const
{ return std::numeric_limits<result_type>::max(); }
/**
* @brief Generating functions.
*/
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)
@ -4219,6 +4249,9 @@ namespace std
max() const
{ return std::numeric_limits<result_type>::max(); }
/**
* @brief Generating functions.
*/
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)
@ -4396,6 +4429,9 @@ namespace std
max() const
{ return std::numeric_limits<result_type>::max(); }
/**
* @brief Generating functions.
*/
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)
@ -4568,6 +4604,9 @@ namespace std
max() const
{ return std::numeric_limits<result_type>::max(); }
/**
* @brief Generating functions.
*/
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)
@ -4756,6 +4795,9 @@ namespace std
max() const
{ return this->_M_param._M_prob.size() - 1; }
/**
* @brief Generating functions.
*/
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)
@ -4960,6 +5002,9 @@ namespace std
max() const
{ return this->_M_param._M_int.back(); }
/**
* @brief Generating functions.
*/
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)
@ -5168,6 +5213,9 @@ namespace std
max() const
{ return this->_M_param._M_int.back(); }
/**
* @brief Generating functions.
*/
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)

View File

@ -27,8 +27,7 @@
* You should not attempt to use it directly.
*/
#include <numeric>
#include <algorithm>
#include <numeric> // std::accumulate and std::partial_sum
namespace std
{
@ -87,6 +86,17 @@ namespace std
__calc(_Tp __x)
{ return __a * __x + __c; }
};
template<typename _InputIterator, typename _OutputIterator,
typename _UnaryOperation>
_OutputIterator
__transform(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _UnaryOperation __unary_op)
{
for (; __first != __last; ++__first, ++__result)
*__result = __unary_op(*__first);
return __result;
}
} // namespace __detail
@ -2177,8 +2187,8 @@ namespace std
const double __sum = std::accumulate(_M_prob.begin(),
_M_prob.end(), 0.0);
// Now normalize the probabilites.
std::transform(_M_prob.begin(), _M_prob.end(), _M_prob.begin(),
std::bind2nd(std::divides<double>(), __sum));
__detail::__transform(_M_prob.begin(), _M_prob.end(), _M_prob.begin(),
std::bind2nd(std::divides<double>(), __sum));
// Accumulate partial sums.
_M_cp.reserve(_M_prob.size());
std::partial_sum(_M_prob.begin(), _M_prob.end(),
@ -2299,8 +2309,8 @@ namespace std
const double __sum = std::accumulate(_M_den.begin(),
_M_den.end(), 0.0);
std::transform(_M_den.begin(), _M_den.end(), _M_den.begin(),
std::bind2nd(std::divides<double>(), __sum));
__detail::__transform(_M_den.begin(), _M_den.end(), _M_den.begin(),
std::bind2nd(std::divides<double>(), __sum));
_M_cp.reserve(_M_den.size());
std::partial_sum(_M_den.begin(), _M_den.end(),
@ -2499,14 +2509,14 @@ namespace std
}
// Now normalize the densities...
std::transform(_M_den.begin(), _M_den.end(), _M_den.begin(),
std::bind2nd(std::divides<double>(), __sum));
__detail::__transform(_M_den.begin(), _M_den.end(), _M_den.begin(),
std::bind2nd(std::divides<double>(), __sum));
// ... and partial sums...
std::transform(_M_cp.begin(), _M_cp.end(), _M_cp.begin(),
std::bind2nd(std::divides<double>(), __sum));
__detail::__transform(_M_cp.begin(), _M_cp.end(), _M_cp.begin(),
std::bind2nd(std::divides<double>(), __sum));
// ... and slopes.
std::transform(_M_m.begin(), _M_m.end(), _M_m.begin(),
std::bind2nd(std::divides<double>(), __sum));
__detail::__transform(_M_m.begin(), _M_m.end(), _M_m.begin(),
std::bind2nd(std::divides<double>(), __sum));
// Make sure the last cumulative probablility is one.
_M_cp[_M_cp.size() - 1] = 1.0;
}

View File

@ -62,6 +62,10 @@
#include <bits/stl_heap.h>
#include <bits/stl_tempbuf.h> // for _Temporary_buffer
#ifdef __GXX_EXPERIMENTAL_CXX0X__
#include <random> // for std::uniform_int_distribution
#endif
// See concept_check.h for the __glibcxx_*_requires macros.
_GLIBCXX_BEGIN_NAMESPACE(std)
@ -2301,29 +2305,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
}
}
/// This is a helper function for the sort routines. Precondition: __n > 0.
template<typename _Size>
inline _Size
__lg(_Size __n)
{
_Size __k;
for (__k = 0; __n != 0; __n >>= 1)
++__k;
return __k - 1;
}
inline int
__lg(int __n)
{ return sizeof(int) * __CHAR_BIT__ - 1 - __builtin_clz(__n); }
inline long
__lg(long __n)
{ return sizeof(long) * __CHAR_BIT__ - 1 - __builtin_clzl(__n); }
inline long long
__lg(long long __n)
{ return sizeof(long long) * __CHAR_BIT__ - 1 - __builtin_clzll(__n); }
// sort
template<typename _RandomAccessIterator, typename _Size>
@ -2386,106 +2367,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
// nth_element
/**
* @brief Finds the first position in which @a val could be inserted
* without changing the ordering.
* @param first An iterator.
* @param last Another iterator.
* @param val The search term.
* @return An iterator pointing to the first element <em>not less
* than</em> @a val, or end() if every element is less than
* @a val.
* @ingroup binary_search_algorithms
*/
template<typename _ForwardIterator, typename _Tp>
_ForwardIterator
lower_bound(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val)
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType;
typedef typename iterator_traits<_ForwardIterator>::difference_type
_DistanceType;
// concept requirements
__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
__glibcxx_function_requires(_LessThanOpConcept<_ValueType, _Tp>)
__glibcxx_requires_partitioned_lower(__first, __last, __val);
_DistanceType __len = std::distance(__first, __last);
_DistanceType __half;
_ForwardIterator __middle;
while (__len > 0)
{
__half = __len >> 1;
__middle = __first;
std::advance(__middle, __half);
if (*__middle < __val)
{
__first = __middle;
++__first;
__len = __len - __half - 1;
}
else
__len = __half;
}
return __first;
}
/**
* @brief Finds the first position in which @a val could be inserted
* without changing the ordering.
* @ingroup binary_search_algorithms
* @param first An iterator.
* @param last Another iterator.
* @param val The search term.
* @param comp A functor to use for comparisons.
* @return An iterator pointing to the first element <em>not less
* than</em> @a val, or end() if every element is less
* than @a val.
* @ingroup binary_search_algorithms
*
* The comparison function should have the same effects on ordering as
* the function used for the initial sort.
*/
template<typename _ForwardIterator, typename _Tp, typename _Compare>
_ForwardIterator
lower_bound(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val, _Compare __comp)
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType;
typedef typename iterator_traits<_ForwardIterator>::difference_type
_DistanceType;
// concept requirements
__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
__glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
_ValueType, _Tp>)
__glibcxx_requires_partitioned_lower_pred(__first, __last,
__val, __comp);
_DistanceType __len = std::distance(__first, __last);
_DistanceType __half;
_ForwardIterator __middle;
while (__len > 0)
{
__half = __len >> 1;
__middle = __first;
std::advance(__middle, __half);
if (__comp(*__middle, __val))
{
__first = __middle;
++__first;
__len = __len - __half - 1;
}
else
__len = __half;
}
return __first;
}
// lower_bound moved to stl_algobase.h
/**
* @brief Finds the last position in which @a val could be inserted
@ -4179,6 +4061,47 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
std::minmax_element(__l.begin(), __l.end(), __comp);
return std::make_pair(*__p.first, *__p.second);
}
#ifdef _GLIBCXX_USE_C99_STDINT_TR1
/**
* @brief Shuffle the elements of a sequence using a uniform random
* number generator.
* @ingroup mutating_algorithms
* @param first A forward iterator.
* @param last A forward iterator.
* @param g A UniformRandomNumberGenerator (26.5.1.3).
* @return Nothing.
*
* Reorders the elements in the range @p [first,last) using @p g to
* provide random numbers.
*/
template<typename _RandomAccessIterator,
typename _UniformRandomNumberGenerator>
void
shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
_UniformRandomNumberGenerator&& __g)
{
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_requires_valid_range(__first, __last);
if (__first == __last)
return;
typedef typename iterator_traits<_RandomAccessIterator>::difference_type
_DistanceType;
typedef typename std::make_unsigned<_DistanceType>::type __ud_type;
typedef typename std::uniform_int_distribution<__ud_type> __distr_type;
typedef typename __distr_type::param_type __p_type;
__distr_type __d;
for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
std::iter_swap(__i, __first + __d(__g, __p_type(0, __i - __first)));
}
#endif
#endif // __GXX_EXPERIMENTAL_CXX0X__
_GLIBCXX_END_NAMESPACE
@ -4996,7 +4919,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_P)
template<typename _RandomAccessIterator, typename _RandomNumberGenerator>
void
random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
#ifdef __GXX_EXPERIMENTAL_CXX0X__
_RandomNumberGenerator&& __rand)
#else
_RandomNumberGenerator& __rand)
#endif
{
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<

View File

@ -938,6 +938,131 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
__first2, __last2);
}
/**
* @brief Finds the first position in which @a val could be inserted
* without changing the ordering.
* @param first An iterator.
* @param last Another iterator.
* @param val The search term.
* @return An iterator pointing to the first element <em>not less
* than</em> @a val, or end() if every element is less than
* @a val.
* @ingroup binary_search_algorithms
*/
template<typename _ForwardIterator, typename _Tp>
_ForwardIterator
lower_bound(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val)
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType;
typedef typename iterator_traits<_ForwardIterator>::difference_type
_DistanceType;
// concept requirements
__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
__glibcxx_function_requires(_LessThanOpConcept<_ValueType, _Tp>)
__glibcxx_requires_partitioned_lower(__first, __last, __val);
_DistanceType __len = std::distance(__first, __last);
_DistanceType __half;
_ForwardIterator __middle;
while (__len > 0)
{
__half = __len >> 1;
__middle = __first;
std::advance(__middle, __half);
if (*__middle < __val)
{
__first = __middle;
++__first;
__len = __len - __half - 1;
}
else
__len = __half;
}
return __first;
}
/**
* @brief Finds the first position in which @a val could be inserted
* without changing the ordering.
* @ingroup binary_search_algorithms
* @param first An iterator.
* @param last Another iterator.
* @param val The search term.
* @param comp A functor to use for comparisons.
* @return An iterator pointing to the first element <em>not less
* than</em> @a val, or end() if every element is less
* than @a val.
* @ingroup binary_search_algorithms
*
* The comparison function should have the same effects on ordering as
* the function used for the initial sort.
*/
template<typename _ForwardIterator, typename _Tp, typename _Compare>
_ForwardIterator
lower_bound(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val, _Compare __comp)
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType;
typedef typename iterator_traits<_ForwardIterator>::difference_type
_DistanceType;
// concept requirements
__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
__glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
_ValueType, _Tp>)
__glibcxx_requires_partitioned_lower_pred(__first, __last,
__val, __comp);
_DistanceType __len = std::distance(__first, __last);
_DistanceType __half;
_ForwardIterator __middle;
while (__len > 0)
{
__half = __len >> 1;
__middle = __first;
std::advance(__middle, __half);
if (__comp(*__middle, __val))
{
__first = __middle;
++__first;
__len = __len - __half - 1;
}
else
__len = __half;
}
return __first;
}
/// This is a helper function for the sort routines and for random.tcc.
// Precondition: __n > 0.
template<typename _Size>
inline _Size
__lg(_Size __n)
{
_Size __k;
for (__k = 0; __n != 0; __n >>= 1)
++__k;
return __k - 1;
}
inline int
__lg(int __n)
{ return sizeof(int) * __CHAR_BIT__ - 1 - __builtin_clz(__n); }
inline long
__lg(long __n)
{ return sizeof(long) * __CHAR_BIT__ - 1 - __builtin_clzl(__n); }
inline long long
__lg(long long __n)
{ return sizeof(long long) * __CHAR_BIT__ - 1 - __builtin_clzll(__n); }
_GLIBCXX_END_NAMESPACE
_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_P)

View File

@ -1645,7 +1645,7 @@ namespace __parallel
// Sequential fallback.
template<typename _RAIter, typename _RandomNumberGenerator>
inline void
random_shuffle(_RAIter __begin, _RAIter __end,
random_shuffle(_RAIter __begin, _RAIter __end,
_RandomNumberGenerator& __rand,
__gnu_parallel::sequential_tag)
{ _GLIBCXX_STD_P::random_shuffle(__begin, __end, __rand); }
@ -1673,8 +1673,12 @@ namespace __parallel
// Parallel algorithm for random access iterators.
template<typename _RAIter, typename _RandomNumberGenerator>
void
random_shuffle(_RAIter __begin, _RAIter __end,
random_shuffle(_RAIter __begin, _RAIter __end,
#ifdef __GXX_EXPERIMENTAL_CXX0X__
_RandomNumberGenerator&& __rand)
#else
_RandomNumberGenerator& __rand)
#endif
{
if (__begin == __end)
return;

View File

@ -1,6 +1,6 @@
// <algorithm> parallel extensions -*- C++ -*-
// Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
// Copyright (C) 2007, 2008, 2009, 2010 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
@ -690,7 +690,12 @@ namespace __parallel
template<typename _RAIter, typename _RandomNumberGenerator>
void
random_shuffle(_RAIter, _RAIter, _RandomNumberGenerator&);
random_shuffle(_RAIter, _RAIter,
#ifdef __GXX_EXPERIMENTAL_CXX0X__
_RandomNumberGenerator&&);
#else
_RandomNumberGenerator&);
#endif
template<typename _IIter1, typename _IIter2, typename _OIter>
_OIter

View File

@ -55,29 +55,6 @@ namespace __detail
return __distance_fw(__first, __last, _Tag());
}
template<typename _RAIter, typename _Tp>
_RAIter
__lower_bound(_RAIter __first, _RAIter __last, const _Tp& __val)
{
typedef typename std::iterator_traits<_RAIter>::difference_type _DType;
_DType __len = __last - __first;
while (__len > 0)
{
_DType __half = __len >> 1;
_RAIter __middle = __first + __half;
if (*__middle < __val)
{
__first = __middle;
++__first;
__len = __len - __half - 1;
}
else
__len = __half;
}
return __first;
}
// Auxiliary types used for all instantiations of _Hashtable: nodes
// and iterators.
@ -440,8 +417,8 @@ namespace __detail
_Prime_rehash_policy::
_M_next_bkt(std::size_t __n) const
{
const unsigned long* __p = __lower_bound(__prime_list, __prime_list
+ _S_n_primes, __n);
const unsigned long* __p = std::lower_bound(__prime_list, __prime_list
+ _S_n_primes, __n);
_M_next_resize =
static_cast<std::size_t>(__builtin_ceil(*__p * _M_max_load_factor));
return *__p;
@ -454,8 +431,8 @@ namespace __detail
_M_bkt_for_elements(std::size_t __n) const
{
const float __min_bkts = __n / _M_max_load_factor;
const unsigned long* __p = __lower_bound(__prime_list, __prime_list
+ _S_n_primes, __min_bkts);
const unsigned long* __p = std::lower_bound(__prime_list, __prime_list
+ _S_n_primes, __min_bkts);
_M_next_resize =
static_cast<std::size_t>(__builtin_ceil(*__p * _M_max_load_factor));
return *__p;
@ -483,8 +460,8 @@ namespace __detail
{
__min_bkts = std::max(__min_bkts, _M_growth_factor * __n_bkt);
const unsigned long* __p =
__lower_bound(__prime_list, __prime_list + _S_n_primes,
__min_bkts);
std::lower_bound(__prime_list, __prime_list + _S_n_primes,
__min_bkts);
_M_next_resize = static_cast<std::size_t>
(__builtin_ceil(*__p * _M_max_load_factor));
return std::make_pair(true, *__p);

View File

@ -0,0 +1,67 @@
// { dg-options "-std=gnu++0x" }
// { dg-require-cstdint "" }
// 2010-03-19 Paolo Carlini <paolo.carlini@oracle.com>
// Copyright (C) 2010 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 3, 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 COPYING3. If not see
// <http://www.gnu.org/licenses/>.
#include <algorithm>
#include <random>
#include <vector>
#include <testsuite_hooks.h>
void test01()
{
bool test __attribute__((unused)) = true;
for (unsigned size = 0; size < 50; ++size)
{
std::vector<int> vref(size);
std::iota(vref.begin(), vref.end(), 0);
std::vector<int> v1(vref), v2(vref);
std::ranlux48_base g1(size), g2(size + 1);
std::shuffle(v1.begin(), v1.end(), g1);
std::shuffle(v2.begin(), v2.end(), g2);
if (size >= 10)
{
VERIFY( !std::equal(v1.begin(), v1.end(), vref.begin()) );
VERIFY( !std::equal(v2.begin(), v2.end(), vref.begin()) );
VERIFY( !std::equal(v1.begin(), v1.end(), v2.begin()) );
}
for (unsigned ind = 0; ind < size; ++ind)
{
auto it1 = std::find(v1.begin(), v1.end(), vref[ind]);
auto it2 = std::find(v2.begin(), v2.end(), vref[ind]);
VERIFY( it1 != v1.end() );
VERIFY( it2 != v2.end() );
v1.erase(it1);
v2.erase(it2);
}
VERIFY( v1.empty() );
VERIFY( v2.empty() );
}
}
int main()
{
test01();
return 0;
}

View File

@ -0,0 +1,38 @@
// { dg-do compile }
// { dg-options "-std=gnu++0x" }
// { dg-require-cstdint "" }
// 2010-03-19 Paolo Carlini <paolo.carlini@oracle.com>
// Copyright (C) 2010 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 3, 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 COPYING3. If not see
// <http://www.gnu.org/licenses/>.
#include <algorithm>
#include <random>
#include <testsuite_api.h>
namespace std
{
using __gnu_test::NonDefaultConstructible;
typedef NonDefaultConstructible value_type;
typedef value_type* iterator_type;
typedef std::mt19937_64 ugenerator_type;
template void shuffle(iterator_type, iterator_type, ugenerator_type&&);
}

View File

@ -0,0 +1,37 @@
// { dg-do compile }
// { dg-options "-std=gnu++0x" }
// { dg-require-cstdint "" }
// 2010-03-19 Paolo Carlini <paolo.carlini@oracle.com>
// Copyright (C) 2010 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 3, 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 COPYING3. If not see
// <http://www.gnu.org/licenses/>.
#include <algorithm>
#include <random>
#include <testsuite_character.h>
namespace std
{
using __gnu_test::pod_int;
typedef pod_int value_type;
typedef value_type* iterator_type;
typedef std::mt19937_64 ugenerator_type;
template void shuffle(iterator_type, iterator_type, ugenerator_type&&);
}