blob: 2f4b8b474541a3e403e5f16a3637e5823f511892 [file] [log] [blame]
///////////////////////////////////////////////////////////////////////////////
// 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;
}