ossrv_pub/boost_apis/boost/lambda/detail/lambda_traits.hpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 // - lambda_traits.hpp --- Boost Lambda Library ----------------------------
       
     2 //
       
     3 // Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
       
     4 //
       
     5 // Distributed under the Boost Software License, Version 1.0. (See
       
     6 // accompanying file LICENSE_1_0.txt or copy at
       
     7 // http://www.boost.org/LICENSE_1_0.txt)
       
     8 //
       
     9 // For more information, see www.boost.org
       
    10 // -------------------------------------------------------------------------
       
    11 
       
    12 #ifndef BOOST_LAMBDA_LAMBDA_TRAITS_HPP
       
    13 #define BOOST_LAMBDA_LAMBDA_TRAITS_HPP
       
    14 
       
    15 #include "boost/type_traits/transform_traits.hpp"
       
    16 #include "boost/type_traits/cv_traits.hpp"
       
    17 #include "boost/type_traits/function_traits.hpp"
       
    18 #include "boost/type_traits/object_traits.hpp"
       
    19 
       
    20 namespace boost {
       
    21 namespace lambda {
       
    22 
       
    23 // -- if construct ------------------------------------------------
       
    24 // Proposed by Krzysztof Czarnecki and Ulrich Eisenecker
       
    25 
       
    26 namespace detail {
       
    27 
       
    28 template <bool If, class Then, class Else> struct IF { typedef Then RET; };
       
    29 
       
    30 template <class Then, class Else> struct IF<false, Then, Else> {
       
    31   typedef Else RET;
       
    32 };
       
    33 
       
    34 
       
    35 // An if construct that doesn't instantiate the non-matching template:
       
    36 
       
    37 // Called as: 
       
    38 //  IF_type<condition, A, B>::type 
       
    39 // The matching template must define the typeded 'type'
       
    40 // I.e. A::type if condition is true, B::type if condition is false
       
    41 // Idea from Vesa Karvonen (from C&E as well I guess)
       
    42 template<class T>
       
    43 struct IF_type_
       
    44 {
       
    45   typedef typename T::type type;
       
    46 };
       
    47 
       
    48 
       
    49 template<bool C, class T, class E>
       
    50 struct IF_type
       
    51 {
       
    52   typedef typename
       
    53     IF_type_<typename IF<C, T, E>::RET >::type type;
       
    54 };
       
    55 
       
    56 // helper that can be used to give typedef T to some type
       
    57 template <class T> struct identity_mapping { typedef T type; };
       
    58 
       
    59 // An if construct for finding an integral constant 'value'
       
    60 // Does not instantiate the non-matching branch
       
    61 // Called as IF_value<condition, A, B>::value
       
    62 // If condition is true A::value must be defined, otherwise B::value
       
    63 
       
    64 template<class T>
       
    65 struct IF_value_
       
    66 {
       
    67   BOOST_STATIC_CONSTANT(int, value = T::value);
       
    68 };
       
    69 
       
    70 
       
    71 template<bool C, class T, class E>
       
    72 struct IF_value
       
    73 {
       
    74   BOOST_STATIC_CONSTANT(int, value = (IF_value_<typename IF<C, T, E>::RET>::value));
       
    75 };
       
    76 
       
    77 
       
    78 // --------------------------------------------------------------
       
    79 
       
    80 // removes reference from other than function types:
       
    81 template<class T> class remove_reference_if_valid
       
    82 {
       
    83 
       
    84   typedef typename boost::remove_reference<T>::type plainT;
       
    85 public:
       
    86   typedef typename IF<
       
    87     boost::is_function<plainT>::value,
       
    88     T,
       
    89     plainT
       
    90   >::RET type;
       
    91 
       
    92 };
       
    93 
       
    94 
       
    95 template<class T> struct remove_reference_and_cv {
       
    96    typedef typename boost::remove_cv<
       
    97      typename boost::remove_reference<T>::type
       
    98    >::type type;
       
    99 };
       
   100 
       
   101 
       
   102    
       
   103 // returns a reference to the element of tuple T
       
   104 template<int N, class T> struct tuple_element_as_reference {   
       
   105   typedef typename
       
   106      boost::tuples::access_traits<
       
   107        typename boost::tuples::element<N, T>::type
       
   108      >::non_const_type type;
       
   109 };
       
   110 
       
   111 // returns the cv and reverence stripped type of a tuple element
       
   112 template<int N, class T> struct tuple_element_stripped {   
       
   113   typedef typename
       
   114      remove_reference_and_cv<
       
   115        typename boost::tuples::element<N, T>::type
       
   116      >::type type;
       
   117 };
       
   118 
       
   119 // is_lambda_functor -------------------------------------------------   
       
   120 
       
   121 template <class T> struct is_lambda_functor_ {
       
   122   BOOST_STATIC_CONSTANT(bool, value = false);
       
   123 };
       
   124    
       
   125 template <class Arg> struct is_lambda_functor_<lambda_functor<Arg> > {
       
   126   BOOST_STATIC_CONSTANT(bool, value = true);
       
   127 };
       
   128    
       
   129 } // end detail
       
   130 
       
   131    
       
   132 template <class T> struct is_lambda_functor {
       
   133   BOOST_STATIC_CONSTANT(bool, 
       
   134      value = 
       
   135        detail::is_lambda_functor_<
       
   136          typename detail::remove_reference_and_cv<T>::type
       
   137        >::value);
       
   138 };
       
   139    
       
   140 
       
   141 namespace detail {
       
   142 
       
   143 // -- parameter_traits_ ---------------------------------------------
       
   144 
       
   145 // An internal parameter type traits class that respects
       
   146 // the reference_wrapper class.
       
   147 
       
   148 // The conversions performed are:
       
   149 // references -> compile_time_error
       
   150 // T1 -> T2, 
       
   151 // reference_wrapper<T> -> T&
       
   152 // const array -> ref to const array
       
   153 // array -> ref to array
       
   154 // function -> ref to function
       
   155 
       
   156 // ------------------------------------------------------------------------
       
   157 
       
   158 template<class T1, class T2> 
       
   159 struct parameter_traits_ {
       
   160   typedef T2 type;
       
   161 };
       
   162 
       
   163 // Do not instantiate with reference types
       
   164 template<class T, class Any> struct parameter_traits_<T&, Any> {
       
   165   typedef typename 
       
   166     generate_error<T&>::
       
   167       parameter_traits_class_instantiated_with_reference_type type;
       
   168 };
       
   169 
       
   170 // Arrays can't be stored as plain types; convert them to references
       
   171 template<class T, int n, class Any> struct parameter_traits_<T[n], Any> {
       
   172   typedef T (&type)[n];
       
   173 };
       
   174    
       
   175 template<class T, int n, class Any> 
       
   176 struct parameter_traits_<const T[n], Any> {
       
   177   typedef const T (&type)[n];
       
   178 };
       
   179 
       
   180 template<class T, int n, class Any> 
       
   181 struct parameter_traits_<volatile T[n], Any> {
       
   182   typedef volatile  T (&type)[n];
       
   183 };
       
   184 template<class T, int n, class Any> 
       
   185 struct parameter_traits_<const volatile T[n], Any> {
       
   186   typedef const volatile T (&type)[n];
       
   187 };
       
   188 
       
   189 
       
   190 template<class T, class Any> 
       
   191 struct parameter_traits_<boost::reference_wrapper<T>, Any >{
       
   192   typedef T& type;
       
   193 };
       
   194 
       
   195 template<class T, class Any> 
       
   196 struct parameter_traits_<const boost::reference_wrapper<T>, Any >{
       
   197   typedef T& type;
       
   198 };
       
   199 
       
   200 template<class T, class Any> 
       
   201 struct parameter_traits_<volatile boost::reference_wrapper<T>, Any >{
       
   202   typedef T& type;
       
   203 };
       
   204 
       
   205 template<class T, class Any> 
       
   206 struct parameter_traits_<const volatile boost::reference_wrapper<T>, Any >{
       
   207   typedef T& type;
       
   208 };
       
   209 
       
   210 template<class Any>
       
   211 struct parameter_traits_<void, Any> {
       
   212   typedef void type;
       
   213 };
       
   214 
       
   215 template<class Arg, class Any>
       
   216 struct parameter_traits_<lambda_functor<Arg>, Any > {
       
   217   typedef lambda_functor<Arg> type;
       
   218 };
       
   219 
       
   220 template<class Arg, class Any>
       
   221 struct parameter_traits_<const lambda_functor<Arg>, Any > {
       
   222   typedef lambda_functor<Arg> type;
       
   223 };
       
   224 
       
   225 // Are the volatile versions needed?
       
   226 template<class Arg, class Any>
       
   227 struct parameter_traits_<volatile lambda_functor<Arg>, Any > {
       
   228   typedef lambda_functor<Arg> type;
       
   229 };
       
   230 
       
   231 template<class Arg, class Any>
       
   232 struct parameter_traits_<const volatile lambda_functor<Arg>, Any > {
       
   233   typedef lambda_functor<Arg> type;
       
   234 };
       
   235 
       
   236 } // end namespace detail
       
   237 
       
   238 
       
   239 // ------------------------------------------------------------------------
       
   240 // traits classes for lambda expressions (bind functions, operators ...)   
       
   241 
       
   242 // must be instantiated with non-reference types
       
   243 
       
   244 // The default is const plain type -------------------------
       
   245 // const T -> const T, 
       
   246 // T -> const T, 
       
   247 // references -> compile_time_error
       
   248 // reference_wrapper<T> -> T&
       
   249 // array -> const ref array
       
   250 template<class T>
       
   251 struct const_copy_argument {
       
   252   typedef typename 
       
   253     detail::parameter_traits_<
       
   254       T,
       
   255       typename detail::IF<boost::is_function<T>::value, T&, const T>::RET
       
   256     >::type type;
       
   257 };
       
   258 
       
   259 // T may be a function type. Without the IF test, const would be added 
       
   260 // to a function type, which is illegal.
       
   261 
       
   262 // all arrays are converted to const.
       
   263 // This traits template is used for 'const T&' parameter passing 
       
   264 // and thus the knowledge of the potential 
       
   265 // non-constness of an actual argument is lost.   
       
   266 template<class T, int n>  struct const_copy_argument <T[n]> {
       
   267   typedef const T (&type)[n];
       
   268 };
       
   269 template<class T, int n>  struct const_copy_argument <volatile T[n]> {
       
   270      typedef const volatile T (&type)[n];
       
   271 };
       
   272    
       
   273 template<class T>
       
   274 struct const_copy_argument<T&> {};
       
   275 // do not instantiate with references
       
   276   //  typedef typename detail::generate_error<T&>::references_not_allowed type;
       
   277 
       
   278 
       
   279 template<>
       
   280 struct const_copy_argument<void> {
       
   281   typedef void type;
       
   282 };
       
   283 
       
   284 
       
   285 // Does the same as const_copy_argument, but passes references through as such
       
   286 template<class T>
       
   287 struct bound_argument_conversion {
       
   288   typedef typename const_copy_argument<T>::type type; 
       
   289 };
       
   290 
       
   291 template<class T>
       
   292 struct bound_argument_conversion<T&> {
       
   293   typedef T& type; 
       
   294 };
       
   295    
       
   296 // The default is non-const reference -------------------------
       
   297 // const T -> const T&, 
       
   298 // T -> T&, 
       
   299 // references -> compile_time_error
       
   300 // reference_wrapper<T> -> T&
       
   301 template<class T>
       
   302 struct reference_argument {
       
   303   typedef typename detail::parameter_traits_<T, T&>::type type; 
       
   304 };
       
   305 
       
   306 template<class T>
       
   307 struct reference_argument<T&> {
       
   308   typedef typename detail::generate_error<T&>::references_not_allowed type; 
       
   309 };
       
   310 
       
   311 template<class Arg>
       
   312 struct reference_argument<lambda_functor<Arg> > {
       
   313   typedef lambda_functor<Arg> type;
       
   314 };
       
   315 
       
   316 template<class Arg>
       
   317 struct reference_argument<const lambda_functor<Arg> > {
       
   318   typedef lambda_functor<Arg> type;
       
   319 };
       
   320 
       
   321 // Are the volatile versions needed?
       
   322 template<class Arg>
       
   323 struct reference_argument<volatile lambda_functor<Arg> > {
       
   324   typedef lambda_functor<Arg> type;
       
   325 };
       
   326 
       
   327 template<class Arg>
       
   328 struct reference_argument<const volatile lambda_functor<Arg> > {
       
   329   typedef lambda_functor<Arg> type;
       
   330 };
       
   331 
       
   332 template<>
       
   333 struct reference_argument<void> {
       
   334   typedef void type;
       
   335 };
       
   336 
       
   337 namespace detail {
       
   338    
       
   339 // Array to pointer conversion
       
   340 template <class T>
       
   341 struct array_to_pointer { 
       
   342   typedef T type;
       
   343 };
       
   344 
       
   345 template <class T, int N>
       
   346 struct array_to_pointer <const T[N]> { 
       
   347   typedef const T* type;
       
   348 };
       
   349 template <class T, int N>
       
   350 struct array_to_pointer <T[N]> { 
       
   351   typedef T* type;
       
   352 };
       
   353 
       
   354 template <class T, int N>
       
   355 struct array_to_pointer <const T (&) [N]> { 
       
   356   typedef const T* type;
       
   357 };
       
   358 template <class T, int N>
       
   359 struct array_to_pointer <T (&) [N]> { 
       
   360   typedef T* type;
       
   361 };
       
   362 
       
   363 
       
   364 // ---------------------------------------------------------------------------
       
   365 // The call_traits for bind
       
   366 // Respects the reference_wrapper class.
       
   367 
       
   368 // These templates are used outside of bind functions as well.
       
   369 // the bind_tuple_mapper provides a shorter notation for default
       
   370 // bound argument storing semantics, if all arguments are treated
       
   371 // uniformly.
       
   372 
       
   373 // from template<class T> foo(const T& t) : bind_traits<const T>::type
       
   374 // from template<class T> foo(T& t) : bind_traits<T>::type
       
   375 
       
   376 // Conversions:
       
   377 // T -> const T,
       
   378 // cv T -> cv T, 
       
   379 // T& -> T& 
       
   380 // reference_wrapper<T> -> T&
       
   381 // const reference_wrapper<T> -> T&
       
   382 // array -> const ref array
       
   383 
       
   384 // make bound arguments const, this is a deliberate design choice, the
       
   385 // purpose is to prevent side effects to bound arguments that are stored
       
   386 // as copies
       
   387 template<class T>
       
   388 struct bind_traits {
       
   389   typedef const T type; 
       
   390 };
       
   391 
       
   392 template<class T>
       
   393 struct bind_traits<T&> {
       
   394   typedef T& type; 
       
   395 };
       
   396 
       
   397 // null_types are an exception, we always want to store them as non const
       
   398 // so that other templates can assume that null_type is always without const
       
   399 template<>
       
   400 struct bind_traits<null_type> {
       
   401   typedef null_type type;
       
   402 };
       
   403 
       
   404 // the bind_tuple_mapper, bind_type_generators may 
       
   405 // introduce const to null_type
       
   406 template<>
       
   407 struct bind_traits<const null_type> {
       
   408   typedef null_type type;
       
   409 };
       
   410 
       
   411 // Arrays can't be stored as plain types; convert them to references.
       
   412 // All arrays are converted to const. This is because bind takes its
       
   413 // parameters as const T& and thus the knowledge of the potential 
       
   414 // non-constness of actual argument is lost.
       
   415 template<class T, int n>  struct bind_traits <T[n]> {
       
   416   typedef const T (&type)[n];
       
   417 };
       
   418 
       
   419 template<class T, int n> 
       
   420 struct bind_traits<const T[n]> {
       
   421   typedef const T (&type)[n];
       
   422 };
       
   423 
       
   424 template<class T, int n>  struct bind_traits<volatile T[n]> {
       
   425   typedef const volatile T (&type)[n];
       
   426 };
       
   427 
       
   428 template<class T, int n> 
       
   429 struct bind_traits<const volatile T[n]> {
       
   430   typedef const volatile T (&type)[n];
       
   431 };
       
   432 
       
   433 template<class T> 
       
   434 struct bind_traits<reference_wrapper<T> >{
       
   435   typedef T& type;
       
   436 };
       
   437 
       
   438 template<class T> 
       
   439 struct bind_traits<const reference_wrapper<T> >{
       
   440   typedef T& type;
       
   441 };
       
   442 
       
   443 template<>
       
   444 struct bind_traits<void> {
       
   445   typedef void type;
       
   446 };
       
   447 
       
   448 
       
   449 
       
   450 template <
       
   451   class T0 = null_type, class T1 = null_type, class T2 = null_type, 
       
   452   class T3 = null_type, class T4 = null_type, class T5 = null_type, 
       
   453   class T6 = null_type, class T7 = null_type, class T8 = null_type, 
       
   454   class T9 = null_type
       
   455 >
       
   456 struct bind_tuple_mapper {
       
   457   typedef
       
   458     tuple<typename bind_traits<T0>::type, 
       
   459           typename bind_traits<T1>::type, 
       
   460           typename bind_traits<T2>::type, 
       
   461           typename bind_traits<T3>::type, 
       
   462           typename bind_traits<T4>::type, 
       
   463           typename bind_traits<T5>::type, 
       
   464           typename bind_traits<T6>::type, 
       
   465           typename bind_traits<T7>::type,
       
   466           typename bind_traits<T8>::type,
       
   467           typename bind_traits<T9>::type> type;
       
   468 };
       
   469 
       
   470 // bind_traits, except map const T& -> const T
       
   471   // this is needed e.g. in currying. Const reference arguments can
       
   472   // refer to temporaries, so it is not safe to store them as references.
       
   473   template <class T> struct remove_const_reference {
       
   474     typedef typename bind_traits<T>::type type;
       
   475   };
       
   476 
       
   477   template <class T> struct remove_const_reference<const T&> {
       
   478     typedef const T type;
       
   479   };
       
   480 
       
   481 
       
   482 // maps the bind argument types to the resulting lambda functor type
       
   483 template <
       
   484   class T0 = null_type, class T1 = null_type, class T2 = null_type, 
       
   485   class T3 = null_type, class T4 = null_type, class T5 = null_type, 
       
   486   class T6 = null_type, class T7 = null_type, class T8 = null_type, 
       
   487   class T9 = null_type
       
   488 >
       
   489 class bind_type_generator {
       
   490 
       
   491   typedef typename
       
   492   detail::bind_tuple_mapper<
       
   493     T0, T1, T2, T3, T4, T5, T6, T7, T8, T9
       
   494   >::type args_t;
       
   495 
       
   496   BOOST_STATIC_CONSTANT(int, nof_elems = boost::tuples::length<args_t>::value);
       
   497 
       
   498   typedef 
       
   499     action<
       
   500       nof_elems, 
       
   501       function_action<nof_elems>
       
   502     > action_type;
       
   503 
       
   504 public:
       
   505   typedef
       
   506     lambda_functor<
       
   507       lambda_functor_base<
       
   508         action_type, 
       
   509         args_t
       
   510       >
       
   511     > type; 
       
   512     
       
   513 };
       
   514 
       
   515 
       
   516    
       
   517 } // detail
       
   518    
       
   519 template <class T> inline const T&  make_const(const T& t) { return t; }
       
   520 
       
   521 
       
   522 } // end of namespace lambda
       
   523 } // end of namespace boost
       
   524 
       
   525 
       
   526    
       
   527 #endif // BOOST_LAMBDA_TRAITS_HPP