cpp-next_bug.cpp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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. #include <vector>
  8. #include <boost/proto/proto.hpp>
  9. #include <boost/test/unit_test.hpp>
  10. namespace mpl = boost::mpl;
  11. namespace proto = boost::proto;
  12. using proto::_;
  13. namespace linear_algebra
  14. {
  15. // A trait that returns true only for std::vector
  16. template<typename T>
  17. struct is_std_vector
  18. : mpl::false_
  19. {};
  20. template<typename T, typename A>
  21. struct is_std_vector<std::vector<T, A> >
  22. : mpl::true_
  23. {};
  24. // A type used as a domain for linear algebra expressions
  25. struct linear_algebra_domain
  26. : proto::domain<>
  27. {};
  28. // Define all the operator overloads for combining std::vectors
  29. BOOST_PROTO_DEFINE_OPERATORS(is_std_vector, linear_algebra_domain)
  30. // Take any expression and turn each node
  31. // into a subscript expression, using the
  32. // state as the RHS.
  33. struct Distribute
  34. : proto::or_<
  35. proto::when<proto::terminal<_>, proto::_make_subscript(_, proto::_state)>
  36. , proto::plus<Distribute, Distribute>
  37. >
  38. {};
  39. struct Optimize
  40. : proto::or_<
  41. proto::when<
  42. proto::subscript<Distribute, proto::terminal<_> >,
  43. Distribute(proto::_left, proto::_right)
  44. >
  45. , proto::plus<Optimize, Optimize>
  46. , proto::terminal<_>
  47. >
  48. {};
  49. }
  50. static const int celems = 4;
  51. static int const value[celems] = {1,2,3,4};
  52. std::vector<int> A(value, value+celems), B(A);
  53. void test1()
  54. {
  55. using namespace linear_algebra;
  56. proto::_default<> eval;
  57. BOOST_CHECK_EQUAL(8, eval(Optimize()((A + B)[3])));
  58. }
  59. using namespace boost::unit_test;
  60. ///////////////////////////////////////////////////////////////////////////////
  61. // init_unit_test_suite
  62. //
  63. test_suite* init_unit_test_suite( int argc, char* argv[] )
  64. {
  65. test_suite *test = BOOST_TEST_SUITE("test for a problem reported on the cpp-next.com blog");
  66. test->add(BOOST_TEST_CASE(&test1));
  67. return test;
  68. }