Ticket #5905: new_switch.2.patch
File new_switch.2.patch, 12.1 KB (added by , 11 years ago) |
---|
-
boost/proto/proto_fwd.hpp
269 269 270 270 using namespace tagns_; 271 271 272 template<typename Expr> 273 struct tag_of; 274 272 275 //////////////////////////////////////////////////////////////////////////////////////////////// 273 276 struct _; 274 277 … … 359 362 template<typename Condition, typename Then = _, typename Else = not_<_> > 360 363 struct if_; 361 364 362 template<typename Cases >365 template<typename Cases, typename Transform = tag_of<_>() > 363 366 struct switch_; 364 367 365 368 template<typename T> … … 462 465 struct is_sub_domain_of; 463 466 464 467 template<typename Expr> 465 struct tag_of;466 467 template<typename Expr>468 468 struct arity_of; 469 469 470 470 template<typename T, typename Void = void> … … 741 741 template<typename Grammar> 742 742 struct pass_through; 743 743 744 template<typename Grammar = detail::_default >744 template<typename Grammar = detail::_default > 745 745 struct _default; 746 746 747 747 struct _expr; -
boost/proto/matches.hpp
10 10 #ifndef BOOST_PROTO_MATCHES_HPP_EAN_11_03_2006 11 11 #define BOOST_PROTO_MATCHES_HPP_EAN_11_03_2006 12 12 13 13 14 #include <boost/config.hpp> 14 15 #include <boost/detail/workaround.hpp> 15 16 #include <boost/preprocessor/cat.hpp> … … 402 403 {}; 403 404 404 405 // handle proto::switch_ 405 template< typename Expr, typename Tag, typename Args, long Arity, typename Cases>406 struct matches_ <Expr, proto::basic_expr<Tag, Args, Arity>, switch_<Cases> >407 : matches_< 408 Expr409 , proto::basic_expr<Tag, Args, Arity>410 , typename Cases::template case_<Tag>::proto_grammar411 >406 template< typename Expr, typename Tag, typename Args, long Arity, typename Cases, typename Transform> 407 struct matches_ < Expr, proto::basic_expr<Tag, Args, Arity>, switch_<Cases,Transform> > 408 : matches_< Expr, proto::basic_expr<Tag, Args, Arity> 409 , typename Cases::template case_<typename 410 when<_,Transform>::template impl<Expr,int,int>::result_type 411 >::proto_grammar 412 > 412 413 { 414 typedef when<_,Transform> applicant; 415 typedef typename applicant::template impl<Expr,int,int>::result_type selected_type; 416 typedef typename Cases::template case_<selected_type> which; 417 }; 418 419 template< typename Expr, typename Tag, typename Args, long Arity, typename Cases > 420 struct matches_ < Expr, proto::basic_expr<Tag, Args, Arity> , switch_<Cases> > 421 : matches_< Expr, proto::basic_expr<Tag, Args, Arity> 422 , typename Cases::template 423 case_<Tag>::proto_grammar 424 > 425 { 413 426 typedef typename Cases::template case_<Tag> which; 414 427 }; 415 428 } … … 449 462 /// not match \c T. 450 463 /// \li An expression \c E matches <tt>switch_\<C\></tt> if 451 464 /// \c E matches <tt>C::case_\<E::proto_tag\></tt>. 465 /// \li An expression \c E matches <tt>switch_\<C,T\></tt> if 466 /// the result type of the transform \c T on \c E matches 467 /// <tt>C::case_\<boost::result_of\<T(E)\>::type\></tt>. 452 468 /// 453 469 /// A terminal expression <tt>expr\<AT,term\<A\> \></tt> matches 454 470 /// a grammar <tt>expr\<BT,term\<B\> \></tt> if \c BT is \c AT or … … 784 800 /// When applying <tt>switch_\<C\></tt> as a transform with an 785 801 /// expression \c e of type \c E, state \c s and data \c d, it is 786 802 /// equivalent to <tt>C::case_\<E::proto_tag\>()(e, s, d)</tt>. 787 template<typename Cases >788 struct switch_ : transform< switch_<Cases> >803 template<typename Cases, typename Transform> 804 struct switch_ : transform< switch_<Cases,Transform> > 789 805 { 790 806 typedef switch_ proto_grammar; 807 typedef when<_,Transform> applicant; 791 808 792 809 /// \param e An expression 793 810 /// \param s The current state 794 811 /// \param d A data of arbitrary type 795 812 /// \pre <tt>matches\<Expr,switch_\>::value</tt> is \c true. 796 813 /// \return <tt>which()(e, s, d)</tt>, where <tt>which</tt> is 797 /// <tt>Cases::case_< typename Expr::proto_tag></tt>814 /// <tt>Cases::case_< typename boost::result_of< Transform(Expr) >::type ></tt> 798 815 799 816 template<typename Expr, typename State, typename Data> 800 817 struct impl 801 : Cases::template case_<typename Expr::proto_tag>::template impl<Expr, State, Data> 818 : Cases::template 819 case_ < typename applicant::template impl<Expr,State,Data>::result_type 820 >::template impl<Expr, State, Data> 802 821 {}; 803 822 804 823 template<typename Expr, typename State, typename Data> 805 824 struct impl<Expr &, State, Data> 806 : Cases::template case_<typename Expr::proto_tag>::template impl<Expr &, State, Data> 825 : Cases::template 826 case_ <typename applicant::template impl<Expr,State,Data>::result_type 827 >::template impl<Expr &, State, Data> 807 828 {}; 808 829 }; 809 830 … … 901 922 902 923 /// INTERNAL ONLY 903 924 /// 904 template<typename Cases >905 struct is_callable<switch_<Cases > >925 template<typename Cases, typename Transform> 926 struct is_callable<switch_<Cases,Transform> > 906 927 : mpl::true_ 907 928 {}; 908 929 -
libs/proto/test/new_switch.cpp
1 /////////////////////////////////////////////////////////////////////////////// 2 // new_switch.cpp 3 // 4 // Copyright 2011 Eric Niebler 5 // Copyright Pierre Esterie & Joel Falcou. 6 // Distributed under the Boost 7 // Software License, Version 1.0. (See accompanying file 8 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 10 #include <boost/proto/core.hpp> 11 #include <boost/proto/transform.hpp> 12 #include <boost/detail/workaround.hpp> 13 #include <boost/proto/debug.hpp> 14 #include <boost/test/unit_test.hpp> 15 #include <boost/mpl/long.hpp> 16 #include <boost/mpl/bool.hpp> 17 18 using namespace boost; 19 using namespace proto; 20 21 struct MyCases 22 { 23 template<typename Tag> 24 struct case_ 25 : proto::not_<proto::_> 26 {}; 27 }; 28 29 template<> 30 struct MyCases::case_<proto::tag::shift_right> 31 : proto::_ 32 {}; 33 34 template<> 35 struct MyCases::case_<proto::tag::plus> 36 : proto::_ 37 {}; 38 39 struct ArityOf; 40 41 struct ArityOfCases 42 { 43 template<typename ArityOf> 44 struct case_ 45 : proto::not_<proto::_> {}; 46 }; 47 48 49 template<> 50 struct ArityOfCases::case_< boost::mpl::long_<1> > 51 : boost::proto::when<boost::proto::_,boost::mpl::false_() > 52 {}; 53 54 template<> 55 struct ArityOfCases::case_< boost::mpl::long_<2> > 56 : boost::proto::when<boost::proto::_, boost::mpl::true_() > 57 {}; 58 59 struct ArityOf 60 : boost::proto::switch_ < ArityOfCases 61 , proto::arity_of<proto::_>() 62 > 63 {}; 64 65 void test_switch() 66 { 67 // Tests for backward compatibility 68 assert_matches< proto::switch_<MyCases> >( lit(1) >> 'a' ); 69 assert_matches< proto::switch_<MyCases> >( lit(1) + 'a' ); 70 assert_matches_not< proto::switch_<MyCases> >( lit(1) << 'a' ); 71 72 //Test new matching on the Transform result type 73 ArityOf ar; 74 75 assert_matches_not< ArityOf >( lit(1) ); 76 assert_matches< ArityOf >( lit(1) + 2 ); 77 assert_matches< ArityOf >( !lit(1)); 78 BOOST_CHECK_EQUAL( ar( !lit(1) ), false); 79 BOOST_CHECK_EQUAL( ar( lit(1) + 2 ), true); 80 } 81 82 using namespace unit_test; 83 /////////////////////////////////////////////////////////////////////////////// 84 // init_unit_test_suite 85 // 86 test_suite* init_unit_test_suite( int argc, char* argv[] ) 87 { 88 test_suite *test = BOOST_TEST_SUITE("test proto::switch_<>"); 89 90 test->add(BOOST_TEST_CASE(&test_switch)); 91 92 return test; 93 } 94 -
libs/proto/test/Jamfile.v2
31 31 [ run make_expr.cpp ] 32 32 [ run matches.cpp ] 33 33 [ run flatten.cpp ] 34 [ run new_switch.cpp ] 34 35 [ run toy_spirit.cpp ] 35 36 [ run toy_spirit2.cpp ] 36 37 [ run make.cpp ] -
libs/proto/doc/reference/matches.xml
1 <?xml version="1.0" encoding="utf-8"?>1 <?xml version="1.0" encoding="utf-8"?> 2 2 <header name="boost/proto/matches.hpp"> 3 3 <para> 4 4 Contains definition of the … … 427 427 <struct name="switch_"> 428 428 <template> 429 429 <template-type-parameter name="Cases"/> 430 <template-type-parameter name="Transform"/> 430 431 </template> 431 <inherit><classname>proto::transform</classname><switch_<Cases> ></inherit> 432 <purpose>For matching one of a set of alternate grammars, which are looked up based on an 433 expression's tag type. When used as a transform, 432 <inherit><classname>proto::transform</classname><switch_<Cases, Transform> ></inherit> 433 <purpose>For matching one of a set of alternate grammars, which are looked up based on 434 the result type of the transform passed in second template parameter. 435 If no transform is passed, the default one is <computeroutput>proto::tag_of()</computeroutput> 436 so the default matching is based on the expression's tag type. When used as a transform, 434 437 <computeroutput>proto::switch_<></computeroutput> applies the transform associated 435 438 with the sub-grammar that matches the expression.</purpose> 436 439 <description> … … 439 442 <computeroutput>proto::switch_<C></computeroutput> if 440 443 <computeroutput>E</computeroutput> matches 441 444 <computeroutput>C::case_<E::proto_tag></computeroutput>. 445 </para> 446 <para> 447 An expression type <computeroutput>E</computeroutput> matches 448 <computeroutput>proto::switch_<C,T></computeroutput> if 449 the result type of the transform <computeroutput>T</computeroutput> 450 on <computeroutput>E</computeroutput> matches 451 <computeroutput>C::case_<boost::result_of<T(E)> ></computeroutput>. 442 452 </para> 443 453 <para> 444 454 When applying <computeroutput>proto::switch_<C></computeroutput> as a transform … … 446 456 <computeroutput>E</computeroutput>, state <computeroutput>s</computeroutput> and 447 457 data <computeroutput>d</computeroutput>, it is equivalent to 448 458 <computeroutput>C::case_<E::proto_tag>()(e, s, d)</computeroutput>. 459 </para> 460 <para> 461 When applying <computeroutput>proto::switch_<C,T></computeroutput> as a transform 462 with an expression <computeroutput>e</computeroutput> of type 463 <computeroutput>E</computeroutput>, state <computeroutput>s</computeroutput> and 464 data <computeroutput>d</computeroutput>, it is equivalent to 465 <computeroutput>C::case_<boost::result_of<T(E)> >()(e, s, d)</computeroutput>. 449 466 </para> 450 467 </description> 451 468 <struct name="impl"> … … 455 472 <template-type-parameter name="Data"/> 456 473 </template> 457 474 <inherit><type> 458 Cases::template case_<typename Expr::tag_type>::template impl<Expr, State, Data></type></inherit> 475 Cases::template case_< typename applicant::template impl<Expr, State, Data>::result_type 476 >::template impl<Expr, State, Data></type> 477 </inherit> 459 478 </struct> 460 479 <typedef name="proto_grammar"> 461 480 <type>switch_</type> 462 481 </typedef> 482 <typedef name="applicant"> 483 <type>when<_, Transform></type> 484 </typedef> 463 485 </struct> 464 486 465 487 <!-- proto::exact -->