Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

more/gen/lambda.h

Go to the documentation of this file.
00001 //  more/lambda.h -- expression templates for generating STL functionals
00002 //  Copyright (C) 1998--2002  Petter Urkedal
00003 //
00004 //  This file is free software; you can redistribute it and/or modify
00005 //  it under the terms of the GNU General Public License as published by
00006 //  the Free Software Foundation; either version 2 of the License, or
00007 //  (at your option) any later version.
00008 //
00009 //  This file is distributed in the hope that it will be useful,
00010 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 //  GNU General Public License for more details.
00013 //
00014 //  You should have received a copy of the GNU General Public License
00015 //  along with this program; if not, write to the Free Software
00016 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 //
00018 //  As a special exception, you may use this file as part of a free
00019 //  software library without restriction.  Specifically, if other files
00020 //  instantiate templates or use macros or inline functions from this
00021 //  file, or you compile this file and link it with other files to
00022 //  produce an executable, this file does not by itself cause the
00023 //  resulting executable to be covered by the GNU General Public
00024 //  License.  This exception does not however invalidate any other
00025 //  reasons why the executable file might be covered by the GNU General
00026 //  Public License.
00027 //
00028 //  $Id: lambda.h,v 1.2 2002/08/24 13:54:41 petter_urkedal Exp $
00029 
00030 
00031 #ifndef MORE_GEN_LAMBDA_H
00032 #define MORE_GEN_LAMBDA_H
00033 
00034 #include <iterator>
00035 #include <more/gen/functional.h>
00036 
00037 ///\if bits
00038 #define MORE_CR1(T) T // arguments to lambda-functionals
00039 #define MORE_CR2(T) T // args and data of placeholder assignments
00040 #define MORE_CR3(T) T // subexpressions of function expressions
00041 #define MORE_CR4(T) T // expression-data of lambda functions
00042 #define MORE_CR5(T) T // arguments to overloaded operators
00043 ///\endif
00044 
00045 //  `#define MORE_CR1(T) const T&' is safe, since MORE_CR1 only
00046 //  appears on arguments to `operator()'.
00047 //
00048 //  placeholder_assignments is never returned out of a context, so all
00049 //  members and arguments can be const T& placeholder_assign is only
00050 //  used in the former, so the same holds.  Thus, `#define MORE_CR2(T)
00051 //  const T&' is safe.
00052 //
00053 //  `#define MORE_CR3(T) const T&' is unsafe since subexressions may
00054 //  contain local data.  `#define MORE_CR4(T) const T&' violates
00055 //  constness.
00056 
00057 
00058 namespace more {
00059 namespace gen {
00060 
00061   //  Since we are using some general templates for operators, we hide
00062   //  all definitions, except for placeholders and interfacing
00063   //  functions, and rely on Koenig lookup.
00064   ///\if bits
00065   namespace lambda_kns {
00066 
00067     using std::unary_function;
00068     using std::binary_function;
00069 
00070     template<typename Expression=void> struct expr {};
00071     struct derivable_void {};
00072 
00073 
00074     // ---   p l a c e h o l d e r   &   v a l u e h o l d e r  ---
00075 
00076     template<typename Placeholder>
00077       struct placeholder_assign {
00078           typedef typename Placeholder::result_type value_type;
00079           MORE_CR2(value_type) value;
00080           placeholder_assign(MORE_CR2(value_type) value_) : value(value_) {}
00081       };
00082 
00083     template<typename Placeholder, typename Rest=derivable_void>
00084       struct placeholder_assignments
00085           : placeholder_assign<Placeholder>, Rest {
00086           typedef typename Placeholder::result_type value_type;
00087           placeholder_assignments(MORE_CR2(value_type) value_)
00088               : placeholder_assign<Placeholder>(value_) {}
00089           placeholder_assignments(MORE_CR2(value_type) value_,
00090                                   const Rest& rest)
00091               : placeholder_assign<Placeholder>(value_), Rest(rest) {}
00092       };
00093 
00094     template<int Place, typename Type> struct placeholder_expr {};
00095     template<int Place, typename Type>
00096       struct expr< placeholder_expr<Place, Type> > {
00097           typedef Type result_type;
00098           expr() {}
00099           expr(placeholder_expr<Place, Type>) {}
00100           template<typename Assign>
00101             result_type operator()(const Assign& assign) const {
00102                 return static_cast
00103                     <const placeholder_assign<expr>&>(assign).value;
00104           }
00105       };
00106 
00107     template<int Place, typename Type>
00108       struct placeholder
00109           : expr< placeholder_expr<Place, Type> > {};
00110 
00111     template<typename T> struct value_expr {};
00112     template<typename T>
00113       struct expr< value_expr<T> > {
00114           typedef T result_type;
00115           expr(const T& x_) : x(x_) {}
00116           template<typename Assign>
00117             const result_type& operator()(const Assign&) const { return x; }
00118           template<typename Assign>
00119             result_type& operator()(const Assign&) { return x; }
00120         private:
00121           result_type x;
00122       };
00123 
00124     template<typename T> struct valueref_expr {};
00125     template<typename T>
00126       struct expr< valueref_expr<T> > {
00127           typedef T& result_type;
00128           expr(T& x_) : x(x_) {}
00129           template<typename Assign>
00130             result_type operator()(const Assign&) const { return x; }
00131         private:
00132           result_type x;
00133       };
00134 
00135 
00136 
00137     // ---   l a m b d a   e x p r e s s i o n s   ---
00138 
00139     template<typename Expr>
00140       struct lambda_generator {
00141           typedef typename Expr::result_type result_type;
00142           lambda_generator() {}
00143           lambda_generator(const Expr& expr_) : expr(expr_) {}
00144           result_type operator()() {
00145               derivable_void vars;
00146               return expr(vars);
00147           }
00148           result_type operator()() const {
00149               derivable_void vars;
00150               return expr(vars);
00151           }
00152         private:
00153           MORE_CR4(Expr) expr;
00154       };
00155 
00156     template<typename Placeholder, typename Expr>
00157       struct unary_lambda_function
00158           : unary_function< typename Placeholder::result_type,
00159                             typename Expr::result_type > {
00160           typedef unary_function< typename Placeholder::result_type,
00161                                   typename Expr::result_type > base;
00162           typedef typename base::argument_type argument_type;
00163           typedef typename base::result_type result_type;
00164           unary_lambda_function() {}
00165           unary_lambda_function(const Expr& expr_) : expr(expr_) {}
00166           result_type operator()(MORE_CR1(argument_type) x) {
00167               typedef placeholder_assignments<Placeholder> asg1;
00168               return expr(asg1(x));
00169           }
00170           template<typename Assign>
00171             result_type operator()(const Assign& a,
00172                                    MORE_CR1(argument_type) x) {
00173                 typedef placeholder_assignments<Placeholder, Assign> asg1;
00174                 return expr(asg1(x, a));
00175           }
00176           result_type operator()(MORE_CR1(argument_type) x) const {
00177               typedef placeholder_assignments<Placeholder> asg1;
00178               return expr(asg1(x));
00179           }
00180           template<typename Assign>
00181             result_type operator()(const Assign& a,
00182                                    MORE_CR1(argument_type) x) const {
00183                 typedef placeholder_assignments<Placeholder, Assign> asg1;
00184                 return expr(asg1(x, a));
00185           }
00186         private:
00187           MORE_CR4(Expr) expr;
00188       };
00189 
00190 
00191     template< typename Placeholder1, typename Placeholder2,
00192               typename Expr >
00193       struct binary_lambda_function
00194           : binary_function< typename Placeholder1::result_type,
00195                              typename Placeholder2::result_type,
00196                              typename Expr::result_type > {
00197           typedef binary_function< typename Placeholder1::result_type,
00198                                    typename Placeholder2::result_type,
00199                                    typename Expr::result_type > base;
00200           typedef typename base::first_argument_type first_argument_type;
00201           typedef typename base::second_argument_type second_argument_type;
00202           typedef typename base::result_type result_type;
00203           binary_lambda_function() {}
00204           binary_lambda_function(const Expr& expr_) : expr(expr_) {}
00205           result_type operator()(MORE_CR1(first_argument_type) x,
00206                                  MORE_CR1(second_argument_type) y) {
00207               typedef placeholder_assignments<Placeholder2> asg2;
00208               typedef placeholder_assignments<Placeholder1, asg2> asg1;
00209               return expr(asg1(x, asg2(y)));
00210           }
00211           template<typename Assign>
00212             result_type operator()(const Assign& a,
00213                                    MORE_CR1(first_argument_type) x,
00214                                    MORE_CR1(second_argument_type) y) {
00215                 typedef placeholder_assignments<Placeholder2, Assign> asg2;
00216                 typedef placeholder_assignments<Placeholder1, asg2> asg1;
00217                 return expr(asg1(x, asg2(y, a)));
00218           }
00219           result_type operator()(MORE_CR1(first_argument_type) x,
00220                                  MORE_CR1(second_argument_type) y) const {
00221               typedef placeholder_assignments<Placeholder2> asg2;
00222               typedef placeholder_assignments<Placeholder1, asg2> asg1;
00223               return expr(asg1(x, asg2(y)));
00224           }
00225           template<typename Assign>
00226             result_type operator()(const Assign& a,
00227                                    MORE_CR1(first_argument_type) x,
00228                                    MORE_CR1(second_argument_type) y) const {
00229                 typedef placeholder_assignments<Placeholder2, Assign> asg2;
00230                 typedef placeholder_assignments<Placeholder1, asg2> asg1;
00231                 return expr(asg1(x, asg2(y, a)));
00232           }
00233         private:
00234           MORE_CR4(Expr) expr;
00235       };
00236 
00237 
00238     template< typename Placeholder1, typename Placeholder2,
00239               typename Placeholder3, typename Expr >
00240       struct ternary_lambda_function
00241           : ternary_function< typename Placeholder1::result_type,
00242                               typename Placeholder2::result_type,
00243                               typename Placeholder3::result_type,
00244                               typename Expr::result_type > {
00245           typedef ternary_function< typename Placeholder1::result_type,
00246                                     typename Placeholder2::result_type,
00247                                     typename Placeholder3::result_type,
00248                                     typename Expr::result_type > base;
00249           typedef typename base::first_argument_type first_argument_type;
00250           typedef typename base::second_argument_type second_argument_type;
00251           typedef typename base::third_argument_type third_argument_type;
00252           typedef typename base::result_type result_type;
00253           ternary_lambda_function() {}
00254           ternary_lambda_function(const Expr& expr_) : expr(expr_) {}
00255           result_type operator()(MORE_CR1(first_argument_type) x,
00256                                  MORE_CR1(second_argument_type) y,
00257                                  MORE_CR1(third_argument_type) z) {
00258               typedef placeholder_assignments< Placeholder3 > asg3;
00259               typedef placeholder_assignments< Placeholder2, asg3 > asg2;
00260               typedef placeholder_assignments< Placeholder1, asg2 > asg1;
00261               return expr(asg1(x, asg2(y, asg3(z))));
00262           }
00263           template<typename Assign>
00264             result_type operator()(const Assign& a,
00265                                    MORE_CR1(first_argument_type) x,
00266                                    MORE_CR1(second_argument_type) y,
00267                                    MORE_CR1(third_argument_type) z) {
00268                 typedef placeholder_assignments< Placeholder3, Assign > asg3;
00269                 typedef placeholder_assignments< Placeholder2, asg3 > asg2;
00270                 typedef placeholder_assignments< Placeholder1, asg2 > asg1;
00271                 return expr(asg1(x, asg2(y, asg3(z, a))));
00272           }
00273           result_type operator()(MORE_CR1(first_argument_type) x,
00274                                  MORE_CR1(second_argument_type) y,
00275                                  MORE_CR1(third_argument_type) z) const {
00276               typedef placeholder_assignments< Placeholder3 > asg3;
00277               typedef placeholder_assignments< Placeholder2, asg3 > asg2;
00278               typedef placeholder_assignments< Placeholder1, asg2 > asg1;
00279               return expr(asg1(x, asg2(y, asg3(z))));
00280           }
00281           template<typename Assign>
00282             result_type operator()(const Assign& a,
00283                                    MORE_CR1(first_argument_type) x,
00284                                    MORE_CR1(second_argument_type) y,
00285                                    MORE_CR1(third_argument_type) z) const {
00286                 typedef placeholder_assignments< Placeholder3, Assign > asg3;
00287                 typedef placeholder_assignments< Placeholder2, asg3 > asg2;
00288                 typedef placeholder_assignments< Placeholder1, asg2 > asg1;
00289                 return expr(asg1(x, asg2(y, asg3(z, a))));
00290           }
00291         private:
00292           MORE_CR4(Expr) expr;
00293       };
00294 
00295 
00296     template<typename Expr> inline
00297       lambda_generator<Expr> lambda(const Expr& a) {
00298           return lambda_generator<Expr>(a);
00299       }
00300 
00301     template<int Place, typename Type, typename Expr> inline
00302       unary_lambda_function< expr< placeholder_expr<Place, Type> >, Expr>
00303       lambda(const expr< placeholder_expr<Place, Type> >&, const Expr& a) {
00304           return unary_lambda_function
00305               < expr< placeholder_expr<Place, Type> >, Expr >(a);
00306       }
00307 
00308     template< int Place1, typename Type1,
00309               int Place2, typename Type2, typename Expr > inline
00310       binary_lambda_function
00311         < expr< placeholder_expr<Place1, Type1> >,
00312           expr< placeholder_expr<Place2, Type2> >, Expr >
00313       lambda(const expr< placeholder_expr<Place1, Type1> >&,
00314              const expr< placeholder_expr<Place2, Type2> >&,
00315              const Expr& a) {
00316         return binary_lambda_function
00317             < expr< placeholder_expr<Place1, Type1> >,
00318               expr< placeholder_expr<Place2, Type2> >, Expr >(a);
00319       }
00320 
00321 
00322     // ---   a p p l y   ---
00323 
00324     // --- metaprogram which reduces the number of
00325     //     function-templates for binary operators from 6 to 1 ---
00326 
00327     template<typename T> struct which_expr
00328         { typedef expr< value_expr<T> > eval; };
00329     template<int N, typename T> struct which_expr< placeholder<N, T> >
00330         { typedef expr< placeholder_expr<N, T> > eval; };
00331     template<typename Expr > struct which_expr< expr<Expr> >
00332         { typedef expr<Expr> eval; };
00333 
00334     template<typename E>
00335       struct which_expr< lambda_generator<E> >
00336         { typedef lambda_generator<E> eval; };
00337     template<typename P, typename E>
00338       struct which_expr< unary_lambda_function<P, E> >
00339         { typedef unary_lambda_function<P, E> eval; };
00340     template<typename P1, typename P2, typename E>
00341       struct which_expr< binary_lambda_function<P1, P2, E> >
00342         { typedef binary_lambda_function<P1, P2, E> eval; };
00343 
00344 
00345     template<typename Generator>
00346       struct generator_expr {};
00347     template<typename Generator>
00348       struct expr< generator_expr<Generator> > {
00349           typedef typename Generator::result_type result_tmp;
00350           typedef typename result_tmp::result_type result_type;
00351           result_type operator()() {
00352               return f(derivable_void())();
00353           }
00354           template<typename Assign>
00355             result_type operator()(const Assign& a) {
00356                 return f(a)();
00357             }
00358           template<typename Assign>
00359             result_type operator()(const Assign& a) const {
00360                 return f(a)();
00361             }
00362           expr(const Generator& f_) : f(f_) {};
00363         private:
00364           MORE_CR3(Generator) f;
00365       };
00366 
00367     template<typename Expr>
00368       struct expr< generator_expr< lambda_generator<Expr> > > {
00369           typedef lambda_generator<Expr> function_type;
00370           typedef typename function_type::result_type result_type;
00371           template<typename Assign>
00372             result_type operator()(const Assign& a) {
00373                 return f(a);
00374             }
00375           template<typename Assign>
00376             result_type operator()(const Assign& a) const {
00377                 return f(a);
00378             }
00379           expr(const function_type& f_) : f(f_) {};
00380         private:
00381           MORE_CR3(function_type) f;
00382       };
00383 
00384     template<typename UnaryFunction, typename Expr>
00385       struct unary_function_expr {};
00386     template<typename UnaryFunction, typename Expr>
00387       struct expr< unary_function_expr<UnaryFunction, Expr> > {
00388           typedef typename UnaryFunction::result_type result_tmp;
00389           typedef typename result_tmp::result_type result_type;
00390           result_type operator()() {
00391               return f(derivable_void())(x(derivable_void()));
00392           }
00393           template<typename Assign>
00394             result_type operator()(const Assign& a) {
00395                 return f(a)(x(a));
00396             }
00397           template<typename Assign>
00398             result_type operator()(const Assign& a) const {
00399                 return f(a)(x(a));
00400             }
00401           expr(const UnaryFunction& f_, const Expr& x_) : f(f_), x(x_) {};
00402         private:
00403           MORE_CR3(UnaryFunction) f;
00404           MORE_CR3(Expr) x;
00405       };
00406 
00407     template<typename Placeholder, typename SubExpr, typename Expr>
00408       struct expr< unary_function_expr
00409                     < unary_lambda_function<Placeholder, SubExpr>, Expr> > {
00410           typedef unary_lambda_function<Placeholder, SubExpr > function_type;
00411           typedef typename function_type::result_type result_type;
00412           template<typename Assign>
00413             result_type operator()(const Assign& a) {
00414                 return f(a, x(a));
00415             }
00416           template<typename Assign>
00417             result_type operator()(const Assign& a) const {
00418                 return f(a, x(a));
00419             }
00420           expr(const function_type& f_, const Expr& x_) : f(f_), x(x_) {};
00421         private:
00422           MORE_CR3(function_type) f;
00423           MORE_CR3(Expr) x;
00424       };
00425 
00426     template<typename BinaryFunction, typename Expr1, typename Expr2>
00427       struct binary_function_expr {};
00428     template<typename BinaryFunction, typename Expr1, typename Expr2>
00429       struct expr< binary_function_expr<BinaryFunction, Expr1, Expr2> > {
00430           typedef typename BinaryFunction::result_type result_tmp;
00431           typedef typename result_tmp::result_type result_type;
00432           result_type operator()() {
00433               return f(derivable_void())(x(derivable_void()),
00434                                          y(derivable_void()));
00435           }
00436           template<typename Assign>
00437             result_type operator()(const Assign& a) {
00438                 return f(a)(x(a), y(a));
00439             }
00440           template<typename Assign>
00441             result_type operator()(const Assign& a) const {
00442                 return f(a)(x(a), y(a));
00443             }
00444           expr(const BinaryFunction& f_, const Expr1& x_, const Expr2& y_)
00445               : f(f_), x(x_), y(y_) {}
00446         private:
00447           MORE_CR3(BinaryFunction) f;
00448           MORE_CR3(Expr1) x;
00449           MORE_CR3(Expr2) y;
00450       };
00451 
00452     template< typename Place1, typename Place2, typename SubExpr,
00453               typename Expr1, typename Expr2 >
00454       struct expr< binary_function_expr
00455                      < binary_lambda_function<Place1, Place2, SubExpr>,
00456                        Expr1, Expr2> > {
00457           typedef binary_lambda_function<Place1, Place2, SubExpr>
00458                   function_type;
00459           typedef typename function_type::result_type result_type;
00460           template<typename Assign>
00461             result_type operator()(const Assign& a) {
00462                 return f(a, x(a), y(a));
00463             }
00464           template<typename Assign>
00465             result_type operator()(const Assign& a) const {
00466                 return f(a, x(a), y(a));
00467             }
00468           expr(const function_type& f_, const Expr1& x_, const Expr2& y_)
00469               : f(f_), x(x_), y(y_) {}
00470         private:
00471           MORE_CR3(function_type) f;
00472           MORE_CR3(Expr1) x;
00473           MORE_CR3(Expr2) y;
00474       };
00475 
00476 
00477     template<typename Generator>
00478       inline expr< generator_expr< typename which_expr<Generator>::eval > >
00479       apply(const Generator& f) {
00480           return expr
00481               < generator_expr< typename which_expr<Generator>::eval> >(f);
00482       }
00483 
00484     template<typename UnaryFunction, typename T> inline
00485       expr< unary_function_expr < typename which_expr<UnaryFunction>::eval,
00486             typename which_expr<T>::eval > >
00487       apply(const UnaryFunction& f, const T& x) {
00488           typedef typename which_expr<UnaryFunction>::eval expr1;
00489           typedef typename which_expr<T>::eval expr2;
00490           return expr< unary_function_expr< expr1, expr2 > >(f, x);
00491       }
00492 
00493     template<typename BinaryFunction, typename T1, typename T2> inline
00494       expr< binary_function_expr
00495              < typename which_expr<BinaryFunction>::eval,
00496                typename which_expr<T1>::eval,
00497                typename which_expr<T2>::eval > >
00498       apply(const BinaryFunction& f, const T1& x1, const T2& x2) {
00499           return expr
00500               < binary_function_expr
00501                 < typename which_expr<BinaryFunction>::eval,
00502                   typename which_expr<T1>::eval,
00503                   typename which_expr<T2>::eval > >(f, x1, x2);
00504       }
00505 
00506 //     template< typename TernaryFunction,
00507 //            typename T1, typename T2, typename T3 > inline
00508 //     expr< ternary_function_expr
00509 //              < TernaryFunction,
00510 //             typename which_expr<T1>::eval,
00511 //             typename which_expr<T2>::eval,
00512 //             typename which_expr<T3>::eval > >
00513 //     apply(const TernaryFunction& f,
00514 //        const T1& x1, const T2& x2, const T3& x3) {
00515 //      return expr
00516 //          < ternary_function_expr
00517 //              < TernaryFunction,
00518 //                typename which_expr<T1>::eval,
00519 //                typename which_expr<T2>::eval,
00520 //                typename which_expr<T3> > >(f, x1, x2);
00521 //     }
00522 
00523 
00524 
00525 
00526     // ---   e x p r e s s i o n s   ---
00527 
00528     // --- where ---
00529 
00530     template<typename Expr1, typename Expr2, typename Expr3>
00531       struct where_expr {};
00532     template<typename Expr1, typename Expr2, typename Expr3>
00533       struct expr< where_expr<Expr1, Expr2, Expr3> > {
00534           typedef typename Expr2::result_type result_type;
00535           template<typename Assign>
00536             result_type operator()(const Assign& a) {
00537                 return cond(a)? pos(a) : neg(a);
00538             }
00539           template<typename Assign>
00540             result_type operator()(const Assign& a) const {
00541                 return cond(a)? pos(a) : neg(a);
00542             }
00543           expr(const Expr1& x, const Expr2& y, const Expr3& z)
00544               : cond(x), pos(y), neg(z) {}
00545         private:
00546           Expr1 cond;
00547           Expr2 pos;
00548           Expr3 neg;
00549       };
00550 
00551     template<typename T1, typename T2, typename T3>
00552       inline
00553       expr< where_expr< typename which_expr<T1>::eval,
00554                         typename which_expr<T2>::eval,
00555                         typename which_expr<T3>::eval > >
00556       where(const T1& x, const T2& y, const T3& z) {
00557           return expr
00558               < where_expr< typename which_expr<T1>::eval,
00559                             typename which_expr<T2>::eval,
00560                             typename which_expr<T3>::eval > >(x, y, z);
00561       }
00562 
00563 
00564     // --- Unary operators ---
00565 
00566     template<typename Expr> struct not_expr {};
00567     template<typename Expr>
00568       struct expr< not_expr<Expr> > {
00569           typedef bool result_type;
00570           template<typename Assign>
00571             result_type operator()(const Assign& a) const {
00572                 return !x(a);
00573             }
00574           explicit expr(const Expr& x_) : x(x_) {}
00575         private:
00576           Expr x;
00577       };
00578 
00579     template<typename Expr> inline
00580       expr< not_expr< expr<Expr> > > operator!(const expr<Expr>& x) {
00581           return expr< not_expr< expr<Expr> > >(x);
00582       }
00583 
00584 
00585     template<typename Expr> struct unary_minus_expr {};
00586     template<typename Expr>
00587       struct expr< unary_minus_expr<Expr> > {
00588           typedef typename Expr::result_type result_type;
00589           template<typename Assign>
00590             result_type operator()(const Assign& a) const {
00591                 return -x(a);
00592             }
00593           explicit expr(const Expr& x_) : x(x_) {}
00594         private:
00595           Expr x;
00596       };
00597 
00598     template<typename Expr> inline
00599       expr< unary_minus_expr< expr<Expr> > >
00600       operator-(const expr<Expr>& x) {
00601           return expr< unary_minus_expr< expr<Expr> > >(x);
00602       }
00603 
00604 
00605     template<typename Expr> struct bitnot_expr {};
00606     template<typename Expr>
00607       struct expr< bitnot_expr<Expr> > {
00608           typedef typename Expr::result_type result_type;
00609           template<typename Assign>
00610             result_type operator()(const Assign& a) const {
00611                 return ~x(a);
00612             }
00613           explicit expr(const Expr& x_) : x(x_) {}
00614         private:
00615           Expr x;
00616       };
00617 
00618     template<typename Expr> inline
00619       expr< bitnot_expr< expr<Expr> > > operator~(const expr<Expr>& x) {
00620           return expr< bitnot_expr< expr<Expr> > >(x);
00621       }
00622 
00623     template<typename Expr> struct dereference_expr {};
00624     template<typename Expr>
00625       struct expr< dereference_expr<Expr> > {
00626           typedef typename Expr::result_type argument_type;
00627           typedef typename std::iterator_traits<argument_type>::value_type
00628                   result_type;
00629           template<typename Assign>
00630             result_type operator()(const Assign& a) const {
00631                 return *x(a);
00632             }
00633           explicit expr(const Expr& x_) : x(x_) {}
00634         private:
00635           Expr x;
00636       };
00637     template<typename Expr> inline
00638       expr< dereference_expr< expr<Expr> > >
00639       dereference(const expr<Expr>& x) {
00640           return expr< dereference_expr< expr<Expr> > >(x);
00641       }
00642 
00643   } // lambda_kns
00644 
00645 #define MORE_DEF(OP, NAME, RESULT)\
00646   namespace lambda_kns {\
00647     template<typename Expr1, typename Expr2> struct NAME##_expr {};\
00648     template<typename Expr1, typename Expr2>\
00649       struct expr< NAME##_expr<Expr1, Expr2> > {\
00650           typedef typename Expr1::result_type first_argument_type;\
00651           typedef typename Expr2::result_type second_argument_type;\
00652           typedef RESULT result_type;\
00653           template<typename Assign>\
00654             result_type operator()(const Assign& a) const {\
00655                 return x(a) OP y(a);\
00656             }\
00657           expr(MORE_CR5(Expr1) x_, MORE_CR5(Expr2) y_) : x(x_), y(y_) {}\
00658         private:\
00659           Expr1 x;\
00660           Expr2 y;\
00661       };\
00662     template<typename T1, typename T2>\
00663       inline\
00664       expr< NAME##_expr< typename which_expr<T1>::eval,\
00665                          typename which_expr<T2>::eval > >\
00666       operator OP(MORE_CR5(T1) x, MORE_CR5(T2) y) {\
00667           return expr\
00668                 < NAME##_expr< typename which_expr<T1>::eval,\
00669                                typename which_expr<T2>::eval > >(x, y);\
00670       }\
00671   } // lambda_kns
00672 
00673   MORE_DEF(==, equal_to, bool)
00674   MORE_DEF(!=, not_equal_to, bool)
00675   MORE_DEF(<, less_than, bool)
00676   MORE_DEF(>, greater_than, bool)
00677   MORE_DEF(<=, less_or_equal_to, bool)
00678   MORE_DEF(>=, greater_or_equal_to, bool)
00679   MORE_DEF(&&, and, bool)
00680   MORE_DEF(||, or, bool)
00681 #define MORE_COMMA ,
00682   MORE_DEF(MORE_COMMA, comma, second_argument_type)
00683 #undef MORE_COMMA
00684 
00685   MORE_DEF(+, plus, first_argument_type)
00686   MORE_DEF(-, minus, first_argument_type)
00687   MORE_DEF(*, multiplies, first_argument_type)
00688   MORE_DEF(/, divides, first_argument_type)
00689   MORE_DEF(%, remainder, first_argument_type)
00690   MORE_DEF(&, bitand, first_argument_type)
00691   MORE_DEF(|, bitor, first_argument_type)
00692   MORE_DEF(^, bitxor, first_argument_type)
00693   MORE_DEF(<<, bitlshift, first_argument_type)
00694   MORE_DEF(>>, bitrshift, first_argument_type)
00695 #undef MORE_DEF
00696   ///\endif bits
00697 
00698   using lambda_kns::placeholder;
00699   using lambda_kns::apply; // because of the generator-version
00700   using lambda_kns::lambda;
00701   using lambda_kns::where;
00702 
00703   /** Pass \a x by reference rather than by value in a lambda
00704    ** expression. */
00705   template<typename T>
00706     inline lambda_kns::expr< lambda_kns::valueref_expr<T> >
00707     refer(T& x) { return x; }
00708 
00709 }} // more::gen
00710 
00711 #undef MORE_CR1
00712 #undef MORE_CR2
00713 #undef MORE_CR3
00714 #undef MORE_CR4
00715 
00716 #endif

Generated on Sat Sep 7 19:11:12 2002 for more with Doxygen 1.2.13.1. Doxygen 1.2.13.1 is written and copyright 1997-2002 by Dimitri van Heesch.