libc++, std::bind, and <random>

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

libc++, std::bind, and <random>

Seth Cantrell
Should the following work with clang and libc++?

> #include <functional>
> #include <random>
>
> int main(int argc,char const *argv[]) {
>     std::mt19937 re;
>     std::normal_distribution<> di(30,8);
>     auto rand = std::bind(di,re);
> }

Clang outputs the following error for this program:

> In file included from test.c++:2:
> /usr/include/c++/v1/random:2234:9: error: no member named 'generate' in 'std::__1::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11,
>       4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>'
>     __q.generate(__ar, __ar + __n * __k);
>     ~~~ ^

It looks to me like clang supports all the features necessary, and the code runs as expected in VS2010. Here's the command line I used:

> clang++ -stdlib=libc++ -std=c++0x -U__STRICT_ANSI__ -pedantic -fno-blocks -frtti -g test.c++

I'm using revision 129268 of libc++ and clang -v outputs:

> clang version 3.0 (http://llvm.org/git/clang.git 067bbd0e11c71a33b51832532e836971be697699)
> Target: x86_64-apple-darwin10
> Thread model: posix




_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: libc++, std::bind, and <random>

John McCall
On Apr 10, 2011, at 10:18 PM, Seth Cantrell wrote:
> Should the following work with clang and libc++?

It certainly should.

>> #include <functional>
>> #include <random>
>>
>> int main(int argc,char const *argv[]) {
>>    std::mt19937 re;
>>    std::normal_distribution<> di(30,8);
>>    auto rand = std::bind(di,re);
>> }
>
> Clang outputs the following error for this program:
>
>> In file included from test.c++:2:
>> /usr/include/c++/v1/random:2234:9: error: no member named 'generate' in 'std::__1::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11,
>>      4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>'
>>    __q.generate(__ar, __ar + __n * __k);
>>    ~~~ ^

It's not clear to me why this is getting instantiated and with what
arguments.  Can you post the full instantiation backtrace, i.e. all the
messages and not just the ultimate error?

John.
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: libc++, std::bind, and <random>

Seth Cantrell
Here's the instantiation backtrace.

> In file included from test.c++:2:
> /usr/include/c++/v1/random:2234:9: error: no member named 'generate' in 'std::__1::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11,
>       4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>'
>     __q.generate(__ar, __ar + __n * __k);
>     ~~~ ^
> /usr/include/c++/v1/random:2117:14: note: in instantiation of function template specialization 'std::__1::mersenne_twister_engine<unsigned int, 32, 624, 397,
>       31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>::__seed<std::__1::mersenne_twister_engine<unsigned int, 32, 624, 397,
>       31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253> >' requested here
>             {__seed(__q, integral_constant<unsigned, 1 + (__w - 1) / 32>());}
>              ^
> /usr/include/c++/v1/random:2107:10: note: in instantiation of function template specialization 'std::__1::mersenne_twister_engine<unsigned int, 32, 624, 397,
>       31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>::seed<std::__1::mersenne_twister_engine<unsigned int, 32, 624, 397, 31,
>       2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253> >' requested here
>         {seed(__q);}
>          ^
> /usr/include/c++/v1/tuple:184:15: note: in instantiation of function template specialization 'std::__1::mersenne_twister_engine<unsigned int, 32, 624, 397,
>       31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>::mersenne_twister_engine<std::__1::mersenne_twister_engine<unsigned int,
>       32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253> >' requested here
>             : value(_STD::forward<_Tp>(__t))
>               ^
> /usr/include/c++/v1/tuple:355:13: note: in instantiation of function template specialization 'std::__1::__tuple_leaf<0,
>       std::__1::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>,
>       false>::__tuple_leaf<std::__1::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18,
>       1812433253> &, void>' requested here
>             __tuple_leaf<_Uf, _Tf>(_STD::forward<_Up>(__u))...,
>             ^
> /usr/include/c++/v1/tuple:471:15: note: in instantiation of function template specialization 'std::__1::__tuple_impl<std::__1::__tuple_indices<0>,
>       std::__1::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>
>       >::__tuple_impl<0, std::__1::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18,
>       1812433253> , , , std::__1::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18,
>       1812433253> &>' requested here
>             : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
>               ^
> /usr/include/c++/v1/functional:1673:11: note: in instantiation of function template specialization
>       'std::__1::tuple<std::__1::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18,
>       1812433253> >::tuple<std::__1::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18,
>       1812433253> &, void>' requested here
>           __bound_args_(_STD::forward<_BA>(__bound_args)...) {}
>           ^
> /usr/include/c++/v1/functional:1738:12: note: in instantiation of function template specialization 'std::__1::__bind<std::__1::normal_distribution<double>,
>       std::__1::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>
>       >::__bind<std::__1::normal_distribution<double> &, std::__1::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7,
>       2636928640, 15, 4022730752, 18, 1812433253> &>' requested here
>     return type(_STD::forward<_F>(__f), _STD::forward<_BoundArgs>(__bound_args)...);
>            ^
> test.c++:7:17: note: in instantiation of function template specialization 'std::__1::bind<std::__1::normal_distribution<double> &,
>       std::__1::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253> &>'
>       requested here
>     auto rand = std::bind(di,re);
>                 ^
> 1 error generated.


On Apr 11, 2011, at 1:46 AM, John McCall wrote:

> On Apr 10, 2011, at 10:18 PM, Seth Cantrell wrote:
>> Should the following work with clang and libc++?
>
> It certainly should.
>
>>> #include <functional>
>>> #include <random>
>>>
>>> int main(int argc,char const *argv[]) {
>>>   std::mt19937 re;
>>>   std::normal_distribution<> di(30,8);
>>>   auto rand = std::bind(di,re);
>>> }
>>
>> Clang outputs the following error for this program:
>>
>>> In file included from test.c++:2:
>>> /usr/include/c++/v1/random:2234:9: error: no member named 'generate' in 'std::__1::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11,
>>>     4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>'
>>>   __q.generate(__ar, __ar + __n * __k);
>>>   ~~~ ^
>
> It's not clear to me why this is getting instantiated and with what
> arguments.  Can you post the full instantiation backtrace, i.e. all the
> messages and not just the ultimate error?
>
> John.


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: libc++, std::bind, and <random>

Steven Watanabe
In reply to this post by Seth Cantrell
AMDG

On 04/10/2011 10:18 PM, Seth Cantrell wrote:

> Should the following work with clang and libc++?
>
>> #include<functional>
>> #include<random>
>>
>> int main(int argc,char const *argv[]) {
>>      std::mt19937 re;
>>      std::normal_distribution<>  di(30,8);
>>      auto rand = std::bind(di,re);
>> }
>
> Clang outputs the following error for this program:
>
>> In file included from test.c++:2:
>> /usr/include/c++/v1/random:2234:9: error: no member named 'generate' in 'std::__1::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11,
>>        4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>'
>>      __q.generate(__ar, __ar + __n * __k);
>>      ~~~ ^
>
> It looks to me like clang supports all the features necessary, and the code runs as expected in VS2010. Here's the command line I used:
>

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&);

In Christ,
Steven Watanabe
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: libc++, std::bind, and <random>

Steven Watanabe
AMDG

On 04/11/2011 08:30 AM, Steven Watanabe wrote:

> On 04/10/2011 10:18 PM, Seth Cantrell wrote:
>> Should the following work with clang and libc++?
>>
>>> #include<functional>
>>> #include<random>
>>>
>>> int main(int argc,char const *argv[]) {
>>> std::mt19937 re;
>>> std::normal_distribution<> di(30,8);
>>> auto rand = std::bind(di,re);
>>> }
>> <snip>
>
> 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.
>

Of course, you probably should use std::ref
to avoid copying the engine.

In Christ,
Steven Watanabe
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: libc++, std::bind, and <random>

Howard Hinnant
In reply to this post by Steven Watanabe

On Apr 11, 2011, at 11:30 AM, Steven Watanabe wrote:

> AMDG
>
> On 04/10/2011 10:18 PM, Seth Cantrell wrote:
>> Should the following work with clang and libc++?
>>
>>> #include<functional>
>>> #include<random>
>>>
>>> int main(int argc,char const *argv[]) {
>>>     std::mt19937 re;
>>>     std::normal_distribution<>  di(30,8);
>>>     auto rand = std::bind(di,re);
>>> }
>>
>> Clang outputs the following error for this program:
>>
>>> In file included from test.c++:2:
>>> /usr/include/c++/v1/random:2234:9: error: no member named 'generate' in 'std::__1::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11,
>>>       4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>'
>>>     __q.generate(__ar, __ar + __n * __k);
>>>     ~~~ ^
>>
>> It looks to me like clang supports all the features necessary, and the code runs as expected in VS2010. Here's the command line I used:
>>
>
> 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.

Howard

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: libc++, std::bind, and <random>

Steven Watanabe
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));

In Christ,
Steven Watanabe
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: libc++, std::bind, and <random>

Howard Hinnant
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

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: libc++, std::bind, and <random>

Howard Hinnant
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

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: libc++, std::bind, and <random>

Howard Hinnant
In reply to this post by Seth Cantrell

On Apr 11, 2011, at 1:18 AM, Seth Cantrell wrote:

> Should the following work with clang and libc++?
>
>> #include <functional>
>> #include <random>
>>
>> int main(int argc,char const *argv[]) {
>>    std::mt19937 re;
>>    std::normal_distribution<> di(30,8);
>>    auto rand = std::bind(di,re);
>> }
>
> Clang outputs the following error for this program:
>
>> In file included from test.c++:2:
>> /usr/include/c++/v1/random:2234:9: error: no member named 'generate' in 'std::__1::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11,
>>      4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>'
>>    __q.generate(__ar, __ar + __n * __k);
>>    ~~~ ^
>
> It looks to me like clang supports all the features necessary, and the code runs as expected in VS2010. Here's the command line I used:
>
>> clang++ -stdlib=libc++ -std=c++0x -U__STRICT_ANSI__ -pedantic -fno-blocks -frtti -g test.c++
>
> I'm using revision 129268 of libc++ and clang -v outputs:
>
>> clang version 3.0 (http://llvm.org/git/clang.git 067bbd0e11c71a33b51832532e836971be697699)
>> Target: x86_64-apple-darwin10
>> Thread model: posix

Fix Committed revision 129285.

Thanks,
Howard

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev