[context] boost::coroutines::asymmetric_coroutine<T>::pull_type iterator does not properly model InputIterator

I’m currently on Boost 1.56 so this might have been fixed by now, but in a simple test Boost.Coroutine fails to properly model the InputIterator concept, because *it++ does not conform to the operational semantics { T tmp = *it; ++it; return tmp; } required by the standard. The failing program: #include <boost/coroutine/asymmetric_coroutine.hpp> #include <iostream> template<typename Continuation> auto foo(Continuation && yield) -> void { yield("Hello"); yield(", "); yield("World"); yield("!\n"); } //using T = char const *; using T = std::string; auto foo() -> boost::coroutines::asymmetric_coroutine<T>::pull_type { using namespace boost::coroutines; return asymmetric_coroutine<T>::pull_type{ [](asymmetric_coroutine<T>::push_type& yield) { foo(yield); } }; } auto main(int, char **) -> int { auto f = foo(); for(auto it = boost::begin(f); it != boost::end(f);) std::cout << *it++; } Which (on my machine) outputs: , World! X☺à r2 ` , ` , Ç2 Ç Failing to model the InputIterator concept is bad, because then it isn’t any kind of standards-conforming iterator at all. Interestingly, if T is char const * and not std::string the program works as expected. Is there some other subtle bug at work here? -- 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

#include <iostream> #include <iterator> #include <string> #include <utility> #include <boost/coroutine/all.hpp> #include <boost/range/begin.hpp> #include <boost/range/end.hpp> template<typename Continuation> void bar(Continuation && yield) { yield("Hello"); yield(", "); yield("World"); yield("!\n"); } using T = std::string; using coro_t = boost::coroutines::asymmetric_coroutine<T>; coro_t::pull_type foo() { return coro_t::pull_type{ [](coro_t::push_type& yield) { bar(std::forward<coro_t::push_type>(yield)); }}; } int main(int, char **) { auto f = foo(); for ( auto i = boost::begin( f); i != boost::end( f); ++i) { std::cout << * i << std::endl; } return 0; } compiles with master branch 2015-02-16 9:22 GMT+01:00 Mueller-Roemer, Johannes Sebastian < Johannes.Sebastian.Mueller-Roemer@igd.fraunhofer.de>:
I’m currently on Boost 1.56 so this might have been fixed by now, but in a simple test Boost.Coroutine fails to properly model the InputIterator concept, because *it++ does not conform to the operational semantics { T tmp = *it; ++it; return tmp; } required by the standard.
The failing program:
#include <boost/coroutine/asymmetric_coroutine.hpp>
#include <iostream>
template<typename Continuation>
auto foo(Continuation && yield) -> void
{
yield("Hello");
yield(", ");
yield("World");
yield("!\n");
}
//using T = char const *;
using T = std::string;
auto foo() -> boost::coroutines::asymmetric_coroutine<T>::pull_type
{
using namespace boost::coroutines;
return asymmetric_coroutine<T>::pull_type{
[](asymmetric_coroutine<T>::push_type& yield) { foo(yield); }
};
}
auto main(int, char **) -> int
{
auto f = foo();
for(auto it = boost::begin(f); it != boost::end(f);)
std::cout << *it++;
}
Which (on my machine) outputs:
, World!
X☺à r2 ` , ` , Ç2 Ç
Failing to model the InputIterator concept is bad, because then it isn’t any kind of standards-conforming iterator at all. Interestingly, if T is char const * and not std::string the program works as expected. Is there some other subtle bug at work here?
--
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
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Compiling is not the issue. Furthermore your example does not test the issue I mentioned, as it does not use *it++; -- 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: Monday, February 16, 2015 13:35 To: boost-users@lists.boost.org Subject: Re: [Boost-users] [context] boost::coroutines::asymmetric_coroutine<T>::pull_type iterator does not properly model InputIterator #include <iostream> #include <iterator> #include <string> #include <utility> #include <boost/coroutine/all.hpp> #include <boost/range/begin.hpp> #include <boost/range/end.hpp> template<typename Continuation> void bar(Continuation && yield) { yield("Hello"); yield(", "); yield("World"); yield("!\n"); } using T = std::string; using coro_t = boost::coroutines::asymmetric_coroutine<T>; coro_t::pull_type foo() { return coro_t::pull_type{ [](coro_t::push_type& yield) { bar(std::forward<coro_t::push_type>(yield)); }}; } int main(int, char **) { auto f = foo(); for ( auto i = boost::begin( f); i != boost::end( f); ++i) { std::cout << * i << std::endl; } return 0; } compiles with master branch 2015-02-16 9:22 GMT+01:00 Mueller-Roemer, Johannes Sebastian <Johannes.Sebastian.Mueller-Roemer@igd.fraunhofer.de<mailto:Johannes.Sebastian.Mueller-Roemer@igd.fraunhofer.de>>: I’m currently on Boost 1.56 so this might have been fixed by now, but in a simple test Boost.Coroutine fails to properly model the InputIterator concept, because *it++ does not conform to the operational semantics { T tmp = *it; ++it; return tmp; } required by the standard. The failing program: #include <boost/coroutine/asymmetric_coroutine.hpp> #include <iostream> template<typename Continuation> auto foo(Continuation && yield) -> void { yield("Hello"); yield(", "); yield("World"); yield("!\n"); } //using T = char const *; using T = std::string; auto foo() -> boost::coroutines::asymmetric_coroutine<T>::pull_type { using namespace boost::coroutines; return asymmetric_coroutine<T>::pull_type{ [](asymmetric_coroutine<T>::push_type& yield) { foo(yield); } }; } auto main(int, char **) -> int { auto f = foo(); for(auto it = boost::begin(f); it != boost::end(f);) std::cout << *it++; } Which (on my machine) outputs: , World! X☺à r2 ` , ` , Ç2 Ç Failing to model the InputIterator concept is bad, because then it isn’t any kind of standards-conforming iterator at all. Interestingly, if T is char const * and not std::string the program works as expected. Is there some other subtle bug at work here? -- 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<tel:%2B49%206151%20155-606> | Fax +49 6151 155-139<tel:%2B49%206151%20155-139> johannes.mueller-roemer@igd.fraunhofer.de<mailto:johannes.mueller-roemer@igd.fraunhofer.de> | www.igd.fraunhofer.de<http://www.igd.fraunhofer.de> _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org<mailto:Boost-users@lists.boost.org> http://lists.boost.org/mailman/listinfo.cgi/boost-users

2015-02-16 13:46 GMT+01:00 Mueller-Roemer, Johannes Sebastian < Johannes.Sebastian.Mueller-Roemer@igd.fraunhofer.de>:
Compiling is not the issue.
it works as expected
Furthermore your example does not test the issue I mentioned, as it does not use *it++;
operator++ has higher precedence than operator* -> each increment triggers an jump/switch operation -> last increment invalidates coroutine

If that is „as expected“ it still violates the requirements for an InputIterator. See the last row in Table 107 in 24.2.3 in the standard http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf As-is the current “iterator” is not a valid iterator of any kind as InputIterator is already the weakest requirement. Example of how it should work (using an istream_iterator, which is an InputIterator): #include <iostream> #include <sstream> #include <iterator> auto main(int, char **) -> int { std::istringstream str("Hello , World !"); for(auto it = std::istream_iterator<std::string>(str); it != std::istream_iterator<std::string>();) std::cout << *it++; std::cout << "\n"; } Which outputs (as expected): Hello,World! The issue can be solved by storing a value in the iterator or returning a proxy object which dereferences to the original value. -- 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: Monday, February 16, 2015 14:20 To: boost-users@lists.boost.org Subject: Re: [Boost-users] [context] boost::coroutines::asymmetric_coroutine<T>::pull_type iterator does not properly model InputIterator 2015-02-16 13:46 GMT+01:00 Mueller-Roemer, Johannes Sebastian <Johannes.Sebastian.Mueller-Roemer@igd.fraunhofer.de<mailto:Johannes.Sebastian.Mueller-Roemer@igd.fraunhofer.de>>: Compiling is not the issue. it works as expected Furthermore your example does not test the issue I mentioned, as it does not use *it++; operator++ has higher precedence than operator* -> each increment triggers an jump/switch operation -> last increment invalidates coroutine

coroutines behave different than ordinary containers - even a temp var, created inside iterator::operator++( int), will influence the state of the attached coroutine (increment operator) you can't count on the feature set described for input iterators in the standard 2015-02-16 15:00 GMT+01:00 Mueller-Roemer, Johannes Sebastian < Johannes.Sebastian.Mueller-Roemer@igd.fraunhofer.de>:
If that is „as expected“ it still violates the requirements for an InputIterator. See the last row in Table 107 in 24.2.3 in the standard http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf
As-is the current “iterator” is not a valid iterator of any kind as InputIterator is already the weakest requirement.
Example of how it should work (using an istream_iterator, which is an InputIterator):
#include <iostream>
#include <sstream>
#include <iterator>
auto main(int, char **) -> int
{
std::istringstream str("Hello , World !");
for(auto it = std::istream_iterator<std::string>(str); it != std::istream_iterator<std::string>();)
std::cout << *it++;
std::cout << "\n";
}
Which outputs (as expected):
Hello,World!
The issue can be solved by storing a value in the iterator or returning a proxy object which dereferences to the original value.
--
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:* Monday, February 16, 2015 14:20 *To:* boost-users@lists.boost.org *Subject:* Re: [Boost-users] [context] boost::coroutines::asymmetric_coroutine<T>::pull_type iterator does not properly model InputIterator
2015-02-16 13:46 GMT+01:00 Mueller-Roemer, Johannes Sebastian < Johannes.Sebastian.Mueller-Roemer@igd.fraunhofer.de>:
Compiling is not the issue.
it works as expected
Furthermore your example does not test the issue I mentioned, as it does not use *it++;
operator++ has higher precedence than operator* -> each increment triggers an jump/switch operation -> last increment invalidates coroutine
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

The temporary variable would not have to store the execution state of the coroutine, only the yielded value. Offering a broken postfix increment is very dangerous and should be avoided. Also, if I can’t count on InputIterator features being supported, the following is a lie: class iterator : public std::iterator< std::input_iterator_tag, typename remove_reference< R >::type > (taken from asymmetric_coroutine.hpp) -- 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: Monday, February 16, 2015 15:28 To: boost-users@lists.boost.org Subject: Re: [Boost-users] [context] boost::coroutines::asymmetric_coroutine<T>::pull_type iterator does not properly model InputIterator coroutines behave different than ordinary containers - even a temp var, created inside iterator::operator++( int), will influence the state of the attached coroutine (increment operator) you can't count on the feature set described for input iterators in the standard 2015-02-16 15:00 GMT+01:00 Mueller-Roemer, Johannes Sebastian <Johannes.Sebastian.Mueller-Roemer@igd.fraunhofer.de<mailto:Johannes.Sebastian.Mueller-Roemer@igd.fraunhofer.de>>: If that is „as expected“ it still violates the requirements for an InputIterator. See the last row in Table 107 in 24.2.3 in the standard http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf As-is the current “iterator” is not a valid iterator of any kind as InputIterator is already the weakest requirement. Example of how it should work (using an istream_iterator, which is an InputIterator): #include <iostream> #include <sstream> #include <iterator> auto main(int, char **) -> int { std::istringstream str("Hello , World !"); for(auto it = std::istream_iterator<std::string>(str); it != std::istream_iterator<std::string>();) std::cout << *it++; std::cout << "\n"; } Which outputs (as expected): Hello,World! The issue can be solved by storing a value in the iterator or returning a proxy object which dereferences to the original value. -- 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<tel:%2B49%206151%20155-606> | Fax +49 6151 155-139<tel:%2B49%206151%20155-139> johannes.mueller-roemer@igd.fraunhofer.de<mailto:johannes.mueller-roemer@igd.fraunhofer.de> | www.igd.fraunhofer.de<http://www.igd.fraunhofer.de> From: Boost-users [mailto:boost-users-bounces@lists.boost.org<mailto:boost-users-bounces@lists.boost.org>] On Behalf Of Oliver Kowalke Sent: Monday, February 16, 2015 14:20 To: boost-users@lists.boost.org<mailto:boost-users@lists.boost.org> Subject: Re: [Boost-users] [context] boost::coroutines::asymmetric_coroutine<T>::pull_type iterator does not properly model InputIterator 2015-02-16 13:46 GMT+01:00 Mueller-Roemer, Johannes Sebastian <Johannes.Sebastian.Mueller-Roemer@igd.fraunhofer.de<mailto:Johannes.Sebastian.Mueller-Roemer@igd.fraunhofer.de>>: Compiling is not the issue. it works as expected Furthermore your example does not test the issue I mentioned, as it does not use *it++; operator++ has higher precedence than operator* -> each increment triggers an jump/switch operation -> last increment invalidates coroutine _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org<mailto:Boost-users@lists.boost.org> http://lists.boost.org/mailman/listinfo.cgi/boost-users

Example of how valid semantics could be achieved (as replacement for the old operator++(int), modulo potential mistakes): struct proxy_reference { proxy_reference(typename iterator::value_type const & v) : v(v) {} typename iterator::value_type const & operator*() const { return v; } private: typename iterator::value_type v; }; proxy_reference operator++( int) { proxy_reference tmp(**this); ++*this; return tmp; } -- 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: Mueller-Roemer, Johannes Sebastian Sent: Monday, February 16, 2015 15:41 To: 'boost-users@lists.boost.org' Subject: RE: [Boost-users] [context] boost::coroutines::asymmetric_coroutine<T>::pull_type iterator does not properly model InputIterator The temporary variable would not have to store the execution state of the coroutine, only the yielded value. Offering a broken postfix increment is very dangerous and should be avoided. Also, if I can’t count on InputIterator features being supported, the following is a lie: class iterator : public std::iterator< std::input_iterator_tag, typename remove_reference< R >::type > (taken from asymmetric_coroutine.hpp) -- 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<mailto:johannes.mueller-roemer@igd.fraunhofer.de> | www.igd.fraunhofer.de<http://www.igd.fraunhofer.de> From: Boost-users [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Oliver Kowalke Sent: Monday, February 16, 2015 15:28 To: boost-users@lists.boost.org<mailto:boost-users@lists.boost.org> Subject: Re: [Boost-users] [context] boost::coroutines::asymmetric_coroutine<T>::pull_type iterator does not properly model InputIterator coroutines behave different than ordinary containers - even a temp var, created inside iterator::operator++( int), will influence the state of the attached coroutine (increment operator) you can't count on the feature set described for input iterators in the standard 2015-02-16 15:00 GMT+01:00 Mueller-Roemer, Johannes Sebastian <Johannes.Sebastian.Mueller-Roemer@igd.fraunhofer.de<mailto:Johannes.Sebastian.Mueller-Roemer@igd.fraunhofer.de>>: If that is „as expected“ it still violates the requirements for an InputIterator. See the last row in Table 107 in 24.2.3 in the standard http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf As-is the current “iterator” is not a valid iterator of any kind as InputIterator is already the weakest requirement. Example of how it should work (using an istream_iterator, which is an InputIterator): #include <iostream> #include <sstream> #include <iterator> auto main(int, char **) -> int { std::istringstream str("Hello , World !"); for(auto it = std::istream_iterator<std::string>(str); it != std::istream_iterator<std::string>();) std::cout << *it++; std::cout << "\n"; } Which outputs (as expected): Hello,World! The issue can be solved by storing a value in the iterator or returning a proxy object which dereferences to the original value. -- 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<tel:%2B49%206151%20155-606> | Fax +49 6151 155-139<tel:%2B49%206151%20155-139> johannes.mueller-roemer@igd.fraunhofer.de<mailto:johannes.mueller-roemer@igd.fraunhofer.de> | www.igd.fraunhofer.de<http://www.igd.fraunhofer.de> From: Boost-users [mailto:boost-users-bounces@lists.boost.org<mailto:boost-users-bounces@lists.boost.org>] On Behalf Of Oliver Kowalke Sent: Monday, February 16, 2015 14:20 To: boost-users@lists.boost.org<mailto:boost-users@lists.boost.org> Subject: Re: [Boost-users] [context] boost::coroutines::asymmetric_coroutine<T>::pull_type iterator does not properly model InputIterator 2015-02-16 13:46 GMT+01:00 Mueller-Roemer, Johannes Sebastian <Johannes.Sebastian.Mueller-Roemer@igd.fraunhofer.de<mailto:Johannes.Sebastian.Mueller-Roemer@igd.fraunhofer.de>>: Compiling is not the issue. it works as expected Furthermore your example does not test the issue I mentioned, as it does not use *it++; operator++ has higher precedence than operator* -> each increment triggers an jump/switch operation -> last increment invalidates coroutine _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org<mailto:Boost-users@lists.boost.org> http://lists.boost.org/mailman/listinfo.cgi/boost-users

Alternatively, if you do not wish to support InputIterator semantics, it might be better to remove operator++(int) or have it return void instead of a conceptually invalid iterator. -- 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: Mueller-Roemer, Johannes Sebastian Sent: Monday, February 16, 2015 15:00 To: boost-users@lists.boost.org Subject: RE: [Boost-users] [context] boost::coroutines::asymmetric_coroutine<T>::pull_type iterator does not properly model InputIterator If that is „as expected“ it still violates the requirements for an InputIterator. See the last row in Table 107 in 24.2.3 in the standard http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf As-is the current “iterator” is not a valid iterator of any kind as InputIterator is already the weakest requirement. Example of how it should work (using an istream_iterator, which is an InputIterator): #include <iostream> #include <sstream> #include <iterator> auto main(int, char **) -> int { std::istringstream str("Hello , World !"); for(auto it = std::istream_iterator<std::string>(str); it != std::istream_iterator<std::string>();) std::cout << *it++; std::cout << "\n"; } Which outputs (as expected): Hello,World! The issue can be solved by storing a value in the iterator or returning a proxy object which dereferences to the original value. -- 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<mailto:johannes.mueller-roemer@igd.fraunhofer.de> | www.igd.fraunhofer.de<http://www.igd.fraunhofer.de> From: Boost-users [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Oliver Kowalke Sent: Monday, February 16, 2015 14:20 To: boost-users@lists.boost.org<mailto:boost-users@lists.boost.org> Subject: Re: [Boost-users] [context] boost::coroutines::asymmetric_coroutine<T>::pull_type iterator does not properly model InputIterator 2015-02-16 13:46 GMT+01:00 Mueller-Roemer, Johannes Sebastian <Johannes.Sebastian.Mueller-Roemer@igd.fraunhofer.de<mailto:Johannes.Sebastian.Mueller-Roemer@igd.fraunhofer.de>>: Compiling is not the issue. it works as expected Furthermore your example does not test the issue I mentioned, as it does not use *it++; operator++ has higher precedence than operator* -> each increment triggers an jump/switch operation -> last increment invalidates coroutine
participants (2)
-
Mueller-Roemer, Johannes Sebastian
-
Oliver Kowalke