noinvoke.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // noinvoke.hpp
  3. //
  4. // Copyright 2008 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 <boost/proto/core.hpp>
  8. #include <boost/proto/transform/make.hpp>
  9. #include <boost/type_traits/add_pointer.hpp>
  10. #include <boost/type_traits/remove_pointer.hpp>
  11. #include <boost/test/unit_test.hpp>
  12. namespace proto=boost::proto;
  13. using proto::_;
  14. struct Test
  15. : proto::when<
  16. _
  17. , proto::noinvoke<
  18. // This remove_pointer invocation is bloked by noinvoke
  19. boost::remove_pointer<
  20. // This add_pointer invocation is *not* blocked by noinvoke
  21. boost::add_pointer<_>
  22. >
  23. >()
  24. >
  25. {};
  26. struct Test2
  27. : proto::when<
  28. _
  29. // This add_pointer gets invoked because a substitution takes place
  30. // within it.
  31. , boost::add_pointer<
  32. proto::noinvoke<
  33. // This remove_pointer invocation is bloked by noinvoke
  34. boost::remove_pointer<
  35. // This add_pointer invocation is *not* blocked by noinvoke
  36. boost::add_pointer<_>
  37. >
  38. >
  39. >()
  40. >
  41. {};
  42. template<typename T, typename U>
  43. struct select2nd
  44. {
  45. typedef U type;
  46. };
  47. struct Test3
  48. : proto::when<
  49. _
  50. // This add_pointer gets invoked because a substitution takes place
  51. // within it.
  52. , select2nd<
  53. void
  54. , proto::noinvoke<
  55. // This remove_pointer invocation is bloked by noinvoke
  56. select2nd<
  57. void
  58. // This add_pointer invocation is *not* blocked by noinvoke
  59. , boost::add_pointer<_>
  60. >
  61. >
  62. >()
  63. >
  64. {};
  65. void test_noinvoke()
  66. {
  67. typedef proto::terminal<int>::type Int;
  68. Int i = {42};
  69. BOOST_MPL_ASSERT((
  70. boost::is_same<
  71. boost::result_of<Test(Int)>::type
  72. , boost::remove_pointer<Int *>
  73. >
  74. ));
  75. boost::remove_pointer<Int *> t = Test()(i);
  76. BOOST_MPL_ASSERT((
  77. boost::is_same<
  78. boost::result_of<Test2(Int)>::type
  79. , boost::remove_pointer<Int *> *
  80. >
  81. ));
  82. boost::remove_pointer<Int *> * t2 = Test2()(i);
  83. BOOST_MPL_ASSERT((
  84. boost::is_same<
  85. boost::result_of<Test3(Int)>::type
  86. , select2nd<void, Int *>
  87. >
  88. ));
  89. select2nd<void, Int *> t3 = Test3()(i);
  90. }
  91. using namespace boost::unit_test;
  92. ///////////////////////////////////////////////////////////////////////////////
  93. // init_unit_test_suite
  94. //
  95. test_suite* init_unit_test_suite( int argc, char* argv[] )
  96. {
  97. test_suite *test = BOOST_TEST_SUITE("test proto::noinvoke");
  98. test->add(BOOST_TEST_CASE(&test_noinvoke));
  99. return test;
  100. }