macro_type_args.hpp 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. // (C) Copyright Tobias Schwinger
  2. //
  3. // Use modification and distribution are subject to the boost Software License,
  4. // Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
  5. //------------------------------------------------------------------------------
  6. //
  7. // This example implements a utility to accept a type expression, that may
  8. // contain commas to a macro.
  9. //
  10. //
  11. // Detailed description
  12. // ====================
  13. //
  14. // Accepting a type as macro argument can cause problems if the type expression
  15. // contains commas:
  16. //
  17. // #define MY_MACRO(a_type)
  18. // ...
  19. // MY_MACRO(std::map<int,int>) // ERROR (wrong number of macro arguments)
  20. //
  21. // This problem can be solved by pasing using a parenthesized type
  22. //
  23. // MY_MACRO((std::map<int,int>) // OK
  24. //
  25. // but then there is no way to remove the parentheses in the macro argument
  26. // with the preprocessor.
  27. // We can, however, form a pointer to a function with a single argument (the
  28. // parentheses become part of the type) and extract the argument with template
  29. // metaprogramming:
  30. //
  31. // // Inside the macro definition
  32. //
  33. // typename mpl::front< parameter_types<void(*)a_type> >::type
  34. //
  35. // This code snippet does not read too expressive so we use another macro
  36. // to encapsulate the solution:
  37. //
  38. // // Inside the macro definition
  39. //
  40. // BOOST_EXAMPLE_MACRO_TYPE_ARGUMENT(a_type)
  41. //
  42. // As a generalization of this technique we can accept a comma-separated list of
  43. // types. Omitting the mpl::front invocation gives us an MPL-sequence.
  44. //
  45. //
  46. // Limitations
  47. // ===========
  48. //
  49. // - only works for types that are valid function arguments
  50. //
  51. // Acknowledgments
  52. // ===============
  53. //
  54. // Thanks go to Dave Abrahams for letting me know this technique.
  55. #ifndef BOOST_EXAMPLE_MACRO_TYPE_ARGUMENT_HPP_INCLUDED
  56. #define BOOST_EXAMPLE_MACRO_TYPE_ARGUMENT_HPP_INCLUDED
  57. #include <boost/function_types/parameter_types.hpp>
  58. #include <boost/mpl/front.hpp>
  59. #define BOOST_EXAMPLE_MACRO_TYPE_ARGUMENT(parenthesized_type) \
  60. boost::mpl::front< \
  61. BOOST_EXAMPLE_MACRO_TYPE_LIST_ARGUMENT(parenthesized_type) >::type
  62. #define BOOST_EXAMPLE_MACRO_TYPE_LIST_ARGUMENT(parenthesized_types) \
  63. ::boost::function_types::parameter_types< void(*) parenthesized_types >
  64. #endif