mirror of git://gcc.gnu.org/git/gcc.git
Avoid including all of <random> in <algorithm>
Backport from mainline
2016-01-25 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/69464
* include/Makefile.am: Add new header.
* include/Makefile.in: Regenerate.
* include/bits/random.h (uniform_int_distribution): Move to
bits/uniform_int_dist.h.
* include/bits/random.tcc (uniform_int_distribution::operator(),
uniform_int_distribution::__generate_impl): Likewise.
* include/bits/uniform_int_dist.h: New header.
* include/bits/stl_algo.h [__cplusplus >= 201103L]: Include
<bits/uniform_int_dist.h> instead of <random>.
* testsuite/20_util/specialized_algorithms/uninitialized_copy/
move_iterators/1.cc: Include correct header for uninitialized_copy.
* testsuite/20_util/specialized_algorithms/uninitialized_copy_n/
move_iterators/1.cc: Likewise.
* testsuite/25_algorithms/nth_element/58800.cc: Include correct
header for vector.
* testsuite/26_numerics/random/pr60037-neg.cc: Adjust dg-error lines.
* testsuite/libstdc++-prettyprinters/whatis.cc: Include <random>.
From-SVN: r235276
This commit is contained in:
parent
445ed9c330
commit
47822deeff
|
|
@ -1,3 +1,27 @@
|
||||||
|
2016-04-20 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
|
Backport from mainline
|
||||||
|
2016-01-25 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
|
PR libstdc++/69464
|
||||||
|
* include/Makefile.am: Add new header.
|
||||||
|
* include/Makefile.in: Regenerate.
|
||||||
|
* include/bits/random.h (uniform_int_distribution): Move to
|
||||||
|
bits/uniform_int_dist.h.
|
||||||
|
* include/bits/random.tcc (uniform_int_distribution::operator(),
|
||||||
|
uniform_int_distribution::__generate_impl): Likewise.
|
||||||
|
* include/bits/uniform_int_dist.h: New header.
|
||||||
|
* include/bits/stl_algo.h [__cplusplus >= 201103L]: Include
|
||||||
|
<bits/uniform_int_dist.h> instead of <random>.
|
||||||
|
* testsuite/20_util/specialized_algorithms/uninitialized_copy/
|
||||||
|
move_iterators/1.cc: Include correct header for uninitialized_copy.
|
||||||
|
* testsuite/20_util/specialized_algorithms/uninitialized_copy_n/
|
||||||
|
move_iterators/1.cc: Likewise.
|
||||||
|
* testsuite/25_algorithms/nth_element/58800.cc: Include correct
|
||||||
|
header for vector.
|
||||||
|
* testsuite/26_numerics/random/pr60037-neg.cc: Adjust dg-error lines.
|
||||||
|
* testsuite/libstdc++-prettyprinters/whatis.cc: Include <random>.
|
||||||
|
|
||||||
2016-04-06 Eric Botcazou <ebotcazou@adacore.com>
|
2016-04-06 Eric Botcazou <ebotcazou@adacore.com>
|
||||||
|
|
||||||
* src/Makefile.am (libstdc++-symbols.ver): Remove useless /dev/null.
|
* src/Makefile.am (libstdc++-symbols.ver): Remove useless /dev/null.
|
||||||
|
|
|
||||||
|
|
@ -178,6 +178,7 @@ bits_headers = \
|
||||||
${bits_srcdir}/stl_vector.h \
|
${bits_srcdir}/stl_vector.h \
|
||||||
${bits_srcdir}/streambuf.tcc \
|
${bits_srcdir}/streambuf.tcc \
|
||||||
${bits_srcdir}/stringfwd.h \
|
${bits_srcdir}/stringfwd.h \
|
||||||
|
${bits_srcdir}/uniform_int_dist.h \
|
||||||
${bits_srcdir}/unique_ptr.h \
|
${bits_srcdir}/unique_ptr.h \
|
||||||
${bits_srcdir}/unordered_map.h \
|
${bits_srcdir}/unordered_map.h \
|
||||||
${bits_srcdir}/unordered_set.h \
|
${bits_srcdir}/unordered_set.h \
|
||||||
|
|
|
||||||
|
|
@ -468,6 +468,7 @@ bits_headers = \
|
||||||
${bits_srcdir}/stl_vector.h \
|
${bits_srcdir}/stl_vector.h \
|
||||||
${bits_srcdir}/streambuf.tcc \
|
${bits_srcdir}/streambuf.tcc \
|
||||||
${bits_srcdir}/stringfwd.h \
|
${bits_srcdir}/stringfwd.h \
|
||||||
|
${bits_srcdir}/uniform_int_dist.h \
|
||||||
${bits_srcdir}/unique_ptr.h \
|
${bits_srcdir}/unique_ptr.h \
|
||||||
${bits_srcdir}/unordered_map.h \
|
${bits_srcdir}/unordered_map.h \
|
||||||
${bits_srcdir}/unordered_set.h \
|
${bits_srcdir}/unordered_set.h \
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
#define _RANDOM_H 1
|
#define _RANDOM_H 1
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <bits/uniform_int_dist.h>
|
||||||
|
|
||||||
namespace std _GLIBCXX_VISIBILITY(default)
|
namespace std _GLIBCXX_VISIBILITY(default)
|
||||||
{
|
{
|
||||||
|
|
@ -149,14 +150,6 @@ _GLIBCXX_END_NAMESPACE_VERSION
|
||||||
__mod(_Tp __x)
|
__mod(_Tp __x)
|
||||||
{ return _Mod<_Tp, __m, __a, __c>::__calc(__x); }
|
{ return _Mod<_Tp, __m, __a, __c>::__calc(__x); }
|
||||||
|
|
||||||
/* Determine whether number is a power of 2. */
|
|
||||||
template<typename _Tp>
|
|
||||||
inline bool
|
|
||||||
_Power_of_2(_Tp __x)
|
|
||||||
{
|
|
||||||
return ((__x - 1) & __x) == 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* An adaptor class for converting the output of any Generator into
|
* An adaptor class for converting the output of any Generator into
|
||||||
* the input for a specific Distribution.
|
* the input for a specific Distribution.
|
||||||
|
|
@ -1656,164 +1649,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
// std::uniform_int_distribution is defined in <bits/uniform_int_dist.h>
|
||||||
* @brief Uniform discrete distribution for random numbers.
|
|
||||||
* A discrete random distribution on the range @f$[min, max]@f$ with equal
|
|
||||||
* probability throughout the range.
|
|
||||||
*/
|
|
||||||
template<typename _IntType = int>
|
|
||||||
class uniform_int_distribution
|
|
||||||
{
|
|
||||||
static_assert(std::is_integral<_IntType>::value,
|
|
||||||
"template argument not an integral type");
|
|
||||||
|
|
||||||
public:
|
|
||||||
/** The type of the range of the distribution. */
|
|
||||||
typedef _IntType result_type;
|
|
||||||
/** Parameter type. */
|
|
||||||
struct param_type
|
|
||||||
{
|
|
||||||
typedef uniform_int_distribution<_IntType> distribution_type;
|
|
||||||
|
|
||||||
explicit
|
|
||||||
param_type(_IntType __a = 0,
|
|
||||||
_IntType __b = std::numeric_limits<_IntType>::max())
|
|
||||||
: _M_a(__a), _M_b(__b)
|
|
||||||
{
|
|
||||||
_GLIBCXX_DEBUG_ASSERT(_M_a <= _M_b);
|
|
||||||
}
|
|
||||||
|
|
||||||
result_type
|
|
||||||
a() const
|
|
||||||
{ return _M_a; }
|
|
||||||
|
|
||||||
result_type
|
|
||||||
b() const
|
|
||||||
{ return _M_b; }
|
|
||||||
|
|
||||||
friend bool
|
|
||||||
operator==(const param_type& __p1, const param_type& __p2)
|
|
||||||
{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
_IntType _M_a;
|
|
||||||
_IntType _M_b;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @brief Constructs a uniform distribution object.
|
|
||||||
*/
|
|
||||||
explicit
|
|
||||||
uniform_int_distribution(_IntType __a = 0,
|
|
||||||
_IntType __b = std::numeric_limits<_IntType>::max())
|
|
||||||
: _M_param(__a, __b)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
explicit
|
|
||||||
uniform_int_distribution(const param_type& __p)
|
|
||||||
: _M_param(__p)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Resets the distribution state.
|
|
||||||
*
|
|
||||||
* Does nothing for the uniform integer distribution.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
reset() { }
|
|
||||||
|
|
||||||
result_type
|
|
||||||
a() const
|
|
||||||
{ return _M_param.a(); }
|
|
||||||
|
|
||||||
result_type
|
|
||||||
b() const
|
|
||||||
{ return _M_param.b(); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns the parameter set of the distribution.
|
|
||||||
*/
|
|
||||||
param_type
|
|
||||||
param() const
|
|
||||||
{ return _M_param; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Sets the parameter set of the distribution.
|
|
||||||
* @param __param The new parameter set of the distribution.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
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)
|
|
||||||
{ return this->operator()(__urng, _M_param); }
|
|
||||||
|
|
||||||
template<typename _UniformRandomNumberGenerator>
|
|
||||||
result_type
|
|
||||||
operator()(_UniformRandomNumberGenerator& __urng,
|
|
||||||
const param_type& __p);
|
|
||||||
|
|
||||||
template<typename _ForwardIterator,
|
|
||||||
typename _UniformRandomNumberGenerator>
|
|
||||||
void
|
|
||||||
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
|
||||||
_UniformRandomNumberGenerator& __urng)
|
|
||||||
{ this->__generate(__f, __t, __urng, _M_param); }
|
|
||||||
|
|
||||||
template<typename _ForwardIterator,
|
|
||||||
typename _UniformRandomNumberGenerator>
|
|
||||||
void
|
|
||||||
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
|
||||||
_UniformRandomNumberGenerator& __urng,
|
|
||||||
const param_type& __p)
|
|
||||||
{ this->__generate_impl(__f, __t, __urng, __p); }
|
|
||||||
|
|
||||||
template<typename _UniformRandomNumberGenerator>
|
|
||||||
void
|
|
||||||
__generate(result_type* __f, result_type* __t,
|
|
||||||
_UniformRandomNumberGenerator& __urng,
|
|
||||||
const param_type& __p)
|
|
||||||
{ this->__generate_impl(__f, __t, __urng, __p); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Return true if two uniform integer distributions have
|
|
||||||
* the same parameters.
|
|
||||||
*/
|
|
||||||
friend bool
|
|
||||||
operator==(const uniform_int_distribution& __d1,
|
|
||||||
const uniform_int_distribution& __d2)
|
|
||||||
{ return __d1._M_param == __d2._M_param; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
template<typename _ForwardIterator,
|
|
||||||
typename _UniformRandomNumberGenerator>
|
|
||||||
void
|
|
||||||
__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
|
|
||||||
_UniformRandomNumberGenerator& __urng,
|
|
||||||
const param_type& __p);
|
|
||||||
|
|
||||||
param_type _M_param;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return true if two uniform integer distributions have
|
* @brief Return true if two uniform integer distributions have
|
||||||
|
|
|
||||||
|
|
@ -872,158 +872,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename _IntType>
|
|
||||||
template<typename _UniformRandomNumberGenerator>
|
|
||||||
typename uniform_int_distribution<_IntType>::result_type
|
|
||||||
uniform_int_distribution<_IntType>::
|
|
||||||
operator()(_UniformRandomNumberGenerator& __urng,
|
|
||||||
const param_type& __param)
|
|
||||||
{
|
|
||||||
typedef typename _UniformRandomNumberGenerator::result_type
|
|
||||||
_Gresult_type;
|
|
||||||
typedef typename std::make_unsigned<result_type>::type __utype;
|
|
||||||
typedef typename std::common_type<_Gresult_type, __utype>::type
|
|
||||||
__uctype;
|
|
||||||
|
|
||||||
const __uctype __urngmin = __urng.min();
|
|
||||||
const __uctype __urngmax = __urng.max();
|
|
||||||
const __uctype __urngrange = __urngmax - __urngmin;
|
|
||||||
const __uctype __urange
|
|
||||||
= __uctype(__param.b()) - __uctype(__param.a());
|
|
||||||
|
|
||||||
__uctype __ret;
|
|
||||||
|
|
||||||
if (__urngrange > __urange)
|
|
||||||
{
|
|
||||||
// downscaling
|
|
||||||
const __uctype __uerange = __urange + 1; // __urange can be zero
|
|
||||||
const __uctype __scaling = __urngrange / __uerange;
|
|
||||||
const __uctype __past = __uerange * __scaling;
|
|
||||||
do
|
|
||||||
__ret = __uctype(__urng()) - __urngmin;
|
|
||||||
while (__ret >= __past);
|
|
||||||
__ret /= __scaling;
|
|
||||||
}
|
|
||||||
else if (__urngrange < __urange)
|
|
||||||
{
|
|
||||||
// upscaling
|
|
||||||
/*
|
|
||||||
Note that every value in [0, urange]
|
|
||||||
can be written uniquely as
|
|
||||||
|
|
||||||
(urngrange + 1) * high + low
|
|
||||||
|
|
||||||
where
|
|
||||||
|
|
||||||
high in [0, urange / (urngrange + 1)]
|
|
||||||
|
|
||||||
and
|
|
||||||
|
|
||||||
low in [0, urngrange].
|
|
||||||
*/
|
|
||||||
__uctype __tmp; // wraparound control
|
|
||||||
do
|
|
||||||
{
|
|
||||||
const __uctype __uerngrange = __urngrange + 1;
|
|
||||||
__tmp = (__uerngrange * operator()
|
|
||||||
(__urng, param_type(0, __urange / __uerngrange)));
|
|
||||||
__ret = __tmp + (__uctype(__urng()) - __urngmin);
|
|
||||||
}
|
|
||||||
while (__ret > __urange || __ret < __tmp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
__ret = __uctype(__urng()) - __urngmin;
|
|
||||||
|
|
||||||
return __ret + __param.a();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename _IntType>
|
|
||||||
template<typename _ForwardIterator,
|
|
||||||
typename _UniformRandomNumberGenerator>
|
|
||||||
void
|
|
||||||
uniform_int_distribution<_IntType>::
|
|
||||||
__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
|
|
||||||
_UniformRandomNumberGenerator& __urng,
|
|
||||||
const param_type& __param)
|
|
||||||
{
|
|
||||||
__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
|
|
||||||
typedef typename _UniformRandomNumberGenerator::result_type
|
|
||||||
_Gresult_type;
|
|
||||||
typedef typename std::make_unsigned<result_type>::type __utype;
|
|
||||||
typedef typename std::common_type<_Gresult_type, __utype>::type
|
|
||||||
__uctype;
|
|
||||||
|
|
||||||
const __uctype __urngmin = __urng.min();
|
|
||||||
const __uctype __urngmax = __urng.max();
|
|
||||||
const __uctype __urngrange = __urngmax - __urngmin;
|
|
||||||
const __uctype __urange
|
|
||||||
= __uctype(__param.b()) - __uctype(__param.a());
|
|
||||||
|
|
||||||
__uctype __ret;
|
|
||||||
|
|
||||||
if (__urngrange > __urange)
|
|
||||||
{
|
|
||||||
if (__detail::_Power_of_2(__urngrange + 1)
|
|
||||||
&& __detail::_Power_of_2(__urange + 1))
|
|
||||||
{
|
|
||||||
while (__f != __t)
|
|
||||||
{
|
|
||||||
__ret = __uctype(__urng()) - __urngmin;
|
|
||||||
*__f++ = (__ret & __urange) + __param.a();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// downscaling
|
|
||||||
const __uctype __uerange = __urange + 1; // __urange can be zero
|
|
||||||
const __uctype __scaling = __urngrange / __uerange;
|
|
||||||
const __uctype __past = __uerange * __scaling;
|
|
||||||
while (__f != __t)
|
|
||||||
{
|
|
||||||
do
|
|
||||||
__ret = __uctype(__urng()) - __urngmin;
|
|
||||||
while (__ret >= __past);
|
|
||||||
*__f++ = __ret / __scaling + __param.a();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (__urngrange < __urange)
|
|
||||||
{
|
|
||||||
// upscaling
|
|
||||||
/*
|
|
||||||
Note that every value in [0, urange]
|
|
||||||
can be written uniquely as
|
|
||||||
|
|
||||||
(urngrange + 1) * high + low
|
|
||||||
|
|
||||||
where
|
|
||||||
|
|
||||||
high in [0, urange / (urngrange + 1)]
|
|
||||||
|
|
||||||
and
|
|
||||||
|
|
||||||
low in [0, urngrange].
|
|
||||||
*/
|
|
||||||
__uctype __tmp; // wraparound control
|
|
||||||
while (__f != __t)
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
const __uctype __uerngrange = __urngrange + 1;
|
|
||||||
__tmp = (__uerngrange * operator()
|
|
||||||
(__urng, param_type(0, __urange / __uerngrange)));
|
|
||||||
__ret = __tmp + (__uctype(__urng()) - __urngmin);
|
|
||||||
}
|
|
||||||
while (__ret > __urange || __ret < __tmp);
|
|
||||||
*__f++ = __ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
while (__f != __t)
|
|
||||||
*__f++ = __uctype(__urng()) - __urngmin + __param.a();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename _IntType, typename _CharT, typename _Traits>
|
template<typename _IntType, typename _CharT, typename _Traits>
|
||||||
std::basic_ostream<_CharT, _Traits>&
|
std::basic_ostream<_CharT, _Traits>&
|
||||||
operator<<(std::basic_ostream<_CharT, _Traits>& __os,
|
operator<<(std::basic_ostream<_CharT, _Traits>& __os,
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@
|
||||||
#include <bits/predefined_ops.h>
|
#include <bits/predefined_ops.h>
|
||||||
|
|
||||||
#if __cplusplus >= 201103L
|
#if __cplusplus >= 201103L
|
||||||
#include <random> // for std::uniform_int_distribution
|
#include <bits/uniform_int_dist.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// See concept_check.h for the __glibcxx_*_requires macros.
|
// See concept_check.h for the __glibcxx_*_requires macros.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,369 @@
|
||||||
|
// Class template uniform_int_distribution -*- C++ -*-
|
||||||
|
|
||||||
|
// Copyright (C) 2009-2016 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.
|
||||||
|
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file bits/uniform_int_dist.h
|
||||||
|
* This is an internal header file, included by other library headers.
|
||||||
|
* Do not attempt to use it directly. @headername{random}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _GLIBCXX_BITS_UNIFORM_INT_DIST_H
|
||||||
|
#define _GLIBCXX_BITS_UNIFORM_INT_DIST_H
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
namespace std _GLIBCXX_VISIBILITY(default)
|
||||||
|
{
|
||||||
|
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
||||||
|
namespace __detail
|
||||||
|
{
|
||||||
|
/* Determine whether number is a power of 2. */
|
||||||
|
template<typename _Tp>
|
||||||
|
inline bool
|
||||||
|
_Power_of_2(_Tp __x)
|
||||||
|
{
|
||||||
|
return ((__x - 1) & __x) == 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Uniform discrete distribution for random numbers.
|
||||||
|
*
|
||||||
|
* A discrete random distribution on the range @f$[min, max]@f$ with equal
|
||||||
|
* probability throughout the range.
|
||||||
|
*
|
||||||
|
* @ingroup random_distributions_uniform
|
||||||
|
*/
|
||||||
|
template<typename _IntType = int>
|
||||||
|
class uniform_int_distribution
|
||||||
|
{
|
||||||
|
static_assert(std::is_integral<_IntType>::value,
|
||||||
|
"template argument not an integral type");
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** The type of the range of the distribution. */
|
||||||
|
typedef _IntType result_type;
|
||||||
|
/** Parameter type. */
|
||||||
|
struct param_type
|
||||||
|
{
|
||||||
|
typedef uniform_int_distribution<_IntType> distribution_type;
|
||||||
|
|
||||||
|
explicit
|
||||||
|
param_type(_IntType __a = 0,
|
||||||
|
_IntType __b = std::numeric_limits<_IntType>::max())
|
||||||
|
: _M_a(__a), _M_b(__b)
|
||||||
|
{
|
||||||
|
_GLIBCXX_DEBUG_ASSERT(_M_a <= _M_b);
|
||||||
|
}
|
||||||
|
|
||||||
|
result_type
|
||||||
|
a() const
|
||||||
|
{ return _M_a; }
|
||||||
|
|
||||||
|
result_type
|
||||||
|
b() const
|
||||||
|
{ return _M_b; }
|
||||||
|
|
||||||
|
friend bool
|
||||||
|
operator==(const param_type& __p1, const param_type& __p2)
|
||||||
|
{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
_IntType _M_a;
|
||||||
|
_IntType _M_b;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Constructs a uniform distribution object.
|
||||||
|
*/
|
||||||
|
explicit
|
||||||
|
uniform_int_distribution(_IntType __a = 0,
|
||||||
|
_IntType __b = std::numeric_limits<_IntType>::max())
|
||||||
|
: _M_param(__a, __b)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
explicit
|
||||||
|
uniform_int_distribution(const param_type& __p)
|
||||||
|
: _M_param(__p)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Resets the distribution state.
|
||||||
|
*
|
||||||
|
* Does nothing for the uniform integer distribution.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
reset() { }
|
||||||
|
|
||||||
|
result_type
|
||||||
|
a() const
|
||||||
|
{ return _M_param.a(); }
|
||||||
|
|
||||||
|
result_type
|
||||||
|
b() const
|
||||||
|
{ return _M_param.b(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the parameter set of the distribution.
|
||||||
|
*/
|
||||||
|
param_type
|
||||||
|
param() const
|
||||||
|
{ return _M_param; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the parameter set of the distribution.
|
||||||
|
* @param __param The new parameter set of the distribution.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
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)
|
||||||
|
{ return this->operator()(__urng, _M_param); }
|
||||||
|
|
||||||
|
template<typename _UniformRandomNumberGenerator>
|
||||||
|
result_type
|
||||||
|
operator()(_UniformRandomNumberGenerator& __urng,
|
||||||
|
const param_type& __p);
|
||||||
|
|
||||||
|
template<typename _ForwardIterator,
|
||||||
|
typename _UniformRandomNumberGenerator>
|
||||||
|
void
|
||||||
|
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
||||||
|
_UniformRandomNumberGenerator& __urng)
|
||||||
|
{ this->__generate(__f, __t, __urng, _M_param); }
|
||||||
|
|
||||||
|
template<typename _ForwardIterator,
|
||||||
|
typename _UniformRandomNumberGenerator>
|
||||||
|
void
|
||||||
|
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
||||||
|
_UniformRandomNumberGenerator& __urng,
|
||||||
|
const param_type& __p)
|
||||||
|
{ this->__generate_impl(__f, __t, __urng, __p); }
|
||||||
|
|
||||||
|
template<typename _UniformRandomNumberGenerator>
|
||||||
|
void
|
||||||
|
__generate(result_type* __f, result_type* __t,
|
||||||
|
_UniformRandomNumberGenerator& __urng,
|
||||||
|
const param_type& __p)
|
||||||
|
{ this->__generate_impl(__f, __t, __urng, __p); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return true if two uniform integer distributions have
|
||||||
|
* the same parameters.
|
||||||
|
*/
|
||||||
|
friend bool
|
||||||
|
operator==(const uniform_int_distribution& __d1,
|
||||||
|
const uniform_int_distribution& __d2)
|
||||||
|
{ return __d1._M_param == __d2._M_param; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<typename _ForwardIterator,
|
||||||
|
typename _UniformRandomNumberGenerator>
|
||||||
|
void
|
||||||
|
__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
|
||||||
|
_UniformRandomNumberGenerator& __urng,
|
||||||
|
const param_type& __p);
|
||||||
|
|
||||||
|
param_type _M_param;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename _IntType>
|
||||||
|
template<typename _UniformRandomNumberGenerator>
|
||||||
|
typename uniform_int_distribution<_IntType>::result_type
|
||||||
|
uniform_int_distribution<_IntType>::
|
||||||
|
operator()(_UniformRandomNumberGenerator& __urng,
|
||||||
|
const param_type& __param)
|
||||||
|
{
|
||||||
|
typedef typename _UniformRandomNumberGenerator::result_type
|
||||||
|
_Gresult_type;
|
||||||
|
typedef typename std::make_unsigned<result_type>::type __utype;
|
||||||
|
typedef typename std::common_type<_Gresult_type, __utype>::type
|
||||||
|
__uctype;
|
||||||
|
|
||||||
|
const __uctype __urngmin = __urng.min();
|
||||||
|
const __uctype __urngmax = __urng.max();
|
||||||
|
const __uctype __urngrange = __urngmax - __urngmin;
|
||||||
|
const __uctype __urange
|
||||||
|
= __uctype(__param.b()) - __uctype(__param.a());
|
||||||
|
|
||||||
|
__uctype __ret;
|
||||||
|
|
||||||
|
if (__urngrange > __urange)
|
||||||
|
{
|
||||||
|
// downscaling
|
||||||
|
const __uctype __uerange = __urange + 1; // __urange can be zero
|
||||||
|
const __uctype __scaling = __urngrange / __uerange;
|
||||||
|
const __uctype __past = __uerange * __scaling;
|
||||||
|
do
|
||||||
|
__ret = __uctype(__urng()) - __urngmin;
|
||||||
|
while (__ret >= __past);
|
||||||
|
__ret /= __scaling;
|
||||||
|
}
|
||||||
|
else if (__urngrange < __urange)
|
||||||
|
{
|
||||||
|
// upscaling
|
||||||
|
/*
|
||||||
|
Note that every value in [0, urange]
|
||||||
|
can be written uniquely as
|
||||||
|
|
||||||
|
(urngrange + 1) * high + low
|
||||||
|
|
||||||
|
where
|
||||||
|
|
||||||
|
high in [0, urange / (urngrange + 1)]
|
||||||
|
|
||||||
|
and
|
||||||
|
|
||||||
|
low in [0, urngrange].
|
||||||
|
*/
|
||||||
|
__uctype __tmp; // wraparound control
|
||||||
|
do
|
||||||
|
{
|
||||||
|
const __uctype __uerngrange = __urngrange + 1;
|
||||||
|
__tmp = (__uerngrange * operator()
|
||||||
|
(__urng, param_type(0, __urange / __uerngrange)));
|
||||||
|
__ret = __tmp + (__uctype(__urng()) - __urngmin);
|
||||||
|
}
|
||||||
|
while (__ret > __urange || __ret < __tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
__ret = __uctype(__urng()) - __urngmin;
|
||||||
|
|
||||||
|
return __ret + __param.a();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename _IntType>
|
||||||
|
template<typename _ForwardIterator,
|
||||||
|
typename _UniformRandomNumberGenerator>
|
||||||
|
void
|
||||||
|
uniform_int_distribution<_IntType>::
|
||||||
|
__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
|
||||||
|
_UniformRandomNumberGenerator& __urng,
|
||||||
|
const param_type& __param)
|
||||||
|
{
|
||||||
|
__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
|
||||||
|
typedef typename _UniformRandomNumberGenerator::result_type
|
||||||
|
_Gresult_type;
|
||||||
|
typedef typename std::make_unsigned<result_type>::type __utype;
|
||||||
|
typedef typename std::common_type<_Gresult_type, __utype>::type
|
||||||
|
__uctype;
|
||||||
|
|
||||||
|
const __uctype __urngmin = __urng.min();
|
||||||
|
const __uctype __urngmax = __urng.max();
|
||||||
|
const __uctype __urngrange = __urngmax - __urngmin;
|
||||||
|
const __uctype __urange
|
||||||
|
= __uctype(__param.b()) - __uctype(__param.a());
|
||||||
|
|
||||||
|
__uctype __ret;
|
||||||
|
|
||||||
|
if (__urngrange > __urange)
|
||||||
|
{
|
||||||
|
if (__detail::_Power_of_2(__urngrange + 1)
|
||||||
|
&& __detail::_Power_of_2(__urange + 1))
|
||||||
|
{
|
||||||
|
while (__f != __t)
|
||||||
|
{
|
||||||
|
__ret = __uctype(__urng()) - __urngmin;
|
||||||
|
*__f++ = (__ret & __urange) + __param.a();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// downscaling
|
||||||
|
const __uctype __uerange = __urange + 1; // __urange can be zero
|
||||||
|
const __uctype __scaling = __urngrange / __uerange;
|
||||||
|
const __uctype __past = __uerange * __scaling;
|
||||||
|
while (__f != __t)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
__ret = __uctype(__urng()) - __urngmin;
|
||||||
|
while (__ret >= __past);
|
||||||
|
*__f++ = __ret / __scaling + __param.a();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (__urngrange < __urange)
|
||||||
|
{
|
||||||
|
// upscaling
|
||||||
|
/*
|
||||||
|
Note that every value in [0, urange]
|
||||||
|
can be written uniquely as
|
||||||
|
|
||||||
|
(urngrange + 1) * high + low
|
||||||
|
|
||||||
|
where
|
||||||
|
|
||||||
|
high in [0, urange / (urngrange + 1)]
|
||||||
|
|
||||||
|
and
|
||||||
|
|
||||||
|
low in [0, urngrange].
|
||||||
|
*/
|
||||||
|
__uctype __tmp; // wraparound control
|
||||||
|
while (__f != __t)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
const __uctype __uerngrange = __urngrange + 1;
|
||||||
|
__tmp = (__uerngrange * operator()
|
||||||
|
(__urng, param_type(0, __urange / __uerngrange)));
|
||||||
|
__ret = __tmp + (__uctype(__urng()) - __urngmin);
|
||||||
|
}
|
||||||
|
while (__ret > __urange || __ret < __tmp);
|
||||||
|
*__f++ = __ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
while (__f != __t)
|
||||||
|
*__f++ = __uctype(__urng()) - __urngmin + __param.a();
|
||||||
|
}
|
||||||
|
|
||||||
|
_GLIBCXX_END_NAMESPACE_VERSION
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
#undef _GLIBCXX_CONCEPT_CHECKS
|
#undef _GLIBCXX_CONCEPT_CHECKS
|
||||||
|
|
||||||
#include <algorithm>
|
#include <memory>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <testsuite_hooks.h>
|
#include <testsuite_hooks.h>
|
||||||
#include <testsuite_iterators.h>
|
#include <testsuite_iterators.h>
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
#undef _GLIBCXX_CONCEPT_CHECKS
|
#undef _GLIBCXX_CONCEPT_CHECKS
|
||||||
|
|
||||||
#include <algorithm>
|
#include <memory>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <testsuite_hooks.h>
|
#include <testsuite_hooks.h>
|
||||||
#include <testsuite_iterators.h>
|
#include <testsuite_iterators.h>
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
// { dg-options "-std=gnu++11" }
|
// { dg-options "-std=gnu++11" }
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
#include <testsuite_hooks.h>
|
#include <testsuite_hooks.h>
|
||||||
#include <testsuite_iterators.h>
|
#include <testsuite_iterators.h>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,6 @@ std::__detail::_Adaptor<std::mt19937, unsigned long> aurng(urng);
|
||||||
auto x = std::generate_canonical<std::size_t,
|
auto x = std::generate_canonical<std::size_t,
|
||||||
std::numeric_limits<std::size_t>::digits>(urng);
|
std::numeric_limits<std::size_t>::digits>(urng);
|
||||||
|
|
||||||
// { dg-error "static assertion failed: template argument not a floating point type" "" { target *-*-* } 167 }
|
// { dg-error "static assertion failed: template argument not a floating point type" "" { target *-*-* } 160 }
|
||||||
|
|
||||||
// { dg-error "static assertion failed: template argument not a floating point type" "" { target *-*-* } 3466 }
|
// { dg-error "static assertion failed: template argument not a floating point type" "" { target *-*-* } 3314 }
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// { dg-do run }
|
// { dg-do run }
|
||||||
// { dg-options "-g -O0 -std=gnu++11" }
|
// { dg-options "-g -O0 -std=gnu++11" }
|
||||||
|
|
||||||
// Copyright (C) 2011-2015 Free Software Foundation, Inc.
|
// Copyright (C) 2011-2016 Free Software Foundation, Inc.
|
||||||
//
|
//
|
||||||
// This file is part of the GNU ISO C++ Library. This library is free
|
// 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
|
// software; you can redistribute it and/or modify it under the
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void
|
void
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue