Cannot use Boost.Croutines with range based for

Hi, I am (again) having issues with the Boost.Coroutines library. Aside from yet another new API, the coroutines no longer work with range based for. Even though the examples include range based for! With the following code (taken directly from the documentation and added the includes and main): #include <boost/coroutine/asymmetric_coroutine.hpp> #include <iostream> int main() { boost::coroutines::asymmetric_coroutine<int>::pull_type source( [&](boost::coroutines::asymmetric_coroutine<int>::push_type& sink){ int first=1, second=1; sink(first); sink(second); for(int i=0;i<8;++i){ int third=first+second; first=second; second=third; sink(third); } } ); for(auto i : source) std::cout << i << " "; } I get this error: D:\projects\combinators\coro_test.cpp: In function 'int main()': D:\projects\combinators\coro_test.cpp:20:15: error: 'begin' was not declared in this scope for(auto i : source) ^ D:\projects\combinators\coro_test.cpp:20:15: note: suggested alternatives: In file included from D:\projects\combinators\coro_test.cpp:1:0: D:/libs/mingw-amd64/boost_1_56_0/include/boost-1_56/boost/coroutine/asymmetric_coroutine.hpp:2255:1: note: 'std::begin' begin( boost::coroutines::push_coroutine< R > & c) ^ In file included from D:/libs/mingw-amd64/boost_1_56_0/include/boost-1_56/boost/range/functions.hpp:18:0, from D:/libs/mingw-amd64/boost_1_56_0/include/boost-1_56/boost/range.hpp:18, from D:/libs/mingw-amd64/boost_1_56_0/include/boost-1_56/boost/coroutine/asymmetric_coroutine.hpp:17, from D:\projects\combinators\coro_test.cpp:1: D:/libs/mingw-amd64/boost_1_56_0/include/boost-1_56/boost/range/begin.hpp:106:61: note: 'boost::range_adl_barrier::begin' inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type begin( const T& r ) ^ D:/libs/mingw-amd64/boost_1_56_0/include/boost-1_56/boost/range/begin.hpp:106:61: note: 'boost::range_adl_barrier::begin' D:\projects\combinators\coro_test.cpp:20:15: error: 'end' was not declared in this scope for(auto i : source) ^ D:\projects\combinators\coro_test.cpp:20:15: note: suggested alternatives: In file included from D:\projects\combinators\coro_test.cpp:1:0: D:/libs/mingw-amd64/boost_1_56_0/include/boost-1_56/boost/coroutine/asymmetric_coroutine.hpp:2260:1: note: 'std::end' end( boost::coroutines::push_coroutine< R > & c) ^ In file included from D:/libs/mingw-amd64/boost_1_56_0/include/boost-1_56/boost/range/functions.hpp:19:0, from D:/libs/mingw-amd64/boost_1_56_0/include/boost-1_56/boost/range.hpp:18, from D:/libs/mingw-amd64/boost_1_56_0/include/boost-1_56/boost/coroutine/asymmetric_coroutine.hpp:17, from D:\projects\combinators\coro_test.cpp:1: D:/libs/mingw-amd64/boost_1_56_0/include/boost-1_56/boost/range/end.hpp:100:61: note: 'boost::range_adl_barrier::end' inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type end( const T& r ) ^ D:/libs/mingw-amd64/boost_1_56_0/include/boost-1_56/boost/range/end.hpp:100:61: note: 'boost::range_adl_barrier::end' mingw32-make[2]: *** [CMakeFiles/coro-test.dir/coro_test.cpp.obj] Error 1 mingw32-make[1]: *** [CMakeFiles/coro-test.dir/all] Error 2 mingw32-make: *** [all] Error 2 For completeness sake: I am using MinGW-w64 with GCC 4.9.1 and the -std=c++11 flag Regards, Johannes S. Mueller-Roemer -- Johannes S. Mueller-Roemer, MSc Wiss. Mitarbeiter - Interactive Engineering Technologies (IET) Fraunhofer-Institut für Graphische Datenverarbeitung IGD Fraunhoferstr. 5 | 64283 Darmstadt | Germany Tel +49 6151 155-606 | Fax +49 6151 155-139 johannes.mueller-roemer@igd.fraunhofer.de | www.igd.fraunhofer.de

2014-08-27 12:57 GMT+02:00 Mueller-Roemer, Johannes Sebastian < Johannes.Sebastian.Mueller-Roemer@igd.fraunhofer.de>:
Hi,
I am (again) having issues with the Boost.Coroutines library. Aside from yet another new API, the coroutines no longer work with range based for. Even though the examples include range based for! With the following code (taken directly from the documentation and added the includes and main):
example/cpp11/asymmetric/fibonacci compiles with gcc-4.8.1 and clang-3.4.1 without problems

It does not compile with GCC-4.9.1 -- Johannes S. Mueller-Roemer, MSc Wiss. Mitarbeiter - Interactive Engineering Technologies (IET) Fraunhofer-Institut für Graphische Datenverarbeitung IGD Fraunhoferstr. 5 | 64283 Darmstadt | Germany Tel +49 6151 155-606 | Fax +49 6151 155-139 johannes.mueller-roemer@igd.fraunhofer.de | www.igd.fraunhofer.de From: Boost-users [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Oliver Kowalke Sent: Wednesday, August 27, 2014 17:16 To: boost-users Subject: Re: [Boost-users] Cannot use Boost.Croutines with range based for 2014-08-27 12:57 GMT+02:00 Mueller-Roemer, Johannes Sebastian <Johannes.Sebastian.Mueller-Roemer@igd.fraunhofer.de<mailto:Johannes.Sebastian.Mueller-Roemer@igd.fraunhofer.de>>: Hi, I am (again) having issues with the Boost.Coroutines library. Aside from yet another new API, the coroutines no longer work with range based for. Even though the examples include range based for! With the following code (taken directly from the documentation and added the includes and main): example/cpp11/asymmetric/fibonacci compiles with gcc-4.8.1 and clang-3.4.1 without problems

As per DR1442 (for C++11), the rule of range-based-for has been changed. ( http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1442 ) The new rule does not add namespace `std` as an associated namespace. So `begin` and `end` should be defined as either - member functions, or - as free functions in the enclosing namespaces (e.g. `boost::coroutines`). Recent gcc and clang implemented the new rule. Regards, Michel

Thanks, I was about to post the same link, didn't know that GCC 4.9 implements it. In any case, isn't adding new overloads to namespace std as Boost.Coroutine does illegal anyway (as per 17.6.4.2.1 which allows specializations for user defined types, not, however, overloads)? -- Johannes S. Mueller-Roemer, MSc Wiss. Mitarbeiter - Interactive Engineering Technologies (IET) Fraunhofer-Institut für Graphische Datenverarbeitung IGD Fraunhoferstr. 5 | 64283 Darmstadt | Germany Tel +49 6151 155-606 | Fax +49 6151 155-139 johannes.mueller-roemer@igd.fraunhofer.de | www.igd.fraunhofer.de -----Original Message----- From: Boost-users [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Michel Morin Sent: Thursday, August 28, 2014 08:32 To: boost-users@lists.boost.org Subject: Re: [Boost-users] Cannot use Boost.Croutines with range based for As per DR1442 (for C++11), the rule of range-based-for has been changed. ( http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1442 ) The new rule does not add namespace `std` as an associated namespace. So `begin` and `end` should be defined as either - member functions, or - as free functions in the enclosing namespaces (e.g. `boost::coroutines`). Recent gcc and clang implemented the new rule. Regards, Michel _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

On 8/27/2014 11:56 PM, Mueller-Roemer, Johannes Sebastian wrote:
Thanks, I was about to post the same link, didn't know that GCC 4.9 implements it. In any case, isn't adding new overloads to namespace std as Boost.Coroutine does illegal anyway (as per 17.6.4.2.1 which allows specializations for user defined types, not, however, overloads)?
It is absolutely illegal, and Boost.Coroutine is wrong to do it. You should file a bug. What is wrong with putting the begin/end overloads in the boost::coroutines namespace and letting them be found by ADL? Eric

On Thu, Aug 28, 2014 at 2:32 AM, Michel Morin <mimomorin@gmail.com> wrote:
As per DR1442 (for C++11), the rule of range-based-for has been changed. ( http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1442 )
The new rule does not add namespace `std` as an associated namespace. So `begin` and `end` should be defined as either
- member functions, or - as free functions in the enclosing namespaces (e.g. `boost::coroutines`).
Recent gcc and clang implemented the new rule.
Please correct me if I'm wrong -- but if Oliver makes such a change unconditionally, won't Boost.Coroutine's range-based-for support break on older compilers? How do other Boost libraries accommodate this change? Are there already canonical Boost workaround macros?

Older compilers should already use ADL, so the solution I posted should be fine for them as well. Replacing the illegal std::begin and end in asymmetric_coroutine.hpp by namespace boost { namespace coroutines { using boost::begin; using boost::end; } } Works just fine on GCC 4.8.1 (don't have a working clang 3.4 to test) -- Johannes S. Mueller-Roemer, MSc Wiss. Mitarbeiter - Interactive Engineering Technologies (IET) Fraunhofer-Institut für Graphische Datenverarbeitung IGD Fraunhoferstr. 5 | 64283 Darmstadt | Germany Tel +49 6151 155-606 | Fax +49 6151 155-139 johannes.mueller-roemer@igd.fraunhofer.de | www.igd.fraunhofer.de -----Original Message----- From: Boost-users [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Nat Goodspeed Sent: Thursday, August 28, 2014 15:19 To: boost-users@lists.boost.org Subject: Re: [Boost-users] Cannot use Boost.Croutines with range based for On Thu, Aug 28, 2014 at 2:32 AM, Michel Morin <mimomorin@gmail.com> wrote:
As per DR1442 (for C++11), the rule of range-based-for has been changed. ( http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1442 )
The new rule does not add namespace `std` as an associated namespace. So `begin` and `end` should be defined as either
- member functions, or - as free functions in the enclosing namespaces (e.g. `boost::coroutines`).
Recent gcc and clang implemented the new rule.
Please correct me if I'm wrong -- but if Oliver makes such a change unconditionally, won't Boost.Coroutine's range-based-for support break on older compilers? How do other Boost libraries accommodate this change? Are there already canonical Boost workaround macros? _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

asymmetric_coroutine.hpp already contains boost::coroutines::begin() and boost::coroutines::end()

I had another look and that isn’t quite true. It does define them, but only if __clang__ is defined. I tried removing that #ifdef (and the std::begin/end) and that works on my GCC-4.8.1 install as well. -- Johannes S. Mueller-Roemer, MSc Wiss. Mitarbeiter - Interactive Engineering Technologies (IET) Fraunhofer-Institut für Graphische Datenverarbeitung IGD Fraunhoferstr. 5 | 64283 Darmstadt | Germany Tel +49 6151 155-606 | Fax +49 6151 155-139 johannes.mueller-roemer@igd.fraunhofer.de | www.igd.fraunhofer.de From: Boost-users [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Oliver Kowalke Sent: Thursday, August 28, 2014 17:14 To: boost-users Subject: Re: [Boost-users] Cannot use Boost.Croutines with range based for asymmetric_coroutine.hpp already contains boost::coroutines::begin() and boost::coroutines::end()

2014-08-28 17:24 GMT+02:00 Mueller-Roemer, Johannes Sebastian < Johannes.Sebastian.Mueller-Roemer@igd.fraunhofer.de>:
I had another look and that isn’t quite true. It does define them, but only if __clang__ is defined. I tried removing that #ifdef (and the std::begin/end) and that works on my GCC-4.8.1 install as well.
but it does not work for gcc+clang on Linux layout.cpp:47:49: error: no matching function for call to 'begin' std::copy(std::begin(words),std::end(words),std::begin(writer)); I'll take a look at boost.range, maybe I find code telling me how to deal with this issue

Hi Oliver, Oliver Kowalke wrote:
but it does not work for gcc+clang on Linux
layout.cpp:47:49: error: no matching function for call to 'begin' std::copy(std::begin(words),std::end(words),std::begin(writer));
For push_coroutine/pull_coroutine, try using boost::begin/end. Regards, Michel

2014-08-28 19:03 GMT+02:00 Michel Morin <mimomorin@gmail.com>:
layout.cpp:47:49: error: no matching function for call to 'begin' std::copy(std::begin(words),std::end(words),std::begin(writer));
For push_coroutine/pull_coroutine, try using boost::begin/end.
and why not std::begin()? should be legal for c++11

Oliver Kowalke wrote:
For push_coroutine/pull_coroutine, try using boost::begin/end.
and why not std::begin()? should be legal for c++11
`std::begin` calls member function `begin`: template <class C> auto begin(C& c) -> decltype(c.begin()) { return c.begin(); } But `push_coroutine`/`pull_coroutine` do not have member function `begin`, and so `std::begin` is not defined for them. Regards, Michel

Hi Johannes,
I tried removing that #ifdef (and the std::begin/end) and that works on my GCC-4.8.1 install as well.
Yep, that should work on compilers with/without DR1442 fix. (It would be helpful to make a patch to avoid any miscommunication.) P.S. Please don't top-post! http://www.boost.org/community/policy.html#quoting Regards, Michel

I've checked in a new version (branch develop) - please let me know if it works for you.

Michel Morin wrote:
Oliver Kowalke wrote:
I've checked in a new version (branch develop) - please let me know if it works for you.
Thanks, `example` and `test` ran successfully on gcc-4.8, 4.9 and clang-3.3 and 3.4 (in a C++11 mode).
Works fine for me as well on MinGW GCC-4.8.1 and 4.9.1

Odd, I tested it with (mingw) gcc-4.8.1 -- Johannes S. Mueller-Roemer, MSc Wiss. Mitarbeiter - Interactive Engineering Technologies (IET) Fraunhofer-Institut für Graphische Datenverarbeitung IGD Fraunhoferstr. 5 | 64283 Darmstadt | Germany Tel +49 6151 155-606 | Fax +49 6151 155-139 johannes.mueller-roemer@igd.fraunhofer.de | www.igd.fraunhofer.de From: Boost-users [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Oliver Kowalke Sent: Thursday, August 28, 2014 17:12 To: boost-users Subject: Re: [Boost-users] Cannot use Boost.Croutines with range based for 2014-08-28 15:36 GMT+02:00 Mueller-Roemer, Johannes Sebastian <Johannes.Sebastian.Mueller-Roemer@igd.fraunhofer.de<mailto:Johannes.Sebastian.Mueller-Roemer@igd.fraunhofer.de>>: Works just fine on GCC 4.8.1 (don't have a working clang 3.4 to test) does not work for gcc-4.8.1 + clang-3.4.1 :(
participants (5)
-
Eric Niebler
-
Michel Morin
-
Mueller-Roemer, Johannes Sebastian
-
Nat Goodspeed
-
Oliver Kowalke