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 namespace proto = boost::proto;
19 
20 struct MyCases
21 {
22     template<typename Tag>
23     struct case_
24       : proto::not_<proto::_>
25     {};
26 };
27 
28 template<>
29 struct MyCases::case_<proto::tag::shift_right>
30   : proto::_
31 {};
32 
33 template<>
34 struct MyCases::case_<proto::tag::plus>
35   : proto::_
36 {};
37 
38 struct ArityOf;
39 
40 struct ArityOfCases
41 {
42     template<typename ArityOf>
43     struct case_
44       : proto::not_<proto::_>
45     {};
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_<
61         ArityOfCases
62       , proto::arity_of<proto::_>()
63     >
64 {};
65 
test_switch()66 void test_switch()
67 {
68     // Tests for backward compatibility
69     proto::assert_matches<proto::switch_<MyCases> >(proto::lit(1) >> 'a');
70     proto::assert_matches<proto::switch_<MyCases> >(proto::lit(1) + 'a');
71     proto::assert_matches_not<proto::switch_<MyCases> >(proto::lit(1) << 'a');
72 
73     //Test new matching on the Transform result type
74     ArityOf ar;
75 
76     proto::assert_matches_not<ArityOf>(proto::lit(1));
77     proto::assert_matches<ArityOf>(proto::lit(1) + 2);
78     proto::assert_matches<ArityOf>(!proto::lit(1));
79     BOOST_CHECK_EQUAL(ar(!proto::lit(1)), false);
80     BOOST_CHECK_EQUAL(ar(proto::lit(1) + 2), true);
81 }
82 
83 using namespace boost::unit_test;
84 ///////////////////////////////////////////////////////////////////////////////
85 // init_unit_test_suite
86 //
init_unit_test_suite(int argc,char * argv[])87 test_suite* init_unit_test_suite(int argc, char* argv[])
88 {
89     test_suite *test = BOOST_TEST_SUITE("test proto::switch_<>");
90 
91     test->add(BOOST_TEST_CASE(&test_switch));
92 
93     return test;
94 }
95 
96