1 //============================================================================== 2 // Copyright 2003 - 2011 LASMEA UMR 6602 CNRS/Univ. Clermont II 3 // Copyright 2009 - 2011 LRI UMR 8623 CNRS/Univ Paris Sud XI 4 // Copyright 2011 Eric Niebler 5 // 6 // Distributed under the Boost Software License, Version 1.0. 7 // See accompanying file LICENSE.txt or copy at 8 // http://www.boost.org/LICENSE_1_0.txt 9 //============================================================================== 10 #ifndef BOOST_PROTO_PREPROCESSOR_REMOVE_TYPENAME_HPP_INCLUDED 11 #define BOOST_PROTO_PREPROCESSOR_REMOVE_TYPENAME_HPP_INCLUDED 12 13 /*! 14 * \file 15 * \brief Defines the BOOST_PROTO_REMOVE_TYPENAME macro 16 */ 17 #include <boost/preprocessor/cat.hpp> 18 #include <boost/preprocessor/expand.hpp> 19 #include <boost/preprocessor/tuple/eat.hpp> 20 #include <boost/preprocessor/control/iif.hpp> 21 #include <boost/preprocessor/detail/is_unary.hpp> 22 23 //============================================================================== 24 // Boost.Preprocessor author P. Mensodines confirmed on an Boost email thread 25 // (subject ``check if a token is a keyword (was "BOOST_PP_IS_UNARY()")'') 26 // that it is OK to used `PP_IS_UNARY()` to check if tokens match predefined 27 // "keyword" as it is done by the macros below (even if `PP_IS_UNARY()` is 28 // technically only part of Boost.Preprocessor private API). 29 //============================================================================== 30 31 //============================================================================== 32 // `checking_prefix ## tokens` expand to unary (e.g., `(1)`) iff `tokens` start 33 // with keyword to check. 34 //============================================================================== 35 #define BOOST_PROTO_DETAILS_KEYWORD_FACILITY_IS_FRONT(T, CHECKING_PREFIX) \ 36 BOOST_PP_IS_UNARY(BOOST_PP_CAT(CHECKING_PREFIX, T)) \ 37 /**/ 38 39 //============================================================================== 40 // `is_front_macro(tokens)` is 1 iff `tokens` start with keyword to remove. 41 // `removing_prefix ## <keyword-to-remove>` must expand to nothing. 42 //============================================================================== 43 #define BOOST_PROTO_DETAILS_KEYWORD_FACILITY_REMOVE_FRONT(TOKENS, IS_FRONT_MACRO, REMOVING_PREFIX) \ 44 BOOST_PP_EXPAND( /* without EXPAND doesn't expand on MSVC */ \ 45 BOOST_PP_IIF( \ 46 IS_FRONT_MACRO(TOKENS) \ 47 , BOOST_PP_CAT \ 48 , TOKENS BOOST_PP_TUPLE_EAT(2) \ 49 )(REMOVING_PREFIX, TOKENS) \ 50 ) \ 51 /**/ 52 53 #define BOOST_PROTO_DETAILS_KEYWORD_TYPENAME_IS_typename (1) /* unary */ 54 #define typename_BOOST_PROTO_DETAILS_KEYWORD_TYPENAME_IS (1) /* unary */ 55 #define BOOST_PROTO_DETAILS_KEYWORD_TYPENAME_REMOVE_typename /* nothing */ 56 #define typename_BOOST_PROTO_DETAILS_KEYWORD_TYPENAME_REMOVE /* nothing */ 57 58 #define BOOST_PROTO_DETAILS_KEYWORD_IS_TYPENAME_FRONT(TOKENS) \ 59 BOOST_PROTO_DETAILS_KEYWORD_FACILITY_IS_FRONT(TOKENS, BOOST_PROTO_DETAILS_KEYWORD_TYPENAME_IS_) \ 60 /**/ 61 62 //============================================================================== 63 /*! 64 * \ingroup preprocessor 65 * For any symbol \c X, this macro returns the same symbol from which a potential 66 * leading \c typename keyword has been removed. If no typename keyword is present, 67 * this macros evaluates to \c X itself without error. 68 * 69 * The original implementation of this macro is from Lorenzo Caminiti. 70 * 71 * \param X Symbol to remove \c typename from 72 */ 73 //============================================================================== 74 #define BOOST_PROTO_REMOVE_TYPENAME(X) \ 75 BOOST_PROTO_DETAILS_KEYWORD_FACILITY_REMOVE_FRONT( \ 76 X \ 77 , BOOST_PROTO_DETAILS_KEYWORD_IS_TYPENAME_FRONT \ 78 , BOOST_PROTO_DETAILS_KEYWORD_TYPENAME_REMOVE_ \ 79 ) \ 80 /**/ 81 82 #endif 83