unfused_typed.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*=============================================================================
  2. Copyright (c) 2006-2007 Tobias Schwinger
  3. Use modification and distribution are subject to the Boost Software
  4. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. http://www.boost.org/LICENSE_1_0.txt).
  6. ==============================================================================*/
  7. #include <boost/fusion/functional/adapter/unfused_typed.hpp>
  8. #include <boost/detail/lightweight_test.hpp>
  9. #include <boost/noncopyable.hpp>
  10. #include <boost/mpl/empty_base.hpp>
  11. #include <boost/mpl/identity.hpp>
  12. #include <boost/mpl/placeholders.hpp>
  13. #include <boost/utility/result_of.hpp>
  14. #include <boost/fusion/algorithm/iteration/fold.hpp>
  15. namespace fusion = boost::fusion;
  16. namespace mpl = boost::mpl;
  17. using mpl::placeholders::_;
  18. using boost::noncopyable;
  19. typedef fusion::vector<> types0;
  20. typedef fusion::vector<long &> types1;
  21. typedef fusion::vector<long &,int,char> types3;
  22. template <class Base = boost::mpl::empty_base>
  23. struct test_func
  24. : Base
  25. {
  26. template<typename T>
  27. struct result;
  28. template <class Self, class Seq>
  29. struct result< Self(Seq) >
  30. : mpl::identity<long>
  31. { };
  32. template <typename Seq>
  33. long operator()(Seq const & seq) const
  34. {
  35. long state = 0;
  36. return fusion::fold(seq, state, fold_op());
  37. }
  38. template < typename Seq >
  39. long operator()(Seq const & seq)
  40. {
  41. long state = 100;
  42. return fusion::fold(seq, state, fold_op());
  43. }
  44. private:
  45. struct fold_op
  46. {
  47. typedef long result_type;
  48. template <typename T>
  49. long operator()(long value, T const & elem) const
  50. {
  51. return value + sizeof(T) * elem;
  52. }
  53. template <typename T>
  54. long operator()(long value, T & elem) const
  55. {
  56. elem += sizeof(T);
  57. return value;
  58. }
  59. };
  60. };
  61. void result_type_tests()
  62. {
  63. using boost::is_same;
  64. typedef fusion::unfused_typed< test_func<>, types0 > t0;
  65. BOOST_TEST(( is_same< boost::result_of< t0 () >::type, long >::value ));
  66. typedef fusion::unfused_typed< test_func<>, types1 > t1;
  67. BOOST_TEST(( is_same< boost::result_of< t1 (long &) >::type, long >::value ));
  68. }
  69. #if defined(BOOST_MSVC) && BOOST_MSVC < 1400
  70. # define BOOST_TEST_NO_VC71(cond) (void)((cond)?0:1)
  71. #else
  72. # define BOOST_TEST_NO_VC71(cond) BOOST_TEST(cond)
  73. #endif
  74. void nullary_tests()
  75. {
  76. test_func<noncopyable> f;
  77. fusion::unfused_typed< test_func<>, types0 > unfused_func;
  78. fusion::unfused_typed< test_func<noncopyable> &, types0 > unfused_func_ref(f);
  79. fusion::unfused_typed< test_func<> const, types0 > unfused_func_c;
  80. fusion::unfused_typed< test_func<>, types0 > const unfused_func_c2;
  81. fusion::unfused_typed< test_func<noncopyable> const &, types0 > unfused_func_c_ref(f);
  82. BOOST_TEST(unfused_func() == 100);
  83. BOOST_TEST(unfused_func_ref() == 100);
  84. BOOST_TEST(unfused_func_c() == 0);
  85. BOOST_TEST(unfused_func_c2() == 0);
  86. BOOST_TEST(unfused_func_c_ref() == 0);
  87. }
  88. void unary_tests()
  89. {
  90. test_func<noncopyable> f;
  91. fusion::unfused_typed< test_func<>, types1 > unfused_func;
  92. fusion::unfused_typed< test_func<noncopyable> &, types1 > unfused_func_ref(f);
  93. fusion::unfused_typed< test_func<> const, types1 > unfused_func_c;
  94. fusion::unfused_typed< test_func<>, types1 > const unfused_func_c2;
  95. fusion::unfused_typed< test_func<noncopyable> const &, types1 > unfused_func_c_ref(f);
  96. long lvalue = 1;
  97. BOOST_TEST_NO_VC71(unfused_func(lvalue) == 100);
  98. BOOST_TEST(lvalue == 1 + 1*sizeof(lvalue));
  99. BOOST_TEST(unfused_func_ref(lvalue) == 100);
  100. BOOST_TEST(lvalue == 1 + 2*sizeof(lvalue));
  101. BOOST_TEST(unfused_func_c(lvalue) == 0);
  102. BOOST_TEST(lvalue == 1 + 3*sizeof(lvalue));
  103. BOOST_TEST(unfused_func_c2(lvalue) == 0);
  104. BOOST_TEST(lvalue == 1 + 4*sizeof(lvalue));
  105. BOOST_TEST(unfused_func_c_ref(lvalue) == 0);
  106. BOOST_TEST(lvalue == 1 + 5*sizeof(lvalue));
  107. }
  108. void ternary_tests()
  109. {
  110. test_func<noncopyable> f;
  111. fusion::unfused_typed< test_func<>, types3 > unfused_func;
  112. fusion::unfused_typed< test_func<noncopyable> &, types3 > unfused_func_ref(f);
  113. fusion::unfused_typed< test_func<> const, types3 > unfused_func_c;
  114. fusion::unfused_typed< test_func<>, types3 > const unfused_func_c2;
  115. fusion::unfused_typed< test_func<noncopyable> const &, types3 > unfused_func_c_ref(f);
  116. long lvalue = 1;
  117. static const long expected = 2*sizeof(int) + 7*sizeof(char);
  118. BOOST_TEST_NO_VC71(unfused_func(lvalue,2,'\007') == 100 + expected);
  119. BOOST_TEST(lvalue == 1 + 1*sizeof(lvalue));
  120. BOOST_TEST(unfused_func_ref(lvalue,2,'\007') == 100 + expected);
  121. BOOST_TEST(lvalue == 1 + 2*sizeof(lvalue));
  122. BOOST_TEST(unfused_func_c(lvalue,2,'\007') == 0 + expected);
  123. BOOST_TEST(lvalue == 1 + 3*sizeof(lvalue));
  124. BOOST_TEST(unfused_func_c2(lvalue,2,'\007') == 0 + expected);
  125. BOOST_TEST(lvalue == 1 + 4*sizeof(lvalue));
  126. BOOST_TEST(unfused_func_c_ref(lvalue,2,'\007') == 0 + expected);
  127. BOOST_TEST(lvalue == 1 + 5*sizeof(lvalue));
  128. }
  129. int main()
  130. {
  131. result_type_tests();
  132. nullary_tests();
  133. unary_tests();
  134. ternary_tests();
  135. return boost::report_errors();
  136. }