blob: 350052456f426ba9d9f0cd76b40442a395b9de54 [file] [log] [blame]
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
//
// This example implements a utility to accept a type expression, that may
// contain commas to a macro.
//
//
// Detailed description
// ====================
//
// Accepting a type as macro argument can cause problems if the type expression
// contains commas:
//
// #define MY_MACRO(a_type)
// ...
// MY_MACRO(std::map<int,int>) // ERROR (wrong number of macro arguments)
//
// This problem can be solved by pasing using a parenthesized type
//
// MY_MACRO((std::map<int,int>) // OK
//
// but then there is no way to remove the parentheses in the macro argument
// with the preprocessor.
// We can, however, form a pointer to a function with a single argument (the
// parentheses become part of the type) and extract the argument with template
// metaprogramming:
//
// // Inside the macro definition
//
// typename mpl::front< parameter_types<void(*)a_type> >::type
//
// This code snippet does not read too expressive so we use another macro
// to encapsulate the solution:
//
// // Inside the macro definition
//
// BOOST_EXAMPLE_MACRO_TYPE_ARGUMENT(a_type)
//
// As a generalization of this technique we can accept a comma-separated list of
// types. Omitting the mpl::front invocation gives us an MPL-sequence.
//
//
// Limitations
// ===========
//
// - only works for types that are valid function arguments
//
// Acknowledgments
// ===============
//
// Thanks go to Dave Abrahams for letting me know this technique.
#ifndef BOOST_EXAMPLE_MACRO_TYPE_ARGUMENT_HPP_INCLUDED
#define BOOST_EXAMPLE_MACRO_TYPE_ARGUMENT_HPP_INCLUDED
#include <boost/function_types/parameter_types.hpp>
#include <boost/mpl/front.hpp>
#define BOOST_EXAMPLE_MACRO_TYPE_ARGUMENT(parenthesized_type) \
boost::mpl::front< \
BOOST_EXAMPLE_MACRO_TYPE_LIST_ARGUMENT(parenthesized_type) >::type
#define BOOST_EXAMPLE_MACRO_TYPE_LIST_ARGUMENT(parenthesized_types) \
::boost::function_types::parameter_types< void(*) parenthesized_types >
#endif