]> git.lyx.org Git - lyx.git/blob - boost/boost/function.hpp
update boost
[lyx.git] / boost / boost / function.hpp
1 // Boost.Function library
2
3 // Copyright (C) 2001 Doug Gregor (gregod@cs.rpi.edu)
4 //
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.
10 //
11 // This software is provided "as is" without express or implied warranty,
12 // and with no claim as to its suitability for any purpose.
13  
14 // For more information, see http://www.boost.org
15  
16 // William Kempf, Jesse Jones and Karl Nelson were all very helpful in the
17 // design of this library.
18
19 #ifndef BOOST_FUNCTION_HPP
20 #define BOOST_FUNCTION_HPP
21
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>
38
39 namespace boost {
40   namespace detail {
41     namespace function {
42 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
43       template<typename Signature> 
44       struct function_traits
45       {
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;
57       };
58
59       template<typename R>
60       struct function_traits<R (*)(void)>
61       {
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;
73       };
74       
75       template<typename R, typename T1>
76       struct function_traits<R (*)(T1)>
77       {
78         typedef R result_type;
79         typedef T1 arg1_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;
89       };
90       
91       template<typename R, typename T1, typename T2>
92       struct function_traits<R (*)(T1, T2)>
93       {
94         typedef R result_type;
95         typedef T1 arg1_type;
96         typedef T2 arg2_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;
105       };
106
107       template<typename R, typename T1, typename T2, typename T3>
108       struct function_traits<R (*)(T1, T2, T3)>
109       {
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;
121       };
122
123       template<typename R, typename T1, typename T2, typename T3, typename T4>
124       struct function_traits<R (*)(T1, T2, T3, T4)>
125       {
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;
137       };
138
139       template<typename R, typename T1, typename T2, typename T3, typename T4,
140                typename T5>
141       struct function_traits<R (*)(T1, T2, T3, T4, T5)>
142       {
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;
154       };
155
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)>
159       {
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;
171       };
172
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)>
176       {
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;
188       };
189
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)>
193       {
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;
205       };
206
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)>
210       {
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;
222       };
223
224       template<typename R, typename T1, typename T2, typename T3, typename T4,
225                typename T5, typename T6, typename T7, typename T8, typename T9,
226                typename T10>
227       struct function_traits<R (*)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)>
228       {
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;
240       };
241 #endif
242
243       // Choose the appropriate underlying implementation
244       template<int Args> struct real_get_function_impl {};
245
246       template<>
247       struct real_get_function_impl<0>
248       {
249         template<
250           typename R, 
251           typename T1,
252           typename T2,
253           typename T3,
254           typename T4,
255           typename T5,
256           typename T6,
257           typename T7,
258           typename T8,
259           typename T9,
260           typename T10,
261           typename Policy,
262           typename Mixin,
263           typename Allocator
264         >
265         struct params
266         {
267           typedef function0<R, Policy, Mixin, Allocator> type;
268         };
269       };
270
271       template<>
272       struct real_get_function_impl<1>
273       {
274         template<
275           typename R, 
276           typename T1,
277           typename T2,
278           typename T3,
279           typename T4,
280           typename T5,
281           typename T6,
282           typename T7,
283           typename T8,
284           typename T9,
285           typename T10,
286           typename Policy,
287           typename Mixin,
288           typename Allocator
289         >
290         struct params
291         {
292           typedef function1<R, T1, Policy, Mixin, Allocator> type;
293         };
294       };
295
296       template<>
297       struct real_get_function_impl<2>
298       {
299         template<
300           typename R, 
301           typename T1,
302           typename T2,
303           typename T3,
304           typename T4,
305           typename T5,
306           typename T6,
307           typename T7,
308           typename T8,
309           typename T9,
310           typename T10,
311           typename Policy,
312           typename Mixin,
313           typename Allocator
314         >
315         struct params
316         {
317           typedef function2<R, T1, T2, Policy, Mixin, Allocator> type;
318         };
319       };
320
321       template<>
322       struct real_get_function_impl<3>
323       {
324         template<
325           typename R, 
326           typename T1,
327           typename T2,
328           typename T3,
329           typename T4,
330           typename T5,
331           typename T6,
332           typename T7,
333           typename T8,
334           typename T9,
335           typename T10,
336           typename Policy,
337           typename Mixin,
338           typename Allocator
339         >
340         struct params
341         {
342           typedef function3<R, T1, T2, T3, Policy, Mixin, Allocator> type;
343         };
344       };
345
346       template<>
347       struct real_get_function_impl<4>
348       {
349         template<
350           typename R, 
351           typename T1,
352           typename T2,
353           typename T3,
354           typename T4,
355           typename T5,
356           typename T6,
357           typename T7,
358           typename T8,
359           typename T9,
360           typename T10,
361           typename Policy,
362           typename Mixin,
363           typename Allocator
364         >
365         struct params
366         {
367           typedef function4<R, T1, T2, T3, T4, Policy, Mixin, Allocator> type;
368         };
369       };
370
371       template<>
372       struct real_get_function_impl<5>
373       {
374         template<
375           typename R, 
376           typename T1,
377           typename T2,
378           typename T3,
379           typename T4,
380           typename T5,
381           typename T6,
382           typename T7,
383           typename T8,
384           typename T9,
385           typename T10,
386           typename Policy,
387           typename Mixin,
388           typename Allocator
389         >
390         struct params
391         {
392           typedef function5<R, T1, T2, T3, T4, T5, Policy, Mixin, Allocator> 
393           type;
394         };
395       };
396
397       template<>
398       struct real_get_function_impl<6>
399       {
400         template<
401           typename R, 
402           typename T1,
403           typename T2,
404           typename T3,
405           typename T4,
406           typename T5,
407           typename T6,
408           typename T7,
409           typename T8,
410           typename T9,
411           typename T10,
412           typename Policy,
413           typename Mixin,
414           typename Allocator
415         >
416         struct params
417         {
418           typedef function6<R, T1, T2, T3, T4, T5, T6, Policy, Mixin, Allocator>
419           type;
420         };
421       };
422
423       template<>
424       struct real_get_function_impl<7>
425       {
426         template<
427           typename R, 
428           typename T1,
429           typename T2,
430           typename T3,
431           typename T4,
432           typename T5,
433           typename T6,
434           typename T7,
435           typename T8,
436           typename T9,
437           typename T10,
438           typename Policy,
439           typename Mixin,
440           typename Allocator
441         >
442         struct params
443         {
444           typedef function7<R, T1, T2, T3, T4, T5, T6, T7, Policy, Mixin, 
445                             Allocator> type;
446         };
447       };
448
449       template<>
450       struct real_get_function_impl<8>
451       {
452         template<
453           typename R, 
454           typename T1,
455           typename T2,
456           typename T3,
457           typename T4,
458           typename T5,
459           typename T6,
460           typename T7,
461           typename T8,
462           typename T9,
463           typename T10,
464           typename Policy,
465           typename Mixin,
466           typename Allocator
467         >
468         struct params
469         {
470           typedef function8<R, T1, T2, T3, T4, T5, T6, T7, T8, Policy, Mixin, 
471                             Allocator> type;
472         };
473       };
474
475       template<>
476       struct real_get_function_impl<9>
477       {
478         template<
479           typename R, 
480           typename T1,
481           typename T2,
482           typename T3,
483           typename T4,
484           typename T5,
485           typename T6,
486           typename T7,
487           typename T8,
488           typename T9,
489           typename T10,
490           typename Policy,
491           typename Mixin,
492           typename Allocator
493         >
494         struct params
495         {
496           typedef function9<R, T1, T2, T3, T4, T5, T6, T7, T8, T9, Policy, 
497                             Mixin, Allocator> type;
498         };
499       };
500
501       template<>
502       struct real_get_function_impl<10>
503       {
504         template<
505           typename R, 
506           typename T1,
507           typename T2,
508           typename T3,
509           typename T4,
510           typename T5,
511           typename T6,
512           typename T7,
513           typename T8,
514           typename T9,
515           typename T10,
516           typename Policy,
517           typename Mixin,
518           typename Allocator
519         >
520         struct params
521         {
522           typedef function10<R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, 
523                              Policy, Mixin, Allocator> type;
524         };
525       };
526
527       template<typename T1, typename T2>
528       struct is_not_same
529       {
530             BOOST_STATIC_CONSTANT(bool, value = !(is_same<T1, T2>::value));
531       };
532
533       template<
534         typename InR, 
535         typename InT1, 
536         typename InT2, 
537         typename InT3, 
538         typename InT4,
539         typename InT5, 
540         typename InT6, 
541         typename InT7, 
542         typename InT8, 
543         typename InT9,
544         typename InT10,
545         typename InPolicy = empty_function_policy,
546         typename InMixin = empty_function_mixin,
547         typename InAllocator = std::allocator<function_base> 
548       >
549       class get_function_impl
550       {
551 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
552         typedef function_traits<typename add_pointer<InR>::type> traits;
553       public:                       
554
555         typedef typename ct_if<(is_function<InR>::value),
556                                typename traits::result_type,
557                                InR>::type R;
558         typedef typename ct_if<(is_function<InR>::value),
559                                typename traits::arg1_type,
560                                InT1>::type T1;
561         typedef typename ct_if<(is_function<InR>::value),
562                                typename traits::arg2_type,
563                                InT2>::type T2;
564         typedef typename ct_if<(is_function<InR>::value),
565                                typename traits::arg3_type,
566                                InT3>::type T3;
567         typedef typename ct_if<(is_function<InR>::value),
568                                typename traits::arg4_type,
569                                InT4>::type T4;
570         typedef typename ct_if<(is_function<InR>::value),
571                                typename traits::arg5_type,
572                                InT5>::type T5;
573         typedef typename ct_if<(is_function<InR>::value),
574                                typename traits::arg6_type,
575                                InT6>::type T6;
576         typedef typename ct_if<(is_function<InR>::value),
577                                typename traits::arg7_type,
578                                InT7>::type T7;
579         typedef typename ct_if<(is_function<InR>::value),
580                                typename traits::arg8_type,
581                                InT8>::type T8;
582         typedef typename ct_if<(is_function<InR>::value),
583                                typename traits::arg9_type,
584                                InT9>::type T9;
585         typedef typename ct_if<(is_function<InR>::value),
586                                typename traits::arg10_type,
587                                InT10>::type T10;        
588         typedef typename ct_if<
589                            (type_traits::ice_and<
590                              (is_function<InR>::value),
591                              (is_not_same<InT1, unusable>::value)
592                             >::value),
593                            InT1,
594                            InPolicy>::type Policy;
595
596         typedef typename ct_if<
597                            (type_traits::ice_and<
598                              (is_function<InR>::value),
599                              (is_not_same<InT2, unusable>::value)
600                             >::value),
601                            InT2,
602                            InMixin>::type Mixin;
603
604         typedef typename ct_if<
605                            (type_traits::ice_and<
606                              (is_function<InR>::value),
607                              (is_not_same<InT3, unusable>::value)
608                             >::value),
609                            InT3,
610                            InAllocator>::type Allocator;
611 #else
612       public:                       
613                 typedef InR R;
614                 typedef InT1 T1;
615                 typedef InT2 T2;
616                 typedef InT3 T3;
617                 typedef InT4 T4;
618                 typedef InT5 T5;
619                 typedef InT6 T6;
620                 typedef InT7 T7;
621                 typedef InT8 T8;
622                 typedef InT9 T9;
623                 typedef InT10 T10;
624                 typedef InPolicy Policy;
625                 typedef InMixin Mixin;
626                 typedef InAllocator Allocator;
627 #endif
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
632         type;
633       };
634
635   template<
636     typename InR, 
637     typename InT1, 
638     typename InT2, 
639     typename InT3, 
640     typename InT4,
641     typename InT5, 
642     typename InT6, 
643     typename InT7, 
644     typename InT8, 
645     typename InT9,
646     typename InT10,
647     typename InMyPolicy = empty_function_policy,
648     typename InMyMixin = empty_function_mixin,
649     typename InMyAllocator = std::allocator<function_base> 
650   >
651   class function_traits_builder
652   {
653     typedef get_function_impl<InR, InT1, InT2, InT3, InT4, InT5, InT6, InT7, 
654                               InT8, InT9, InT10, InMyPolicy, InMyMixin, 
655                               InMyAllocator>
656       impl;
657
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;
672
673   public:
674     typedef typename impl::type type;
675     typedef MyPolicy    policy_type;
676     typedef MyMixin     mixin_type;
677     typedef MyAllocator allocator_type;
678
679 #ifndef BOOST_NO_DEPENDENT_NESTED_DERIVATIONS
680     template<typename Policy>
681     struct policy : 
682         public function_traits_builder<MyR, MyT1, MyT2, MyT3, MyT4, MyT5, MyT6,
683                                        MyT7, MyT8, MyT9, MyT10, Policy, 
684                                        mixin_type, allocator_type> {};
685
686     template<typename Mixin>
687     struct mixin : 
688         public function_traits_builder<MyR, MyT1, MyT2, MyT3, MyT4, MyT5, MyT6,
689                                        MyT7, MyT8, MyT9, MyT10, policy_type, 
690                                        Mixin, allocator_type> {};
691
692     template<typename Allocator>
693     struct allocator : 
694         public function_traits_builder<MyR, MyT1, MyT2, MyT3, MyT4, MyT5, MyT6,
695                                        MyT7, MyT8, MyT9, MyT10, policy_type, 
696                                        mixin_type, Allocator> {};
697 #else
698     template<typename Policy>
699     struct policy 
700     {
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
705         type;
706     };
707
708     template<typename Mixin>
709     struct mixin
710     {
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
715         type;
716     };
717
718     template<typename Allocator>
719     struct allocator
720     {
721       typedef typename function_traits_builder<MyR, MyT1, MyT2, MyT3, MyT4, 
722                                                MyT5, MyT6, MyT7, MyT8, MyT9, 
723                                                MyT10, policy_type, mixin_type,
724                                                Allocator>::type
725         type;
726     };
727 #endif
728   };
729
730     } // end namespace function
731   } // end namespace detail
732
733   template<
734     typename R, 
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
745   >
746   class function :
747     public detail::function::get_function_impl<R, T1, T2, T3, T4, T5, T6, T7, 
748                                                T8, T9, T10>::type,
749     public detail::function::function_traits_builder<R, T1, T2, T3, T4, T5, T6,
750                                                      T7, T8, T9, T10>
751   {
752     typedef typename detail::function::get_function_impl<R, T1, T2, T3, T4, T5,
753                                                          T6, T7, T8, T9, T10
754                                                          >::type 
755       base_type;
756
757   public:
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;                                     
762                                                                             
763     function() : base_type() {}                                     
764                                                                             
765     template<typename Functor>                                              
766     function(Functor BOOST_FUNCTION_TARGET_FIX(const &) f) : base_type(f) {}
767                       
768     function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
769          
770     template<typename Functor>
771     self_type& operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
772     {
773       self_type(f).swap(*this);
774       return *this;
775     }
776
777     self_type& operator=(const base_type& f)
778     {
779       self_type(f).swap(*this);
780       return *this;
781     }
782
783     self_type& operator=(const self_type& f)
784     {   
785       self_type(f).swap(*this);
786       return *this;
787     }
788
789     template<typename Functor>
790     void set(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
791     {
792       int deprecated;
793       self_type(f).swap(*this);
794     }
795
796     void set(const base_type& f)
797     {
798       int deprecated;
799       self_type(f).swap(*this);
800     }
801
802     void set(const self_type& f)                             
803     {
804       int deprecated;
805       self_type(f).swap(*this);
806     }   
807   };
808
809   template<typename R,
810            typename T1, 
811            typename T2,
812            typename T3,
813            typename T4,
814            typename T5,
815            typename T6,
816            typename T7,
817            typename T8,
818            typename T9,
819            typename T10>
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)
822   {
823     f1.swap(f2);
824   }
825 } // end namespace boost
826
827 #endif