Parent Directory
|
Revision Log
initial version. Needs work to eliminate need for mpl::vector. Maybe ideas from move_ptr of enable_if.
1 //macros to generate CTOR forwarding methods 2 #ifndef BOOST_MANAGED_PTR_PP_CTOR_FORWARDER_HPP_LJE20040327 3 #define BOOST_MANAGED_PTR_PP_CTOR_FORWARDER_HPP_LJE20040327 4 #include <boost/preprocessor/arithmetic/inc.hpp> 5 #include <boost/preprocessor/cat.hpp> 6 #include <boost/preprocessor/control/iif.hpp> 7 #include <boost/preprocessor/punctuation/comma_if.hpp> 8 #include <boost/preprocessor/repetition/enum.hpp> 9 #include <boost/preprocessor/repetition/enum_params.hpp> 10 #include <boost/preprocessor/repetition/enum_trailing_params.hpp> 11 #include <boost/preprocessor/repetition/repeat.hpp> 12 #include <boost/preprocessor/seq/elem.hpp> 13 #include <boost/preprocessor/seq/fold_right.hpp> 14 #include <boost/preprocessor/seq/rest_n.hpp> 15 #include <boost/preprocessor/tuple/rem.hpp> 16 #include <boost/mpl/vector.hpp> 17 #include <boost/mpl/at.hpp> 18 19 #define MANAGED_PTR_CTOR_FORWARDER_MAX_ARGS 3 20 #define FORWARDER_TYPE_PARAM(z, n, _) \ 21 typename boost::mpl::at_c<VecOfTypes, n>::type BOOST_PP_CAT(a, n) \ 22 /**/ 23 //Macro: 24 // FORWARDER_TUPLE 25 //Purpose: 26 // Generate a 1 element tuple containing a pair. 27 #define FORWARDER_TUPLE(s, arg_tuple, name) \ 28 (name arg_tuple) \ 29 /**/ 30 #define FORWARDER_TRGT(z, arity, pass_signature, target_seq) \ 31 : \ 32 BOOST_PP_TUPLE_REM_CTOR( \ 33 1, \ 34 BOOST_PP_SEQ_FOLD_RIGHT( \ 35 FORWARDER_TUPLE, \ 36 ( BOOST_PP_IIF(pass_signature, signature BOOST_PP_ENUM_TRAILING_PARAMS_Z, \ 37 BOOST_PP_ENUM_PARAMS_Z)(z, arity, a) \ 38 ), \ 39 target_seq \ 40 ) \ 41 ) { } \ 42 /**/ 43 //Macro: 44 // MANAGED_PTR_CTOR_FORWARDER_SRC_TRGT(z, arity, pass_signature, source, target_seq) 45 // 46 // Where: 47 // { 48 // 49 // z is the "next available repetition depth" as defined for the BOOST_PP_REPEAT 50 // macro argument. 51 // 52 // arity >= 0 and is the number of arguments passed to targetn (see target_seq) 53 // 54 // pass_signature := 0 or 1 and is flag indicating whether targetn takes a signature. 55 // 56 // source = a class name, this is the class which passes the arguments on. 57 // 58 // target_seq := 59 // (target0)(target1)...(targetn) 60 // where: 61 // { n >= 1 62 // } 63 // 64 // } 65 // 66 //Purpose: 67 // Generate templated constructors with arity+1 arguments for source. 68 // The first argument to CTOR specifies the types of the remaining arguments. 69 // This 1st arg can be a boost::mpl::vector<T1,...Tarity> const&. 70 // 71 //Requires: 72 // BOOST_PP_SEQ_SIZE(target_seq) >= 1 73 // 74 //Example1: 75 // For arity=2, pass_signature=0, source=src, target_seq=(tgt0)(tgt1)(tgt2) 76 // generated ctor is: 77 // 78 // template<typename VecOfTypes> 79 // src(VecOfTypes const& signature 80 // , boost::mpl::at_c<VecOfTypes,0>::type a0 81 // , boost::mpl::at_c<VecOfTypes,1>::type a1 82 // ) 83 // :tgt0(tgt1(tgt2(a0,a1)) 84 // {} 85 // 86 // If pass_signature=1, then the tgt line would be: 87 // 88 // :tgt0(tgt1(tgt2(signature,a0,a1))) 89 // 90 #define FORWARDER_SRC_TRGT(z, arity, pass_signature, source, target_seq) \ 91 template<typename VecOfTypes> source( \ 92 VecOfTypes const& signature BOOST_PP_COMMA_IF(arity) \ 93 BOOST_PP_ENUM_ ## z(arity, FORWARDER_TYPE_PARAM, ~) \ 94 ) \ 95 FORWARDER_TRGT(z, arity, pass_signature, target_seq) \ 96 /**/ 97 #define FORWARDER_OVERLOAD_REMAP(z, arity, seq) \ 98 FORWARDER_SRC_TRGT(z, BOOST_PP_INC(arity), BOOST_PP_SEQ_ELEM(0, seq), \ 99 BOOST_PP_SEQ_ELEM(1, seq), BOOST_PP_SEQ_REST_N(2, seq) \ 100 ) \ 101 /**/ 102 //Macro: 103 // MANAGED_PTR_CTOR_FORWARDER_OVERLOAD(max_arity, source, target_seq, pass_signature) 104 //Purpose: 105 // Invoke 106 // MANAGED_PTR_CTOR_FORWARDER_SRC_TRGT(z, arity, name_seq, pass_signature) for arity=0,max_arity 107 //Acknowledgements: 108 // Special thanks to Paul Mensonides who generously provided all this code 109 // in response to: 110 // 111 // http://article.gmane.org/gmane.comp.lib.boost.devel/35348 112 // 113 #define MANAGED_PTR_CTOR_FORWARDER_OVERLOAD(max_arity, source, target_seq, pass_signature ) \ 114 template<typename ZeroArgs>source( \ 115 boost::mpl::vector<ZeroArgs> const& signature \ 116 ) \ 117 FORWARDER_TRGT(2, 0, pass_signature, target_seq) \ 118 BOOST_PP_REPEAT(max_arity, FORWARDER_OVERLOAD_REMAP, (pass_signature)(source)target_seq ) \ 119 /**/ 120 #endif 121