preprocessor.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #pragma once
  2. /*!
  3. * \file preprocessor.h
  4. * \brief Preprocessor metaprogramming macros
  5. */
  6. #if !defined(_MSC_VER) && !defined(__GNUC__)
  7. # error Your compiler is not currently supported.
  8. #endif
  9. /*!
  10. * \defgroup yt_pp Preprocessor metaprogramming macros
  11. * \ingroup yt_commons
  12. *
  13. * This is collection of macro definitions for various metaprogramming tasks
  14. * with the preprocessor.
  15. *
  16. * \{
  17. *
  18. * \page yt_pp_sequences Sequences
  19. * Everything revolves around the concept of a \em sequence. A typical
  20. * sequence is encoded like <tt>(1)(2)(3)...</tt>. Internally this allows
  21. * to apply some macro to the every element in the sequence (see #PP_FOR_EACH).
  22. *
  23. * Note that sequences can be nested, i. e. <tt>((1)(2)(3))(a)(b)(c)</tt>
  24. *
  25. * \page yt_pp_examples Examples
  26. * Please refer to the unit test for an actual example of usage
  27. * (unittests/preprocessor_ut.cpp).
  28. *
  29. */
  30. //! Concatenates two tokens.
  31. #define PP_CONCAT(x, y) PP_CONCAT_A(x, y)
  32. //! \cond Implementation
  33. #define PP_CONCAT_A(x, y) PP_CONCAT_B(x, y)
  34. #define PP_CONCAT_B(x, y) x ## y
  35. //! \endcond
  36. //! Transforms token into the string forcing argument expansion.
  37. #define PP_STRINGIZE(x) PP_STRINGIZE_A(x)
  38. //! \cond Implementation
  39. #define PP_STRINGIZE_A(x) PP_STRINGIZE_B(x)
  40. #define PP_STRINGIZE_B(x) #x
  41. //! \endcond
  42. //! \cond Implementation
  43. #define PP_LEFT_PARENTHESIS (
  44. #define PP_RIGHT_PARENTHESIS )
  45. #define PP_COMMA() ,
  46. #define PP_EMPTY()
  47. //! \endcond
  48. //! Removes the enclosing parens, if any.
  49. #define PP_DEPAREN(...) PP_DEPAREN_A(PP_DEPAREN_C __VA_ARGS__)
  50. //! \cond Implementation
  51. #define PP_DEPAREN_C(...) PP_DEPAREN_C __VA_ARGS__
  52. #define PP_DEPAREN_A(...) PP_DEPAREN_B(__VA_ARGS__)
  53. #define PP_DEPAREN_B(...) PP_DEPAREN_D_ ## __VA_ARGS__
  54. #define PP_DEPAREN_D_PP_DEPAREN_C
  55. //! \endcond
  56. //! Performs (non-lazy) conditional expansion.
  57. /*!
  58. * \param cond Condition; should expands to either \c PP_TRUE or \c PP_FALSE.
  59. * \param _then Expansion result in case when \c cond holds.
  60. * \param _else Expansion result in case when \c cond does not hold.
  61. */
  62. #define PP_IF(cond, _then, _else) PP_CONCAT(PP_IF_, cond)(_then, _else)
  63. //! \cond Implementation
  64. #define PP_IF_PP_TRUE(x, y) x
  65. #define PP_IF_PP_FALSE(x, y) y
  66. //! \endcond
  67. //! Tests whether supplied argument can be treated as a sequence
  68. //! (i. e. <tt>()()()...</tt>)
  69. #define PP_IS_SEQUENCE(arg) PP_CONCAT(PP_IS_SEQUENCE_B_, PP_COUNT((PP_NIL PP_IS_SEQUENCE_A arg PP_NIL)))
  70. //! \cond Implementation
  71. #define PP_IS_SEQUENCE_A(_) PP_RIGHT_PARENTHESIS PP_LEFT_PARENTHESIS
  72. #define PP_IS_SEQUENCE_B_1 PP_FALSE
  73. #define PP_IS_SEQUENCE_B_2 PP_TRUE
  74. //! \endcond
  75. //! Computes the number of elements in the sequence.
  76. #define PP_COUNT(...) PP_COUNT_IMPL(__VA_ARGS__)
  77. //! Removes first \c n elements from the sequence.
  78. #define PP_KILL(seq, n) PP_KILL_IMPL(seq, n)
  79. //! Extracts the head of the sequence.
  80. /*! For example, \code PP_HEAD((0)(1)(2)(3)) == 0 \endcode
  81. */
  82. #define PP_HEAD(...) PP_HEAD_IMPL(__VA_ARGS__)
  83. //! Extracts the tail of the sequence.
  84. /*! For example, \code PP_TAIL((0)(1)(2)(3)) == (1)(2)(3) \endcode
  85. */
  86. #define PP_TAIL(...) PP_TAIL_IMPL(__VA_ARGS__)
  87. //! Extracts the element with the specified index from the sequence.
  88. /*! For example, \code PP_ELEMENT((0)(1)(2)(3), 1) == 1 \endcode
  89. */
  90. #define PP_ELEMENT(seq, index) PP_ELEMENT_IMPL(seq, index)
  91. //! Applies the macro to every member of the sequence.
  92. /*! For example,
  93. * \code
  94. * #define MyFunctor(x) +x+
  95. * PP_FOR_EACH(MyFunctor, (0)(1)(2)(3)) == +0+ +1+ +2+ +3+
  96. * \encode
  97. */
  98. #define PP_FOR_EACH(what, seq) PP_FOR_EACH_IMPL(what, seq)
  99. //! Declares an anonymous variable.
  100. #ifdef __COUNTER__
  101. #define PP_ANONYMOUS_VARIABLE(str) PP_CONCAT(str, __COUNTER__)
  102. #else
  103. #define PP_ANONYMOUS_VARIABLE(str) PP_CONCAT(str, __LINE__)
  104. #endif
  105. //! Insert prefix based on presence of additional arguments.
  106. #define PP_ONE_OR_NONE(a, ...) PP_THIRD(a, ## __VA_ARGS__, a)
  107. #define PP_THIRD(a, b, ...) __VA_ARGS__
  108. //! \cond Implementation
  109. #define PREPROCESSOR_GEN_H_
  110. #include "preprocessor-gen.h"
  111. #undef PREPROCESSOR_GEN_H_
  112. //! \endcond
  113. /*! \} */