switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Utils / type_traits.hh
1 // $Id$
2 //
3 // Copyright (C) 2008
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief type_traits public header */
30
31 #ifndef HH_SENF_Utils_type_traits_
32 #define HH_SENF_Utils_type_traits_ 1
33
34 // Custom includes
35 #include <boost/type_traits/function_traits.hpp>
36 #include <boost/type_traits/remove_pointer.hpp>
37 #include <boost/type_traits/is_function.hpp>
38 #include <boost/type_traits/remove_cv.hpp>
39 #include <boost/type_traits/remove_reference.hpp>
40 #include <boost/bind.hpp>
41 #include <senf/config.hh>
42
43 #include "type_traits.mpp"
44 //-/////////////////////////////////////////////////////////////////////////////////////////////////
45
46 namespace senf
47 {
48
49     /** \defgroup typetraits Type traits
50      */
51
52     ///\addtogroup typetraits
53     //\{
54
55     /** \brief Strip first parameter from function traits
56
57         This meta-function will remove the first argument from \a Traits. The return value is a new
58         function trait with one less argument.
59
60         If the function described in \a Traits does not take any arguments, it is returned
61         unchanged.
62
63         \code
64         typedef boost::function_traits<void (int, double)> traits
65         BOOST_STATIC_ASSERT(( boost::is_same<
66             senf::function_traits_remove_arg< traits >::type,
67             boost::function_traits<void (double)>
68         >::value ));
69         \endcode
70
71         \tparam Traits \c boost::function_traits instantiation
72      */
73     template < class Traits, unsigned arity = Traits::arity >
74     struct function_traits_remove_arg {};
75
76     /** \brief Get argument type from function traits
77
78         function_traits_arg<Traits, index> will return the type of the \a index-th argument from \a
79         Traits. If the function has no argument at that index, \c void is returned
80
81         \code
82         typedef boost::function_traits<void (int, double)> traits;
83         BOOST_STATIC_ASSERT(( boost:is_same<
84             senf::function_traits_arg_type< traits, 0 >::type,
85             int
86         >::value ));
87         BOOST_STATIC_ASSERT(( boost::is_same<
88             senf::function_traits_arg_type< traits, 2 >::type,
89             void
90         >::value ));
91         \endcode
92
93         \tparam Traits \c boost::function_traits instantiation
94         \tparam index 0 based argument index
95      */
96     template < class Traits, int index, bool flag = (index < Traits::arity) >
97     struct function_traits_arg_type {};
98
99 #ifndef DOXYGEN
100
101     template < class Traits, int index >
102     struct function_traits_arg_type <Traits, index, false >
103     {
104         typedef void type;
105     };
106
107 #endif
108
109     /** \brief Remove member pointer from type
110
111         This meta function will remove any type of member pointer from it's argument. Other types
112         will be returned unchanged.
113
114         \code
115         BOOST_STATIC_ASSERT(( boost::is_same<
116             senf::remove_member_pointer< int (Class::*) >::type,
117             int
118         >::value ));
119         BOOST_STATIC_ASSERT(( boost::is_same<
120             senf::remove_member_pointer< void (Class::*)(int) >::type,
121             void (int)
122         >::value ));
123         \endcode
124
125         \tparam MemberPointer type to remove member pointer from
126      */
127     template < class MemberPointer > struct remove_member_pointer
128     {
129         typedef MemberPointer type;
130     };
131
132 #ifndef DOXYGEN
133
134     template < class C, class T > struct remove_member_pointer <T (C::*) >
135     {
136         typedef T type;
137     };
138
139     template < class C, class T > struct remove_member_pointer <T (C::* const) >
140     {
141         typedef T type;
142     };
143
144 #endif
145
146     /** \brief Get class of a member pointer
147
148         Returns the class, an arbitrary member pointer belongs to. If the argument is not a member
149         pointer, void is returned.
150
151         \code
152         BOOST_STATIC_ASSERT(( boost::is_same<
153             senf::member_class< int (Class::*) >::type,
154             Class
155         >::value ));
156         BOOST_STATIC_ASSERT(( boost::is_Same<
157             senf::member_class< int * >::type,
158             void
159         >::value ));
160         \endcode
161
162         \tparam MemberPointer Type to get the member pointer class from
163      */
164     template < class MemberPointer > struct member_class
165     {
166         typedef void type;
167     };
168
169 #ifndef DOXYGEN
170
171     template < class C, class T > struct member_class <T (C::*) >
172     {
173         typedef C type;
174     };
175
176     template < class C, class T > struct member_class <T (C::* const) >
177     {
178         typedef C type;
179     };
180
181 #endif
182
183     /** \brief Remove any type of pointer from type
184
185         This meta function will remove a plain or member pointer from the given type. If \a T is
186         neither a member pointer nor an ordinary pointer, \a T will be returned unchanged.
187
188         \code
189         BOOST_STATIC_ASSERT(( boost::is_same<
190             senf::remove_any_pointer< int (Class::*) >::type,
191             int
192         >::value ));
193         BOOST_STATIC_ASSERT(( boost::is_same<
194             senf::remove_any_pointer< void (Class::*)(int) >::type,
195             void (int) > );
196         BOOST_STATIC_ASSERT(( boost::is_same<
197             senf::remove_any_pointer < int (*)() >::type,
198             int (
199         >::value ));
200         BOOST_STATIC_ASSERT(( boost::is_same<
201             senf::remove_any_pointer < int >::type,
202             int
203         >::value ));
204         \endcode
205
206         \tparam T type to remove member pointer from
207      */
208     template < class T >
209     struct remove_any_pointer
210         : public remove_member_pointer < typename boost::remove_pointer < T >::type >
211     {};
212
213     /** \brief Test object if it is a function or member-function (pointer)
214
215         is_any_function will inherit from \c boost::true_type, when \a T is a function type,
216         function pointer type or a member function pointer type. Otherwise, it will inherit from \c
217         boost::false_type.
218
219         \code
220         BOOST_STATIC_ASSERT((   senf::is_any_function< void () >::value ));
221         BOOST_STATIC_ASSERT((   senf::is_any_function< void (*)(int) >::value ));
222         BOOST_STATIC_ASSERT((   senf::is_any_function< void (Class::*)() >::value ));
223         BOOST_STATIC_ASSERT(( ! senf::is_any_function< int * >::value ));
224         \endcode
225
226         \tparam T type to test
227      */
228     template < class T >
229     struct is_any_function
230         : public boost::is_function < typename senf::remove_any_pointer < T >::type >
231     {};
232
233     /** \brief Remove reference and CV qualification from type
234
235         remove_cvref will remove all the 'ornaments' from a type as typically used to pass
236         arguments: references and any CV spec. It will thus convert a typical argument type into
237         it's basic type.
238
239         \code
240         BOOST_STATIC_ASSERT(( boost::is_same<
241             senf::remove_cvref<int const &>::type,
242             int
243         >::value ));
244         \endcode
245      */
246     template < class T >
247     struct remove_cvref
248         : public boost::remove_cv< typename boost::remove_reference<T>::type >
249     {};
250
251     /** \brief Get arity of function T
252
253         \a T may be any function like type: function, pointer to function or (pointer to)
254         member-function.
255
256         \code
257         BOOST_STATIC_ASSERT(( senf::function_arity<void (Class::*)(int)>::value == 1 ));
258         \endcode
259      */
260     template < class T >
261     struct function_arity
262         : public boost::integral_constant<
263               unsigned,
264               boost::function_traits<
265                   typename senf::remove_any_pointer<T>::type>::arity>
266     {};
267
268     /** Test object if it is any \c std::pair type
269
270         if \a Pair is any \c std::pair type, this trait will inherit from \c boost::true_type,
271         otherwise it will inherit from \c boost::false_type.
272
273         \code
274         BOOST_STATIC_ASSERT((   senf::is_pair< std::pair<int,void*> >::value ));
275         BOOST_STATIC_ASSERT(( ! senf::is_pair< void () >::value ));
276         \endcode
277      */
278     template <class Pair>
279     struct is_pair
280         : public boost::false_type
281     {};
282
283 #ifndef DOXYGEN
284     template <class First, class Second>
285     struct is_pair< std::pair<First,Second> >
286         : public boost::true_type
287     {};
288 #endif
289
290     //\}
291
292 #ifndef DOXYGEN
293
294 #   define BOOST_PP_ITERATION_PARAMS_1 (4, (0, 10,                                                \
295                                             SENF_ABSOLUTE_INCLUDE_PATH(Utils/type_traits.mpp),    \
296                                             1))
297 #   include BOOST_PP_ITERATE()
298
299 #endif
300
301 }
302
303 //-/////////////////////////////////////////////////////////////////////////////////////////////////
304 //#include "type_traits.cci"
305 //#include "type_traits.ct"
306 //#include "type_traits.cti"
307 #endif
308
309 \f
310 // Local Variables:
311 // mode: c++
312 // fill-column: 100
313 // comment-column: 40
314 // c-file-style: "senf"
315 // indent-tabs-mode: nil
316 // ispell-local-dictionary: "american"
317 // compile-command: "scons -u test"
318 // End: