[Gridflow-cvs] [svn] commit: r6370 - in /trunk/src: classes1.cxx classes3.cxx expr.cxx gridflow.cxx gridflow.hxx mmx.rb numop2.cxx

svn-gridflow at artengine.ca svn-gridflow at artengine.ca
Mon Sep 27 16:09:52 EDT 2010


Author: matju
Date: Mon Sep 27 16:09:50 2010
New Revision: 6370

Log:
rename Numop to Numop2; introduce superclass Numop for Numop2; introduce subclass Numop1 for Numop (and don't use it yet)

Modified:
    trunk/src/classes1.cxx
    trunk/src/classes3.cxx
    trunk/src/expr.cxx
    trunk/src/gridflow.cxx
    trunk/src/gridflow.hxx
    trunk/src/mmx.rb
    trunk/src/numop2.cxx

Modified: trunk/src/classes1.cxx
==============================================================================
--- trunk/src/classes1.cxx (original)
+++ trunk/src/classes1.cxx Mon Sep 27 16:09:50 2010
@@ -50,7 +50,7 @@
 	{ *(int32 *)a=*(int32 *)b; }
 };*/
 
-Numop *op_add, *op_sub, *op_mul, *op_div, *op_mod, *op_shl, *op_and, *op_put;
+Numop2 *op_add, *op_sub, *op_mul, *op_div, *op_mod, *op_shl, *op_and, *op_put;
 
 static CONSTRAINT(expect_dim_dim_list) {if (d.n!=1) RAISE("dimension list should be Dim[n], not %s",d.to_s());}
 //static CONSTRAINT(expect_min_one_dim) {if (d.n<1 ) RAISE("minimum 1 dimension");}
@@ -337,7 +337,7 @@
 \class GridStore : FObject {
 	P<Grid> r; // can't be \attr (why ?)
 	P<Grid> put_at; // can't be //\attr (why ?)
-	\attr Numop *op;
+	\attr Numop2 *op;
 	int32 *wdex ; // temporary buffer, copy of put_at
 	int32 *fromb;
 	int32 *to2  ;
@@ -522,9 +522,9 @@
 //{ Dim[*As]<T> -> Dim[*As]<T> } or
 //{ Dim[*As]<T>,Dim[*Bs]<T> -> Dim[*As]<T> }
 \class GridOp : FObject {
-	\attr Numop *op;
+	\attr Numop2 *op; // should allow Numop1 too
 	P<Grid> r;
-	\constructor (Numop *op, Grid *r=0) {this->op=op; this->r=r?r:new Grid(Dim(),int32_e,true);}
+	\constructor (Numop2 *op, Grid *r=0) {this->op=op; this->r=r?r:new Grid(Dim(),int32_e,true);}
 	\grin 0
 	\grin 1
 };
@@ -567,9 +567,9 @@
 
 //****************************************************************
 \class GridFold : FObject {
-	\attr Numop *op;
+	\attr Numop2 *op;
 	\attr P<Grid> seed;
-	\constructor (Numop *op) {this->op=op;}
+	\constructor (Numop2 *op) {this->op=op;}
 	\grin 0
 };
 
@@ -612,9 +612,9 @@
 \end class {install("#fold",1,1);}
 
 \class GridScan : FObject {
-	\attr Numop *op;
+	\attr Numop2 *op;
 	\attr P<Grid> seed;
-	\constructor (Numop *op) {this->op = op;}
+	\constructor (Numop2 *op) {this->op = op;}
 	\grin 0
 };
 
@@ -655,8 +655,8 @@
 // result is a Dim[*si,   *sk,*ss]<T>
 // Currently *ss can only be = Dim[]
 \class GridInner : FObject {
-	\attr Numop *op;
-	\attr Numop *fold;
+	\attr Numop2 *op;
+	\attr Numop2 *fold;
 	\attr P<Grid> seed;
 	P<Grid> r;
 	P<Grid> r2; // temporary
@@ -777,9 +777,9 @@
 /* **************************************************************** */
 /*{ Dim[*As]<T>,Dim[*Bs]<T> -> Dim[*As,*Bs]<T> }*/
 \class GridOuter : FObject {
-	\attr Numop *op;
+	\attr Numop2 *op;
 	P<Grid> r;
-	\constructor (Numop *op, Grid *r=0) {
+	\constructor (Numop2 *op, Grid *r=0) {
 		this->op = op;
 		this->r = r ? r : new Grid(Dim(),int32_e,true);
 	}
@@ -974,7 +974,7 @@
 
 \end class {install("#redim",2,1); add_creator("@redim");}
 
-#define OP(x) op_dict[string(#x)]
+#define OP(x) dynamic_cast<Numop2 *>(op_dict[string(#x)])
 void startup_classes1 () {
 	op_add = OP(+);
 	op_sub = OP(-);

Modified: trunk/src/classes3.cxx
==============================================================================
--- trunk/src/classes3.cxx (original)
+++ trunk/src/classes3.cxx Mon Sep 27 16:09:50 2010
@@ -596,8 +596,8 @@
 	struct  PlanEntry {long y; long x; bool neutral;
 		PlanEntry (long y, long x, bool neutral) : y(y), x(x), neutral(neutral) {}
 	};
-	\attr Numop *op;
-	\attr Numop *fold;
+	\attr Numop2 *op;
+	\attr Numop2 *fold;
 	\attr P<Grid> seed;
 	\attr P<Grid> b;
 	\attr bool wrap;
@@ -909,7 +909,7 @@
 	RAISE("unknown OmitMode '%s' (want none or last or odd)",s->s_name);
 }
 \class DrawPolygon : FObject {
-	\attr Numop *op;
+	\attr Numop2 *op;
 	\attr P<Grid> color;
 	\attr P<Grid> polygon;
 	\attr DrawMode draw;
@@ -918,7 +918,7 @@
 	P<Grid> lines;
 	int lines_start;
 	int lines_stop;
-	\constructor (Numop *op=op_put, Grid *color=0, Grid *polygon=0) {
+	\constructor (Numop2 *op=op_put, Grid *color=0, Grid *polygon=0) {
 		draw=DRAW_FILL;
 		omit=OMIT_NONE;
 		this->color  .but(expect_one_dim);
@@ -1050,12 +1050,12 @@
 }
 
 \class DrawImage : FObject {
-	\attr Numop *op;
+	\attr Numop2 *op;
 	\attr P<Grid> image;
 	\attr P<Grid> position;
 	\attr bool alpha;
 	\attr bool tile;
-	\constructor (Numop *op=op_put, Grid *image=0, Grid *position=0) {
+	\constructor (Numop2 *op=op_put, Grid *image=0, Grid *position=0) {
 		alpha=false; tile=false;
 		this->op = op;
 		this->position.but(expect_position);
@@ -1155,13 +1155,13 @@
 
 /* NOT FINISHED */
 \class GridDrawPoints : FObject {
-	\attr Numop *op;
+	\attr Numop2 *op;
 	\attr P<Grid> color;
 	\attr P<Grid> points;
 	\grin 0
 	\grin 1 int32
 	\grin 2 int32
-	\constructor (Numop *op=op_put, Grid *color=0, Grid *points=0) {
+	\constructor (Numop2 *op=op_put, Grid *color=0, Grid *points=0) {
 		this->op = op;
 		this->color  = color  ? color  : new Grid(Dim(),int32_e,true);
 		this->points = points ? points : new Grid(Dim(),int32_e,true);
@@ -1299,7 +1299,7 @@
 static CONSTRAINT(expect_min_one_dim) {
 	if (d.n<1) RAISE("expecting at least one dimension, got %s",d.to_s());}
 
-#define OP(x) op_dict[string(#x)]
+#define OP(x) dynamic_cast<Numop2 *>(op_dict[string(#x)])
 \class GridClusterAvg : FObject {
 	\attr int numClusters;
 	\attr P<Grid> r;

Modified: trunk/src/expr.cxx
==============================================================================
--- trunk/src/expr.cxx (original)
+++ trunk/src/expr.cxx Mon Sep 27 16:09:50 2010
@@ -203,14 +203,14 @@
 				stack.push_back(inputs[code[i].a_index & 255]);
 			  } break;
 			  case A_OP: {
-				Numop *op = TO(Numop *,t_atom2(code[i].a_symbol->s_name));
+				Numop2 *op = TO(Numop2 *,t_atom2(code[i].a_symbol->s_name));
 				float b = lookup(stack.back()); stack.pop_back();
 				float a = lookup(stack.back());
 				op->map(1,&a,b);
 				stack.back() = a;
 			  } break;
 			  case A_OP1: {
-				Numop *op = TO(Numop *,t_atom2(code[i].a_symbol->s_name));
+				Numop2 *op = TO(Numop2 *,t_atom2(code[i].a_symbol->s_name));
 				float a = lookup(stack.back());
 				op->map(1,&a,0.f);
 				stack.back() = a;

Modified: trunk/src/gridflow.cxx
==============================================================================
--- trunk/src/gridflow.cxx (original)
+++ trunk/src/gridflow.cxx Mon Sep 27 16:09:50 2010
@@ -239,6 +239,18 @@
 	string s = atomtype_to_s(a.a_type);
 	RAISE("don't know how to compare elements of type %s",s.data());
 }
+
+Numop *convert(const t_atom2 &x, Numop **bogus) {
+	if (x.a_type!=A_SYMBOL) RAISE("expected numop (as symbol)");
+	string k = string(x.a_symbol->s_name);
+	if (op_dict.find(k)==op_dict.end()) {
+		if (vop_dict.find(k)==vop_dict.end()) RAISE("expected two-input-operator, not '%s'", k.data());
+		return vop_dict[k];
+	} else return op_dict[k];
+}
+
+int Numop::arity () {RAISE("Numop::arity() : pure-virtual function called !");}
+
 //----------------------------------------------------------------
 // Dim
 

Modified: trunk/src/gridflow.hxx
==============================================================================
--- trunk/src/gridflow.hxx (original)
+++ trunk/src/gridflow.hxx Mon Sep 27 16:09:50 2010
@@ -510,8 +510,15 @@
 
 enum LeftRight { at_left, at_right };
 
-template <class T>
-struct NumopOn {
+template <class T> struct Numop1On {
+	// Function Vectorisations
+	typedef void (*Map)(         long n, T *as       ); Map map;
+	Numop1On(Map m) : map(m) {}
+	Numop1On()      : map(0) {}
+	Numop1On(const Numop1On &z) {map=z.map;}
+};
+
+template <class T> struct Numop2On {
 	// Function Vectorisations
 	typedef void (*Map )(         long n, T *as, T  b ); Map  map;
 	typedef void (*Zip )(         long n, T *as, T *bs); Zip  zip;
@@ -523,47 +530,68 @@
 	// absorbent: right: exists a forall y {f(x,y)=a}; ...
 	void (*neutral)(T *,LeftRight); // default neutral: e.g. 0 for addition, 1 for multiplication
 	AlgebraicCheck is_neutral, is_absorbent;
-	NumopOn(Map m, Zip z, Fold f, Scan s,
+	Numop2On(Map m, Zip z, Fold f, Scan s,
 	void (*neu)(T *,LeftRight), AlgebraicCheck n, AlgebraicCheck a) :
 		    map(m),zip(z),fold(f),scan(s),neutral(neu),is_neutral(n),is_absorbent(a) {}
-	NumopOn() : map(0),zip(0),fold(0),scan(0),neutral(0)  ,is_neutral(0),is_absorbent(0) {}
-	NumopOn(const NumopOn &z) {
+	Numop2On() : map(0),zip(0),fold(0),scan(0),neutral(0)  ,is_neutral(0),is_absorbent(0) {}
+	Numop2On(const Numop2On &z) {
 		map=z.map; zip=z.zip; fold=z.fold; scan=z.scan;
 		is_neutral = z.is_neutral; neutral = z.neutral;
 		is_absorbent = z.is_absorbent; }
 };
 
-// semigroup property: associativity: f(a,f(b,c))=f(f(a,b),c)
-#define OP_ASSOC (1<<0)
-// abelian property: commutativity: f(a,b)=f(b,a)
-#define OP_COMM (1<<1)
-
 struct Numop {
 	const char *name;
 	t_symbol *sym;
+	int size; // 1 means regular numop; more than 1 means vecop
+	virtual int arity ();
+};
+
+struct Numop1 : Numop {
+	virtual int arity () {return 1;}
+	#define FOO(T) Numop1On<T> on_##T; Numop1On<T> *on(T &foo) { \
+		if (!on_##T.map) RAISE("operator %s does not support type "#T,name); else return &on_##T;}
+	EACH_NUMBER_TYPE(FOO)
+	#undef FOO
+	template <class T> inline void map(long n, T *as) {on(*as)->map(n,(T *)as);}
+	Numop1(const char *name_,
+		#define FOO(T) Numop1On<T> op_##T, 
+		EACH_NUMBER_TYPE(FOO)
+		#undef FOO
+	int size_) {
+		name=name_; size=size_;
+		#define FOO(T) on_##T = op_##T;
+		EACH_NUMBER_TYPE(FOO)
+		#undef FOO
+		sym=gensym((char *)name);
+	}
+};
+
+struct Numop2 : Numop {
+	virtual int arity () {return 2;}
 	int flags;
-	int size; // numop=1; vecop>1
-#define FOO(T) NumopOn<T> on_##T; \
-  NumopOn<T> *on(T &foo) { \
-    if (!on_##T.map) RAISE("operator %s does not support type "#T,name); \
-    return &on_##T;}
-EACH_NUMBER_TYPE(FOO)
-#undef FOO
+		#define OP_ASSOC (1<<0) /* semigroup property: associativity: f(a,f(b,c))=f(f(a,b),c) */
+		#define OP_COMM (1<<1)  /* abelian property: commutativity: f(a,b)=f(b,a) */
+	#define FOO(T) Numop2On<T> on_##T; Numop2On<T> *on(T &foo) { \
+		if (!on_##T.map) RAISE("operator %s does not support type "#T,name); else return &on_##T;}
+	EACH_NUMBER_TYPE(FOO)
+	#undef FOO
 	template <class T> inline void map(long n, T *as, T b)   {on(*as)->map(n,(T *)as,     b );}
 	template <class T> inline void zip(long n, T *as, T *bs) {on(*as)->zip(n,(T *)as,(T *)bs);}
-	template <class T> inline void fold(long an, long n, T *as, T *bs) {typename NumopOn<T>::Fold f = on(*as)->fold;
+	template <class T> inline void fold(long an, long n, T *as, T *bs) {typename Numop2On<T>::Fold f = on(*as)->fold;
 		if (f) f(an,n,as,bs); else RAISE("operator %s does not support fold",name);}
-	template <class T> inline void scan(long an, long n, T *as, T *bs) {typename NumopOn<T>::Scan f = on(*as)->scan;
+	template <class T> inline void scan(long an, long n, T *as, T *bs) {typename Numop2On<T>::Scan f = on(*as)->scan;
 		if (f) f(an,n,as,bs); else RAISE("operator %s does not support scan",name);}
 
-	Numop(const char *name_,
-#define FOO(T) NumopOn<T> op_##T, 
-EACH_NUMBER_TYPE(FOO)
-#undef FOO
-	int flags_, int size_) : name(name_), flags(flags_), size(size_) {
-#define FOO(T) on_##T = op_##T;
-EACH_NUMBER_TYPE(FOO)
-#undef FOO
+	Numop2(const char *name_,
+		#define FOO(T) Numop2On<T> op_##T, 
+		EACH_NUMBER_TYPE(FOO)
+		#undef FOO
+	int flags_, int size_) {
+		name=name_; size=size_; flags=flags_;
+		#define FOO(T) on_##T = op_##T;
+		EACH_NUMBER_TYPE(FOO)
+		#undef FOO
 		sym=gensym((char *)name);
 	}
 };
@@ -576,14 +604,13 @@
 static inline NumberTypeE convert(const t_atom2 &x, NumberTypeE *bogus) {
 	if (x.a_type!=A_SYMBOL) RAISE("expected number-type, got %s",x.to_s().data()); return NumberTypeE_find(string(x.a_symbol->s_name));}
 
-static Numop *convert(const t_atom2 &x, Numop **bogus) {
-	if (x.a_type!=A_SYMBOL) RAISE("expected numop (as symbol)");
-	string k = string(x.a_symbol->s_name);
-	if (op_dict.find(k)==op_dict.end()) {
-		if (vop_dict.find(k)==vop_dict.end()) RAISE("expected two-input-operator, not '%s'", k.data());
-		return vop_dict[k];
-	} else return op_dict[k];
-}
+       Numop  *convert(const t_atom2 &x, Numop  **bogus);
+static Numop1 *convert(const t_atom2 &x, Numop1 **bogus) {
+	Numop *nu = convert(x,(Numop **)0); if (nu->arity()!=1) RAISE("this Numop doesn't have one argument" );
+	return (Numop1 *)nu;}
+static Numop2 *convert(const t_atom2 &x, Numop2 **bogus) {
+	Numop *nu = convert(x,(Numop **)0); if (nu->arity()!=2) RAISE("this Numop doesn't have two arguments");
+	return (Numop2 *)nu;}
 
 // ****************************************************************
 struct Grid : CObject {
@@ -875,7 +902,7 @@
 
 uint64 gf_timeofday();
 extern "C" void Init_gridflow ();
-extern Numop *op_add,*op_sub,*op_mul,*op_div,*op_mod,*op_shl,*op_and,*op_put;
+extern Numop2 *op_add,*op_sub,*op_mul,*op_div,*op_mod,*op_shl,*op_and,*op_put;
 
 #undef ARGS
 #define ARGS(OBJ) ((OBJ) ? (OBJ)->bself->binbuf_string().data() : "[???]")

Modified: trunk/src/mmx.rb
==============================================================================
--- trunk/src/mmx.rb (original)
+++ trunk/src/mmx.rb Mon Sep 27 16:09:50 2010
@@ -133,7 +133,7 @@
 		puts "emms"
 	}
 	$decls << "void #{s}(long,#{type}*,#{type});\n"
-	$install << "op_dict[string(\"#{sym}\")]->on_#{type}.map = #{s};\n"
+	$install << "((Numop2 *)op_dict[string(\"#{sym}\")])->on_#{type}.map = #{s};\n"
 	$count += 1
 end
 
@@ -183,7 +183,7 @@
 	}
 	#$decls << "void #{s}(long,#{type}*,#{type}*,#{type}*);\n"
 	$decls << "void #{s}(long,#{type}*,#{type}*);\n"
-	$install << "op_dict[string(\"#{sym}\")]->on_#{type}.zip = #{s};\n"
+	$install << "((Numop2 *)op_dict[string(\"#{sym}\")])->on_#{type}.zip = #{s};\n"
 	$count += 1
 end
 

Modified: trunk/src/numop2.cxx
==============================================================================
--- trunk/src/numop2.cxx (original)
+++ trunk/src/numop2.cxx Mon Sep 27 16:09:50 2010
@@ -59,7 +59,7 @@
 	static bool is_absorbent(T x, LeftRight side) {assert(!"Op::is_absorbent called?"); return false;}
 };
 
-template <class O, class T> class OpLoops: public NumopOn<T> {
+template <class O, class T> class OpLoops: public Numop2On<T> {
 public:
   static inline T f(T a, T b) {return O::f(a,b);}
   #define FOO(I) as[I]=f(as[I],b);
@@ -146,20 +146,20 @@
 
 #define  OL(O,T) OpLoops<Y##O<T>,T>
 #define VOL(O,T) OpLoops<Y##O<Plex<T> >,Plex<T> >
-#define DECL_OPON(L,O,T) NumopOn<T>( \
-	(NumopOn<T>::Map) L(O,T)::_map,  (NumopOn<T>::Zip) L(O,T)::_zip, \
-	(NumopOn<T>::Fold)L(O,T)::_fold, (NumopOn<T>::Scan)L(O,T)::_scan, \
+#define DECL_OPON(L,O,T) Numop2On<T>( \
+	(Numop2On<T>::Map) L(O,T)::_map,  (Numop2On<T>::Zip) L(O,T)::_zip, \
+	(Numop2On<T>::Fold)L(O,T)::_fold, (Numop2On<T>::Scan)L(O,T)::_scan, \
 	&Y##O<T>::neutral, &Y##O<T>::is_neutral, &Y##O<T>::is_absorbent)
-#define DECL_OPON_NOFOLD(L,O,T) NumopOn<T>( \
-	(NumopOn<T>::Map)L(O,T)::_map, (NumopOn<T>::Zip)L(O,T)::_zip, 0,0, \
+#define DECL_OPON_NOFOLD(L,O,T) Numop2On<T>( \
+	(Numop2On<T>::Map)L(O,T)::_map, (Numop2On<T>::Zip)L(O,T)::_zip, 0,0, \
 	&Y##O<T>::neutral, &Y##O<T>::is_neutral, &Y##O<T>::is_absorbent)
-#define DECLOP(        L,M,O,sym,flags,dim) Numop(sym,M(L,O,uint8),M(L,O,int16),M(L,O,int32) \
+#define DECLOP(        L,M,O,sym,flags,dim) Numop2(sym,M(L,O,uint8),M(L,O,int16),M(L,O,int32) \
 	NONLITE(,M(L,O,int64)),  M(L,O,float32)   NONLITE(,M(L,O,float64)),flags,dim)
-#define DECLOP_NOFLOAT(L,M,O,sym,flags,dim) Numop(sym,M(L,O,uint8),M(L,O,int16),M(L,O,int32) \
-	NONLITE(,M(L,O,int64)),NumopOn<float32>() NONLITE(,NumopOn<float64>()), flags,dim)
-//	NONLITE(,M(L,O,int64),NumopOn<float32>(),NumopOn<float64>()), flags,dim)
-#define DECLOP_FLOAT(  L,M,O,sym,flags,dim) Numop(sym,NumopOn<uint8>(),NumopOn<int16>(),NumopOn<int32>() \
-	NONLITE(,NumopOn<int64>()),M(L,O,float32) NONLITE(,M(L,O,float64)),flags,dim)
+#define DECLOP_NOFLOAT(L,M,O,sym,flags,dim) Numop2(sym,M(L,O,uint8),M(L,O,int16),M(L,O,int32) \
+	NONLITE(,M(L,O,int64)),Numop2On<float32>() NONLITE(,Numop2On<float64>()), flags,dim)
+//	NONLITE(,M(L,O,int64),Numop2On<float32>(),Numop2On<float64>()), flags,dim)
+#define DECLOP_FLOAT(  L,M,O,sym,flags,dim) Numop2(sym,Numop2On<uint8>(),Numop2On<int16>(),Numop2On<int32>() \
+	NONLITE(,Numop2On<int64>()),M(L,O,float32) NONLITE(,M(L,O,float64)),flags,dim)
 
 #define DECL_OP(                O,sym,flags)     DECLOP(         OL,DECL_OPON       ,O,sym,flags,1)
 #define DECL_OP_NOFLOAT(        O,sym,flags)     DECLOP_NOFLOAT( OL,DECL_OPON       ,O,sym,flags,1)
@@ -293,11 +293,11 @@
 DEF_OP(p2c,     gf_p2c(a)+b, 0, false, false)
 #endif
 
-extern Numop      op_table1[], op_table2[], op_table3[], op_table4[];
+extern Numop2     op_table1[], op_table2[], op_table3[], op_table4[];
 extern const long op_table1_n, op_table2_n, op_table3_n, op_table4_n;
 
 #ifdef PASS1
-Numop op_table1[] = {
+Numop2 op_table1[] = {
 	DECL_OP(ignore, "ignore", OP_ASSOC),
 	DECL_OP(put, "put", OP_ASSOC),
 	DECL_OP(add, "+", OP_ASSOC|OP_COMM), // "LINV=sub"
@@ -317,7 +317,7 @@
 const long op_table1_n = COUNT(op_table1);
 #endif
 #ifdef PASS2
-Numop op_table2[] = {
+Numop2 op_table2[] = {
 	DECL_OP_NOFLOAT(gcd,  "gcd",  OP_ASSOC|OP_COMM),
 	DECL_OP_NOFLOAT(gcd2, "gcd2", OP_ASSOC|OP_COMM),
 	DECL_OP_NOFLOAT(lcm,  "lcm",  OP_ASSOC|OP_COMM),
@@ -353,7 +353,7 @@
 	int64 p=nt_smallest((int64 *)0), q=nt_greatest((int64 *)0);
 	return c<p/2?p:c>q/2?q:a-b; }
 
-Numop op_table3[] = {
+Numop2 op_table3[] = {
 	DECL_OP_NOFOLD(sinmul, "sin*", 0),
 	DECL_OP_NOFOLD(cosmul, "cos*", 0),
 	DECL_OP_NOFOLD(atan,   "atan", 0),
@@ -387,7 +387,7 @@
 const long op_table3_n = COUNT(op_table3);
 #endif
 #ifdef PASS4
-Numop op_table4[] = {
+Numop2 op_table4[] = {
 	DECL_VOP(cx_mul,     "C.*",     OP_ASSOC|OP_COMM,2),
 	DECL_VOP(cx_mulconj, "C.*conj", OP_ASSOC|OP_COMM,2),
 	DECL_VOP(cx_div,     "C./",     0,2),
@@ -436,7 +436,7 @@
 	}
 // S:name; M:mode; F:replacement function;
 #define OVERRIDE_INT(S,M,F) { \
-	Numop *foo = op_dict[string(#S)]; \
+	Numop2 *foo = dynamic_cast<Numop2 *>(op_dict[string(#S)]); \
 	foo->on_uint8.M=F; \
 	foo->on_int16.M=F; \
 	foo->on_int32.M=F; }



More information about the Gridflow-cvs mailing list