[cfe-dev] libc++, std::bind, and <random>
Howard Hinnant
hhinnant at apple.com
Mon Apr 11 10:47:35 PDT 2011
On Apr 11, 2011, at 12:38 PM, Howard Hinnant wrote:
> On Apr 11, 2011, at 12:22 PM, Steven Watanabe wrote:
>
>> AMDG
>>
>> On 04/11/2011 08:38 AM, Howard Hinnant wrote:
>>>
>>> On Apr 11, 2011, at 11:30 AM, Steven Watanabe wrote:
>>>
>>>> When calling the copy constructor of a Random
>>>> Number Engine with a non-const argument, the library is
>>>> incorrectly treating the argument as a SeedSeq.
>>>> The two declarations in question are:
>>>>
>>>> mersenne_twister(const mersenne_twister&);
>>>> template<typename SeedSeq> mersenne_twister(SeedSeq&);
>>>
>>> Thanks Steven. I'm working on an improved constraint
>>> for the SeedSeq template parameter. The current
>>> constraint is simply that it is not implicitly
>>> convertible to the engine's result_type.
>>>
>>
>> I think that constraint is wrong. (I don't have
>> the final draft, so my information could be
>> out of date, however. I'm referencing n3242)
>>
>> Here are the relevant sections:
>> a) T is the type named by E's associated result_type;
>> c) s is a value of T;
>> d) q is an lvalue satisfying the requirements of
>> a seed sequence (26.5.1.2);
>>
>> Table 117 -- Random number engine requirements
>> E(s) -- Creates an engine with initial state determined by s.
>> E(q) -- Creates an engine with an initial state that
>> depends on a sequence produced by one call
>> to q.generate.
>>
>> Now consider the following class:
>>
>> class my_seed_seq
>> {
>> public:
>> ...all members required for a seed sequence...
>> operator bool() const;
>> };
>>
>> According to the above,
>>
>> my_seed_seq q;
>> std::mt19937 gen(q);
>>
>> should call the seed sequence constructor.
>> If you use a convertible constraint, it will
>> be equivalent to
>>
>> std::mt19937 gen(bool(q));
>
> I'm in search of a seed sequence constraint that clang will compile without -std=c++0x. Suggestions welcome. What I'm doing at the moment:
>
> I've created a new trait:
>
> template <class _Sseq, class _Engine>
> struct __is_seed_sequence;
>
> to replace each place in <random> where I'm currently using !isconvertible. That will make fixing this bug easier. My current definition is:
>
> template <class _Sseq, class _Engine>
> struct __is_seed_sequence
> {
> static const bool value =
> !is_convertible<_Sseq, typename _Engine::result_type>::value &&
> !is_same<typename remove_cv<_Sseq>::type, _Engine>::value;
> };
>
> That passes Seth's test, but fails yours.
>
> Ideally I'd like to test for the generate member of the seed sequence (with C++03 mode turned on). But as that member function may take random access iterators that may take an infinite number of forms, I'm currently lacking a test to detect the member generate.
>
> Suggestions welcome.
I should have added that I expect the following test to pass:
int seed = 5;
std::mt19937 re3(seed);
which is the motivation for the part of the constraint that Sseq is not implicitly convertible to Engine::result_type. I would also expect the Engine to be seedable with a BigInt class which has an implicit conversion to Engine::result_type.
Oh, one more thing. 26.5.3 [rand.eng]/6 ends with:
> The extent to which an implementation determines that a type cannot be a seed sequence is unspecified, except that as a minimum a type shall not qualify as a seed sequence if it is implicitly convertible to X::result_type.
Howard
More information about the cfe-dev
mailing list