1 2 #if !defined(BOOST_PP_IS_ITERATING) 3 4 ///// header body 5 6 #ifndef BOOST_MPL_AUX_TEMPLATE_ARITY_HPP_INCLUDED 7 #define BOOST_MPL_AUX_TEMPLATE_ARITY_HPP_INCLUDED 8 9 // Copyright Aleksey Gurtovoy 2001-2004 10 // 11 // Distributed under the Boost Software License, Version 1.0. 12 // (See accompanying file LICENSE_1_0.txt or copy at 13 // http://www.boost.org/LICENSE_1_0.txt) 14 // 15 // See http://www.boost.org/libs/mpl for documentation. 16 17 // $Id$ 18 // $Date$ 19 // $Revision$ 20 21 #include <boost/mpl/aux_/config/ttp.hpp> 22 #include <boost/mpl/aux_/config/lambda.hpp> 23 24 #if !defined(BOOST_MPL_PREPROCESSING_MODE) 25 # include <boost/mpl/aux_/template_arity_fwd.hpp> 26 # include <boost/mpl/int.hpp> 27 # if !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT) 28 # if defined(BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING) 29 # include <boost/mpl/aux_/type_wrapper.hpp> 30 # endif 31 # else 32 # include <boost/mpl/aux_/has_rebind.hpp> 33 # endif 34 #endif 35 36 #include <boost/mpl/aux_/config/static_constant.hpp> 37 #include <boost/mpl/aux_/config/use_preprocessed.hpp> 38 39 #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ 40 && !defined(BOOST_MPL_PREPROCESSING_MODE) 41 42 # define BOOST_MPL_PREPROCESSED_HEADER template_arity.hpp 43 # include <boost/mpl/aux_/include_preprocessed.hpp> 44 45 #else 46 47 # if !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT) 48 # if defined(BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING) 49 50 # include <boost/mpl/limits/arity.hpp> 51 # include <boost/mpl/aux_/preprocessor/range.hpp> 52 # include <boost/mpl/aux_/preprocessor/repeat.hpp> 53 # include <boost/mpl/aux_/preprocessor/params.hpp> 54 # include <boost/mpl/aux_/nttp_decl.hpp> 55 56 # include <boost/preprocessor/seq/fold_left.hpp> 57 # include <boost/preprocessor/comma_if.hpp> 58 # include <boost/preprocessor/iterate.hpp> 59 # include <boost/preprocessor/inc.hpp> 60 # include <boost/preprocessor/cat.hpp> 61 62 # define AUX778076_ARITY BOOST_PP_INC(BOOST_MPL_LIMIT_METAFUNCTION_ARITY) 63 64 namespace boost { namespace mpl { namespace aux { 65 66 template< BOOST_MPL_AUX_NTTP_DECL(int, N) > struct arity_tag 67 { 68 typedef char (&type)[N + 1]; 69 }; 70 71 # define AUX778076_MAX_ARITY_OP(unused, state, i_) \ 72 ( BOOST_PP_CAT(C,i_) > 0 ? BOOST_PP_CAT(C,i_) : state ) \ 73 /**/ 74 75 template< 76 BOOST_MPL_PP_PARAMS(AUX778076_ARITY, BOOST_MPL_AUX_NTTP_DECL(int, C)) 77 > 78 struct max_arity 79 { 80 BOOST_STATIC_CONSTANT(int, value = 81 BOOST_PP_SEQ_FOLD_LEFT( 82 AUX778076_MAX_ARITY_OP 83 , -1 84 , BOOST_MPL_PP_RANGE(1, AUX778076_ARITY) 85 ) 86 ); 87 }; 88 89 # undef AUX778076_MAX_ARITY_OP 90 91 arity_tag<0>::type arity_helper(...); 92 93 # define BOOST_PP_ITERATION_LIMITS (1, AUX778076_ARITY) 94 # define BOOST_PP_FILENAME_1 <boost/mpl/aux_/template_arity.hpp> 95 # include BOOST_PP_ITERATE() 96 97 template< typename F, BOOST_MPL_AUX_NTTP_DECL(int, N) > 98 struct template_arity_impl 99 { 100 BOOST_STATIC_CONSTANT(int, value = 101 sizeof(::boost::mpl::aux::arity_helper(type_wrapper<F>(),arity_tag<N>())) - 1 102 ); 103 }; 104 105 # define AUX778076_TEMPLATE_ARITY_IMPL_INVOCATION(unused, i_, F) \ 106 BOOST_PP_COMMA_IF(i_) template_arity_impl<F,BOOST_PP_INC(i_)>::value \ 107 /**/ 108 109 template< typename F > 110 struct template_arity 111 { 112 BOOST_STATIC_CONSTANT(int, value = ( 113 max_arity< BOOST_MPL_PP_REPEAT( 114 AUX778076_ARITY 115 , AUX778076_TEMPLATE_ARITY_IMPL_INVOCATION 116 , F 117 ) >::value 118 )); 119 120 typedef mpl::int_<value> type; 121 }; 122 123 # undef AUX778076_TEMPLATE_ARITY_IMPL_INVOCATION 124 125 # undef AUX778076_ARITY 126 127 }}} 128 129 # endif // BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING 130 # else // BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT 131 132 # include <boost/mpl/aux_/config/eti.hpp> 133 134 namespace boost { namespace mpl { namespace aux { 135 136 template< bool > 137 struct template_arity_impl 138 { 139 template< typename F > struct result_ 140 : mpl::int_<-1> 141 { 142 }; 143 }; 144 145 template<> 146 struct template_arity_impl<true> 147 { 148 template< typename F > struct result_ 149 : F::arity 150 { 151 }; 152 }; 153 154 template< typename F > 155 struct template_arity 156 : template_arity_impl< ::boost::mpl::aux::has_rebind<F>::value > 157 ::template result_<F> 158 { 159 }; 160 161 #if defined(BOOST_MPL_CFG_MSVC_ETI_BUG) 162 template<> 163 struct template_arity<int> 164 : mpl::int_<-1> 165 { 166 }; 167 #endif 168 169 }}} 170 171 # endif // BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT 172 173 #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS 174 #endif // BOOST_MPL_AUX_TEMPLATE_ARITY_HPP_INCLUDED 175 176 ///// iteration 177 178 #else 179 #define i_ BOOST_PP_FRAME_ITERATION(1) 180 181 template< 182 template< BOOST_MPL_PP_PARAMS(i_, typename P) > class F 183 , BOOST_MPL_PP_PARAMS(i_, typename T) 184 > 185 typename arity_tag<i_>::type 186 arity_helper(type_wrapper< F<BOOST_MPL_PP_PARAMS(i_, T)> >, arity_tag<i_>); 187 188 #undef i_ 189 #endif // BOOST_PP_IS_ITERATING 190