override.hpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #ifndef BOOST_CONTRACT_OVERRIDE_HPP_
  2. #define BOOST_CONTRACT_OVERRIDE_HPP_
  3. // Copyright (C) 2008-2018 Lorenzo Caminiti
  4. // Distributed under the Boost Software License, Version 1.0 (see accompanying
  5. // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
  6. // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
  7. /** @file
  8. Handle public function overrides (for subcontracting).
  9. */
  10. // IMPORTANT: Included by contract_macro.hpp so must #if-guard all its includes.
  11. #include <boost/contract/core/config.hpp>
  12. #include <boost/preprocessor/cat.hpp>
  13. #include <boost/preprocessor/config/config.hpp>
  14. #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
  15. /**
  16. Declare an override type with an arbitrary name.
  17. Declare the override type to pass as an explicit template parameter to
  18. @RefFunc{boost::contract::public_function} for public function overrides.
  19. @see @RefSect{advanced.named_overrides, Named Overrides}
  20. @param type_name Name of the override type this macro will declare.
  21. (This is not a variadic macro parameter but it should
  22. never contain commas because it is an identifier.)
  23. @param func_name Function name of the public function override.
  24. This macro is called just once even if the function name
  25. is overloaded (the same override type is used for all
  26. overloaded functions with the same name, see
  27. @RefSect{advanced.function_overloads,
  28. Function Overloads}).
  29. (This is not a variadic macro parameter but it should
  30. never contain commas because it is an identifier.)
  31. */
  32. #define BOOST_CONTRACT_NAMED_OVERRIDE(type_name, func_name)
  33. #elif !defined(BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS)
  34. #include <boost/contract/core/virtual.hpp>
  35. #include <boost/contract/detail/type_traits/mirror.hpp>
  36. #include <boost/contract/detail/tvariadic.hpp>
  37. #include <boost/contract/detail/none.hpp>
  38. #include <boost/contract/detail/name.hpp>
  39. /* PRIVATE */
  40. #define BOOST_CONTRACT_OVERRIDE_CALL_BASE_(z, arity, arity_compl, \
  41. func_name) \
  42. template< \
  43. class BOOST_CONTRACT_DETAIL_NAME1(B), \
  44. class BOOST_CONTRACT_DETAIL_NAME1(C) \
  45. BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
  46. BOOST_CONTRACT_DETAIL_TVARIADIC_TPARAMS_Z(z, arity, \
  47. BOOST_CONTRACT_DETAIL_NAME1(Args)) \
  48. > \
  49. static void BOOST_CONTRACT_DETAIL_NAME1(call_base)( \
  50. boost::contract::virtual_* BOOST_CONTRACT_DETAIL_NAME1(v), \
  51. BOOST_CONTRACT_DETAIL_NAME1(C)* BOOST_CONTRACT_DETAIL_NAME1(obj) \
  52. BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
  53. BOOST_CONTRACT_DETAIL_TVARIADIC_FPARAMS_Z(z, arity, \
  54. BOOST_CONTRACT_DETAIL_NAME1(Args), \
  55. &, \
  56. BOOST_CONTRACT_DETAIL_NAME1(args) \
  57. ) \
  58. BOOST_CONTRACT_DETAIL_NO_TVARIADIC_COMMA(arity_compl) \
  59. BOOST_CONTRACT_DETAIL_NO_TVARIADIC_ENUM_Z(z, arity_compl, \
  60. boost::contract::detail::none&) \
  61. ) { \
  62. BOOST_CONTRACT_DETAIL_NAME1(obj)-> \
  63. BOOST_CONTRACT_DETAIL_NAME1(B)::func_name( \
  64. BOOST_CONTRACT_DETAIL_TVARIADIC_ARGS_Z(z, arity, \
  65. BOOST_CONTRACT_DETAIL_NAME1(args)) \
  66. BOOST_CONTRACT_DETAIL_TVARIADIC_COMMA(arity) \
  67. BOOST_CONTRACT_DETAIL_NAME1(v) \
  68. ); \
  69. }
  70. #if BOOST_CONTRACT_DETAIL_TVARIADIC
  71. #define BOOST_CONTRACT_OVERRIDE_CALL_BASE_DECL_(func_name) \
  72. BOOST_CONTRACT_OVERRIDE_CALL_BASE_(1, ~, ~, func_name)
  73. #else
  74. #include <boost/preprocessor/repetition/repeat.hpp>
  75. #include <boost/preprocessor/arithmetic/inc.hpp>
  76. #include <boost/preprocessor/arithmetic/sub.hpp>
  77. #define BOOST_CONTRACT_OVERRIDE_CALL_BASE_DECL_(func_name) \
  78. BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_CONTRACT_MAX_ARGS), \
  79. BOOST_CONTRACT_OVERRIDE_CALL_BASE_ARITY_, func_name) \
  80. #define BOOST_CONTRACT_OVERRIDE_CALL_BASE_ARITY_(z, arity, func_name) \
  81. BOOST_CONTRACT_OVERRIDE_CALL_BASE_(z, arity, \
  82. BOOST_PP_SUB(BOOST_CONTRACT_MAX_ARGS, arity), func_name)
  83. #endif
  84. /* PUBLIC */
  85. #define BOOST_CONTRACT_NAMED_OVERRIDE(type_name, func_name) \
  86. struct type_name { \
  87. BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION( \
  88. BOOST_CONTRACT_DETAIL_NAME1(has_member_function), \
  89. func_name \
  90. ) \
  91. BOOST_CONTRACT_OVERRIDE_CALL_BASE_DECL_(func_name) \
  92. };
  93. #else
  94. #define BOOST_CONTRACT_NAMED_OVERRIDE(type_name, func_name) \
  95. struct type_name {}; /* empty (not used), just to compile */
  96. #endif
  97. /* PUBLIC */
  98. /**
  99. Declare an override type named <c>override_<i>func_name</i></c>.
  100. Declare the override type to pass as an explicit template parameter to
  101. @RefFunc{boost::contract::public_function} for public function overrides.
  102. @see @RefSect{tutorial.public_function_overrides__subcontracting_,
  103. Public Function Overrides}
  104. @param func_name Function name of the public function override.
  105. This macro is called just once even if the function name is
  106. overloaded (the same override type is used for all
  107. overloaded functions with the same name, see
  108. @RefSect{advanced.function_overloads, Function Overloads}).
  109. (This is not a variadic macro parameter but it should never
  110. contain any comma because it is an identifier.)
  111. */
  112. #define BOOST_CONTRACT_OVERRIDE(func_name) \
  113. BOOST_CONTRACT_NAMED_OVERRIDE(BOOST_PP_CAT(override_, func_name), func_name)
  114. #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
  115. /**
  116. Declare multiple override types at once naming them <c>override_...</c> (for
  117. convenience).
  118. This variadic macro is provided for convenience only,
  119. <c>BOOST_CONTRACT_OVERRIDES(f_1, f_2, ..., f_n)</c> expands to code
  120. equivalent to:
  121. @code
  122. BOOST_CONTRACT_OVERRIDE(f_1)
  123. BOOST_CONTRACT_OVERRIDE(f_2)
  124. ...
  125. BOOST_CONTRACT_OVERRIDE(f_n)
  126. @endcode
  127. On compilers that do not support variadic macros,
  128. the override types can be equivalently programmed one-by-one calling
  129. @RefMacro{BOOST_CONTRACT_OVERRIDE} for each function name as shown above.
  130. @see @RefSect{tutorial.public_function_overrides__subcontracting_,
  131. Public Function Overrides}
  132. @param ... A comma separated list of one or more function names of public
  133. function overrides.
  134. (Each function name should never contain commas because it is an
  135. identifier.)
  136. */
  137. #define BOOST_CONTRACT_OVERRIDES(...)
  138. #elif BOOST_PP_VARIADICS
  139. #include <boost/preprocessor/seq/for_each.hpp>
  140. #include <boost/preprocessor/variadic/to_seq.hpp>
  141. /* PRIVATE */
  142. #define BOOST_CONTRACT_OVERRIDES_SEQ_(r, unused, func_name) \
  143. BOOST_CONTRACT_OVERRIDE(func_name)
  144. /* PUBLIC */
  145. #define BOOST_CONTRACT_OVERRIDES(...) \
  146. BOOST_PP_SEQ_FOR_EACH(BOOST_CONTRACT_OVERRIDES_SEQ_, ~, \
  147. BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
  148. #else
  149. #define BOOST_CONTRACT_OVERRIDES \
  150. BOOST_CONTRACT_ERROR_macro_OVERRIDES_requires_variadic_macros_otherwise_manually_repeat_OVERRIDE_macro
  151. #endif
  152. #endif // #include guard