1 ///////////////////////////////////////////////////////////////////////////////
2 // mpl.hpp
3 //
4 // Copyright 2012 Eric Niebler. Distributed under the Boost
5 // Software License, Version 1.0. (See accompanying file
6 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8 #include <boost/proto/proto.hpp>
9 #include <boost/fusion/mpl.hpp>
10 #include <boost/mpl/pop_back.hpp>
11 #include <boost/type_traits/is_same.hpp>
12 #include <boost/static_assert.hpp>
13 #include <boost/test/unit_test.hpp>
14 namespace mpl = boost::mpl;
15 namespace proto = boost::proto;
16 namespace fusion = boost::fusion;
17 using proto::_;
18
19 template<class E>
20 struct my_expr;
21
22 struct my_domain
23 : proto::domain<proto::generator<my_expr> >
24 {};
25
26 template<class E>
27 struct my_expr
28 : proto::extends<E, my_expr<E>, my_domain>
29 {
my_exprmy_expr30 my_expr(E const &e = E())
31 : proto::extends<E, my_expr<E>, my_domain>(e)
32 {}
33
34 typedef fusion::fusion_sequence_tag tag;
35 };
36
37 template<typename T>
test_impl(T const &)38 void test_impl(T const &)
39 {
40 typedef typename mpl::pop_back<T>::type result_type;
41 BOOST_STATIC_ASSERT(
42 (boost::is_same<
43 result_type
44 , my_expr<proto::basic_expr<proto::tag::plus, proto::list1<my_expr<proto::terminal<int>::type>&> > >
45 >::value)
46 );
47 }
48
49 // Test that we can call mpl algorithms on proto expression types, and get proto expression types back
test_mpl()50 void test_mpl()
51 {
52 my_expr<proto::terminal<int>::type> i;
53 test_impl(i + i);
54 }
55
56 using namespace boost::unit_test;
57 ///////////////////////////////////////////////////////////////////////////////
58 // init_unit_test_suite
59 //
init_unit_test_suite(int argc,char * argv[])60 test_suite* init_unit_test_suite( int argc, char* argv[] )
61 {
62 test_suite *test = BOOST_TEST_SUITE("test proto mpl integration via fusion");
63
64 test->add(BOOST_TEST_CASE(&test_mpl));
65
66 return test;
67 }
68