1 ///////////////////////////////////////////////////////////////////////////////
2 // constrained_ops.cpp
3 //
4 // Copyright 2010 Thomas Heller
5 // Copyright 2011 Eric Niebler
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
10 #include <boost/proto/proto.hpp>
11 #include <boost/test/unit_test.hpp>
12
13 using namespace boost;
14
15 typedef proto::terminal<int>::type term;
16
17 struct equation;
18
19 struct addition:
20 proto::or_
21 <
22 proto::terminal<proto::_>,
23 proto::plus<addition, addition>
24 >
25 {};
26
27 struct equation:
28 proto::or_
29 <
30 proto::equal_to<addition, addition>
31 >
32 {};
33
34 template<class Expr>
35 struct extension;
36
37 struct my_domain:
38 proto::domain
39 <
40 proto::pod_generator<extension>,
41 equation,
42 proto::default_domain
43 >
44 {};
45
46 template<class Expr>
47 struct lhs_extension;
48
49 struct my_lhs_domain:
50 proto::domain
51 <
52 proto::pod_generator<lhs_extension>,
53 addition,
54 my_domain
55 >
56 {};
57
58 template<class Expr>
59 struct rhs_extension;
60
61 struct my_rhs_domain:
62 proto::domain
63 <
64 proto::pod_generator<rhs_extension>,
65 addition,
66 my_domain
67 >
68 {};
69
70 template<class Expr>
71 struct extension
72 {
BOOST_PROTO_BASIC_EXTENDSextension73 BOOST_PROTO_BASIC_EXTENDS(
74 Expr
75 , extension<Expr>
76 , my_domain
77 )
78
79 void test() const
80 {}
81 };
82
83 template<class Expr>
84 struct lhs_extension
85 {
86 BOOST_PROTO_BASIC_EXTENDS(
87 Expr
88 , lhs_extension<Expr>
89 , my_lhs_domain
90 )
91 };
92
93 template<class Expr>
94 struct rhs_extension
95 {
96 BOOST_PROTO_BASIC_EXTENDS(
97 Expr
98 , rhs_extension<Expr>
99 , my_rhs_domain
100 )
101 };
102
test_constrained_ops()103 void test_constrained_ops()
104 {
105 lhs_extension<term> const i = {};
106 rhs_extension<term> const j = {};
107
108 proto::assert_matches_not<equation>(i); // false
109 proto::assert_matches_not<equation>(j); // false
110 proto::assert_matches_not<equation>(i + i); // false
111 proto::assert_matches_not<equation>(j + j); // false
112 #if 0
113 proto::assert_matches_not<equation>(i + j); // compile error (by design)
114 proto::assert_matches_not<equation>(j + i); // compile error (by design)
115 #endif
116 proto::assert_matches<equation>(i == j); // true
117 proto::assert_matches<equation>(i == j + j); // true
118 proto::assert_matches<equation>(i + i == j); // true
119 proto::assert_matches<equation>(i + i == j + j); // true
120 }
121
122 using namespace boost::unit_test;
123 ///////////////////////////////////////////////////////////////////////////////
124 // init_unit_test_suite
125 //
init_unit_test_suite(int argc,char * argv[])126 test_suite* init_unit_test_suite( int argc, char* argv[] )
127 {
128 test_suite *test = BOOST_TEST_SUITE("test constrained EDSLs");
129 test->add(BOOST_TEST_CASE(&test_constrained_ops));
130 return test;
131 }
132