/////////////////////////////////////////////////////////////////////////////// // cpp-next_bug.hpp // // Copyright 2012 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 #include #include namespace mpl = boost::mpl; namespace proto = boost::proto; using proto::_; namespace linear_algebra { // A trait that returns true only for std::vector template struct is_std_vector : mpl::false_ {}; template struct is_std_vector > : mpl::true_ {}; // A type used as a domain for linear algebra expressions struct linear_algebra_domain : proto::domain<> {}; // Define all the operator overloads for combining std::vectors BOOST_PROTO_DEFINE_OPERATORS(is_std_vector, linear_algebra_domain) // Take any expression and turn each node // into a subscript expression, using the // state as the RHS. struct Distribute : proto::or_< proto::when, proto::_make_subscript(_, proto::_state)> , proto::plus > {}; struct Optimize : proto::or_< proto::when< proto::subscript >, Distribute(proto::_left, proto::_right) > , proto::plus , proto::terminal<_> > {}; } static const int celems = 4; static int const value[celems] = {1,2,3,4}; std::vector A(value, value+celems), B(A); void test1() { using namespace linear_algebra; proto::_default<> eval; BOOST_CHECK_EQUAL(8, eval(Optimize()((A + B)[3]))); } 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 for a problem reported on the cpp-next.com blog"); test->add(BOOST_TEST_CASE(&test1)); return test; }