• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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