try_catch.hpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /*=============================================================================
  2. Copyright (c) 2005-2007 Dan Marsden
  3. Copyright (c) 2005-2007 Joel de Guzman
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. ==============================================================================*/
  7. #ifndef PHOENIX_STATEMENT_TRY_CATCH_HPP
  8. #define PHOENIX_STATEMENT_TRY_CATCH_HPP
  9. #include <boost/spirit/home/phoenix/core/actor.hpp>
  10. #include <boost/spirit/home/phoenix/core/composite.hpp>
  11. #include <boost/fusion/include/push_back.hpp>
  12. #include <boost/fusion/include/as_vector.hpp>
  13. #include <boost/spirit/home/phoenix/statement/detail/catch_composite.hpp>
  14. #include <boost/spirit/home/phoenix/statement/detail/catch_eval.hpp>
  15. #include <boost/spirit/home/phoenix/statement/detail/catch_all_eval.hpp>
  16. #if defined(BOOST_MSVC)
  17. # pragma warning(push)
  18. # pragma warning(disable:4355)
  19. #endif
  20. namespace boost { namespace phoenix {
  21. template<typename Tuple> struct try_catch_composite;
  22. namespace meta
  23. {
  24. template<typename Composite, typename Actor>
  25. struct try_catch_composite_push_back
  26. {
  27. typedef typename Composite::base_type actor_tuple;
  28. typedef try_catch_composite<
  29. typename fusion::result_of::as_vector<
  30. typename fusion::result_of::push_back<
  31. actor_tuple, Actor>::type>::type> type;
  32. };
  33. template<typename Composite, typename Actor>
  34. struct catch_all_composite_push_back
  35. {
  36. typedef typename Composite::base_type actor_tuple;
  37. typedef composite<
  38. catch_all_eval,
  39. typename fusion::result_of::as_vector<
  40. typename fusion::result_of::push_back<
  41. actor_tuple, Actor>::type>::type> type;
  42. };
  43. }
  44. namespace detail
  45. {
  46. struct try_catch_composite_push_back
  47. {
  48. template<typename Composite, typename Actor>
  49. struct result
  50. : meta::try_catch_composite_push_back<Composite, Actor>
  51. {};
  52. template<typename Composite, typename Actor>
  53. typename result<Composite, Actor>::type
  54. operator()(
  55. const Composite& composite, const Actor& actor) const
  56. {
  57. typedef typename result<Composite, Actor>::type result;
  58. return result(
  59. fusion::as_vector(
  60. fusion::push_back(composite, actor)));
  61. }
  62. };
  63. struct catch_all_composite_push_back
  64. {
  65. template<typename Composite, typename Actor>
  66. struct result
  67. : meta::catch_all_composite_push_back<Composite, Actor>
  68. {};
  69. template<typename Composite, typename Actor>
  70. typename result<Composite, Actor>::type
  71. operator()(
  72. const Composite& composite, const Actor& actor) const
  73. {
  74. typedef typename result<Composite, Actor>::type result;
  75. return result(
  76. fusion::as_vector(
  77. fusion::push_back(composite, actor)));
  78. }
  79. };
  80. }
  81. detail::try_catch_composite_push_back const try_catch_composite_push_back
  82. = detail::try_catch_composite_push_back();
  83. detail::catch_all_composite_push_back const catch_all_composite_push_back
  84. = detail::catch_all_composite_push_back();
  85. template<typename Exception, typename SourceComposite>
  86. struct catch_gen
  87. {
  88. explicit catch_gen(
  89. const SourceComposite& sourceComposite)
  90. : mSourceComposite(sourceComposite) { }
  91. template<typename Actor>
  92. actor<typename meta::try_catch_composite_push_back<
  93. SourceComposite,
  94. detail::catch_composite<Exception, Actor> >::type>
  95. operator[](const Actor& actor) const
  96. {
  97. return try_catch_composite_push_back(
  98. mSourceComposite, detail::catch_composite<Exception, Actor>(actor));
  99. }
  100. const SourceComposite& mSourceComposite;
  101. };
  102. template<typename SourceComposite>
  103. struct catch_all_gen
  104. {
  105. explicit catch_all_gen(
  106. const SourceComposite& sourceComposite)
  107. : mSourceComposite(sourceComposite) { }
  108. template<typename Actor>
  109. actor<typename meta::catch_all_composite_push_back<SourceComposite, Actor>::type>
  110. operator[](const Actor& actor) const
  111. {
  112. return catch_all_composite_push_back(
  113. mSourceComposite, actor);
  114. }
  115. const SourceComposite& mSourceComposite;
  116. };
  117. template<typename Tuple>
  118. struct try_catch_composite
  119. : composite<catch_eval, Tuple>
  120. {
  121. explicit try_catch_composite(
  122. const Tuple& t)
  123. :
  124. composite<catch_eval, Tuple>(t),
  125. catch_all(*this) { }
  126. try_catch_composite(
  127. const try_catch_composite& rhs)
  128. : composite<catch_eval, Tuple>(rhs),
  129. catch_all(*this) { }
  130. template<typename Exception>
  131. catch_gen<Exception, try_catch_composite> catch_() const
  132. {
  133. return catch_gen<Exception, try_catch_composite>(
  134. *this);
  135. }
  136. const catch_all_gen<try_catch_composite> catch_all;
  137. private:
  138. try_catch_composite& operator=(const try_catch_composite&);
  139. };
  140. struct try_gen
  141. {
  142. template<typename Try>
  143. try_catch_composite<fusion::vector<Try> > operator[](
  144. const Try& try_) const
  145. {
  146. typedef fusion::vector<Try> tuple_type;
  147. return try_catch_composite<tuple_type>(
  148. tuple_type(try_));
  149. }
  150. };
  151. try_gen const try_ = try_gen();
  152. }}
  153. #if defined(BOOST_MSVC)
  154. # pragma warning(pop)
  155. #endif
  156. #endif