SCM Repositories - cpp-experiment


Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (download) (annotate)
Mon Jan 9 19:36:40 2006 UTC (3 years, 6 months ago) by alnsn
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +30 -30 lines
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