variant_fwd.hpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. //-----------------------------------------------------------------------------
  2. // boost variant/variant_fwd.hpp header file
  3. // See http://www.boost.org for updates, documentation, and revision history.
  4. //-----------------------------------------------------------------------------
  5. //
  6. // Copyright (c) 2003 Eric Friedman, Itay Maman
  7. // Copyright (c) 2013-2024 Antony Polukhin
  8. //
  9. // Distributed under the Boost Software License, Version 1.0. (See
  10. // accompanying file LICENSE_1_0.txt or copy at
  11. // http://www.boost.org/LICENSE_1_0.txt)
  12. #ifndef BOOST_VARIANT_VARIANT_FWD_HPP
  13. #define BOOST_VARIANT_VARIANT_FWD_HPP
  14. #include <boost/variant/detail/config.hpp>
  15. #include <boost/blank_fwd.hpp>
  16. #include <boost/mpl/arg.hpp>
  17. #include <boost/mpl/limits/arity.hpp>
  18. #include <boost/mpl/aux_/na.hpp>
  19. #include <boost/preprocessor/cat.hpp>
  20. #include <boost/preprocessor/enum.hpp>
  21. #include <boost/preprocessor/enum_params.hpp>
  22. #include <boost/preprocessor/enum_shifted_params.hpp>
  23. #include <boost/preprocessor/repeat.hpp>
  24. ///////////////////////////////////////////////////////////////////////////////
  25. // macro BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT
  26. //
  27. // Defined if make_recursive_variant cannot be supported as documented.
  28. //
  29. // Note: Currently, MPL lambda facility is used as workaround if defined, and
  30. // so only types declared w/ MPL lambda workarounds will work.
  31. //
  32. #include <boost/variant/detail/substitute_fwd.hpp>
  33. #include <boost/preprocessor/seq/size.hpp>
  34. #define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_class class)(
  35. #define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_typename typename)(
  36. #define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_VARIADIC_class class...
  37. #define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_VARIADIC_typename typename...
  38. #define ARGS_VARIADER_1(x) x ## N...
  39. #define ARGS_VARIADER_2(x) BOOST_VARIANT_CLASS_OR_TYPENAME_TO_VARIADIC_ ## x ## N
  40. #define BOOST_VARIANT_MAKE_VARIADIC(sequence, x) BOOST_VARIANT_MAKE_VARIADIC_I(BOOST_PP_SEQ_SIZE(sequence), x)
  41. #define BOOST_VARIANT_MAKE_VARIADIC_I(argscount, x) BOOST_VARIANT_MAKE_VARIADIC_II(argscount, x)
  42. #define BOOST_VARIANT_MAKE_VARIADIC_II(argscount, orig) ARGS_VARIADER_ ## argscount(orig)
  43. ///////////////////////////////////////////////////////////////////////////////
  44. // BOOST_VARIANT_ENUM_PARAMS and BOOST_VARIANT_ENUM_SHIFTED_PARAMS
  45. //
  46. // Convenience macro for enumeration of variant params.
  47. // When variadic templates are available expands:
  48. // BOOST_VARIANT_ENUM_PARAMS(class Something) => class Something0, class... SomethingN
  49. // BOOST_VARIANT_ENUM_PARAMS(typename Something) => typename Something0, typename... SomethingN
  50. // BOOST_VARIANT_ENUM_PARAMS(Something) => Something0, SomethingN...
  51. // BOOST_VARIANT_ENUM_PARAMS(Something) => Something0, SomethingN...
  52. // BOOST_VARIANT_ENUM_SHIFTED_PARAMS(class Something) => class... SomethingN
  53. // BOOST_VARIANT_ENUM_SHIFTED_PARAMS(typename Something) => typename... SomethingN
  54. // BOOST_VARIANT_ENUM_SHIFTED_PARAMS(Something) => SomethingN...
  55. // BOOST_VARIANT_ENUM_SHIFTED_PARAMS(Something) => SomethingN...
  56. //
  57. // Rationale: Cleaner, simpler code for clients of variant library. Minimal
  58. // code modifications to move from C++03 to C++11.
  59. //
  60. #define BOOST_VARIANT_ENUM_PARAMS(x) \
  61. x ## 0, \
  62. BOOST_VARIANT_MAKE_VARIADIC( (BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_ ## x), x) \
  63. /**/
  64. #define BOOST_VARIANT_ENUM_SHIFTED_PARAMS(x) \
  65. BOOST_VARIANT_MAKE_VARIADIC( (BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_ ## x), x) \
  66. /**/
  67. namespace boost {
  68. namespace detail { namespace variant {
  69. ///////////////////////////////////////////////////////////////////////////////
  70. // (detail) class void_ and class template convert_void
  71. //
  72. // Provides the mechanism by which void(NN) types are converted to
  73. // mpl::void_ (and thus can be passed to mpl::list).
  74. //
  75. // Rationale: This is particularly needed for the using-declarations
  76. // workaround (below), but also to avoid associating mpl namespace with
  77. // variant in argument dependent lookups (which used to happen because of
  78. // defaulting of template parameters to mpl::void_).
  79. //
  80. struct void_;
  81. template <typename T>
  82. struct convert_void
  83. {
  84. typedef T type;
  85. };
  86. template <>
  87. struct convert_void< void_ >
  88. {
  89. typedef mpl::na type;
  90. };
  91. }} // namespace detail::variant
  92. #define BOOST_VARIANT_AUX_DECLARE_PARAMS BOOST_VARIANT_ENUM_PARAMS(typename T)
  93. ///////////////////////////////////////////////////////////////////////////////
  94. // class template variant (concept inspired by Andrei Alexandrescu)
  95. //
  96. // Efficient, type-safe bounded discriminated union.
  97. //
  98. // Preconditions:
  99. // - Each type must be unique.
  100. // - No type may be const-qualified.
  101. //
  102. // Proper declaration form:
  103. // variant<types> (where types is a type-sequence)
  104. // or
  105. // variant<T0,T1,...,Tn> (where T0 is NOT a type-sequence)
  106. //
  107. template < BOOST_VARIANT_AUX_DECLARE_PARAMS > class variant;
  108. ///////////////////////////////////////////////////////////////////////////////
  109. // metafunction make_recursive_variant
  110. //
  111. // Exposes a boost::variant with recursive_variant_ tags (below) substituted
  112. // with the variant itself (wrapped as needed with boost::recursive_wrapper).
  113. //
  114. template < BOOST_VARIANT_AUX_DECLARE_PARAMS > struct make_recursive_variant;
  115. #undef BOOST_VARIANT_AUX_DECLARE_PARAMS_IMPL
  116. #undef BOOST_VARIANT_AUX_DECLARE_PARAMS
  117. ///////////////////////////////////////////////////////////////////////////////
  118. // type recursive_variant_
  119. //
  120. // Tag type indicates where recursive variant substitution should occur.
  121. //
  122. #if !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
  123. struct recursive_variant_ {};
  124. #else
  125. typedef mpl::arg<1> recursive_variant_;
  126. #endif
  127. ///////////////////////////////////////////////////////////////////////////////
  128. // metafunction make_variant_over
  129. //
  130. // Result is a variant w/ types of the specified type sequence.
  131. //
  132. template <typename Types> struct make_variant_over;
  133. ///////////////////////////////////////////////////////////////////////////////
  134. // metafunction make_recursive_variant_over
  135. //
  136. // Result is a recursive variant w/ types of the specified type sequence.
  137. //
  138. template <typename Types> struct make_recursive_variant_over;
  139. } // namespace boost
  140. #endif // BOOST_VARIANT_VARIANT_FWD_HPP