
In the program below, I expected the proto::lazy transform to call the times2() function, but it doesn't. It does work correctly if you substitute times2<int> for proto::_state. Is this a bug or am I forgetting something? Thanks, Dave Jenkins #include <iostream> #include <boost/proto/proto.hpp> #include <boost/proto/transform.hpp> namespace proto = boost::proto; template<typename T, typename Callable = proto::callable> struct times2 { typedef T result_type; T operator()(T i) const { std::cout << "Called times2()\n"; return i * 2; } }; struct IntTimes2 : proto::when< proto::terminal<proto::_> , proto::lazy<proto::_state(proto::_value) > //, proto::lazy<times2<int>(proto::_value) > > {}; int main() { int dummy = 0; proto::terminal<int>::type i = {1}; IntTimes2()(i, times2<int>(), dummy); }

Dave Jenkins wrote:
In the program below, I expected the proto::lazy transform to call the times2() function, but it doesn't. It does work correctly if you substitute times2<int> for proto::_state. Is this a bug or am I forgetting something?
A bug. It's fixed now on the trunk and release branches. Thanks. -- Eric Niebler BoostPro Computing http://www.boostpro.com

A bug. It's fixed now on the trunk and release branches. Thanks.
Thank you, Eric. That works, but now proto::lazy isn't working with proto::fold. Below is a program you posted to boost.devel on 3/29/2008, updated with s/bind/lazy/ and s/_arg/_child/. It's giving me the following syntax error. Any idea what's wrong? Thanks, Dave Jenkins error C2664: 'Accumulator<IsValid,Value>::Accumulator(const Accumulator<IsValid,Value> &)' : cannot convert parameter 1 from 'Accumulator<IsValid,Value>' to 'const Accumulator<IsValid,Value> &' c:\boost\boost\proto\transform\call.hpp 156 #include <iostream> #include <boost/assert.hpp> #include <boost/mpl/or.hpp> #include <boost/mpl/and.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/type_traits/is_void.hpp> #include <boost/proto/proto.hpp> #include <boost/proto/transform.hpp> namespace mpl = boost::mpl; namespace proto = boost::proto; template<typename IsValid = mpl::true_, typename Value = void> struct Accumulator : IsValid { template<typename Value2> struct validate : mpl::and_< IsValid , mpl::or_< boost::is_void<Value> , boost::is_same<Value, Value2> > > {}; template<typename Sig> struct result; template<typename This, typename Value2> struct result<This(Value2)> { typedef Accumulator<validate<Value2>, Value2> type; }; template<typename Value2> typename result<void(Value2)>::type operator ()(Value2 const &) const { return typename result<void(Value2)>::type(); } }; struct SameTerminals : proto::or_< proto::when< proto::terminal<proto::_> // treat the current state as a callable // object and pass it the value of the terminal. , proto::lazy<proto::_state(proto::_child)> > , proto::otherwise< proto::fold<proto::_, proto::_state, SameTerminals> > > {}; int main() { int dummy = 0; proto::terminal<int>::type i = {0}, j = {1}, k = {2}; proto::terminal<short>::type s = {42}; BOOST_ASSERT( SameTerminals()(i+j*k, Accumulator<>(), dummy) ); BOOST_ASSERT(!SameTerminals()(i+s*k, Accumulator<>(), dummy) ); }

Dave Jenkins wrote:
A bug. It's fixed now on the trunk and release branches. Thanks.
Thank you, Eric. That works, but now proto::lazy isn't working with proto::fold.
Below is a program you posted to boost.devel on 3/29/2008, updated with s/bind/lazy/ and s/_arg/_child/. It's giving me the following syntax error. Any idea what's wrong?
Yes, the new code is actually correct, but it requires you to correctly handle references in your function object. Just add the following result<> specializations to the Accumulator<> class template: template<typename This, typename Value2> struct result<This(Value2 &)> : result<This(Value2)> {}; template<typename This, typename Value2> struct result<This(Value2 const &)> : result<This(Value2)> {}; With this change, it works for me. -- Eric Niebler BoostPro Computing http://www.boostpro.com
participants (3)
-
Dave Jenkins
-
Eric Niebler
-
Eric Niebler