result.hpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. // Copyright (C) 2009-2012 Lorenzo Caminiti
  2. // Distributed under the Boost Software License, Version 1.0
  3. // (see accompanying file LICENSE_1_0.txt or a copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. // Home at http://www.boost.org/libs/local_function
  6. #ifndef BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_HPP_
  7. #define BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_HPP_
  8. #include <boost/local_function/aux_/symbol.hpp>
  9. #include <boost/local_function/aux_/preprocessor/traits/decl_returns.hpp>
  10. #include <boost/scope_exit.hpp>
  11. #include <boost/typeof/typeof.hpp>
  12. #include <boost/type_traits/remove_pointer.hpp>
  13. #include <boost/type_traits/function_traits.hpp>
  14. #include <boost/preprocessor/control/iif.hpp>
  15. #include <boost/preprocessor/control/expr_iif.hpp>
  16. #include <boost/preprocessor/list/adt.hpp>
  17. #include <boost/preprocessor/cat.hpp>
  18. // PRIVATE //
  19. #define BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_FUNC_(id) \
  20. /* symbol (not internal) also gives error if missing result type */ \
  21. BOOST_PP_CAT( \
  22. ERROR_missing_result_type_before_the_local_function_parameter_macro_id, \
  23. id)
  24. #define BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_PARAMS_(id) \
  25. BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (deduce_result_params)(id) )
  26. #define BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_TYPE_(id) \
  27. BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (result_type)(id) )
  28. #define BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_INDEX_ \
  29. /* this does not have to be an integral index because ScopeExit uses */ \
  30. /* just as a symbol to concatenate go generate unique symbols (but */ \
  31. /* if it'd ever needed to became integral, the number of function */ \
  32. /* params + 1 as in the macro CONFIG_ARITY_MAX could be used) */ \
  33. result
  34. // User did not explicitly specified result type, deduce it (using Typeof).
  35. #define BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_DEDUCE_( \
  36. id, typename01, decl_traits) \
  37. /* user specified result type here */ \
  38. BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_DECL(id) \
  39. /* tagging, wrapping, etc as from ScopeExit type deduction are */ \
  40. /* necessary within templates (at least on GCC) to work around an */ \
  41. /* compiler internal errors) */ \
  42. BOOST_SCOPE_EXIT_DETAIL_TAG_DECL(0, /* no recursive step r */ \
  43. id, BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_INDEX_, \
  44. BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_FUNC_(id)) \
  45. BOOST_SCOPE_EXIT_DETAIL_CAPTURE_DECL(0, /* no recursive step r */ \
  46. ( id, BOOST_PP_EXPR_IIF(typename01, typename) ), \
  47. BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_INDEX_, \
  48. BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_FUNC_(id)) \
  49. /* extra struct to workaround GCC and other compiler's issues */ \
  50. struct BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_PARAMS_(id) { \
  51. typedef \
  52. BOOST_PP_EXPR_IIF(typename01, typename) \
  53. ::boost::function_traits< \
  54. BOOST_PP_EXPR_IIF(typename01, typename) \
  55. ::boost::remove_pointer< \
  56. BOOST_SCOPE_EXIT_DETAIL_CAPTURE_T(id, \
  57. BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_INDEX_, \
  58. BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_FUNC_(id)) \
  59. >::type \
  60. >::result_type \
  61. BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_TYPE_(id) \
  62. ; \
  63. };
  64. // Use result type as explicitly specified by user (no type deduction needed).
  65. // Precondition: RETURNS(decl_traits) != NIL
  66. #define BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_TYPED_( \
  67. id, typename01, decl_traits) \
  68. /* user specified result type here */ \
  69. struct BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_PARAMS_(id) { \
  70. typedef \
  71. BOOST_PP_LIST_FIRST( \
  72. BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_RETURNS( \
  73. decl_traits)) \
  74. BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_TYPE_(id) \
  75. ; \
  76. };
  77. // PUBLIC //
  78. #define BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_TYPE(id, typename01) \
  79. BOOST_PP_EXPR_IIF(typename01, typename) \
  80. BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_PARAMS_(id) :: \
  81. BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_TYPE_(id)
  82. #define BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_DECL(id) \
  83. /* result type here */ (*BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_FUNC_(id))();
  84. #define BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT(id, typename01, decl_traits) \
  85. BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS( \
  86. BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_RETURNS(decl_traits)), \
  87. BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_TYPED_ \
  88. , \
  89. BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_DEDUCE_ \
  90. )(id, typename01, decl_traits)
  91. #endif // #include guard