
Eric Niebler schrieb:
Hi Fusion gurus. I'm chasing an elusive bug that the following Proto test has exposed:
http://beta.boost.org/development/tests/trunk/developer/output/RW_WinXP_VC-b...
All is well on the release branch, but on trunk, Proto's examples.cpp test is failing -- but only on MSVC! I suspect Fusion because if I replace the version of Fusion on trunk with the one on release all is well. (Caveat: when I do this, I also need to make a corresponding change to the as_callable function object in proto/transform/fold.hpp to accommodate the changed argument order of fusion::fold's functor.) It seems something is causing MSVC to prematurely instantiate a template used in a Proto transform, but I can't see what.
I first suspected the recent changes to fusion::fold, but that seems not to be the case. If I just take the release version of fusion::fold, the problem still manifests. The problem must be elsewhere.
Does anyone from Fusion team want to give this a crack? I'll be happy to help.
Changeset 57337, in particular the change in boost/fusion/view/reverse_view/reverse_view.hpp, causes the trouble. I only tested this changeset with my default toolchain (gcc 4.4) as I did not consider any of my changes to be breaking. I am awfully sorry. The change in reverse_view.hpp causes fusion::reverse_view to always be a bidirectional access sequence, even if the underlying sequence is a random access one. This is correct behaviour according to the documentation. The problem in proto is probably caused by a bug in the VC9/VC10 compiler. The non-random-access implementation of fusion::detail::fold wrongly causes the compiler to instantiate nested template parameters of the functor. I attached a minimal sample which reproduces this problem. Interestingly, the random-access fold implementation works fine in your particular usecase, whereas my sample reproduces the problem for forward and random access sequences. I also attached a temporary workaround-patch for proto. Unfortunately I have no idea of how to "fix" fusion in the first place. BTW, compiling the examples.cpp testcase with the upcoming C++0x port of fusion and VC9 works fine. -Christopher Index: boost/proto/transform/fold.hpp =================================================================== --- boost/proto/transform/fold.hpp (revision 58271) +++ boost/proto/transform/fold.hpp (working copy) @@ -198,10 +198,11 @@ { typename when<_, Sequence>::template impl<Expr, State, Data> seq; detail::as_callable<Fun, Data> f(d); - return fusion::fold( + return fusion::detail::fold( seq(e, s, d) , typename when<_, State0>::template impl<Expr, State, Data>()(e, s, d) , f + , fusion::random_access_traversal_tag() ); } };