
On 2/26/06, Tobias Schwinger <tschwinger@neoscientists.org> wrote:
Peder Holt wrote:
In confix_parser_gen: Adding another level of indirection solves the problem: [...]
Now rule_parser_1_1 passes without problems.
Great!
Attached is a patch with this fix.
I applied the workaround to all functions in the CVS version of confix.hpp. Unfortunately the same trick won't help to get rid of the ICE in rule_parser_2_2 when applied to the subscript operator of spirit::parser (would've been too easy)...
I have looked at this, and this is a problem between VC7.1 and the way the typeof emulation works, as you showed in the simplified test-case. The problem lies in the use of the operator[] with function pointers. The only workaround for this problem that I have found, apart from rewriting the user code, is to separate the sizeof operation and the typedef. (like in the #if ! defined BOOM clause) Problem is, this has to be done inside a struct, and can not be made to emulate the BOOST_TYPEOF syntax. The proposed solution is then to add a new macro called something like: BOOST_TYPEOF_NESTED_TYPEDEF(name,expr) which looks roughly like this: struct name { //Twophase typeof using expr typedef resulting_type_calculated type; }; To access the type, you have to do a typedef typename name::type my_type; outside BOOST_TYPEOF_NESTED_TYPEDEF. Introducing this construct has two positive effects: 1. rule_parser_2_2 (and similar tests) pass. 2. In emulation mode, there is no longer any limit to the complexity of the types passed to BOOST_TYPEOF_NESTED_TYPEDEF. BOOST_TYPEOF_LIMIT_SIZE is no longer a limiting factor. The downside is the added complexity of the library. It also doesn't reflect any proposed C++ features. Is there any interest in adding this feature to the typeof library? Regards, Peder

"Peder Holt" <peder.holt@gmail.com> wrote
2. In emulation mode, there is no longer any limit to the complexity of the types passed to BOOST_TYPEOF_NESTED_TYPEDEF. BOOST_TYPEOF_LIMIT_SIZE is no longer a limiting factor.
Interesting. I think I can see how you avoid the limit related to the number of template parameters (which is a major improvement by itself). However, I don't think you can get over the preprocessor limit, can you? Also, BOOST_TYPEOF_LIMIT_SIZE is there to avoid unnecessary evaluations of the expression, and again, I don't see how you are planning to not depend on it... Assumming, of course, that I figured out things correctly, and you are planning to do something like this: struct name { enum { value1 = sizeof(encode(expr).item1), value2 = sizeof(encode(expr).item2), ... valueN = sizeof(encode(expr).itemN), }; typedef<decode<some_iterator<name> >::type type; }; encode still needs to be called BOOST_TYPEOF_LIMIT_SIZE times, doesn't it? Am I missing something? Regards, Arkadiy

On 3/1/06, Arkadiy Vertleyb <vertleyb@hotmail.com> wrote:
"Peder Holt" <peder.holt@gmail.com> wrote
2. In emulation mode, there is no longer any limit to the complexity of the types passed to BOOST_TYPEOF_NESTED_TYPEDEF. BOOST_TYPEOF_LIMIT_SIZE is no longer a limiting factor.
Interesting.
I think I can see how you avoid the limit related to the number of template parameters (which is a major improvement by itself).
However, I don't think you can get over the preprocessor limit, can you?
Also, BOOST_TYPEOF_LIMIT_SIZE is there to avoid unnecessary evaluations of the expression, and again, I don't see how you are planning to not depend on it... Assumming, of course, that I figured out things correctly, and you are planning to do something like this:
struct name { enum { value1 = sizeof(encode(expr).item1), value2 = sizeof(encode(expr).item2), ... valueN = sizeof(encode(expr).itemN), }; typedef<decode<some_iterator<name> >::type type; };
encode still needs to be called BOOST_TYPEOF_LIMIT_SIZE times, doesn't it? Am I missing something?
Yep. What I do is basically the following: struct name { template<int Iteration> struct encode_part { static int Offset=Iteration*BOOST_TYPEOF_NESTED_SIZE (currently 50) typedef offset_vector<nested_vector0<>,boost::mpl::size_t<Offset>
start_vector; template<typename T> static sizer<encode_type<start,vector,T> > encode(const T& arg); static int value0=sizeof(encode(expr).item0); typedef boost::mpl::size_t<value0> item0; ... }; template<typename Pos> struct decode_iter { static const int pos=Pos::value; static const int where=pos%BOOST_TYPEOF_NESTED_SIZE; static const int iteration=pos/BOOST_TYPEOF_NESTED_SIZE; typedef typename v_iter<encode_part<iteration>,mpl::size_t<where> >::type type; typedef decode_iter<Pos::next> next; }; typedef typename decode_type<decode_iter<mpl::size_t<0> > >::type type; };
What this means, is that a new encode_vector of size BOOST_TYPEOF_NESTED_SIZE will be calculated if the expresion is greater than BOOST_TYPEOF_NESTED_SIZE. E.g. if the expression needs 151 integers to be encoded, 4 separate encoding vectors will be used to represent the expression. push_back for offset_vector decrements the offset, until the offset is 0, then it calls push_back on the nested_vector. push_back on a nested_vector of size BOOST_TYPEOF_NESTED_SIZE returns the input vector. Regards, Peder.
Regards, Arkadiy
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (2)
-
Arkadiy Vertleyb
-
Peder Holt