1 #ifndef _RHEOLEF_VEC_EXPR_H
2 #define _RHEOLEF_VEC_EXPR_H
3 #include "rheolef/vec.h"
4 #include "rheolef/dis_inner_product.h"
5 #include "rheolef/dis_accumulate.h"
6 #include "rheolef/pretty_name.h"
8 #include <boost/mpl/bool.hpp>
9 #include <boost/proto/core.hpp>
10 #include <boost/proto/debug.hpp>
11 #include <boost/proto/context.hpp>
12 #include <boost/proto/transform.hpp>
13 #include <boost/proto/operators.hpp>
14 #include <boost/utility/enable_if.hpp>
15 #include <boost/typeof/std/vector.hpp>
16 #include <boost/typeof/std/complex.hpp>
17 #include <boost/type_traits/remove_reference.hpp>
20 namespace mpl = boost::mpl;
21 namespace proto = boost::proto;
27 template<
class Iterator>
37 template<
class This,
class Container>
38 struct result<This(Container)> : proto::result_of::as_expr
41 typename boost::remove_reference<Container>::type::const_iterator>
44 template<
class Container>
45 typename result<vec_begin(const Container&)>::type
48 return proto::as_expr (iter);
53 proto::when <proto::terminal<vec<_, _> >, vec_begin(proto::_value)>
54 , proto::when <proto::terminal<_> >
55 , proto::when <proto::nary_expr<_, proto::vararg<vec_grammar_begin> > >
60 template<
class Expr,
class EnableIf =
void>
61 struct eval : proto::default_eval<Expr, const vec_dereference_context> {};
65 typename boost::enable_if<
66 proto::matches<Expr, proto::terminal<vec_iterator_wrapper<_> > >
70 typedef typename IteratorWrapper::iterator
iterator;
71 typedef typename std::iterator_traits<iterator>::reference
result_type;
74 return *proto::value(expr).iter;
79 template<
class Expr,
class EnableIf =
void>
80 struct eval : proto::null_eval<Expr, const vec_increment_context> {};
82 template<
class Expr>
struct eval<Expr,
83 typename boost::enable_if<
84 proto::matches<Expr, proto::terminal<vec_iterator_wrapper<_> > >
90 ++proto::value(expr).iter;
97 template<
class Expr,
class EnableIf =
void>
98 struct eval : proto::default_eval<Expr, const vec_subscript_context> {};
100 struct eval<Expr, typename boost::enable_if<
101 proto::matches<Expr, proto::terminal<vec<_, _> > > >::type> {
102 typedef typename proto::result_of::value<Expr>::type::value_type
result_type;
104 return proto::value(expr)[ctx.
_i];
108 struct eval<Expr, typename boost::enable_if<
109 proto::matches<Expr, proto::terminal<vec_iterator_wrapper<_> > > >::type > {
111 typedef typename IteratorWrapper::iterator
iterator;
112 typedef typename std::iterator_traits<iterator>::reference
result_type;
114 return *proto::value(expr).iter[ctx.
_i];
123 template<
class Expr,
class EnableIf =
void>
124 struct eval : proto::null_eval<Expr, const vec_get_size_context> {};
127 struct eval<Expr, typename boost::enable_if<
128 proto::matches<Expr, proto::terminal<vec<_,_> > > >::type> {
131 ctx.
_ownership = proto::value(expr).ownership();
142 template<
class Expr,
class EnableIf =
void>
143 struct eval : proto::null_eval<Expr, const vec_check_size_context> {};
146 struct eval<Expr, typename boost::enable_if<
147 proto::matches<Expr, proto::terminal<vec<_,_> > > >::type> {
150 if (ctx.
_size != proto::value(expr).size()) {
152 << proto::value(expr).size() <<
" in vec<T> expression "
162 template<
class Tag,
int D = 0>
struct case_ : proto::not_<_> {};
164 template<
int D>
struct case_< proto::tag::plus_assign, D > : _ {};
165 template<
int D>
struct case_< proto::tag::minus_assign, D > : _ {};
166 template<
int D>
struct case_< proto::tag::multiplies_assign, D > : _ {};
167 template<
int D>
struct case_< proto::tag::divides_assign, D > : _ {};
168 template<
int D>
struct case_< proto::tag::modulus_assign, D > : _ {};
169 template<
int D>
struct case_< proto::tag::shift_left_assign, D > : _ {};
170 template<
int D>
struct case_< proto::tag::shift_right_assign, D > : _ {};
171 template<
int D>
struct case_< proto::tag::bitwise_and_assign, D > : _ {};
172 template<
int D>
struct case_< proto::tag::bitwise_or_assign, D > : _ {};
173 template<
int D>
struct case_< proto::tag::bitwise_xor_assign, D > : _ {};
179 proto::nary_expr<_, proto::vararg<vec_grammar> >
180 , proto::not_<vec_assign_operators>
190 struct vec_expr : proto::extends<Expr, vec_expr<Expr>, vec_domain> {
196 typedef typename boost::result_of<vec_grammar_begin(const Expr&)>::type
raw_iterator;
206 proto::eval (*
this, get_size);
218 typedef typename proto::result_of::eval<raw_iterator,vec_dereference_context>::type
value_type;
223 #if BOOST_VERSION < 104601
227 #else // BOOST_VERSION < 104601
232 #endif // BOOST_VERSION < 104601
235 proto::eval (*
this, inc);
245 typedef typename proto::result_of::eval<raw_iterator,vec_dereference_context>::type my_ref;
246 reference value = proto::eval(*
this, deref);
256 typedef typename proto::result_of::eval<const Expr, const vec_subscript_context>::type
value_type;
260 return proto::eval(*
this, get_subscript);
263 using proto::extends<Expr, vec_expr<Expr>,
vec_domain>::operator[];
268 template<
class T,
class M>
271 namespace vec_detail {
272 template<
class ForwardIterator,
class Expr,
class Op>
273 void evaluate (ForwardIterator begin, ForwardIterator end,
const Expr& expr, Op op) {
276 typename boost::result_of<vec_grammar_begin(const Expr&)>::type expr_begin
279 for (; begin != end; ++begin) {
280 op (*begin, proto::eval(expr_begin, deref));
281 proto::eval (expr_begin, inc);
283 #endif // TRY_VEC_EXPR
286 template<
class T,
class U>
291 template<
class T,
class M>
297 proto::eval (proto::as_expr<vec_domain>(expr), get_size);
299 if (array<T,M>::dis_size() == 0) {
301 resize (expr_ownership);
304 proto::eval (proto::as_expr<vec_domain>(expr), check_size);
308 template<
class T,
class M>
316 template<
class T,
class M>
323 template<
class T,
class M>
332 #endif // _RHEOLEF_VEC_EXPR_H