1 // Copyright David Abrahams 2006. Distributed under the Boost
2 // 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 #ifndef BOOST_PARAMETER_AUX_PARENTHESIZED_TYPE_DWA2006414_HPP
5 # define BOOST_PARAMETER_AUX_PARENTHESIZED_TYPE_DWA2006414_HPP
7 # include <boost/config.hpp>
8 # include <boost/detail/workaround.hpp>
10 namespace boost { namespace parameter { namespace aux {
12 // A macro that takes a parenthesized C++ type name (T) and transforms
13 // it into an un-parenthesized type expression equivalent to T.
14 # define BOOST_PARAMETER_PARENTHESIZED_TYPE(x) \
15 boost::parameter::aux::unaryfunptr_arg_type< void(*)x >::type
17 // A metafunction that transforms void(*)(T) -> T
18 template <class UnaryFunctionPointer>
19 struct unaryfunptr_arg_type;
21 # if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
24 struct unaryfunptr_arg_type<void(*)(Arg)>
31 // Use the "native typeof" bugfeatures of older versions of MSVC to
32 // accomplish what we'd normally do with partial specialization. This
33 // capability was discovered by Igor Chesnokov.
35 # if BOOST_WORKAROUND(BOOST_MSVC, != 1300)
37 // This version applies to VC6.5 and VC7.1 (except that we can just
38 // use partial specialization for the latter in this case).
40 // This gets used as a base class.
41 template<typename Address>
42 struct msvc_type_memory
44 // A nullary metafunction that will yield the Value type "stored"
49 template<typename Value, typename Address>
50 struct msvc_store_type : msvc_type_memory<Address>
52 // VC++ somehow lets us define the base's nested storage
53 // metafunction here, where we have the Value type we'd like to
54 // "store" in it. Later we can come back to the base class and
55 // extract the "stored type."
56 typedef msvc_type_memory<Address> location;
57 struct location::storage
65 // This slightly more complicated version of the same thing is
66 // required for msvc-7.0
67 template<typename Address>
68 struct msvc_type_memory
73 typedef storage_impl<true> storage;
76 template<typename Value, typename Address>
77 struct msvc_store_type : msvc_type_memory<Address>
79 // Rather than supplying a definition for the base class' nested
80 // class, we specialize the base class' nested template
82 struct storage_impl<true>
90 // Function template argument deduction does many of the same things
91 // as type matching during partial specialization, so we call a
92 // function template to "store" T into the type memory addressed by
95 msvc_store_type<T,void(*)(T)>
96 msvc_store_argument_type(void(*)(T));
98 template <class FunctionPointer>
99 struct unaryfunptr_arg_type
101 // We don't want the function to be evaluated, just instantiated,
102 // so protect it inside of sizeof.
103 enum { dummy = sizeof(msvc_store_argument_type((FunctionPointer)0)) };
105 // Now pull the type out of the instantiated base class
106 typedef typename msvc_type_memory<FunctionPointer>::storage::type type;
112 struct unaryfunptr_arg_type<void(*)(void)>
117 }}} // namespace boost::parameter::aux
119 #endif // BOOST_PARAMETER_AUX_PARENTHESIZED_TYPE_DWA2006414_HPP