]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/proto/example/tarray.cpp
2 ///////////////////////////////////////////////////////////////////////////////
3 // Copyright 2008 Eric Niebler. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 // This example constructs a mini-library for linear algebra, using
8 // expression templates to eliminate the need for temporaries when
9 // adding arrays of numbers. It duplicates the TArray example from
10 // PETE (http://www.codesourcery.com/pooma/download.html)
13 #include <boost/mpl/int.hpp>
14 #include <boost/proto/core.hpp>
15 #include <boost/proto/context.hpp>
16 namespace mpl
= boost::mpl
;
17 namespace proto
= boost::proto
;
20 // This grammar describes which TArray expressions
21 // are allowed; namely, int and array terminals
22 // plus, minus, multiplies and divides of TArray expressions.
25 proto::terminal
< int >
26 , proto::terminal
< int[3] >
27 , proto::plus
< TArrayGrammar
, TArrayGrammar
>
28 , proto::minus
< TArrayGrammar
, TArrayGrammar
>
29 , proto::multiplies
< TArrayGrammar
, TArrayGrammar
>
30 , proto::divides
< TArrayGrammar
, TArrayGrammar
>
34 template<typename Expr
>
37 // Tell proto that in the TArrayDomain, all
38 // expressions should be wrapped in TArrayExpr<> and
39 // must conform to the TArrayGrammar
41 : proto::domain
<proto::generator
<TArrayExpr
>, TArrayGrammar
>
44 // Here is an evaluation context that indexes into a TArray
45 // expression, and combines the result.
46 struct TArraySubscriptCtx
47 : proto::callable_context
< TArraySubscriptCtx
const >
49 typedef int result_type
;
51 TArraySubscriptCtx(std::ptrdiff_t i
)
55 // Index array terminals with our subscript. Everything
56 // else will be handled by the default evaluation context.
57 int operator ()(proto::tag::terminal
, int const (&data
)[3]) const
59 return data
[this->i_
];
65 // Here is an evaluation context that prints a TArray expression.
67 : proto::callable_context
< TArrayPrintCtx
const >
69 typedef std::ostream
&result_type
;
73 std::ostream
&operator ()(proto::tag::terminal
, int i
) const
75 return std::cout
<< i
;
78 std::ostream
&operator ()(proto::tag::terminal
, int const (&arr
)[3]) const
80 return std::cout
<< '{' << arr
[0] << ", " << arr
[1] << ", " << arr
[2] << '}';
83 template<typename L
, typename R
>
84 std::ostream
&operator ()(proto::tag::plus
, L
const &l
, R
const &r
) const
86 return std::cout
<< '(' << l
<< " + " << r
<< ')';
89 template<typename L
, typename R
>
90 std::ostream
&operator ()(proto::tag::minus
, L
const &l
, R
const &r
) const
92 return std::cout
<< '(' << l
<< " - " << r
<< ')';
95 template<typename L
, typename R
>
96 std::ostream
&operator ()(proto::tag::multiplies
, L
const &l
, R
const &r
) const
98 return std::cout
<< l
<< " * " << r
;
101 template<typename L
, typename R
>
102 std::ostream
&operator ()(proto::tag::divides
, L
const &l
, R
const &r
) const
104 return std::cout
<< l
<< " / " << r
;
108 // Here is the domain-specific expression wrapper, which overrides
109 // operator [] to evaluate the expression using the TArraySubscriptCtx.
110 template<typename Expr
>
112 : proto::extends
<Expr
, TArrayExpr
<Expr
>, TArrayDomain
>
114 typedef proto::extends
<Expr
, TArrayExpr
<Expr
>, TArrayDomain
> base_type
;
116 TArrayExpr( Expr
const & expr
= Expr() )
120 // Use the TArraySubscriptCtx to implement subscripting
121 // of a TArray expression tree.
122 int operator []( std::ptrdiff_t i
) const
124 TArraySubscriptCtx
const ctx(i
);
125 return proto::eval(*this, ctx
);
128 // Use the TArrayPrintCtx to display a TArray expression tree.
129 friend std::ostream
&operator <<(std::ostream
&sout
, TArrayExpr
<Expr
> const &expr
)
131 TArrayPrintCtx
const ctx
;
132 return proto::eval(expr
, ctx
);
136 // Here is our TArray terminal, implemented in terms of TArrayExpr
137 // It is basically just an array of 3 integers.
139 : TArrayExpr
< proto::terminal
< int[3] >::type
>
141 explicit TArray( int i
= 0, int j
= 0, int k
= 0 )
148 // Here we override operator [] to give read/write access to
149 // the elements of the array. (We could use the TArrayExpr
150 // operator [] if we made the subscript context smarter about
151 // returning non-const reference when appropriate.)
152 int &operator [](std::ptrdiff_t i
)
154 return proto::value(*this)[i
];
157 int const &operator [](std::ptrdiff_t i
) const
159 return proto::value(*this)[i
];
162 // Here we define a operator = for TArray terminals that
163 // takes a TArray expression.
164 template< typename Expr
>
165 TArray
&operator =(Expr
const & expr
)
167 // proto::as_expr<TArrayDomain>(expr) is the same as
168 // expr unless expr is an integer, in which case it
169 // is made into a TArrayExpr terminal first.
170 return this->assign(proto::as_expr
<TArrayDomain
>(expr
));
173 template< typename Expr
>
174 TArray
&printAssign(Expr
const & expr
)
177 std::cout
<< *this << " = " << expr
<< std::endl
;
182 template< typename Expr
>
183 TArray
&assign(Expr
const & expr
)
185 // expr[i] here uses TArraySubscriptCtx under the covers.
186 (*this)[0] = expr
[0];
187 (*this)[1] = expr
[1];
188 (*this)[2] = expr
[2];
199 std::cout
<< a
<< std::endl
;
200 std::cout
<< b
<< std::endl
;
202 b
[0] = 7; b
[1] = 33; b
[2] = -99;
206 std::cout
<< c
<< std::endl
;
210 std::cout
<< a
<< std::endl
;
211 std::cout
<< b
<< std::endl
;
212 std::cout
<< c
<< std::endl
;
216 std::cout
<< a
<< std::endl
;
218 a
.printAssign(b
+c
*(b
+ 3*c
));