1 // Boost.Function library
3 // Copyright (C) 2001, 2002 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>
39 // Don't compile any of this code if we've asked not to include the deprecated
40 // syntax and we don't have partial specialization, because none of this code
42 #if !defined (BOOST_FUNCTION_NO_DEPRECATED) || !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
47 // Choose the appropriate underlying implementation
48 template<int Args> struct real_get_function_impl {};
51 struct real_get_function_impl<0>
65 #ifndef BOOST_FUNCTION_NO_DEPRECATED
68 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
74 #ifndef BOOST_FUNCTION_NO_DEPRECATED
76 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
82 struct real_get_function_impl<1>
96 #ifndef BOOST_FUNCTION_NO_DEPRECATED
99 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
104 typedef function1<R, T1,
105 #ifndef BOOST_FUNCTION_NO_DEPRECATED
107 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
113 struct real_get_function_impl<2>
127 #ifndef BOOST_FUNCTION_NO_DEPRECATED
130 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
135 typedef function2<R, T1, T2,
136 #ifndef BOOST_FUNCTION_NO_DEPRECATED
138 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
144 struct real_get_function_impl<3>
158 #ifndef BOOST_FUNCTION_NO_DEPRECATED
161 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
166 typedef function3<R, T1, T2, T3,
167 #ifndef BOOST_FUNCTION_NO_DEPRECATED
169 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
175 struct real_get_function_impl<4>
189 #ifndef BOOST_FUNCTION_NO_DEPRECATED
192 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
197 typedef function4<R, T1, T2, T3, T4,
198 #ifndef BOOST_FUNCTION_NO_DEPRECATED
200 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
206 struct real_get_function_impl<5>
220 #ifndef BOOST_FUNCTION_NO_DEPRECATED
223 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
228 typedef function5<R, T1, T2, T3, T4, T5,
229 #ifndef BOOST_FUNCTION_NO_DEPRECATED
231 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
238 struct real_get_function_impl<6>
252 #ifndef BOOST_FUNCTION_NO_DEPRECATED
255 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
260 typedef function6<R, T1, T2, T3, T4, T5, T6,
261 #ifndef BOOST_FUNCTION_NO_DEPRECATED
263 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
270 struct real_get_function_impl<7>
284 #ifndef BOOST_FUNCTION_NO_DEPRECATED
287 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
292 typedef function7<R, T1, T2, T3, T4, T5, T6, T7,
293 #ifndef BOOST_FUNCTION_NO_DEPRECATED
295 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
301 struct real_get_function_impl<8>
315 #ifndef BOOST_FUNCTION_NO_DEPRECATED
318 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
323 typedef function8<R, T1, T2, T3, T4, T5, T6, T7, T8,
324 #ifndef BOOST_FUNCTION_NO_DEPRECATED
326 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
332 struct real_get_function_impl<9>
346 #ifndef BOOST_FUNCTION_NO_DEPRECATED
349 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
354 typedef function9<R, T1, T2, T3, T4, T5, T6, T7, T8, T9,
355 #ifndef BOOST_FUNCTION_NO_DEPRECATED
357 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
363 struct real_get_function_impl<10>
377 #ifndef BOOST_FUNCTION_NO_DEPRECATED
380 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
385 typedef function10<R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
386 #ifndef BOOST_FUNCTION_NO_DEPRECATED
388 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
393 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
394 template<bool GetIt, typename Traits>
397 typedef unusable type;
400 template<typename Traits>
401 struct get_arg1_type<true, Traits>
403 typedef typename Traits::arg1_type type;
406 template<bool GetIt, typename Traits>
409 typedef unusable type;
412 template<typename Traits>
413 struct get_arg2_type<true, Traits>
415 typedef typename Traits::arg2_type type;
418 template<bool GetIt, typename Traits>
421 typedef unusable type;
424 template<typename Traits>
425 struct get_arg3_type<true, Traits>
427 typedef typename Traits::arg3_type type;
430 template<bool GetIt, typename Traits>
433 typedef unusable type;
436 template<typename Traits>
437 struct get_arg4_type<true, Traits>
439 typedef typename Traits::arg4_type type;
442 template<bool GetIt, typename Traits>
445 typedef unusable type;
448 template<typename Traits>
449 struct get_arg5_type<true, Traits>
451 typedef typename Traits::arg5_type type;
454 template<bool GetIt, typename Traits>
457 typedef unusable type;
460 template<typename Traits>
461 struct get_arg6_type<true, Traits>
463 typedef typename Traits::arg6_type type;
466 template<bool GetIt, typename Traits>
469 typedef unusable type;
472 template<typename Traits>
473 struct get_arg7_type<true, Traits>
475 typedef typename Traits::arg7_type type;
478 template<bool GetIt, typename Traits>
481 typedef unusable type;
484 template<typename Traits>
485 struct get_arg8_type<true, Traits>
487 typedef typename Traits::arg8_type type;
490 template<bool GetIt, typename Traits>
493 typedef unusable type;
496 template<typename Traits>
497 struct get_arg9_type<true, Traits>
499 typedef typename Traits::arg9_type type;
502 template<bool GetIt, typename Traits>
503 struct get_arg10_type
505 typedef unusable type;
508 template<typename Traits>
509 struct get_arg10_type<true, Traits>
511 typedef typename Traits::arg10_type type;
514 template<int X, int Y>
517 BOOST_STATIC_CONSTANT(bool, value = (X >= Y));
520 template<bool IsFunction,
532 #ifndef BOOST_FUNCTION_NO_DEPRECATED
535 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
536 typename InAllocator>
537 struct maybe_decode_function_args
539 typedef function_traits<InR> traits;
541 typedef typename traits::result_type R;
542 typedef typename get_arg1_type<(gte<(traits::arity), 1>::value),
544 typedef typename get_arg2_type<(gte<(traits::arity), 2>::value),
546 typedef typename get_arg3_type<(gte<(traits::arity), 3>::value),
548 typedef typename get_arg4_type<(gte<(traits::arity), 4>::value),
550 typedef typename get_arg5_type<(gte<(traits::arity), 5>::value),
552 typedef typename get_arg6_type<(gte<(traits::arity), 6>::value),
554 typedef typename get_arg7_type<(gte<(traits::arity), 7>::value),
556 typedef typename get_arg8_type<(gte<(traits::arity), 8>::value),
558 typedef typename get_arg9_type<(gte<(traits::arity), 9>::value),
560 typedef typename get_arg10_type<(gte<(traits::arity), 10>::value),
563 #ifndef BOOST_FUNCTION_NO_DEPRECATED
564 typedef typename ct_if<(is_same<InT1, unusable>::value),
565 empty_function_policy,
567 typedef typename ct_if<(is_same<InT2, unusable>::value),
568 empty_function_mixin,
570 typedef typename ct_if<(is_same<InT3, unusable>::value),
571 std::allocator<function_base>,
572 InT3>::type Allocator;
574 typedef typename ct_if<(is_same<InT1, unusable>::value),
575 std::allocator<function_base>,
576 InT1>::type Allocator;
577 #endif // BOOST_FUNCTION_NO_DEPRECATED
580 #ifndef BOOST_FUNCTION_NO_DEPRECATED
581 template<typename InR,
592 #ifndef BOOST_FUNCTION_NO_DEPRECATED
595 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
596 typename InAllocator>
597 struct maybe_decode_function_args<false, InR, InT1, InT2, InT3, InT4,
598 InT5, InT6, InT7, InT8, InT9, InT10,
599 #ifndef BOOST_FUNCTION_NO_DEPRECATED
601 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
604 // Not a function, so just map the types directly
616 #ifndef BOOST_FUNCTION_NO_DEPRECATED
617 typedef InPolicy Policy;
618 typedef InMixin Mixin;
619 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
620 typedef InAllocator Allocator;
623 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
625 #endif // ndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
639 typename InPolicy = empty_function_policy,
640 typename InMixin = empty_function_mixin,
641 typename InAllocator = std::allocator<function_base>
643 struct get_function_impl
645 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
646 typedef maybe_decode_function_args<(is_function<InR>::value),
647 InR, InT1, InT2, InT3, InT4, InT5,
648 InT6, InT7, InT8, InT9, InT10,
649 #ifndef BOOST_FUNCTION_NO_DEPRECATED
651 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
652 InAllocator> decoder;
653 typedef typename decoder::R R;
654 typedef typename decoder::T1 T1;
655 typedef typename decoder::T2 T2;
656 typedef typename decoder::T3 T3;
657 typedef typename decoder::T4 T4;
658 typedef typename decoder::T5 T5;
659 typedef typename decoder::T6 T6;
660 typedef typename decoder::T7 T7;
661 typedef typename decoder::T8 T8;
662 typedef typename decoder::T9 T9;
663 typedef typename decoder::T10 T10;
664 #ifndef BOOST_FUNCTION_NO_DEPRECATED
665 typedef typename decoder::Policy Policy;
666 typedef typename decoder::Mixin Mixin;
667 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
668 typedef typename decoder::Allocator Allocator;
681 typedef InPolicy Policy;
682 typedef InMixin Mixin;
683 typedef InAllocator Allocator;
684 #endif // def BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
686 typedef typename real_get_function_impl<
687 (count_used_args<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>::value)
688 >::template params<R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
689 #ifndef BOOST_FUNCTION_NO_DEPRECATED
691 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
696 #ifndef BOOST_FUNCTION_NO_DEPRECATED
709 typename InMyPolicy = empty_function_policy,
710 typename InMyMixin = empty_function_mixin,
711 typename InMyAllocator = std::allocator<function_base>
713 class function_traits_builder
715 typedef get_function_impl<InR, InT1, InT2, InT3, InT4, InT5, InT6, InT7,
716 InT8, InT9, InT10, InMyPolicy, InMyMixin,
720 typedef typename impl::R MyR;
721 typedef typename impl::T1 MyT1;
722 typedef typename impl::T2 MyT2;
723 typedef typename impl::T3 MyT3;
724 typedef typename impl::T4 MyT4;
725 typedef typename impl::T5 MyT5;
726 typedef typename impl::T6 MyT6;
727 typedef typename impl::T7 MyT7;
728 typedef typename impl::T8 MyT8;
729 typedef typename impl::T9 MyT9;
730 typedef typename impl::T10 MyT10;
731 typedef typename impl::Policy MyPolicy;
732 typedef typename impl::Mixin MyMixin;
733 typedef typename impl::Allocator MyAllocator;
736 typedef typename impl::type type;
737 typedef MyPolicy policy_type;
738 typedef MyMixin mixin_type;
739 typedef MyAllocator allocator_type;
741 #ifndef BOOST_NO_DEPENDENT_NESTED_DERIVATIONS
742 template<typename Policy>
744 public function_traits_builder<MyR, MyT1, MyT2, MyT3, MyT4, MyT5, MyT6,
745 MyT7, MyT8, MyT9, MyT10, Policy,
746 mixin_type, allocator_type> {};
748 template<typename Mixin>
750 public function_traits_builder<MyR, MyT1, MyT2, MyT3, MyT4, MyT5, MyT6,
751 MyT7, MyT8, MyT9, MyT10, policy_type,
752 Mixin, allocator_type> {};
754 template<typename Allocator>
756 public function_traits_builder<MyR, MyT1, MyT2, MyT3, MyT4, MyT5, MyT6,
757 MyT7, MyT8, MyT9, MyT10, policy_type,
758 mixin_type, Allocator> {};
760 template<typename Policy>
763 typedef typename function_traits_builder<MyR, MyT1, MyT2, MyT3, MyT4,
764 MyT5, MyT6, MyT7, MyT8, MyT9,
765 MyT10, Policy, mixin_type,
766 allocator_type>::type
770 template<typename Mixin>
773 typedef typename function_traits_builder<MyR, MyT1, MyT2, MyT3, MyT4,
774 MyT5, MyT6, MyT7, MyT8, MyT9,
775 MyT10, policy_type, Mixin,
776 allocator_type>::type
780 template<typename Allocator>
783 typedef typename function_traits_builder<MyR, MyT1, MyT2, MyT3, MyT4,
784 MyT5, MyT6, MyT7, MyT8, MyT9,
785 MyT10, policy_type, mixin_type,
789 #endif // ndef NO_DEPENDENT_NESTED_DERIVATIONS
791 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
792 } // end namespace function
793 } // end namespace detail
797 typename T1 = detail::function::unusable,
798 typename T2 = detail::function::unusable,
799 typename T3 = detail::function::unusable,
800 typename T4 = detail::function::unusable,
801 typename T5 = detail::function::unusable,
802 typename T6 = detail::function::unusable,
803 typename T7 = detail::function::unusable,
804 typename T8 = detail::function::unusable,
805 typename T9 = detail::function::unusable,
806 typename T10 = detail::function::unusable
809 public detail::function::get_function_impl<R, T1, T2, T3, T4, T5, T6, T7,
811 #ifndef BOOST_FUNCTION_NO_DEPRECATED
812 , public detail::function::function_traits_builder<R, T1, T2, T3, T4, T5,
814 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
816 typedef typename detail::function::get_function_impl<R, T1, T2, T3, T4, T5,
822 #ifndef BOOST_FUNCTION_NO_DEPRECATED
823 typedef typename base_type::policy_type policy_type;
824 typedef typename base_type::mixin_type mixin_type;
825 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
826 typedef typename base_type::allocator_type allocator_type;
827 typedef function self_type;
829 function() : base_type() {}
831 template<typename Functor>
832 function(Functor BOOST_FUNCTION_TARGET_FIX(const &) f) : base_type(f) {}
834 function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
836 template<typename Functor>
837 self_type& operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
839 self_type(f).swap(*this);
843 self_type& operator=(const base_type& f)
845 self_type(f).swap(*this);
849 self_type& operator=(const self_type& f)
851 self_type(f).swap(*this);
855 #ifndef BOOST_FUNCTION_NO_DEPRECATED
856 template<typename Functor>
857 BOOST_FUNCTION_DEPRECATED_PRE
858 void set(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
860 BOOST_FUNCTION_DEPRECATED_INNER
861 self_type(f).swap(*this);
864 BOOST_FUNCTION_DEPRECATED_PRE
865 void set(const base_type& f)
867 BOOST_FUNCTION_DEPRECATED_INNER
868 self_type(f).swap(*this);
871 BOOST_FUNCTION_DEPRECATED_PRE
872 void set(const self_type& f)
874 BOOST_FUNCTION_DEPRECATED_INNER
875 self_type(f).swap(*this);
877 #endif // ndef BOOST_FUNCTION_NO_DEPRECATED
891 inline void swap(function<R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>& f1,
892 function<R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>& f2)
896 } // end namespace boost
898 #endif // !no deprecated || !no partial specialization