diff options
Diffstat (limited to 'src/boost/libs/metaparse/example/meta_lambda/main.cpp')
-rw-r--r-- | src/boost/libs/metaparse/example/meta_lambda/main.cpp | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/src/boost/libs/metaparse/example/meta_lambda/main.cpp b/src/boost/libs/metaparse/example/meta_lambda/main.cpp new file mode 100644 index 00000000..892e5756 --- /dev/null +++ b/src/boost/libs/metaparse/example/meta_lambda/main.cpp @@ -0,0 +1,265 @@ +// Copyright Abel Sinkovics (abel@sinkovics.hu) 2012. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/metaparse/repeated.hpp> +#include <boost/metaparse/sequence.hpp> +#include <boost/metaparse/lit_c.hpp> +#include <boost/metaparse/last_of.hpp> +#include <boost/metaparse/space.hpp> +#include <boost/metaparse/int_.hpp> +#include <boost/metaparse/foldl_reject_incomplete_start_with_parser.hpp> +#include <boost/metaparse/one_of.hpp> +#include <boost/metaparse/get_result.hpp> +#include <boost/metaparse/token.hpp> +#include <boost/metaparse/entire_input.hpp> +#include <boost/metaparse/string.hpp> +#include <boost/metaparse/transform.hpp> +#include <boost/metaparse/always.hpp> +#include <boost/metaparse/build_parser.hpp> + +#include <boost/mpl/apply_wrap.hpp> +#include <boost/mpl/front.hpp> +#include <boost/mpl/back.hpp> +#include <boost/mpl/plus.hpp> +#include <boost/mpl/minus.hpp> +#include <boost/mpl/times.hpp> +#include <boost/mpl/divides.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/mpl/equal_to.hpp> +#include <boost/mpl/if.hpp> + +using boost::metaparse::sequence; +using boost::metaparse::lit_c; +using boost::metaparse::last_of; +using boost::metaparse::space; +using boost::metaparse::repeated; +using boost::metaparse::build_parser; +using boost::metaparse::int_; +using boost::metaparse::foldl_reject_incomplete_start_with_parser; +using boost::metaparse::get_result; +using boost::metaparse::one_of; +using boost::metaparse::token; +using boost::metaparse::entire_input; +using boost::metaparse::transform; +using boost::metaparse::always; + +using boost::mpl::apply_wrap1; +using boost::mpl::front; +using boost::mpl::back; +using boost::mpl::plus; +using boost::mpl::minus; +using boost::mpl::times; +using boost::mpl::divides; +using boost::mpl::if_; +using boost::mpl::bool_; +using boost::mpl::equal_to; + +/* + * The grammar + * + * expression ::= plus_exp + * plus_exp ::= prod_exp ((plus_token | minus_token) prod_exp)* + * prod_exp ::= value_exp ((mult_token | div_token) value_exp)* + * value_exp ::= int_token | '_' + */ + +typedef token<lit_c<'+'> > plus_token; +typedef token<lit_c<'-'> > minus_token; +typedef token<lit_c<'*'> > mult_token; +typedef token<lit_c<'/'> > div_token; + +typedef token<int_> int_token; +typedef token<lit_c<'_'> > arg_token; + +template <class T, char C> +struct is_c : bool_<T::type::value == C> {}; + +struct build_plus +{ + template <class A, class B> + struct _plus + { + typedef _plus type; + + template <class T> + struct apply : + plus<typename apply_wrap1<A, T>::type, typename apply_wrap1<B, T>::type> + {}; + }; + + template <class A, class B> + struct _minus + { + typedef _minus type; + + template <class T> + struct apply : + minus<typename apply_wrap1<A, T>::type, typename apply_wrap1<B, T>::type> + {}; + }; + + template <class State, class C> + struct apply : + if_< + typename is_c<front<C>, '+'>::type, + _plus<State, typename back<C>::type>, + _minus<State, typename back<C>::type> + > + {}; +}; + +struct build_mult +{ + template <class A, class B> + struct _mult + { + typedef _mult type; + + template <class T> + struct apply : + times<typename apply_wrap1<A, T>::type, typename apply_wrap1<B, T>::type> + {}; + }; + + template <class A, class B> + struct _div + { + typedef _div type; + + template <class T> + struct apply : + divides< + typename apply_wrap1<A, T>::type, + typename apply_wrap1<B, T>::type + > + {}; + }; + + template <class State, class C> + struct apply : + if_< + typename is_c<front<C>, '*'>::type, + _mult<State, typename back<C>::type>, + _div<State, typename back<C>::type> + > + {}; +}; + +class build_value +{ +private: + template <class V> + struct impl + { + typedef impl type; + + template <class T> + struct apply : V {}; + }; + +public: + typedef build_value type; + + template <class V> + struct apply : impl<typename V::type> {}; +}; + +struct arg +{ + typedef arg type; + + template <class T> + struct apply + { + typedef T type; + }; +}; + +typedef + one_of<transform<int_token, build_value>, always<arg_token, arg> > + value_exp; + +typedef + foldl_reject_incomplete_start_with_parser< + sequence<one_of<mult_token, div_token>, value_exp>, + value_exp, + build_mult + > + prod_exp; + +typedef + foldl_reject_incomplete_start_with_parser< + sequence<one_of<plus_token, minus_token>, prod_exp>, + prod_exp, + build_plus + > + plus_exp; + +typedef last_of<repeated<space>, plus_exp> expression; + +typedef build_parser<entire_input<expression> > metafunction_parser; + +#if BOOST_METAPARSE_STD < 2011 + +template <class Exp> +struct meta_lambda : apply_wrap1<metafunction_parser, Exp> {}; + +int main() +{ + using std::cout; + using std::endl; + using boost::metaparse::string; + + typedef meta_lambda<string<'1','3'> >::type metafunction_class_1; + typedef meta_lambda<string<'2',' ','+',' ','3'> >::type metafunction_class_2; + typedef meta_lambda<string<'2',' ','*',' ','2'> >::type metafunction_class_3; + typedef + meta_lambda<string<' ','1','+',' ','2','*','4','-','6','/','2'> >::type + metafunction_class_4; + typedef meta_lambda<string<'2',' ','*',' ','_'> >::type metafunction_class_5; + + typedef boost::mpl::int_<11> int11; + + cout + << apply_wrap1<metafunction_class_1, int11>::type::value << endl + << apply_wrap1<metafunction_class_2, int11>::type::value << endl + << apply_wrap1<metafunction_class_3, int11>::type::value << endl + << apply_wrap1<metafunction_class_4, int11>::type::value << endl + << apply_wrap1<metafunction_class_5, int11>::type::value << endl + ; +} + +#else + +#ifdef META_LAMBDA + #error META_LAMBDA already defined +#endif +#define META_LAMBDA(exp) \ + apply_wrap1<metafunction_parser, BOOST_METAPARSE_STRING(#exp)>::type + +int main() +{ + using std::cout; + using std::endl; + + typedef META_LAMBDA(13) metafunction_class_1; + typedef META_LAMBDA(2 + 3) metafunction_class_2; + typedef META_LAMBDA(2 * 2) metafunction_class_3; + typedef META_LAMBDA( 1+ 2*4-6/2) metafunction_class_4; + typedef META_LAMBDA(2 * _) metafunction_class_5; + + typedef boost::mpl::int_<11> int11; + + cout + << apply_wrap1<metafunction_class_1, int11>::type::value << endl + << apply_wrap1<metafunction_class_2, int11>::type::value << endl + << apply_wrap1<metafunction_class_3, int11>::type::value << endl + << apply_wrap1<metafunction_class_4, int11>::type::value << endl + << apply_wrap1<metafunction_class_5, int11>::type::value << endl + ; +} + +#endif + |