1 // Copyright Daniel Wallin 2006. Use, modification and distribution is 2 // subject to the Boost Software License, Version 1.0. (See accompanying 3 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 5 #ifndef BOOST_PARAMETER_CAST_060902_HPP 6 # define BOOST_PARAMETER_CAST_060902_HPP 7 8 # include <boost/detail/workaround.hpp> 9 10 # if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) 11 # include <boost/type_traits/add_reference.hpp> 12 # include <boost/type_traits/remove_const.hpp> 13 # endif 14 15 namespace boost { namespace parameter { namespace aux { 16 17 struct use_default_tag {}; 18 19 # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) 20 21 # define BOOST_PARAMETER_FUNCTION_CAST(value, predicate) value 22 23 # else 24 25 // Handles possible implicit casts. Used by preprocessor.hpp to 26 // normalize user input. 27 // 28 // cast<void*>::execute() is identity 29 // cast<void*(X)>::execute() is identity 30 // cast<void(X)>::execute() casts to X 31 // 32 // preprocessor.hpp uses this like this: 33 // 34 // #define X(value, predicate) 35 // cast<void predicate>::execute(value) 36 // 37 // X(something, *) 38 // X(something, *(predicate)) 39 // X(something, (int)) 40 41 template <class T, class Args> 42 struct cast; 43 44 template <class Args> 45 struct cast<void*, Args> 46 { executeboost::parameter::aux::cast47 static use_default_tag execute(use_default_tag) 48 { 49 return use_default_tag(); 50 } 51 remove_constboost::parameter::aux::cast52 static use_default_tag remove_const(use_default_tag) 53 { 54 return use_default_tag(); 55 } 56 57 template <class U> executeboost::parameter::aux::cast58 static U& execute(U& value) 59 { 60 return value; 61 } 62 63 template <class U> remove_constboost::parameter::aux::cast64 static U& remove_const(U& x) 65 { 66 return x; 67 } 68 }; 69 70 #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580)) 71 72 typedef void* voidstar; 73 74 template <class T, class Args> 75 struct cast<voidstar(T), Args> 76 : cast<void*, Args> 77 { 78 }; 79 80 #else 81 82 template <class T, class Args> 83 struct cast<void*(T), Args> 84 : cast<void*, Args> 85 { 86 }; 87 88 #endif 89 90 // This is a hack used in cast<> to turn the user supplied type, 91 // which may or may not be a placeholder expression into one, so 92 // that it will be properly evaluated by mpl::apply. 93 template <class T, class Dummy = mpl::_1> 94 struct as_placeholder_expr 95 { 96 typedef T type; 97 }; 98 99 template <class T, class Args> 100 struct cast<void(T), Args> 101 { 102 typedef typename mpl::apply2< 103 as_placeholder_expr<T>, Args, Args>::type type0; 104 105 typedef typename boost::add_reference< 106 typename boost::remove_const<type0>::type 107 >::type reference; 108 executeboost::parameter::aux::cast109 static use_default_tag execute(use_default_tag) 110 { 111 return use_default_tag(); 112 } 113 remove_constboost::parameter::aux::cast114 static use_default_tag remove_const(use_default_tag) 115 { 116 return use_default_tag(); 117 } 118 executeboost::parameter::aux::cast119 static type0 execute(type0 value) 120 { 121 return value; 122 } 123 124 template <class U> remove_constboost::parameter::aux::cast125 static reference remove_const(U const& x) 126 { 127 return const_cast<reference>(x); 128 } 129 }; 130 131 # define BOOST_PARAMETER_FUNCTION_CAST(value, predicate, args) \ 132 boost::parameter::aux::cast<void predicate, args>::remove_const( \ 133 boost::parameter::aux::cast<void predicate, args>::execute(value) \ 134 ) 135 136 # endif 137 138 }}} // namespace boost::parameter::aux 139 140 #endif // BOOST_PARAMETER_CAST_060902_HPP 141 142