Parent Directory
|
Revision Log
Major rewrite
1 // Copyright Alexander Nasonov 2005-2006 2 // 3 // Distributed under the Boost Software License, Version 1.0. 4 // (See accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt) 6 7 // TODO: rename to end.hpp 8 #if !BOOST_PP_IS_ITERATING 9 10 #ifndef FILE_boost_overloads_aux_get_end_hpp_INCLUDED 11 #define FILE_boost_overloads_aux_get_end_hpp_INCLUDED 12 13 #include <boost/config.hpp> 14 15 #include <boost/overloads/aux_/config.hpp> 16 #include <boost/overloads/aux_/not_id.hpp> 17 #include <boost/overloads/aux_/type_with_size.hpp> 18 19 #include <boost/overloads/config.hpp> 20 21 #include <boost/mpl/eval_if.hpp> 22 #include <boost/mpl/integral_c.hpp> 23 24 #include <boost/preprocessor/iteration/iterate.hpp> 25 #include <boost/preprocessor/repetition/enum_trailing_params.hpp> 26 27 namespace boost { namespace overloads { namespace aux { 28 29 template<class ID> 30 struct end_tester 31 { 32 template<class C> 33 static char test(void (C::*)(not_id) const, ...); 34 35 // Include end_tester declarations: 36 #define BOOST_PP_FILENAME_1 <boost/overloads/aux_/get_end_id.hpp> 37 #define BOOST_PP_ITERATION_LIMITS (0, BOOST_OVERLOADS_LIMIT_ARITY) 38 #include BOOST_PP_ITERATE() 39 40 }; 41 42 template<class T, long ID> 43 struct id_exists 44 { 45 // TODO: bind to an appropriate integral constant 46 typedef end_tester< ::boost::mpl::int_<ID> > tester; 47 48 BOOST_STATIC_CONSTANT(bool, 49 value = sizeof(tester::test(&add_not_id<T>::overload, 0)) != 1 50 ); 51 }; 52 53 template< 54 class T 55 , long Start 56 , long Finish 57 > 58 struct get_end_in_range 59 : mpl::eval_if< 60 id_exists<T,((Start+Finish)/2)> 61 , get_end_in_range<T,(1+(Start+Finish)/2),Finish> 62 , get_end_in_range<T,Start,((Start+Finish)/2)> 63 > 64 { 65 }; 66 67 template< 68 class T 69 , long ID 70 > 71 struct get_end_in_range<T,ID,ID> 72 { 73 typedef mpl::integral_c<long,ID> type; 74 }; 75 76 template< 77 class T 78 , long Start 79 , long Step 80 > 81 struct get_end_forward 82 : mpl::eval_if< 83 id_exists<T,(Start+Step)> 84 , get_end_forward<T,(Start+Step+1),Step> 85 , get_end_in_range<T,Start,(Start+Step)> 86 > 87 { 88 }; 89 90 template<class T> 91 struct end 92 : get_end_forward<T,1,BOOST_OVERLOADS_AUX_GET_END_ID_STEP> 93 { 94 }; 95 96 } } } 97 98 #endif // #ifndef FILE_boost_overloads_aux_get_end_hpp_INCLUDED 99 100 #else 101 102 #define n BOOST_PP_ITERATION() 103 104 template< class R, class C BOOST_PP_ENUM_TRAILING_PARAMS(n, class T) > 105 static typename type_with_size_c<2>::type 106 test( R (C::*)( ID BOOST_PP_ENUM_TRAILING_PARAMS(n, T)) const, int); 107 108 #undef n 109 110 #endif 111