struct_macros.hpp.erb 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. <%#
  2. This is an ERB [1] template file used to generate the
  3. <boost/hana/detail/struct_macros.hpp> header. The maximum
  4. number of members that can be handled by the macros can
  5. be controlled with the 'MAX_NUMBER_OF_MEMBERS' variable,
  6. which can be set when calling ERB to generate the header:
  7. export MAX_NUMBER_OF_MEMBERS=55; erb struct_macros.hpp.erb
  8. 'MAX_NUMBER_OF_MEMBERS' must be greater than 0. In case 'MAX_NUMBER_OF_MEMBERS'
  9. is not specified, it defaults to 55. To regenerate the default struct macros,
  10. issue the following command from the root of the project:
  11. erb include/boost/hana/detail/struct_macros.hpp.erb > include/boost/hana/detail/struct_macros.hpp
  12. [1]: http://en.wikipedia.org/wiki/ERuby
  13. %>
  14. <%
  15. MAX_NUMBER_OF_MEMBERS = (ENV["MAX_NUMBER_OF_MEMBERS"] || 55).to_i
  16. raise "MAX_NUMBER_OF_MEMBERS must be > 0" if not MAX_NUMBER_OF_MEMBERS > 0
  17. %>
  18. /*!
  19. @file
  20. Defines the `BOOST_HANA_DEFINE_STRUCT`, `BOOST_HANA_ADAPT_STRUCT`, and
  21. `BOOST_HANA_ADAPT_ADT` macros.
  22. Copyright Louis Dionne 2013-2022
  23. Distributed under the Boost Software License, Version 1.0.
  24. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  25. */
  26. //////////////////////////////////////////////////////////////////////////////
  27. // THIS FILE IS GENERATED FROM THE <boost/hana/detail/struct_macros.erb.hpp>
  28. // ERB TEMPLATE. DO NOT EDIT THIS FILE DIRECTLY.
  29. //
  30. // THE ERB TEMPLATE CONTAINS INFORMATION ABOUT HOW TO REGENERATE THIS FILE.
  31. //////////////////////////////////////////////////////////////////////////////
  32. #ifndef BOOST_HANA_DETAIL_STRUCT_MACROS_HPP
  33. #define BOOST_HANA_DETAIL_STRUCT_MACROS_HPP
  34. #include <boost/hana/config.hpp>
  35. #include <boost/hana/detail/preprocessor.hpp>
  36. #include <boost/hana/pair.hpp>
  37. #include <boost/hana/string.hpp>
  38. #include <boost/hana/tuple.hpp>
  39. #include <cstddef>
  40. #include <utility>
  41. namespace boost { namespace hana { namespace struct_detail {
  42. template <typename Memptr, Memptr ptr>
  43. struct member_ptr {
  44. template <typename T>
  45. constexpr decltype(auto) operator()(T&& t) const
  46. { return static_cast<T&&>(t).*ptr; }
  47. };
  48. constexpr std::size_t strlen(char const* s) {
  49. std::size_t n = 0;
  50. while (*s++ != '\0')
  51. ++n;
  52. return n;
  53. }
  54. template <std::size_t n, typename Names, std::size_t ...i>
  55. constexpr auto prepare_member_name_impl(std::index_sequence<i...>) {
  56. return hana::string_c<hana::at_c<n>(Names::get())[i]...>;
  57. }
  58. template <std::size_t n, typename Names>
  59. constexpr auto prepare_member_name() {
  60. constexpr std::size_t len = strlen(hana::at_c<n>(Names::get()));
  61. return prepare_member_name_impl<n, Names>(std::make_index_sequence<len>{});
  62. }
  63. } }} // end namespace boost::hana
  64. //////////////////////////////////////////////////////////////////////////////
  65. // BOOST_HANA_PP_NARG
  66. //////////////////////////////////////////////////////////////////////////////
  67. //! @ingroup group-details
  68. //! Macro expanding to the number of arguments it is passed.
  69. //!
  70. //! Specifically, `BOOST_HANA_PP_NARG(x1, ..., xn)` expands to `n`. It is
  71. //! an error to call this macro with 0 arguments.
  72. #ifdef BOOST_HANA_WORKAROUND_MSVC_PREPROCESSOR_616033
  73. # define BOOST_HANA_PP_NARG(...) \
  74. BOOST_HANA_PP_CONCAT(BOOST_HANA_PP_NARG_IMPL(__VA_ARGS__, <%= (1..MAX_NUMBER_OF_MEMBERS).to_a.reverse.join(',') %>,),)
  75. #else
  76. # define BOOST_HANA_PP_NARG(...) \
  77. BOOST_HANA_PP_NARG_IMPL(__VA_ARGS__, <%= (1..MAX_NUMBER_OF_MEMBERS).to_a.reverse.join(',') %>,)
  78. #endif
  79. #define BOOST_HANA_PP_NARG_IMPL(<%= (1..MAX_NUMBER_OF_MEMBERS).to_a.map { |i| "e#{i}" }.join(',') %>, N, ...) N
  80. //////////////////////////////////////////////////////////////////////////////
  81. // BOOST_HANA_PP_BACK
  82. //////////////////////////////////////////////////////////////////////////////
  83. //! @ingroup group-details
  84. //! Expands to its last argument.
  85. #define BOOST_HANA_PP_BACK(...) \
  86. BOOST_HANA_PP_BACK_IMPL(BOOST_HANA_PP_NARG(__VA_ARGS__), __VA_ARGS__)
  87. #ifdef BOOST_HANA_WORKAROUND_MSVC_PREPROCESSOR_616033
  88. # define BOOST_HANA_PP_BACK_IMPL(N, ...) BOOST_HANA_PP_BACK_IMPL_I(N, __VA_ARGS__)
  89. # define BOOST_HANA_PP_BACK_IMPL_I(N, ...) \
  90. BOOST_HANA_PP_CONCAT(BOOST_HANA_PP_CONCAT(BOOST_HANA_PP_BACK_IMPL_, N)(__VA_ARGS__),)
  91. #else
  92. # define BOOST_HANA_PP_BACK_IMPL(N, ...) \
  93. BOOST_HANA_PP_CONCAT(BOOST_HANA_PP_BACK_IMPL_, N)(__VA_ARGS__)
  94. #endif
  95. <% (1..MAX_NUMBER_OF_MEMBERS).each do |n| %>
  96. #define BOOST_HANA_PP_BACK_IMPL_<%= n %>(<%= (1..n).to_a.map { |i| "e#{i}" }.join(', ') %>) e<%= n %>
  97. <% end %>
  98. //////////////////////////////////////////////////////////////////////////////
  99. // BOOST_HANA_PP_DROP_BACK
  100. //////////////////////////////////////////////////////////////////////////////
  101. //! @ingroup group-details
  102. //! Expands to all of its arguments, except for the last one.
  103. #define BOOST_HANA_PP_DROP_BACK(...) \
  104. BOOST_HANA_PP_DROP_BACK_IMPL(BOOST_HANA_PP_NARG(__VA_ARGS__), __VA_ARGS__)
  105. #ifdef BOOST_HANA_WORKAROUND_MSVC_PREPROCESSOR_616033
  106. # define BOOST_HANA_PP_DROP_BACK_IMPL(N, ...) BOOST_HANA_PP_DROP_BACK_IMPL_I(N, __VA_ARGS__)
  107. # define BOOST_HANA_PP_DROP_BACK_IMPL_I(N, ...) \
  108. BOOST_HANA_PP_CONCAT(BOOST_HANA_PP_CONCAT(BOOST_HANA_PP_DROP_BACK_IMPL_, N)(__VA_ARGS__),)
  109. #else
  110. # define BOOST_HANA_PP_DROP_BACK_IMPL(N, ...) \
  111. BOOST_HANA_PP_CONCAT(BOOST_HANA_PP_DROP_BACK_IMPL_, N)(__VA_ARGS__)
  112. #endif
  113. <% (1..MAX_NUMBER_OF_MEMBERS).each do |n| %>
  114. #define BOOST_HANA_PP_DROP_BACK_IMPL_<%= n %>(<%= (1..n).to_a.map { |i| "e#{i}" }.join(', ') %>)<%= (1..n-1).to_a.map { |i| "e#{i}" }.join(', ') %>
  115. <% end %>
  116. //////////////////////////////////////////////////////////////////////////////
  117. // BOOST_HANA_ADAPT_STRUCT
  118. //////////////////////////////////////////////////////////////////////////////
  119. template <typename ...>
  120. struct BOOST_HANA_ADAPT_STRUCT_must_be_called_in_the_global_namespace;
  121. #define BOOST_HANA_ADAPT_STRUCT(...) \
  122. template <> \
  123. struct BOOST_HANA_ADAPT_STRUCT_must_be_called_in_the_global_namespace<>; \
  124. BOOST_HANA_ADAPT_STRUCT_IMPL(BOOST_HANA_PP_NARG(__VA_ARGS__), __VA_ARGS__)\
  125. static_assert(true, "force the usage of a trailing semicolon") \
  126. /**/
  127. #ifdef BOOST_HANA_WORKAROUND_MSVC_PREPROCESSOR_616033
  128. # define BOOST_HANA_ADAPT_STRUCT_IMPL(N, ...) BOOST_HANA_ADAPT_STRUCT_IMPL_I(N, __VA_ARGS__)
  129. # define BOOST_HANA_ADAPT_STRUCT_IMPL_I(N, ...) \
  130. BOOST_HANA_PP_CONCAT(BOOST_HANA_PP_CONCAT(BOOST_HANA_ADAPT_STRUCT_IMPL_, N)(__VA_ARGS__),)
  131. #else
  132. # define BOOST_HANA_ADAPT_STRUCT_IMPL(N, ...) \
  133. BOOST_HANA_PP_CONCAT(BOOST_HANA_ADAPT_STRUCT_IMPL_, N)(__VA_ARGS__)
  134. #endif
  135. <% (0..MAX_NUMBER_OF_MEMBERS).each do |n| %>
  136. #define BOOST_HANA_ADAPT_STRUCT_IMPL_<%= n+1 %>(TYPE <%= (1..n).map { |i| ", m#{i}" }.join %>) \
  137. namespace boost { namespace hana { \
  138. template <> \
  139. struct accessors_impl<TYPE> { \
  140. static constexpr auto apply() { \
  141. struct member_names { \
  142. static constexpr auto get() { \
  143. return ::boost::hana::make_tuple( \
  144. <%= (1..n).map { |i| "BOOST_HANA_PP_STRINGIZE(m#{i})" }.join(', ') %> \
  145. ); \
  146. } \
  147. }; \
  148. return ::boost::hana::make_tuple( \
  149. <%= (1..n).map { |i| "::boost::hana::make_pair(::boost::hana::struct_detail::prepare_member_name<#{i-1}, member_names>(), ::boost::hana::struct_detail::member_ptr<decltype(&TYPE::m#{i}), &TYPE::m#{i}>{})" }.join(', ') %>\
  150. ); \
  151. } \
  152. }; \
  153. }} \
  154. /**/
  155. <% end %>
  156. //////////////////////////////////////////////////////////////////////////////
  157. // BOOST_HANA_ADAPT_ADT
  158. //////////////////////////////////////////////////////////////////////////////
  159. template <typename ...>
  160. struct BOOST_HANA_ADAPT_ADT_must_be_called_in_the_global_namespace;
  161. #define BOOST_HANA_ADAPT_ADT(...) \
  162. template <> \
  163. struct BOOST_HANA_ADAPT_ADT_must_be_called_in_the_global_namespace<>; \
  164. BOOST_HANA_ADAPT_ADT_IMPL(BOOST_HANA_PP_NARG(__VA_ARGS__), __VA_ARGS__) \
  165. static_assert(true, "force the usage of a trailing semicolon") \
  166. /**/
  167. #ifdef BOOST_HANA_WORKAROUND_MSVC_PREPROCESSOR_616033
  168. # define BOOST_HANA_ADAPT_ADT_IMPL(N, ...) BOOST_HANA_ADAPT_ADT_IMPL_I(N, __VA_ARGS__)
  169. # define BOOST_HANA_ADAPT_ADT_IMPL_I(N, ...) \
  170. BOOST_HANA_PP_CONCAT(BOOST_HANA_PP_CONCAT(BOOST_HANA_ADAPT_ADT_IMPL_, N)(__VA_ARGS__),)
  171. #else
  172. # define BOOST_HANA_ADAPT_ADT_IMPL(N, ...) \
  173. BOOST_HANA_PP_CONCAT(BOOST_HANA_ADAPT_ADT_IMPL_, N)(__VA_ARGS__)
  174. #endif
  175. <% (0..MAX_NUMBER_OF_MEMBERS).each do |n| %>
  176. #define BOOST_HANA_ADAPT_ADT_IMPL_<%= n+1 %>(TYPE <%= (1..n).map { |i| ", m#{i}" }.join %>) \
  177. namespace boost { namespace hana { \
  178. template <> \
  179. struct accessors_impl<TYPE> { \
  180. template <typename ...> \
  181. static constexpr auto apply() { \
  182. struct member_names { \
  183. static constexpr auto get() { \
  184. return ::boost::hana::make_tuple( \
  185. <%= (1..n).map { |i| "BOOST_HANA_PP_STRINGIZE(BOOST_HANA_PP_FRONT m#{i})" }.join(', ') %>\
  186. ); \
  187. } \
  188. }; \
  189. return ::boost::hana::make_tuple( \
  190. <%= (1..n).map { |i| "::boost::hana::make_pair(::boost::hana::struct_detail::prepare_member_name<#{i-1}, member_names>(), BOOST_HANA_PP_DROP_FRONT m#{i})" }.join(', ') %>\
  191. ); \
  192. } \
  193. }; \
  194. }} \
  195. /**/
  196. <% end %>
  197. //////////////////////////////////////////////////////////////////////////////
  198. // BOOST_HANA_DEFINE_STRUCT
  199. //////////////////////////////////////////////////////////////////////////////
  200. #define BOOST_HANA_DEFINE_STRUCT(...) \
  201. BOOST_HANA_DEFINE_STRUCT_IMPL(BOOST_HANA_PP_NARG(__VA_ARGS__), __VA_ARGS__)
  202. #ifdef BOOST_HANA_WORKAROUND_MSVC_PREPROCESSOR_616033
  203. # define BOOST_HANA_DEFINE_STRUCT_IMPL(N, ...) BOOST_HANA_DEFINE_STRUCT_IMPL_I(N, __VA_ARGS__)
  204. # define BOOST_HANA_DEFINE_STRUCT_IMPL_I(N, ...) \
  205. BOOST_HANA_PP_CONCAT(BOOST_HANA_PP_CONCAT(BOOST_HANA_DEFINE_STRUCT_IMPL_, N)(__VA_ARGS__),)
  206. #else
  207. # define BOOST_HANA_DEFINE_STRUCT_IMPL(N, ...) \
  208. BOOST_HANA_PP_CONCAT(BOOST_HANA_DEFINE_STRUCT_IMPL_, N)(__VA_ARGS__)
  209. #endif
  210. <% (0..MAX_NUMBER_OF_MEMBERS).each do |n| %>
  211. #define BOOST_HANA_DEFINE_STRUCT_IMPL_<%= n+1 %>(TYPE <%= (1..n).map { |i| ", m#{i}" }.join %>) \
  212. <%= (1..n).map { |i| "BOOST_HANA_PP_DROP_BACK m#{i} BOOST_HANA_PP_BACK m#{i};" }.join(' ') %> \
  213. \
  214. struct hana_accessors_impl { \
  215. static constexpr auto apply() { \
  216. struct member_names { \
  217. static constexpr auto get() { \
  218. return ::boost::hana::make_tuple( \
  219. <%= (1..n).map { |i| "BOOST_HANA_PP_STRINGIZE(BOOST_HANA_PP_BACK m#{i})" }.join(', ') %>\
  220. ); \
  221. } \
  222. }; \
  223. return ::boost::hana::make_tuple( \
  224. <%= (1..n).map { |i| "::boost::hana::make_pair(::boost::hana::struct_detail::prepare_member_name<#{i-1}, member_names>(), ::boost::hana::struct_detail::member_ptr<decltype(&TYPE::BOOST_HANA_PP_BACK m#{i}), &TYPE::BOOST_HANA_PP_BACK m#{i}>{})" }.join(', ') %>\
  225. ); \
  226. } \
  227. } \
  228. /**/
  229. <% end %>
  230. #endif // !BOOST_HANA_DETAIL_STRUCT_MACROS_HPP