Utils: Refactor hexdump() helper to move code out of template function
[senf.git] / Utils / type_traits.hh
1 // $Id$
2 //
3 // Copyright (C) 2008 
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief type_traits public header */
25
26 #ifndef HH_type_traits_
27 #define HH_type_traits_ 1
28
29 // Custom includes
30 #include <boost/type_traits/function_traits.hpp>
31 #include <boost/type_traits/remove_pointer.hpp>
32 #include <boost/type_traits/is_function.hpp>
33 #include <boost/type_traits/remove_cv.hpp>
34 #include <boost/type_traits/remove_reference.hpp>
35 #include <boost/bind.hpp>
36 #include "../config.hh"
37
38 #include "type_traits.mpp"
39 ///////////////////////////////hh.p////////////////////////////////////////
40
41 namespace senf
42 {
43
44     /** \defgroup typetraits Type traits
45      */
46
47     ///\addtogroup typetraits
48     ///\{
49
50     /** \brief Strip first parameter from function traits
51
52         This meta-function will remove the first argument from \a Traits. The return value is a new
53         function trait with one less argument.
54
55         If the function described in \a Traits does not take any arguments, it is returned
56         unchanged.
57         
58         \code
59         typedef boost::function_traits<void (int, double)> traits
60         BOOST_STATIC_ASSERT(( boost::is_same< 
61             senf::function_traits_remove_arg< traits >::type, 
62             boost::function_traits<void (double)> 
63         >::value ));
64         \endcode
65
66         \tparam Traits \c boost::function_traits instantiation
67      */
68     template < class Traits, unsigned arity = Traits::arity >
69     struct function_traits_remove_arg {};
70
71     /** \brief Get argument type from function traits
72         
73         function_traits_arg<Traits, index> will return the type of the \a index-th argument from \a
74         Traits. If the function has no argument at that index, \c void is returned
75
76         \code
77         typedef boost::function_traits<void (int, double)> traits;
78         BOOST_STATIC_ASSERT(( boost:is_same<
79             senf::function_traits_arg_type< traits, 0 >::type,
80             int 
81         >::value ));
82         BOOST_STATIC_ASSERT(( boost::is_same<
83             senf::function_traits_arg_type< traits, 2 >::type,
84             void
85         >::value ));
86         \endcode
87         
88         \tparam Traits \c boost::function_traits instantiation
89         \tparam index 0 based argument index
90      */
91     template < class Traits, int index, bool flag = (index < Traits::arity) > 
92     struct function_traits_arg_type {};
93
94 #ifndef DOXYGEN
95
96     template < class Traits, int index >
97     struct function_traits_arg_type <Traits, index, false >
98     {
99         typedef void type;
100     };
101
102 #endif
103
104     /** \brief Remove member pointer from type
105
106         This meta function will remove any type of member pointer from it's argument. Other types
107         will be returned unchanged.
108
109         \code
110         BOOST_STATIC_ASSERT(( boost::is_same< 
111             senf::remove_member_pointer< int (Class::*) >::type, 
112             int 
113         >::value ));
114         BOOST_STATIC_ASSERT(( boost::is_same< 
115             senf::remove_member_pointer< void (Class::*)(int) >::type, 
116             void (int)
117         >::value ));
118         \endcode
119
120         \tparam MemberPointer type to remove member pointer from
121      */
122     template < class MemberPointer > struct remove_member_pointer
123     {
124         typedef MemberPointer type;
125     };
126
127 #ifndef DOXYGEN
128
129     template < class C, class T > struct remove_member_pointer <T (C::*) >
130     {
131         typedef T type;
132     };
133
134 #endif
135
136     /** \brief Get class of a member pointer
137
138         Returns the class, an arbitrary member pointer belongs to. If the argument is not a member
139         pointer, void is returned.
140
141         \code
142         BOOST_STATIC_ASSERT(( boost::is_same<
143             senf::member_class< int (Class::*) >::type,
144             Class
145         >::value ));
146         BOOST_STATIC_ASSERT(( boost::is_Same<
147             senf::member_class< int * >::type,
148             void
149         >::value ));
150         \endcode
151
152         \tparam MemberPointer Type to get the member pointer class from
153      */
154     template < class MemberPointer > struct member_class
155     {
156         typedef void type;
157     };
158     
159 #ifndef DOXYGEN
160
161     template < class C, class T > struct member_class <T (C::*) >
162     {
163         typedef C type;
164     };
165
166 #endif
167
168     /** \brief Remove any type of pointer from type
169
170         This meta function will remove a plain or member pointer from the given type. If \a T is
171         neither a member pointer nor an ordinary pointer, \a T will be returned unchanged.
172         
173         \code
174         BOOST_STATIC_ASSERT(( boost::is_same< 
175             senf::remove_any_pointer< int (Class::*) >::type, 
176             int
177         >::value ));
178         BOOST_STATIC_ASSERT(( boost::is_same< 
179             senf::remove_any_pointer< void (Class::*)(int) >::type, 
180             void (int) > );
181         BOOST_STATIC_ASSERT(( boost::is_same<
182             senf::remove_any_pointer < int (*)() >::type,
183             int (
184         >::value ));
185         BOOST_STATIC_ASSERT(( boost::is_same<
186             senf::remove_any_pointer < int >::type,
187             int
188         >::value ));
189         \endcode
190
191         \tparam T type to remove member pointer from
192      */
193     template < class T >
194     struct remove_any_pointer
195         : public remove_member_pointer < typename boost::remove_pointer < T >::type >
196     {};
197
198     /** \brief Test object if it is a function or member-function (pointer)
199         
200         is_any_function will inherit from \c boost::true_type, when \a T is a function type,
201         function pointer type or a member function pointer type. Otherwise, it will inherit from \c
202         boost::false_type.
203
204         \code
205         BOOST_STATIC_ASSERT((   senf::is_any_function< void () >::value ));
206         BOOST_STATIC_ASSERT((   senf::is_any_function< void (*)(int) >::value ));
207         BOOST_STATIC_ASSERT((   senf::is_any_function< void (Class::*)() >::value ));
208         BOOST_STATIC_ASSERT(( ! senf::is_any_function< int * >::value ));
209         \endcode
210
211         \tparam T type to test
212      */
213     template < class T >
214     struct is_any_function
215         : public boost::is_function < typename senf::remove_any_pointer < T >::type >
216     {};
217
218     /** \brief Remove reference and CV qualification from type
219        
220         remove_cvref will remove all the 'ornaments' from a type as typically used to pass
221         arguments: references and any CV spec. It will thus convert a typical argument type into
222         it's basic type.
223
224         \code
225         BOOST_STATIC_ASSERT(( boost::is_same<
226             senf::remove_cvref<int const &>::type,
227             int
228         >::value ));
229         \endcode
230      */
231     template < class T >
232     struct remove_cvref
233         : public boost::remove_cv< typename boost::remove_reference<T>::type >
234     {};
235
236   ///}
237
238 #ifndef DOXYGEN
239
240 #   define BOOST_PP_ITERATION_PARAMS_1 (4, (0, 10,                                                \
241                                             SENF_ABSOLUTE_INCLUDE_PATH(Utils/type_traits.mpp),    \
242                                             1))
243 #   include BOOST_PP_ITERATE()
244
245 #endif
246
247 }
248
249 ///////////////////////////////hh.e////////////////////////////////////////
250 //#include "type_traits.cci"
251 //#include "type_traits.ct"
252 //#include "type_traits.cti"
253 #endif
254 \f
255
256 // Local Variables:
257 // mode: c++
258 // fill-column: 100
259 // comment-column: 40
260 // c-file-style: "senf"
261 // indent-tabs-mode: nil
262 // ispell-local-dictionary: "american"
263 // compile-command: "scons -u test"
264 // End: