[cfe-dev] libc++, std::bind, and <random>

Howard Hinnant hhinnant at apple.com
Mon Apr 11 09:38:21 PDT 2011


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.

Howard




More information about the cfe-dev mailing list