summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/proto/test/cpp-next_bug.cpp
blob: 2f4b8b474541a3e403e5f16a3637e5823f511892 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
///////////////////////////////////////////////////////////////////////////////
// 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;
}