1 // Boost.Function library
3 // Copyright (C) 2001 Doug Gregor (gregod@cs.rpi.edu)
5 // Permission to copy, use, sell and distribute this software is granted
6 // provided this copyright notice appears in all copies.
7 // Permission to modify the code and to distribute modified code is granted
8 // provided this copyright notice appears in all copies, and a notice
9 // that the code was modified is included with the copyright notice.
11 // This software is provided "as is" without express or implied warranty,
12 // and with no claim as to its suitability for any purpose.
14 // For more information, see http://www.boost.org
16 // William Kempf, Jesse Jones and Karl Nelson were all very helpful in the
17 // design of this library.
19 #ifndef BOOST_FUNCTION_HPP
20 #define BOOST_FUNCTION_HPP
22 #include <boost/function/function_base.hpp>
23 #include <boost/type_traits/function_traits.hpp>
24 #include <boost/type_traits/same_traits.hpp>
25 #include <boost/type_traits/transform_traits.hpp>
26 #include <boost/type_traits/ice.hpp>
27 #include <boost/function/function0.hpp>
28 #include <boost/function/function1.hpp>
29 #include <boost/function/function2.hpp>
30 #include <boost/function/function3.hpp>
31 #include <boost/function/function4.hpp>
32 #include <boost/function/function5.hpp>
33 #include <boost/function/function6.hpp>
34 #include <boost/function/function7.hpp>
35 #include <boost/function/function8.hpp>
36 #include <boost/function/function9.hpp>
37 #include <boost/function/function10.hpp>
42 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
43 template<typename Signature>
44 struct function_traits
46 typedef void result_type;
47 typedef void arg1_type;
48 typedef void arg2_type;
49 typedef void arg3_type;
50 typedef void arg4_type;
51 typedef void arg5_type;
52 typedef void arg6_type;
53 typedef void arg7_type;
54 typedef void arg8_type;
55 typedef void arg9_type;
56 typedef void arg10_type;
60 struct function_traits<R (*)(void)>
62 typedef R result_type;
63 typedef unusable arg1_type;
64 typedef unusable arg2_type;
65 typedef unusable arg3_type;
66 typedef unusable arg4_type;
67 typedef unusable arg5_type;
68 typedef unusable arg6_type;
69 typedef unusable arg7_type;
70 typedef unusable arg8_type;
71 typedef unusable arg9_type;
72 typedef unusable arg10_type;
75 template<typename R, typename T1>
76 struct function_traits<R (*)(T1)>
78 typedef R result_type;
80 typedef unusable arg2_type;
81 typedef unusable arg3_type;
82 typedef unusable arg4_type;
83 typedef unusable arg5_type;
84 typedef unusable arg6_type;
85 typedef unusable arg7_type;
86 typedef unusable arg8_type;
87 typedef unusable arg9_type;
88 typedef unusable arg10_type;
91 template<typename R, typename T1, typename T2>
92 struct function_traits<R (*)(T1, T2)>
94 typedef R result_type;
97 typedef unusable arg3_type;
98 typedef unusable arg4_type;
99 typedef unusable arg5_type;
100 typedef unusable arg6_type;
101 typedef unusable arg7_type;
102 typedef unusable arg8_type;
103 typedef unusable arg9_type;
104 typedef unusable arg10_type;
107 template<typename R, typename T1, typename T2, typename T3>
108 struct function_traits<R (*)(T1, T2, T3)>
110 typedef R result_type;
111 typedef T1 arg1_type;
112 typedef T2 arg2_type;
113 typedef T3 arg3_type;
114 typedef unusable arg4_type;
115 typedef unusable arg5_type;
116 typedef unusable arg6_type;
117 typedef unusable arg7_type;
118 typedef unusable arg8_type;
119 typedef unusable arg9_type;
120 typedef unusable arg10_type;
123 template<typename R, typename T1, typename T2, typename T3, typename T4>
124 struct function_traits<R (*)(T1, T2, T3, T4)>
126 typedef R result_type;
127 typedef T1 arg1_type;
128 typedef T2 arg2_type;
129 typedef T3 arg3_type;
130 typedef T4 arg4_type;
131 typedef unusable arg5_type;
132 typedef unusable arg6_type;
133 typedef unusable arg7_type;
134 typedef unusable arg8_type;
135 typedef unusable arg9_type;
136 typedef unusable arg10_type;
139 template<typename R, typename T1, typename T2, typename T3, typename T4,
141 struct function_traits<R (*)(T1, T2, T3, T4, T5)>
143 typedef R result_type;
144 typedef T1 arg1_type;
145 typedef T2 arg2_type;
146 typedef T3 arg3_type;
147 typedef T4 arg4_type;
148 typedef T5 arg5_type;
149 typedef unusable arg6_type;
150 typedef unusable arg7_type;
151 typedef unusable arg8_type;
152 typedef unusable arg9_type;
153 typedef unusable arg10_type;
156 template<typename R, typename T1, typename T2, typename T3, typename T4,
157 typename T5, typename T6>
158 struct function_traits<R (*)(T1, T2, T3, T4, T5, T6)>
160 typedef R result_type;
161 typedef T1 arg1_type;
162 typedef T2 arg2_type;
163 typedef T3 arg3_type;
164 typedef T4 arg4_type;
165 typedef T5 arg5_type;
166 typedef T6 arg6_type;
167 typedef unusable arg7_type;
168 typedef unusable arg8_type;
169 typedef unusable arg9_type;
170 typedef unusable arg10_type;
173 template<typename R, typename T1, typename T2, typename T3, typename T4,
174 typename T5, typename T6, typename T7>
175 struct function_traits<R (*)(T1, T2, T3, T4, T5, T6, T7)>
177 typedef R result_type;
178 typedef T1 arg1_type;
179 typedef T2 arg2_type;
180 typedef T3 arg3_type;
181 typedef T4 arg4_type;
182 typedef T5 arg5_type;
183 typedef T6 arg6_type;
184 typedef T7 arg7_type;
185 typedef unusable arg8_type;
186 typedef unusable arg9_type;
187 typedef unusable arg10_type;
190 template<typename R, typename T1, typename T2, typename T3, typename T4,
191 typename T5, typename T6, typename T7, typename T8>
192 struct function_traits<R (*)(T1, T2, T3, T4, T5, T6, T7, T8)>
194 typedef R result_type;
195 typedef T1 arg1_type;
196 typedef T2 arg2_type;
197 typedef T3 arg3_type;
198 typedef T4 arg4_type;
199 typedef T5 arg5_type;
200 typedef T6 arg6_type;
201 typedef T7 arg7_type;
202 typedef T8 arg8_type;
203 typedef unusable arg9_type;
204 typedef unusable arg10_type;
207 template<typename R, typename T1, typename T2, typename T3, typename T4,
208 typename T5, typename T6, typename T7, typename T8, typename T9>
209 struct function_traits<R (*)(T1, T2, T3, T4, T5, T6, T7, T8, T9)>
211 typedef R result_type;
212 typedef T1 arg1_type;
213 typedef T2 arg2_type;
214 typedef T3 arg3_type;
215 typedef T4 arg4_type;
216 typedef T5 arg5_type;
217 typedef T6 arg6_type;
218 typedef T7 arg7_type;
219 typedef T8 arg8_type;
220 typedef T9 arg9_type;
221 typedef unusable arg10_type;
224 template<typename R, typename T1, typename T2, typename T3, typename T4,
225 typename T5, typename T6, typename T7, typename T8, typename T9,
227 struct function_traits<R (*)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)>
229 typedef R result_type;
230 typedef T1 arg1_type;
231 typedef T2 arg2_type;
232 typedef T3 arg3_type;
233 typedef T4 arg4_type;
234 typedef T5 arg5_type;
235 typedef T6 arg6_type;
236 typedef T7 arg7_type;
237 typedef T8 arg8_type;
238 typedef T9 arg9_type;
239 typedef T10 arg10_type;
243 // Choose the appropriate underlying implementation
244 template<int Args> struct real_get_function_impl {};
247 struct real_get_function_impl<0>
267 typedef function0<R, Policy, Mixin, Allocator> type;
272 struct real_get_function_impl<1>
292 typedef function1<R, T1, Policy, Mixin, Allocator> type;
297 struct real_get_function_impl<2>
317 typedef function2<R, T1, T2, Policy, Mixin, Allocator> type;
322 struct real_get_function_impl<3>
342 typedef function3<R, T1, T2, T3, Policy, Mixin, Allocator> type;
347 struct real_get_function_impl<4>
367 typedef function4<R, T1, T2, T3, T4, Policy, Mixin, Allocator> type;
372 struct real_get_function_impl<5>
392 typedef function5<R, T1, T2, T3, T4, T5, Policy, Mixin, Allocator>
398 struct real_get_function_impl<6>
418 typedef function6<R, T1, T2, T3, T4, T5, T6, Policy, Mixin, Allocator>
424 struct real_get_function_impl<7>
444 typedef function7<R, T1, T2, T3, T4, T5, T6, T7, Policy, Mixin,
450 struct real_get_function_impl<8>
470 typedef function8<R, T1, T2, T3, T4, T5, T6, T7, T8, Policy, Mixin,
476 struct real_get_function_impl<9>
496 typedef function9<R, T1, T2, T3, T4, T5, T6, T7, T8, T9, Policy,
497 Mixin, Allocator> type;
502 struct real_get_function_impl<10>
522 typedef function10<R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
523 Policy, Mixin, Allocator> type;
527 template<typename T1, typename T2>
530 BOOST_STATIC_CONSTANT(bool, value = !(is_same<T1, T2>::value));
545 typename InPolicy = empty_function_policy,
546 typename InMixin = empty_function_mixin,
547 typename InAllocator = std::allocator<function_base>
549 class get_function_impl
551 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
552 typedef function_traits<typename add_pointer<InR>::type> traits;
555 typedef typename ct_if<(is_function<InR>::value),
556 typename traits::result_type,
558 typedef typename ct_if<(is_function<InR>::value),
559 typename traits::arg1_type,
561 typedef typename ct_if<(is_function<InR>::value),
562 typename traits::arg2_type,
564 typedef typename ct_if<(is_function<InR>::value),
565 typename traits::arg3_type,
567 typedef typename ct_if<(is_function<InR>::value),
568 typename traits::arg4_type,
570 typedef typename ct_if<(is_function<InR>::value),
571 typename traits::arg5_type,
573 typedef typename ct_if<(is_function<InR>::value),
574 typename traits::arg6_type,
576 typedef typename ct_if<(is_function<InR>::value),
577 typename traits::arg7_type,
579 typedef typename ct_if<(is_function<InR>::value),
580 typename traits::arg8_type,
582 typedef typename ct_if<(is_function<InR>::value),
583 typename traits::arg9_type,
585 typedef typename ct_if<(is_function<InR>::value),
586 typename traits::arg10_type,
588 typedef typename ct_if<
589 (type_traits::ice_and<
590 (is_function<InR>::value),
591 (is_not_same<InT1, unusable>::value)
594 InPolicy>::type Policy;
596 typedef typename ct_if<
597 (type_traits::ice_and<
598 (is_function<InR>::value),
599 (is_not_same<InT2, unusable>::value)
602 InMixin>::type Mixin;
604 typedef typename ct_if<
605 (type_traits::ice_and<
606 (is_function<InR>::value),
607 (is_not_same<InT3, unusable>::value)
610 InAllocator>::type Allocator;
624 typedef InPolicy Policy;
625 typedef InMixin Mixin;
626 typedef InAllocator Allocator;
628 typedef typename real_get_function_impl<
629 (count_used_args<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>::value)
630 >::template params<R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
631 Policy, Mixin, Allocator>::type
647 typename InMyPolicy = empty_function_policy,
648 typename InMyMixin = empty_function_mixin,
649 typename InMyAllocator = std::allocator<function_base>
651 class function_traits_builder
653 typedef get_function_impl<InR, InT1, InT2, InT3, InT4, InT5, InT6, InT7,
654 InT8, InT9, InT10, InMyPolicy, InMyMixin,
658 typedef typename impl::R MyR;
659 typedef typename impl::T1 MyT1;
660 typedef typename impl::T2 MyT2;
661 typedef typename impl::T3 MyT3;
662 typedef typename impl::T4 MyT4;
663 typedef typename impl::T5 MyT5;
664 typedef typename impl::T6 MyT6;
665 typedef typename impl::T7 MyT7;
666 typedef typename impl::T8 MyT8;
667 typedef typename impl::T9 MyT9;
668 typedef typename impl::T10 MyT10;
669 typedef typename impl::Policy MyPolicy;
670 typedef typename impl::Mixin MyMixin;
671 typedef typename impl::Allocator MyAllocator;
674 typedef typename impl::type type;
675 typedef MyPolicy policy_type;
676 typedef MyMixin mixin_type;
677 typedef MyAllocator allocator_type;
679 #ifndef BOOST_NO_DEPENDENT_NESTED_DERIVATIONS
680 template<typename Policy>
682 public function_traits_builder<MyR, MyT1, MyT2, MyT3, MyT4, MyT5, MyT6,
683 MyT7, MyT8, MyT9, MyT10, Policy,
684 mixin_type, allocator_type> {};
686 template<typename Mixin>
688 public function_traits_builder<MyR, MyT1, MyT2, MyT3, MyT4, MyT5, MyT6,
689 MyT7, MyT8, MyT9, MyT10, policy_type,
690 Mixin, allocator_type> {};
692 template<typename Allocator>
694 public function_traits_builder<MyR, MyT1, MyT2, MyT3, MyT4, MyT5, MyT6,
695 MyT7, MyT8, MyT9, MyT10, policy_type,
696 mixin_type, Allocator> {};
698 template<typename Policy>
701 typedef typename function_traits_builder<MyR, MyT1, MyT2, MyT3, MyT4,
702 MyT5, MyT6, MyT7, MyT8, MyT9,
703 MyT10, Policy, mixin_type,
704 allocator_type>::type
708 template<typename Mixin>
711 typedef typename function_traits_builder<MyR, MyT1, MyT2, MyT3, MyT4,
712 MyT5, MyT6, MyT7, MyT8, MyT9,
713 MyT10, policy_type, Mixin,
714 allocator_type>::type
718 template<typename Allocator>
721 typedef typename function_traits_builder<MyR, MyT1, MyT2, MyT3, MyT4,
722 MyT5, MyT6, MyT7, MyT8, MyT9,
723 MyT10, policy_type, mixin_type,
730 } // end namespace function
731 } // end namespace detail
735 typename T1 = detail::function::unusable,
736 typename T2 = detail::function::unusable,
737 typename T3 = detail::function::unusable,
738 typename T4 = detail::function::unusable,
739 typename T5 = detail::function::unusable,
740 typename T6 = detail::function::unusable,
741 typename T7 = detail::function::unusable,
742 typename T8 = detail::function::unusable,
743 typename T9 = detail::function::unusable,
744 typename T10 = detail::function::unusable
747 public detail::function::get_function_impl<R, T1, T2, T3, T4, T5, T6, T7,
749 public detail::function::function_traits_builder<R, T1, T2, T3, T4, T5, T6,
752 typedef typename detail::function::get_function_impl<R, T1, T2, T3, T4, T5,
758 typedef typename base_type::policy_type policy_type;
759 typedef typename base_type::mixin_type mixin_type;
760 typedef typename base_type::allocator_type allocator_type;
761 typedef function self_type;
763 function() : base_type() {}
765 template<typename Functor>
766 function(Functor BOOST_FUNCTION_TARGET_FIX(const &) f) : base_type(f) {}
768 function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
770 template<typename Functor>
771 self_type& operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
773 self_type(f).swap(*this);
777 self_type& operator=(const base_type& f)
779 self_type(f).swap(*this);
783 self_type& operator=(const self_type& f)
785 self_type(f).swap(*this);
789 template<typename Functor>
790 void set(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
793 self_type(f).swap(*this);
796 void set(const base_type& f)
799 self_type(f).swap(*this);
802 void set(const self_type& f)
805 self_type(f).swap(*this);
820 inline void swap(function<R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>& f1,
821 function<R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>& f2)
825 } // end namespace boost