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