📄 examples.cpp
字号:
// from the arguments.struct MakePair : proto::when< /*<< Match expressions like `make_pair_(1, 3.14)` >>*/ proto::function< proto::terminal<make_pair_tag> , proto::terminal<_> , proto::terminal<_> > /*<< Return `std::pair<F,S>(f,s)` where `f` and `s` are the first and second arguments to the lazy `make_pair_()` function. (This uses `proto::make<>` under the covers to evaluate the transform.)>>*/ , std::pair< proto::_value(proto::_child1) , proto::_value(proto::_child2) >( proto::_value(proto::_child1) , proto::_value(proto::_child2) ) >{};//]namespace lazy_make_pair2{ //[ LazyMakePair2 struct make_pair_tag {}; proto::terminal<make_pair_tag>::type const make_pair_ = {{}}; // Like std::make_pair(), only as a function object. /*<<Inheriting from `proto::callable` lets Proto know that this is a callable transform, so we can use it without having to wrap it in `proto::call<>`.>>*/ struct make_pair : proto::callable { template<typename Sig> struct result; template<typename This, typename First, typename Second> struct result<This(First, Second)> { typedef std::pair< BOOST_PROTO_UNCVREF(First) , BOOST_PROTO_UNCVREF(Second) > type; }; template<typename First, typename Second> std::pair<First, Second> operator()(First const &first, Second const &second) const { return std::make_pair(first, second); } }; // This transform matches lazy function invocations like // `make_pair_(1, 3.14)` and actually builds a `std::pair<>` // from the arguments. struct MakePair : proto::when< /*<< Match expressions like `make_pair_(1, 3.14)` >>*/ proto::function< proto::terminal<make_pair_tag> , proto::terminal<_> , proto::terminal<_> > /*<< Return `make_pair()(f,s)` where `f` and `s` are the first and second arguments to the lazy `make_pair_()` function. (This uses `proto::call<>` under the covers to evaluate the transform.)>>*/ , make_pair( proto::_value(proto::_child1) , proto::_value(proto::_child2) ) > {}; //]}//[ NegateIntstruct NegateInt : proto::when<proto::terminal<int>, proto::negate<_>(_)>{};//]#ifndef BOOST_MSVC//[ SquareAndPromoteIntstruct SquareAndPromoteInt : proto::when< proto::terminal<int> , proto::_make_multiplies( proto::terminal<long>::type(proto::_value) , proto::terminal<long>::type(proto::_value) ) >{};//]#endifnamespace lambda_transform{ //[LambdaTransform template<typename N> struct placeholder { typedef typename N::type type; static typename N::value_type const value = N::value; }; // A function object that calls fusion::at() struct at : proto::callable { template<typename Sig> struct result; template<typename This, typename Cont, typename Index> struct result<This(Cont, Index)> : fusion::result_of::at< typename boost::remove_reference<Cont>::type , typename boost::remove_reference<Index>::type > {}; template<typename Cont, typename Index> typename fusion::result_of::at<Cont, Index>::type operator ()(Cont &cont, Index const &) const { return fusion::at<Index>(cont); } }; // A transform that evaluates a lambda expression. struct LambdaEval : proto::or_< /*<<When you match a placeholder ...>>*/ proto::when< proto::terminal<placeholder<_> > /*<<... call at() with the data parameter, which is a tuple, and the placeholder, which is an MPL Integral Constant.>>*/ , at(proto::_data, proto::_value) > /*<<Otherwise, use the _default<> transform, which gives the operators their usual C++ meanings.>>*/ , proto::otherwise< proto::_default<LambdaEval> > > {}; // Define the lambda placeholders proto::terminal<placeholder<mpl::int_<0> > >::type const _1 = {{}}; proto::terminal<placeholder<mpl::int_<1> > >::type const _2 = {{}}; void test_lambda() { // a tuple that contains the values // of _1 and _2 fusion::tuple<int, int> tup(2,3); // Use LambdaEval to evaluate a lambda expression int j = LambdaEval()( _2 - _1, 0, tup ); BOOST_CHECK_EQUAL(j, 1); // You can mutate leaves in an expression tree proto::literal<int> k(42); int &l = LambdaEval()( k += 4, 0, tup ); BOOST_CHECK_EQUAL(k.get(), 46); BOOST_CHECK_EQUAL(&l, &k.get()); // You can mutate the values in the tuple, too. LambdaEval()( _1 += 4, 0, tup ); BOOST_CHECK_EQUAL(6, fusion::at_c<0>(tup)); } //]}void test_examples(){ //[ CalculatorArityTest int i = 0; // not used, dummy state and data parameter std::cout << CalculatorArity()( proto::lit(100) * 200, i, i) << '\n'; std::cout << CalculatorArity()( (_1 - _1) / _1 * 100, i, i) << '\n'; std::cout << CalculatorArity()( (_2 - _1) / _2 * 100, i, i) << '\n'; //] BOOST_CHECK_EQUAL(0, CalculatorArity()( proto::lit(100) * 200, i, i)); BOOST_CHECK_EQUAL(1, CalculatorArity()( (_1 - _1) / _1 * 100, i, i)); BOOST_CHECK_EQUAL(2, CalculatorArity()( (_2 - _1) / _2 * 100, i, i)); BOOST_CHECK_EQUAL(0, CalcArity()( proto::lit(100) * 200, i, i)); BOOST_CHECK_EQUAL(1, CalcArity()( (_1 - _1) / _1 * 100, i, i)); BOOST_CHECK_EQUAL(2, CalcArity()( (_2 - _1) / _2 * 100, i, i)); using boost::fusion::cons; using boost::fusion::nil; cons<int, cons<char, cons<std::string> > > args(ArgsAsList()( _1(1, 'a', std::string("b")), i, i )); BOOST_CHECK_EQUAL(args.car, 1); BOOST_CHECK_EQUAL(args.cdr.car, 'a'); BOOST_CHECK_EQUAL(args.cdr.cdr.car, std::string("b")); cons<int, cons<char, cons<std::string> > > lst(FoldTreeToList()( (_1 = 1, 'a', std::string("b")), i, i )); BOOST_CHECK_EQUAL(lst.car, 1); BOOST_CHECK_EQUAL(lst.cdr.car, 'a'); BOOST_CHECK_EQUAL(lst.cdr.cdr.car, std::string("b")); proto::plus< proto::terminal<double>::type , proto::terminal<double>::type >::type p = Promote()( proto::lit(1.f) + 2.f, i, i ); //[ LazyMakePairTest int j = 0; // not used, dummy state and data parameter std::pair<int, double> p2 = MakePair()( make_pair_(1, 3.14), j, j ); std::cout << p2.first << std::endl; std::cout << p2.second << std::endl; //] BOOST_CHECK_EQUAL(p2.first, 1); BOOST_CHECK_EQUAL(p2.second, 3.14); std::pair<int, double> p3 = lazy_make_pair2::MakePair()( lazy_make_pair2::make_pair_(1, 3.14), j, j ); std::cout << p3.first << std::endl; std::cout << p3.second << std::endl; BOOST_CHECK_EQUAL(p3.first, 1); BOOST_CHECK_EQUAL(p3.second, 3.14); NegateInt()(proto::lit(1), i, i); #ifndef BOOST_MSVC SquareAndPromoteInt()(proto::lit(1), i, i); #endif lambda_transform::test_lambda();}using namespace boost::unit_test;///////////////////////////////////////////////////////////////////////////////// init_unit_test_suite//test_suite* init_unit_test_suite( int argc, char* argv[] ){ test_suite *test = BOOST_TEST_SUITE("test examples from the documentation"); test->add(BOOST_TEST_CASE(&test_examples)); return test;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -