00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_VEC_SCAL_AOP_EXPR_INCLUDE
00013 #define MTL_VEC_SCAL_AOP_EXPR_INCLUDE
00014
00015 #include <boost/numeric/mtl/utility/exception.hpp>
00016 #include <boost/numeric/mtl/vector/vec_expr.hpp>
00017 #include <boost/numeric/mtl/operation/sfunctor.hpp>
00018
00019
00020 namespace mtl { namespace vector {
00021
00022
00023
00024 template <class E1, class E2, typename SFunctor>
00025 struct vec_scal_aop_expr
00026 : public vec_expr< vec_scal_aop_expr<E1, E2, SFunctor> >
00027 {
00028 typedef vec_expr< vec_scal_aop_expr<E1, E2, SFunctor> > expr_base;
00029 typedef vec_scal_aop_expr self;
00030 typedef typename E1::value_type value_type;
00031
00032
00033 typedef typename E1::size_type size_type;
00034
00035
00036 typedef value_type reference_type ;
00037
00038 typedef E1 first_argument_type ;
00039 typedef E2 second_argument_type ;
00040
00041 vec_scal_aop_expr( first_argument_type& v1, second_argument_type const& v2 )
00042 : first( v1 ), second( v2 ), delayed_assign( false ), with_comma( false ), index(0)
00043 {}
00044
00045 ~vec_scal_aop_expr()
00046 {
00047 if (!delayed_assign) {
00048 if (with_comma) {
00049 MTL_DEBUG_THROW_IF(index != size(first), incompatible_size("Not all vector entries initialized!"));
00050 } else
00051 for (size_type i= 0; i < size(first); ++i)
00052 SFunctor::apply( first(i), second );
00053 }
00054 }
00055
00056 void delay_assign() const
00057 {
00058 MTL_DEBUG_THROW_IF(with_comma, logic_error("Comma notation conflicts with rich expression templates."));
00059 delayed_assign= true;
00060 }
00061
00062 friend size_type inline size(const self& v) { return size(v.first); }
00063
00064 #if 0
00065 size_type size() const
00066 {
00067 return first.size() ;
00068 }
00069 #endif
00070
00071 value_type& operator() ( size_type i ) const
00072 {
00073 assert( delayed_assign && !with_comma);
00074 return SFunctor::apply( first(i), second );
00075 }
00076
00077 value_type& operator[] ( size_type i ) const
00078 {
00079 assert( delayed_assign );
00080 return SFunctor::apply( first(i), second );
00081 }
00082
00083 template <typename Source>
00084 self& operator, (Source val)
00085 {
00086
00087 if (!with_comma) {
00088 with_comma= true;
00089 assert(index == 0);
00090 SFunctor::apply( first(index++), second);
00091 }
00092 MTL_DEBUG_THROW_IF(index >= size(first), range_error());
00093 SFunctor::apply( first(index++), val);
00094 return *this;
00095 }
00096
00097 private:
00098 mutable first_argument_type& first ;
00099 second_argument_type const& second ;
00100 mutable bool delayed_assign, with_comma;
00101 size_type index;
00102 } ;
00103
00104 } }
00105
00106
00107
00108
00109
00110 #endif
00111