/////////////////////////////////////////////////////////////////////////////// // constrained_ops.cpp // // Copyright 2010 Thomas Heller // Copyright 2011 Eric Niebler // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #include <boost/proto/proto.hpp> #include <boost/test/unit_test.hpp> using namespace boost; typedef proto::terminal<int>::type term; struct equation; struct addition: proto::or_ < proto::terminal<proto::_>, proto::plus<addition, addition> > {}; struct equation: proto::or_ < proto::equal_to<addition, addition> > {}; template<class Expr> struct extension; struct my_domain: proto::domain < proto::pod_generator<extension>, equation, proto::default_domain > {}; template<class Expr> struct lhs_extension; struct my_lhs_domain: proto::domain < proto::pod_generator<lhs_extension>, addition, my_domain > {}; template<class Expr> struct rhs_extension; struct my_rhs_domain: proto::domain < proto::pod_generator<rhs_extension>, addition, my_domain > {}; template<class Expr> struct extension { BOOST_PROTO_BASIC_EXTENDS( Expr , extension<Expr> , my_domain ) void test() const {} }; template<class Expr> struct lhs_extension { BOOST_PROTO_BASIC_EXTENDS( Expr , lhs_extension<Expr> , my_lhs_domain ) }; template<class Expr> struct rhs_extension { BOOST_PROTO_BASIC_EXTENDS( Expr , rhs_extension<Expr> , my_rhs_domain ) }; void test_constrained_ops() { lhs_extension<term> const i = {}; rhs_extension<term> const j = {}; proto::assert_matches_not<equation>(i); // false proto::assert_matches_not<equation>(j); // false proto::assert_matches_not<equation>(i + i); // false proto::assert_matches_not<equation>(j + j); // false #if 0 proto::assert_matches_not<equation>(i + j); // compile error (by design) proto::assert_matches_not<equation>(j + i); // compile error (by design) #endif proto::assert_matches<equation>(i == j); // true proto::assert_matches<equation>(i == j + j); // true proto::assert_matches<equation>(i + i == j); // true proto::assert_matches<equation>(i + i == j + j); // true } 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 constrained EDSLs"); test->add(BOOST_TEST_CASE(&test_constrained_ops)); return test; }