make_unfused.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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/generation/make_unfused.hpp>
  8. #include <boost/detail/lightweight_test.hpp>
  9. #include <boost/noncopyable.hpp>
  10. #include <boost/mpl/empty_base.hpp>
  11. #include <boost/mpl/if.hpp>
  12. #include <boost/mpl/and.hpp>
  13. #include <boost/mpl/not.hpp>
  14. #include <boost/mpl/bool.hpp>
  15. #include <boost/utility/result_of.hpp>
  16. #include <boost/core/enable_if.hpp>
  17. #include <boost/fusion/sequence/intrinsic/empty.hpp>
  18. #include <boost/fusion/algorithm/iteration/fold.hpp>
  19. #include <boost/ref.hpp>
  20. namespace fusion = boost::fusion;
  21. namespace mpl = boost::mpl;
  22. using boost::noncopyable;
  23. typedef mpl::true_ no_nullary_call;
  24. using boost::ref;
  25. using boost::cref;
  26. template <class Base = mpl::empty_base, class RemoveNullary = mpl::false_>
  27. struct test_func
  28. : Base
  29. {
  30. template <typename Sig>
  31. struct result;
  32. template <class Self, class Seq>
  33. struct result< Self(Seq &) >
  34. : boost::enable_if<
  35. mpl::not_<mpl::and_<boost::fusion::result_of::empty<Seq>, RemoveNullary> >,
  36. long>
  37. { };
  38. template <typename Seq>
  39. long operator()(Seq const & seq) const
  40. {
  41. long state = 0;
  42. return fusion::fold(seq, state, fold_op());
  43. }
  44. template < typename Seq >
  45. long operator()(Seq const & seq)
  46. {
  47. long state = 100;
  48. return fusion::fold(seq, state, fold_op());
  49. }
  50. private:
  51. struct fold_op
  52. {
  53. typedef long result_type;
  54. template <typename T>
  55. long operator()(long value, T & elem) const
  56. {
  57. elem += sizeof(T);
  58. return value + elem;
  59. }
  60. };
  61. };
  62. template <typename T>
  63. inline T const & const_(T const & t)
  64. {
  65. return t;
  66. }
  67. int main()
  68. {
  69. test_func<> f;
  70. test_func<noncopyable> f_nc;
  71. boost::fusion::result_of::make_unfused< test_func<> >::type unfused_func =
  72. fusion::make_unfused(f);
  73. boost::fusion::result_of::make_unfused< boost::reference_wrapper<
  74. test_func<noncopyable> > >::type unfused_func_ref =
  75. fusion::make_unfused(ref(f_nc));
  76. boost::fusion::result_of::make_unfused< boost::reference_wrapper<
  77. test_func<noncopyable> const> >::type unfused_func_c_ref =
  78. fusion::make_unfused(cref(f_nc));
  79. BOOST_TEST(unfused_func() == 100);
  80. BOOST_TEST(const_(unfused_func)() == 0);
  81. BOOST_TEST(unfused_func_ref() == 100);
  82. BOOST_TEST(unfused_func_c_ref() == 0);
  83. long lv1 = 2; int lv2 = 3l; char lv3 = '\007';
  84. long expected;
  85. expected = lv1+sizeof(lv1) + lv2+sizeof(lv2) + lv3+sizeof(lv3);
  86. BOOST_TEST(unfused_func(lv1,lv2,lv3) == 100 + expected);
  87. BOOST_TEST(lv1 == 2+1*sizeof(lv1) && lv2 == 3+1*sizeof(lv2) && lv3 == 7+1*sizeof(lv3));
  88. expected = lv1+sizeof(lv1) + lv2+sizeof(lv2) + lv3+sizeof(lv3);
  89. BOOST_TEST(const_(unfused_func)(lv1,lv2,lv3) == 0 + expected);
  90. BOOST_TEST(lv1 == 2+2*sizeof(lv1) && lv2 == 3+2*sizeof(lv2) && lv3 == 7+2*sizeof(lv3));
  91. expected = lv1+sizeof(lv1) + lv2+sizeof(lv2) + lv3+sizeof(lv3);
  92. BOOST_TEST(unfused_func_ref(lv1,lv2,lv3) == 100 + expected);
  93. BOOST_TEST(lv1 == 2+3*sizeof(lv1) && lv2 == 3+3*sizeof(lv2) && lv3 == 7+3*sizeof(lv3));
  94. expected = lv1+sizeof(lv1) + lv2+sizeof(lv2) + lv3+sizeof(lv3);
  95. BOOST_TEST(unfused_func_c_ref(lv1,lv2,lv3) == 0 + expected);
  96. BOOST_TEST(lv1 == 2+4*sizeof(lv1) && lv2 == 3+4*sizeof(lv2) && lv3 == 7+4*sizeof(lv3));
  97. return boost::report_errors();
  98. }