Re: [boost] [Spirit-devel] [fusion] Short-circuited Exception-based View Iteration

On 9/23/07, Joel de Guzman <joel@boost-consulting.com> wrote:
Dean Michael Berris wrote:
Almost... But 'any' will just return a boolean, but not which element in seq (or a view of which elements in seq) where f returns true.
Do it in f where you know both.
This may make f a bit bloated for my taste, but this will work. Thanks. :)
Perhaps 'filter' is what I'm looking for, but I'm just interested in the first one where a predicate holds true, so even a find_if(...) might suit my needs.
No. There's no way to do that. You can't have a runtime predicate determine a compile time return type.
There might be special cases where this might happen though... Let me illustrate below what I mean...
I'll explore a bit more.
BTW, i haven't found a `find_first_if(...)` implementation (like what the STL has) which works with a homogeneous tuple -- somehow that container might be a special case that deserves attention (?) -- which returns a single value? Thoughts on this?
Maybe this will solve at least my problem... :D
The world fusion (and for that matter, mpl) lives in has some peculiar constraints. As I noted above, one is that you cannot determine a type from a runtime predicate. You can, however, do it inside-out. IOTW, let the predicate itself get the info that you need. If you really need to return a type, somehow, you can, for example, use a pointer to a base class, hold the value in a boost::any, etc. In other words use type erasure. If I were you, I'd use the visitor, f, itself to do the action as soon as the correct type is obtained. No type erasure magic.
This makes sense, though there might be a possibility where a homogeneous tuple would be able to return just a single value: struct equals_2 { template <typename T> T operator() (T element) const { if (element == 2) return element; }; }; typedef fusion::tuple<int, int, int> point_type; point_type point(1, 2, 3); assert(fusion::is_homogenous<point_type>::value == true); assert(fusion::find_first_if<equals_2>(point) == 2); // only works if 'point' is a homogeneous container
HTH.
It does indeed. Thanks for the tips! (Goes back to hacking... :D) -- Dean Michael C. Berris Software Engineer, Friendster, Inc. [http://cplusplus-soup.blogspot.com/] [mikhailberis@gmail.com] [+63 928 7291459] [+1 408 4049523]

Dean Michael Berris wrote:
struct equals_2 { template <typename T> T operator() (T element) const { if (element == 2) return element; }; };
typedef fusion::tuple<int, int, int> point_type; point_type point(1, 2, 3); assert(fusion::is_homogenous<point_type>::value == true); assert(fusion::find_first_if<equals_2>(point) == 2); // only works if 'point' is a homogeneous container
FWIW, a few weeks ago, I had a radical idea about an iterator which runs through a tuple/fusion. rectangle r; triangle t; circle c; boost::tuple<rectangle*, triangle*, circle*> tup(&r, &t, &c); BOOST_FOREACH (shape *s, oven::hetero<shape *>(tup)) { s->draw(); } If interested, here is the implementation: http://tinyurl.com/2gojyw Regards, -- Shunsuke Sogame

shunsuke wrote:
Dean Michael Berris wrote:
struct equals_2 { template <typename T> T operator() (T element) const { if (element == 2) return element; }; };
typedef fusion::tuple<int, int, int> point_type; point_type point(1, 2, 3); assert(fusion::is_homogenous<point_type>::value == true); assert(fusion::find_first_if<equals_2>(point) == 2); // only works if 'point' is a homogeneous container
FWIW, a few weeks ago, I had a radical idea about an iterator which runs through a tuple/fusion.
rectangle r; triangle t; circle c; boost::tuple<rectangle*, triangle*, circle*> tup(&r, &t, &c); BOOST_FOREACH (shape *s, oven::hetero<shape *>(tup)) { s->draw(); }
If interested, here is the implementation: http://tinyurl.com/2gojyw
I'm interested! This ought to be part of fusion :-) Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Dean Michael Berris wrote:
The world fusion (and for that matter, mpl) lives in has some peculiar constraints. As I noted above, one is that you cannot determine a type from a runtime predicate. You can, however, do it inside-out. IOTW, let the predicate itself get the info that you need. If you really need to return a type, somehow, you can, for example, use a pointer to a base class, hold the value in a boost::any, etc. In other words use type erasure. If I were you, I'd use the visitor, f, itself to do the action as soon as the correct type is obtained. No type erasure magic.
This makes sense, though there might be a possibility where a homogeneous tuple would be able to return just a single value:
struct equals_2 { template <typename T> T operator() (T element) const { if (element == 2) return element; }; };
typedef fusion::tuple<int, int, int> point_type; point_type point(1, 2, 3); assert(fusion::is_homogenous<point_type>::value == true); assert(fusion::find_first_if<equals_2>(point) == 2); // only works if 'point' is a homogeneous container
If that was the case, I'd use boost::array which is a nice data structure that has a special property: it is *both* a fusion sequence *and* an stl sequence. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

-----Original Message----- From: spirit-devel-bounces@lists.sourceforge.net [mailto:spirit-devel- bounces@lists.sourceforge.net] On Behalf Of Joel de Guzman Sent: Monday, September 24, 2007 1:18 AM To: spirit-devel@lists.sourceforge.net Cc: boost@lists.boost.org Subject: Re: [Spirit-devel] [fusion] Short-circuited Exception-based ViewIteration
Dean Michael Berris wrote:
This makes sense, though there might be a possibility where a homogeneous tuple would be able to return just a single value:
struct equals_2 { template <typename T> T operator() (T element) const { if (element == 2) return element; }; };
typedef fusion::tuple<int, int, int> point_type; point_type point(1, 2, 3); assert(fusion::is_homogenous<point_type>::value == true); assert(fusion::find_first_if<equals_2>(point) == 2); // only works
if
'point' is a homogeneous container
If that was the case, I'd use boost::array which is a nice data structure that has a special property: it is *both* a fusion sequence *and* an stl sequence.
Brilliant! I think that solves my predicament! :D
Regards,
Thank you very much! -- Dean Michael Berris <dmberris@friendster.com> Mobile: +639287291459 YMID: mikhailberis
participants (4)
-
Dean Michael Berris
-
Dean Michael C. Berris
-
Joel de Guzman
-
shunsuke