/////////////////////////////////////////////////////////////////////////////// // 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 <vector> #include <boost/proto/proto.hpp> #include <boost/test/unit_test.hpp> namespace mpl = boost::mpl; namespace proto = boost::proto; using proto::_; namespace linear_algebra { // A trait that returns true only for std::vector template<typename T> struct is_std_vector : mpl::false_ {}; template<typename T, typename A> struct is_std_vector<std::vector<T, A> > : 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::terminal<_>, proto::_make_subscript(_, proto::_state)> , proto::plus<Distribute, Distribute> > {}; struct Optimize : proto::or_< proto::when< proto::subscript<Distribute, proto::terminal<_> >, Distribute(proto::_left, proto::_right) > , proto::plus<Optimize, Optimize> , proto::terminal<_> > {}; } static const int celems = 4; static int const value[celems] = {1,2,3,4}; std::vector<int> 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; }