• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 ///////////////////////////////////////////////////////////////////////////////
2 // cpp-next_bug.hpp
3 //
4 //  Copyright 2012 Eric Niebler. Distributed under the Boost
5 //  Software License, Version 1.0. (See accompanying file
6 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 
8 #include <vector>
9 #include <boost/proto/proto.hpp>
10 #include <boost/test/unit_test.hpp>
11 namespace mpl = boost::mpl;
12 namespace proto = boost::proto;
13 using proto::_;
14 
15 namespace linear_algebra
16 {
17     // A trait that returns true only for std::vector
18     template<typename T>
19     struct is_std_vector
20       : mpl::false_
21     {};
22 
23     template<typename T, typename A>
24     struct is_std_vector<std::vector<T, A> >
25       : mpl::true_
26     {};
27 
28     // A type used as a domain for linear algebra expressions
29     struct linear_algebra_domain
30       : proto::domain<>
31     {};
32 
33     // Define all the operator overloads for combining std::vectors
34     BOOST_PROTO_DEFINE_OPERATORS(is_std_vector, linear_algebra_domain)
35 
36     // Take any expression and turn each node
37     // into a subscript expression, using the
38     // state as the RHS.
39     struct Distribute
40       : proto::or_<
41             proto::when<proto::terminal<_>, proto::_make_subscript(_, proto::_state)>
42           , proto::plus<Distribute, Distribute>
43         >
44     {};
45 
46     struct Optimize
47       : proto::or_<
48             proto::when<
49                 proto::subscript<Distribute, proto::terminal<_> >,
50                 Distribute(proto::_left, proto::_right)
51             >
52           , proto::plus<Optimize, Optimize>
53           , proto::terminal<_>
54         >
55     {};
56 }
57 
58 static const int celems = 4;
59 static int const value[celems] = {1,2,3,4};
60 std::vector<int> A(value, value+celems), B(A);
61 
test1()62 void test1()
63 {
64     using namespace linear_algebra;
65     proto::_default<> eval;
66     BOOST_CHECK_EQUAL(8, eval(Optimize()((A + B)[3])));
67 }
68 
69 using namespace boost::unit_test;
70 ///////////////////////////////////////////////////////////////////////////////
71 // init_unit_test_suite
72 //
init_unit_test_suite(int argc,char * argv[])73 test_suite* init_unit_test_suite( int argc, char* argv[] )
74 {
75     test_suite *test = BOOST_TEST_SUITE("test for a problem reported on the cpp-next.com blog");
76 
77     test->add(BOOST_TEST_CASE(&test1));
78 
79     return test;
80 }
81