Hi, The "for-each" in mpl is used to generate codes, which apply some function to each element in a sequence. Well, I wonder if there could be more generators, "select"(a better name?) for example.
"select" is used to apply some function to a specified element in a sequence(the case in the FSM example, not each element). So it could be used to generate codes like the "if-else/switch" structure. Here's an example. #include <boost/mpl/range_c.hpp> #include "select.hpp" #include <boost/mpl/alias.hpp> struct find_helper { private: const double* X_; // array const double& a_; // element to be found int& pos_; // result, position of the given element public: find_helper(const double* X, const double& a, int& pos) : X_(X), a_(a), pos_(pos) {} bool operator ()(int i) { if(X_[i] == a_) { pos_ = i; return true; // "true" means it's been handled } return false; // "false" means to continue } }; template <typename T, int N> struct find_element_c { static int do_(T* X, const T& a) { int r = N; mpl::select< // "select" returns true if mpl::range_c<int, 0, N> // the functor has been applied, >(find_helper(X, a, r)); // otherwise false. return r; } }; #include <iostream> int main() { double X[5] = {1.0, 2.1, 3.5, 6.6, 5.4}; std::cout << find_element_c<double, 5>::do_(X, 3.5) << std::endl; } output: 2 The generated code might look like: if(X[0] == 3.5) return 0; if(X[1] == 3.5) return 1; if(X[2] == 3.5) return 2; if(X[3] == 3.5) return 3; if(X[4] == 3.5) return 4; The implementation of the "select" template could be rather similar to "for_each". namespace boost { namespace mpl { namespace aux { template <bool done = true> struct select_impl { template< typename Iterator , typename LastIterator , typename TransformFunc , typename F > static bool execute( Iterator* , LastIterator* , TransformFunc* , F ) { return false; } }; template <> struct select_impl<false> { template< typename Iterator , typename LastIterator , typename TransformFunc , typename F > static bool execute( Iterator* , LastIterator* , TransformFunc* , F f ) { typedef typename Iterator::type item; typedef typename apply1<TransformFunc,item>::type arg; value_initialized<arg> x; if(aux::unwrap(f, 0)(boost::get(x))) return true; typedef typename Iterator::next iter; return select_impl<boost::is_same<iter,LastIterator>::value>::execute( (iter*)0, (LastIterator*)0, (TransformFunc*)0, f); } }; } // namespace aux template< typename Sequence , typename TransformOp , typename F > inline bool select(F f, Sequence* = 0, TransformOp* = 0) { typedef typename begin<Sequence>::type first; typedef typename end<Sequence>::type last; typedef typename lambda<TransformOp>::type transform_op; return aux::select_impl< boost::is_same<first,last>::value >::execute( (first*)0, (last*)0, (transform_op*)0, f); } template< typename Sequence , typename F > inline bool select(F f, Sequence* = 0) { return select<Sequence, identity<> >(f); } } // namespace mpl } // namespace boost Regards, Jonathan Wang [EMAIL PROTECTED] 2003-02-13 _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost