[PD-cvs] externals/gridflow/base bitpacking.c, 1.1, 1.2 flow_objects.c, 1.1, 1.2 flow_objects_for_image.c, 1.1, 1.2 flow_objects_for_matrix.c, 1.1, 1.2 grid.c, 1.1, 1.2 grid.h, 1.1, 1.2 main.c, 1.1, 1.2 number.c, 1.1, 1.2

Mathieu Bouchard matju at users.sourceforge.net
Wed Mar 15 05:37:10 CET 2006


Update of /cvsroot/pure-data/externals/gridflow/base
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18270

Modified Files:
	bitpacking.c flow_objects.c flow_objects_for_image.c 
	flow_objects_for_matrix.c grid.c grid.h main.c number.c 
Log Message:
0.8.1



Index: number.c
===================================================================
RCS file: /cvsroot/pure-data/externals/gridflow/base/number.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** number.c	4 Oct 2005 02:02:13 -0000	1.1
--- number.c	15 Mar 2006 04:37:08 -0000	1.2
***************
*** 45,50 ****
  	// I call abort() on those because I can't say they're purevirtual.
  	static T f(T a, T b) {abort();}
! 	static bool is_neutral(T x, LeftRight side)   {assert(!"Op::is_neutral called?");}
! 	static bool is_absorbent(T x, LeftRight side) {assert(!"Op::is_absorbent called?");}
  };
  
--- 45,50 ----
  	// I call abort() on those because I can't say they're purevirtual.
  	static T f(T a, T b) {abort();}
! 	static bool is_neutral(T x, LeftRight side)   {assert(!"Op::is_neutral called?");   return false;}
! 	static bool is_absorbent(T x, LeftRight side) {assert(!"Op::is_absorbent called?"); return false;}
  };
  
***************
*** 59,63 ****
  	template <class T> static void op_zip (int n, T *as, T *bs) {
  		if (!n) return;
! 		int ba=bs-as; // really!
  #define FOO(I) as[I]=O::f(as[I],as[ba+I]);
  	UNROLL_8(FOO,n,as)
--- 59,63 ----
  	template <class T> static void op_zip (int n, T *as, T *bs) {
  		if (!n) return;
! 		ptrdiff_t ba=bs-as; // really!
  #define FOO(I) as[I]=O::f(as[I],as[ba+I]);
  	UNROLL_8(FOO,n,as)
***************
*** 67,71 ****
  	template <class T> static void op_zip2 (int n, T *as, T *bs, T *cs) {
  		if (!n) return;
! 		int ba=bs-as, ca=cs-as;
  #define FOO(I) as[ca+I]=O::f(as[I],as[ba+I]);
  	UNROLL_8(FOO,n,as)
--- 67,71 ----
  	template <class T> static void op_zip2 (int n, T *as, T *bs, T *cs) {
  		if (!n) return;
! 		ptrdiff_t ba=bs-as, ca=cs-as;
  #define FOO(I) as[ca+I]=O::f(as[I],as[ba+I]);
  	UNROLL_8(FOO,n,as)
***************
*** 137,175 ****
  
  // classic two-input operator
! #define DEF_OP(op,expr,neutral,absorbent) \
  	template <class T> class Y##op : Op<T> { public: \
  		inline static T f(T a, T b) { return expr; } \
! 		inline static bool is_neutral  (T x, LeftRight side) { return neutral; } \
! 		inline static bool is_absorbent(T x, LeftRight side) { return absorbent; } };
! #define DEF_OPFT(op,expr,neutral,absorbent,T) \
  	template <> class Y##op<T> : Op<T> { public: \
  		inline static T f(T a, T b) { return expr; } \
! 		inline static bool is_neutral  (T x, LeftRight side) { return neutral; } \
! 		inline static bool is_absorbent(T x, LeftRight side) { return absorbent; } }; \
  // this macro is for operators that have different code for the float version
! #define DEF_OPF(op,expr,expr2,neutral,absorbent) \
! 	DEF_OP( op,expr,      neutral,absorbent) \
! 	DEF_OPFT(op,expr2,neutral,absorbent,float32) \
! 	DEF_OPFT(op,expr2,neutral,absorbent,float64)
  
  #define DECL_OPON(base,op,T) NumopOn<T>( \
  	&base<Y##op<T> >::op_map, &base<Y##op<T> >::op_zip, \
  	&base<Y##op<T> >::op_fold, &base<Y##op<T> >::op_scan, \
! 	&Y##op<T>::is_neutral, &Y##op<T>::is_absorbent)
  #define DECL_OPON_NOFOLD(base,op,T) NumopOn<T>( \
  	&base<Y##op<T> >::op_map, &base<Y##op<T> >::op_zip, 0,0, \
! 	&Y##op<T>::is_neutral, &Y##op<T>::is_absorbent)
  #define DECL_OP(op,sym,flags) Numop(0, sym, \
  	DECL_OPON(OpLoops,op,uint8), DECL_OPON(OpLoops,op,int16), \
  	DECL_OPON(OpLoops,op,int32) NONLITE(, DECL_OPON(OpLoops,op,int64), \
! 	DECL_OPON(OpLoops,op,float32), DECL_OPON(OpLoops,op,float64)), flags)
  #define DECL_OP_NOFLOAT(op,sym,flags) Numop(0, sym, \
  	DECL_OPON(OpLoops,op,uint8), DECL_OPON(OpLoops,op,int16), \
  	DECL_OPON(OpLoops,op,int32) NONLITE(, DECL_OPON(OpLoops,op,int64), \
! 	NumopOn<float32>(0,0,0,0,0,0), NumopOn<float64>(0,0,0,0,0,0)), flags)
  #define DECL_OP_NOFOLD(op,sym,flags) Numop(0, sym, \
  	DECL_OPON_NOFOLD(OpLoops,op,uint8), DECL_OPON_NOFOLD(OpLoops,op,int16), \
  	DECL_OPON_NOFOLD(OpLoops,op,int32) NONLITE(, DECL_OPON_NOFOLD(OpLoops,op,int64), \
! 	DECL_OPON_NOFOLD(OpLoops,op,float32), DECL_OPON_NOFOLD(OpLoops,op,float64)), flags)
  
  template <class T> static inline T gf_floor (T a) {
--- 137,180 ----
  
  // classic two-input operator
! #define DEF_OP(op,expr,neu,isneu,isorb) \
  	template <class T> class Y##op : Op<T> { public: \
  		inline static T f(T a, T b) { return expr; } \
! 		inline static T neutral (LeftRight side) {return neu;} \
! 		inline static bool is_neutral  (T x, LeftRight side) {return isneu;} \
! 		inline static bool is_absorbent(T x, LeftRight side) {return isorb;}};
! #define DEF_OPFT(op,expr,neu,isneu,isorb,T) \
  	template <> class Y##op<T> : Op<T> { public: \
  		inline static T f(T a, T b) { return expr; } \
! 		inline static T neutral (LeftRight side) {return neu;} \
! 		inline static bool is_neutral  (T x, LeftRight side) {return isneu;} \
! 		inline static bool is_absorbent(T x, LeftRight side) {return isorb;}};
  // this macro is for operators that have different code for the float version
! #define DEF_OPF(op,expr,expr2,neu,isneu,isorb) \
! 	DEF_OP( op,expr,      neu,isneu,isorb) \
! 	DEF_OPFT(op,expr2,neu,isneu,isorb,float32) \
! 	DEF_OPFT(op,expr2,neu,isneu,isorb,float64)
  
  #define DECL_OPON(base,op,T) NumopOn<T>( \
  	&base<Y##op<T> >::op_map, &base<Y##op<T> >::op_zip, \
  	&base<Y##op<T> >::op_fold, &base<Y##op<T> >::op_scan, \
! 	&Y##op<T>::neutral, &Y##op<T>::is_neutral, &Y##op<T>::is_absorbent)
  #define DECL_OPON_NOFOLD(base,op,T) NumopOn<T>( \
  	&base<Y##op<T> >::op_map, &base<Y##op<T> >::op_zip, 0,0, \
! 	&Y##op<T>::neutral, &Y##op<T>::is_neutral, &Y##op<T>::is_absorbent)
  #define DECL_OP(op,sym,flags) Numop(0, sym, \
  	DECL_OPON(OpLoops,op,uint8), DECL_OPON(OpLoops,op,int16), \
  	DECL_OPON(OpLoops,op,int32) NONLITE(, DECL_OPON(OpLoops,op,int64), \
! 	DECL_OPON(OpLoops,op,float32), DECL_OPON(OpLoops,op,float64), \
! 	DECL_OPON(OpLoops,op,ruby)), flags)
  #define DECL_OP_NOFLOAT(op,sym,flags) Numop(0, sym, \
  	DECL_OPON(OpLoops,op,uint8), DECL_OPON(OpLoops,op,int16), \
  	DECL_OPON(OpLoops,op,int32) NONLITE(, DECL_OPON(OpLoops,op,int64), \
! 	NumopOn<float32>(0,0,0,0,0,0,0), NumopOn<float64>(0,0,0,0,0,0,0), \
! 	DECL_OPON(OpLoops,op,ruby)), flags)
  #define DECL_OP_NOFOLD(op,sym,flags) Numop(0, sym, \
  	DECL_OPON_NOFOLD(OpLoops,op,uint8), DECL_OPON_NOFOLD(OpLoops,op,int16), \
  	DECL_OPON_NOFOLD(OpLoops,op,int32) NONLITE(, DECL_OPON_NOFOLD(OpLoops,op,int64), \
! 	DECL_OPON_NOFOLD(OpLoops,op,float32), DECL_OPON_NOFOLD(OpLoops,op,float64), \
! 	DECL_OPON_NOFOLD(OpLoops,op,ruby)), flags)
  
  template <class T> static inline T gf_floor (T a) {
***************
*** 178,253 ****
  	return (T) floor(abs((double)a)) * (a<0?-1:1); }
  
! /*
! uint8 clipadd(uint8 a, uint8 b) { int32 c=a+b; return c<0?0:c>255?255:c; }
! int16 clipadd(int16 a, int16 b) { int32 c=a+b; return c<-0x8000?-0x8000:c>0x7fff?0x7fff:c; }
! int32 clipadd(int32 a, int32 b) { int64 c=a+b; return c<-0x80000000?-0x80000000:c>0x7fffffff?0x7fffffff:c; }
! int64 clipadd(int64 a, int64 b) { int64 c=(a>>1)+(b>>1)+(a&b&1);
! 	return c<(nt_smallest(0LL)/2?nt_smallest(0LL):c>nt_greatest(0LL)/2?nt_greatest(0LL):a+b; }
! uint8 clipsub(uint8 a, uint8 b) { int32 c=a-b; return c<0?0:c>255?255:c; }
! int16 clipsub(int16 a, int16 b) { int32 c=a-b; return c<-0x8000?-0x8000:c>0x7fff?0x7fff:c; }
! int32 clipsub(int32 a, int32 b) { int64 c=a-b; return c<-0x80000000?-0x80000000:c>0x7fffffff?0x7fffffff:c; }
! int64 clipsub(int64 a, int64 b) { int64 c=(a>>1)-(b>>1); //???
! 	return c<(nt_smallest(0LL)/2?nt_smallest(0LL):c>nt_greatest(0LL)/2?nt_greatest(0LL):a-b; }
! */
  
  #ifdef PASS1
! DEF_OP(ignore, a, side==at_right, side==at_left)
! DEF_OP(put, b, side==at_left, side==at_right)
! DEF_OP(add, a+b, x==0, false)
! DEF_OP(sub, a-b, side==at_right && x==0, false)
! DEF_OP(bus, b-a, side==at_left  && x==0, false)
! DEF_OP(mul, a*b, x==1, x==0)
! DEF_OP(mulshr8, ((int32)a*(int32)b)>>8, (int64)x==256, x==0) //!@#$ bug with int64
! DEF_OP(div, b==0 ? 0 : a/b, side==at_right && x==1, false)
! DEF_OP(div2, b==0 ? 0 : div2(a,b), side==at_right && x==1, false)
! DEF_OP(vid, a==0 ? 0 : b/a, side==at_left && x==1, false)
! DEF_OP(vid2, a==0 ? 0 : div2(b,a), side==at_left && x==1, false)
! DEF_OPF(mod, b==0 ? 0 : mod(a,b), b==0 ? 0 : a-b*gf_floor(a/b),
! 	false, side==at_left && x==0 || side==at_right && x==1)
! DEF_OPF(dom, a==0 ? 0 : mod(b,a), a==0 ? 0 : b-a*gf_floor(b/a),
! 	false, side==at_left && x==0 || side==at_right && x==1)
  //DEF_OPF(rem, b==0 ? 0 : a%b, b==0 ? 0 : a-b*gf_trunc(a/b))
  //DEF_OPF(mer, a==0 ? 0 : b%a, a==0 ? 0 : b-a*gf_trunc(b/a))
! DEF_OP(rem, b==0?0:a%b, false, side==at_left&&x==0 || side==at_right&&x==1)
! DEF_OP(mer, a==0?0:b%a, false, side==at_left&&x==0 || side==at_right&&x==1)
  #endif
  #ifdef PASS2
! DEF_OP(gcd, gcd(a,b), x==0, x==1)
! DEF_OP(gcd2, gcd2(a,b), x==0, x==1) // should test those and pick one of the two
! DEF_OP(lcm, a==0 || b==0 ? 0 : lcm(a,b), x==1, x==0)
! DEF_OPF(or , a|b, (float32)((int32)a | (int32)b), x==0, x==nt_all_ones(&x))
! DEF_OPF(xor, a^b, (float32)((int32)a ^ (int32)b), x==0, false)
! DEF_OPF(and, a&b, (float32)((int32)a & (int32)b), x==nt_all_ones(&x), x==0)
! DEF_OPF(shl, a<<b, a*pow(2.0,+b), side==at_right && x==0, false)
! DEF_OPF(shr, a>>b, a*pow(2.0,-b), side==at_right && x==0, false)
! DEF_OP(sc_and, a ? b : a, side==at_left && x!=0, side==at_left && x==0)
! DEF_OP(sc_or,  a ? a : b, side==at_left && x==0, side==at_left && x!=0)
! DEF_OP(min, min(a,b), x==nt_greatest(&x), x==nt_smallest(&x))
! DEF_OP(max, max(a,b), x==nt_smallest(&x), x==nt_greatest(&x))
  #endif
  #ifdef PASS3
! DEF_OP(cmp, cmp(a,b), false, false)
! DEF_OP(eq,  a == b, false, false)
! DEF_OP(ne,  a != b, false, false)
! DEF_OP(gt,  a >  b, false, side==at_left&&x==nt_smallest(&x)||side==at_right&&x==nt_greatest(&x))
! DEF_OP(le,  a <= b, false, side==at_left&&x==nt_smallest(&x)||side==at_right&&x==nt_greatest(&x))
! DEF_OP(lt,  a <  b, false, side==at_left&&x==nt_greatest(&x)||side==at_right&&x==nt_smallest(&x))
! DEF_OP(ge,  a >= b, false, side==at_left&&x==nt_greatest(&x)||side==at_right&&x==nt_smallest(&x))
! DEF_OP(sin, (T)(b * sin(a * (M_PI / 18000))), false, false) // "LN=9000+36000n RA=0 LA=..."
! DEF_OP(cos, (T)(b * cos(a * (M_PI / 18000))), false, false) // "LN=36000n RA=0 LA=..."
! DEF_OP(atan, (T)(atan2(a,b) * (18000 / M_PI)), false, false) // "LA=0"
! DEF_OP(tanh, (T)(b * tanh(a * (M_PI / 18000))), false, x==0)
! DEF_OP(gamma, b<=0 ? 0 : (T)(0+floor(pow(a/256.0,256.0/b)*256.0)), false, false) // "RN=256"
! DEF_OP(pow, ipow(a,b), false, false) // "RN=1"
! DEF_OP(log, (T)(a==0 ? 0 : b * log(gf_abs(a))), false, false) // "RA=0"
! // 0.7.8
! //DEF_OPF(clipadd, clipadd(a,b), a+b, x==0, false)
! //DEF_OPF(clipsub, clipsub(a,b), a-b, side==at_right && x==0, false)
! DEF_OP(abssub,  gf_abs(a-b), false, false)
! DEF_OP(sqsub, (a-b)*(a-b), false, false)
! DEF_OP(avg, (a+b)/2, false, false)
! DEF_OP(hypot, (T)(0+floor(sqrt(a*a+b*b))), false, false)
! DEF_OP(sqrt, (T)(0+floor(sqrt(a))), false, false)
! DEF_OP(rand, a==0 ? 0 : random()%(int32)a, false, false)
  //DEF_OP(erf,"erf*", 0)
  #endif
--- 183,247 ----
  	return (T) floor(abs((double)a)) * (a<0?-1:1); }
  
! // trying to avoid GCC warning about uint8 too small for ==256
! template <class T> static bool equal256 (T     x) {return x==256;}
! template <>        static bool equal256 (uint8 x) {return false;}
  
  #ifdef PASS1
! DEF_OP(ignore, a, 0, side==at_right, side==at_left)
! DEF_OP(put,    b, 0, side==at_left, side==at_right)
! DEF_OP(add,  a+b, 0, x==0, false)
! DEF_OP(sub,  a-b, 0, side==at_right && x==0, false)
! DEF_OP(bus,  b-a, 0, side==at_left  && x==0, false)
! DEF_OP(mul,  a*b, 1, x==1, x==0)
! DEF_OP(mulshr8, (a*b)>>8, 256, equal256(x), x==0)
! DEF_OP(div,  b==0 ? (T)0 :      a/b , 1, side==at_right && x==1, false)
! DEF_OP(div2, b==0 ?    0 : div2(a,b), 1, side==at_right && x==1, false)
! DEF_OP(vid,  a==0 ? (T)0 :      b/a , 1, side==at_left  && x==1, false)
! DEF_OP(vid2, a==0 ?    0 : div2(b,a), 1, side==at_left  && x==1, false)
! DEF_OPF(mod, b==0 ? 0 : mod(a,b), b==0 ? 0 : a-b*gf_floor(a/b), 0, false, side==at_left && x==0 || side==at_right && x==1)
! DEF_OPF(dom, a==0 ? 0 : mod(b,a), a==0 ? 0 : b-a*gf_floor(b/a), 0, false, side==at_left && x==0 || side==at_right && x==1)
  //DEF_OPF(rem, b==0 ? 0 : a%b, b==0 ? 0 : a-b*gf_trunc(a/b))
  //DEF_OPF(mer, a==0 ? 0 : b%a, a==0 ? 0 : b-a*gf_trunc(b/a))
! DEF_OP(rem, b==0?(T)0:a%b, 0, false, side==at_left&&x==0 || side==at_right&&x==1)
! DEF_OP(mer, a==0?(T)0:b%a, 0, false, side==at_left&&x==0 || side==at_right&&x==1)
  #endif
  #ifdef PASS2
! DEF_OP(gcd,   gcd(a,b), 0, x==0, x==1)
! DEF_OP(gcd2, gcd2(a,b), 0, x==0, x==1) // should test those and pick one of the two
! DEF_OP(lcm, a==0 || b==0 ? (T)0 : lcm(a,b), 1, x==1, x==0)
! DEF_OPF(or , a|b, (float32)((int32)a | (int32)b), 0, x==0, x==nt_all_ones(&x))
! DEF_OPF(xor, a^b, (float32)((int32)a ^ (int32)b), 0, x==0, false)
! DEF_OPF(and, a&b, (float32)((int32)a & (int32)b), -1 /*nt_all_ones((T*)0)*/, x==nt_all_ones(&x), x==0)
! DEF_OPF(shl, a<<b, a*pow(2.0,+b), 0, side==at_right && x==0, false)
! DEF_OPF(shr, a>>b, a*pow(2.0,-b), 0, side==at_right && x==0, false)
! DEF_OP(sc_and, a ? b : a, 1, side==at_left && x!=0, side==at_left && x==0)
! DEF_OP(sc_or,  a ? a : b, 0, side==at_left && x==0, side==at_left && x!=0)
! DEF_OP(min, min(a,b), nt_greatest((T*)0), x==nt_greatest(&x), x==nt_smallest(&x))
! DEF_OP(max, max(a,b), nt_smallest((T*)0), x==nt_smallest(&x), x==nt_greatest(&x))
! DEF_OP(cmp, cmp(a,b), 0, false, false)
! DEF_OP(eq,  a == b, 0, false, false)
! DEF_OP(ne,  a != b, 0, false, false)
! DEF_OP(gt,  a >  b, 0, false, side==at_left&&x==nt_smallest(&x)||side==at_right&&x==nt_greatest(&x))
! DEF_OP(le,  a <= b, 0, false, side==at_left&&x==nt_smallest(&x)||side==at_right&&x==nt_greatest(&x))
! DEF_OP(lt,  a <  b, 0, false, side==at_left&&x==nt_greatest(&x)||side==at_right&&x==nt_smallest(&x))
! DEF_OP(ge,  a >= b, 0, false, side==at_left&&x==nt_greatest(&x)||side==at_right&&x==nt_smallest(&x))
  #endif
  #ifdef PASS3
! DEF_OP(sin, (T)((float64)b * sin((float64)a * (M_PI / 18000))), 0, false, false) // "LN=9000+36000n RA=0 LA=..."
! DEF_OP(cos, (T)((float64)b * cos((float64)a * (M_PI / 18000))), 0, false, false) // "LN=36000n RA=0 LA=..."
! DEF_OP(atan, (T)(atan2(a,b) * (18000 / M_PI)), 0, false, false) // "LA=0"
! DEF_OP(tanh, (T)((float64)b * tanh((float64)a * (M_PI / 18000))), 0, false, x==0)
! DEF_OP(gamma, b<=0 ? (T)0 : (T)(0+floor(pow((float64)a/256.0,256.0/(float64)b)*256.0)), 0, false, false) // "RN=256"
! DEF_OP(pow, ipow(a,b), 0, false, false) // "RN=1"
! DEF_OP(log, (T)(a==0 ? (T)0 : (T)((float64)b * log((float64)gf_abs(a)))), 0, false, false) // "RA=0"
! // 0.8
! DEF_OPF(clipadd, clipadd(a,b), a+b, 0, x==0, false)
! DEF_OPF(clipsub, clipsub(a,b), a-b, 0, side==at_right && x==0, false)
! DEF_OP(abssub,  gf_abs(a-b), 0, false, false)
! DEF_OP(sqsub,   (a-b)*(a-b), 0, false, false)
! DEF_OP(avg,         (a+b)/2, 0, false, false)
! DEF_OP(hypot, (T)(0+floor(sqrt(a*a+b*b))), 0, false, false)
! DEF_OP(sqrt,  (T)(0+floor(sqrt(a))),       0, false, false)
! DEF_OP(rand, a==0 ? (T)0 : (T)(random()%(int32)a), 0, false, false)
  //DEF_OP(erf,"erf*", 0)
  #endif
***************
*** 290,307 ****
  	DECL_OP(min, "min", OP_ASSOC|OP_COMM),
  	DECL_OP(max, "max", OP_ASSOC|OP_COMM),
  };
  const long op_table2_n = COUNT(op_table2);
  #endif
  #ifdef PASS3
  Numop op_table3[] = {
! 	DECL_OP_NOFOLD(eq,  "==", OP_COMM),
! 	DECL_OP_NOFOLD(ne,  "!=", OP_COMM),
! 	DECL_OP_NOFOLD(gt,  ">", 0),
! 	DECL_OP_NOFOLD(le,  "<=", 0),
! 	DECL_OP_NOFOLD(lt,  "<", 0),
! 	DECL_OP_NOFOLD(ge,  ">=", 0),
! 	DECL_OP_NOFOLD(cmp, "cmp", 0),
! 	DECL_OP_NOFOLD(sin, "sin*", 0),
! 	DECL_OP_NOFOLD(cos, "cos*", 0),
  	DECL_OP_NOFOLD(atan, "atan", 0),
  	DECL_OP_NOFOLD(tanh, "tanh*", 0),
--- 284,316 ----
  	DECL_OP(min, "min", OP_ASSOC|OP_COMM),
  	DECL_OP(max, "max", OP_ASSOC|OP_COMM),
+ 	DECL_OP_NOFOLD(eq,   "==", OP_COMM),
+ 	DECL_OP_NOFOLD(ne,   "!=", OP_COMM),
+ 	DECL_OP_NOFOLD(gt,   ">", 0),
+ 	DECL_OP_NOFOLD(le,   "<=", 0),
+ 	DECL_OP_NOFOLD(lt,   "<", 0),
+ 	DECL_OP_NOFOLD(ge,   ">=", 0),
+ 	DECL_OP_NOFOLD(cmp,  "cmp", 0),
  };
  const long op_table2_n = COUNT(op_table2);
  #endif
  #ifdef PASS3
+ uint8 clipadd(uint8 a, uint8 b) { int32 c=a+b; return c<0?0:c>255?255:c; }
+ int16 clipadd(int16 a, int16 b) { int32 c=a+b; return c<-0x8000?-0x8000:c>0x7fff?0x7fff:c; }
+ int32 clipadd(int32 a, int32 b) { int64 c=a+b; return c<-0x80000000?-0x80000000:c>0x7fffffff?0x7fffffff:c; }
+ int64 clipadd(int64 a, int64 b) { int64 c=(a>>1)+(b>>1)+(a&b&1), p=nt_smallest((int64 *)0), q=nt_greatest((int64 *)0);
+ 	return c<p/2?p:c>q/2?q:a+b; }
+ uint8 clipsub(uint8 a, uint8 b) { int32 c=a-b; return c<0?0:c>255?255:c; }
+ int16 clipsub(int16 a, int16 b) { int32 c=a-b; return c<-0x8000?-0x8000:c>0x7fff?0x7fff:c; }
+ int32 clipsub(int32 a, int32 b) { int64 c=a-b; return c<-0x80000000?-0x80000000:c>0x7fffffff?0x7fffffff:c; }
+ int64 clipsub(int64 a, int64 b) { int64 c=(a>>1)-(b>>1); //???
+ 	int64 p=nt_smallest((int64 *)0), q=nt_greatest((int64 *)0);
+ 	return c<p/2?p:c>q/2?q:a-b; }
+ 
+ ruby clipadd(ruby a, ruby b) { return a+b; }
+ ruby clipsub(ruby a, ruby b) { return a-b; }
+ 
  Numop op_table3[] = {
! 	DECL_OP_NOFOLD(sin,  "sin*", 0),
! 	DECL_OP_NOFOLD(cos,  "cos*", 0),
  	DECL_OP_NOFOLD(atan, "atan", 0),
  	DECL_OP_NOFOLD(tanh, "tanh*", 0),
***************
*** 309,315 ****
  	DECL_OP_NOFOLD(pow, "**", 0),
  	DECL_OP_NOFOLD(log, "log*", 0),
! // 0.7.8
! //	DECL_OP(clipadd,"clip+", OP_ASSOC|OP_COMM),
! //	DECL_OP(clipsub,"clip-", 0),
  	DECL_OP_NOFOLD(abssub,"abs-", OP_COMM),
  	DECL_OP_NOFOLD(sqsub,"sq-", OP_COMM),
--- 318,324 ----
  	DECL_OP_NOFOLD(pow, "**", 0),
  	DECL_OP_NOFOLD(log, "log*", 0),
! // 0.8
! 	DECL_OP(clipadd,"clip+", OP_ASSOC|OP_COMM),
! 	DECL_OP(clipsub,"clip-", 0),
  	DECL_OP_NOFOLD(abssub,"abs-", OP_COMM),
  	DECL_OP_NOFOLD(sqsub,"sq-", OP_COMM),

Index: flow_objects_for_image.c
===================================================================
RCS file: /cvsroot/pure-data/externals/gridflow/base/flow_objects_for_image.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** flow_objects_for_image.c	4 Oct 2005 02:02:13 -0000	1.1
--- flow_objects_for_image.c	15 Mar 2006 04:37:08 -0000	1.2
***************
*** 3,7 ****
  
  	GridFlow
! 	Copyright (c) 2001,2002,2003 by Mathieu Bouchard
  
  	This program is free software; you can redistribute it and/or
--- 3,7 ----
  
  	GridFlow
! 	Copyright (c) 2001,2002,2003,2004,2005 by Mathieu Bouchard
  
  	This program is free software; you can redistribute it and/or
***************
*** 208,212 ****
  		#define LOOP(z) \
  			for (int i=0; i<rowsize; i+=z) \
! 			for (int k=0; k<scalex; k++, p+=3)
  		switch (chans) {
  		case 3: LOOP(3) {Z(0);Z(1);Z(2);} break;
--- 208,212 ----
  		#define LOOP(z) \
  			for (int i=0; i<rowsize; i+=z) \
! 			for (int k=0; k<scalex; k++, p+=z)
  		switch (chans) {
  		case 3: LOOP(3) {Z(0);Z(1);Z(2);} break;
***************
*** 478,481 ****
--- 478,482 ----
  } GRID_END
  
+ 
  GRID_INPUT(DrawPolygon,1,color) {} GRID_END
  GRID_INPUT(DrawPolygon,2,polygon) {init_lines();} GRID_END

Index: flow_objects.c
===================================================================
RCS file: /cvsroot/pure-data/externals/gridflow/base/flow_objects.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** flow_objects.c	4 Oct 2005 02:02:13 -0000	1.1
--- flow_objects.c	15 Mar 2006 04:37:08 -0000	1.2
***************
*** 3,7 ****
  
  	GridFlow
! 	Copyright (c) 2001,2002,2003,2004 by Mathieu Bouchard
  
  	This program is free software; you can redistribute it and/or
--- 3,7 ----
  
  	GridFlow
! 	Copyright (c) 2001,2002,2003,2004,2005 by Mathieu Bouchard
  
  	This program is free software; you can redistribute it and/or
***************
*** 159,162 ****
--- 159,163 ----
  static Ruby INTORFLOAT2NUM(float32 value) {return rb_float_new(value);}
  static Ruby INTORFLOAT2NUM(float64 value) {return rb_float_new(value);}
+ static Ruby INTORFLOAT2NUM(ruby    value) {return value.r;}
  
  GRID_INLET(GridExport,0) {
***************
*** 214,220 ****
  	PtrGrid put_at; // can't be //\attr
  	\attr Numop *op;
! 	int32 wdex [Dim::MAX_DIMENSIONS]; // temporary buffer, copy of put_at
! 	int32 fromb[Dim::MAX_DIMENSIONS];
! 	int32 to2  [Dim::MAX_DIMENSIONS];
  	int lsd; // lsd = Last Same Dimension (for put_at)
  	int d; // goes with wdex
--- 215,221 ----
  	PtrGrid put_at; // can't be //\attr
  	\attr Numop *op;
! 	int32 wdex [Dim::MAX_DIM]; // temporary buffer, copy of put_at
! 	int32 fromb[Dim::MAX_DIM];
! 	int32 to2  [Dim::MAX_DIM];
  	int lsd; // lsd = Last Same Dimension (for put_at)
  	int d; // goes with wdex
***************
*** 259,263 ****
  	int nb = r->dim->n;
  	int nc = in->dim->get(na-1);
! 	STACK_ARRAY(int32,v,Dim::MAX_DIMENSIONS);
  	if (na<1) RAISE("must have at least 1 dimension.",na,1,1+nb);
  	int lastindexable = r->dim->prod()/r->dim->prod(nc) - 1;
--- 260,264 ----
  	int nb = r->dim->n;
  	int nc = in->dim->get(na-1);
! 	STACK_ARRAY(int32,v,Dim::MAX_DIM);
  	if (na<1) RAISE("must have at least 1 dimension.",na,1,1+nb);
  	int lastindexable = r->dim->prod()/r->dim->prod(nc) - 1;
***************
*** 414,417 ****
--- 415,420 ----
  	out=new GridOutlet(this,0,in->dim,in->nt);
  	in->set_mode(6);
+ } GRID_ALLOC {
+ 	//out->ask(in->allocn,(Pt<T> &)in->alloc,in->allocfactor,in->allocmin,in->allocmax);
  } GRID_FLOW {
  	Pt<T> rdata = (Pt<T>)*r;
***************
*** 788,792 ****
  		RAISE("dimension mismatch");
  #define FOO(T) trigger((T)0);
! 	TYPESWITCH_NOFLOAT(from->nt,FOO,);
  #undef FOO
  }
--- 791,795 ----
  		RAISE("dimension mismatch");
  #define FOO(T) trigger((T)0);
! 	TYPESWITCH_JUSTINT(from->nt,FOO,);
  #undef FOO
  }
***************
*** 1049,1053 ****
  	STACK_ARRAY(T,res,na*nb*nc*nd);
  	if (dim1==dim2) { out->send(n,data); return; }
! 	for (; n; n-=na*nb*nc*nd, data+=na*nb*nc*nd) {
  		for (int a=0; a<na; a++)
  			for (int b=0; b<nb; b++)
--- 1052,1057 ----
  	STACK_ARRAY(T,res,na*nb*nc*nd);
  	if (dim1==dim2) { out->send(n,data); return; }
! 	int prod = na*nb*nc*nd;
! 	for (; n; n-=prod, data+=prod) {
  		for (int a=0; a<na; a++)
  			for (int b=0; b<nb; b++)
***************
*** 1108,1113 ****
  
  //****************************************************************
! \class GridCentroid2 < GridObject
! struct GridCentroid2 : GridObject {
  	\decl void initialize ();
  	\grin 0 int
--- 1112,1117 ----
  
  //****************************************************************
! \class GridCentroid < GridObject
! struct GridCentroid : GridObject {
  	\decl void initialize ();
  	\grin 0 int
***************
*** 1115,1119 ****
  };
  
! GRID_INLET(GridCentroid2,0) {
  	if (in->dim->n != 3) RAISE("expecting 3 dims");
  	if (in->dim->v[2] != 1) RAISE("expecting 1 channel");
--- 1119,1123 ----
  };
  
! GRID_INLET(GridCentroid,0) {
  	if (in->dim->n != 3) RAISE("expecting 3 dims");
  	if (in->dim->v[2] != 1) RAISE("expecting 1 channel");
***************
*** 1138,1141 ****
--- 1142,1147 ----
  	blah[1] = sum ? sumx/sum : 0;
  	out->send(2,blah);
+ 	rb_funcall(rself,SI(send_out),2,INT2NUM(1),INT2NUM(blah[0]));
+ 	rb_funcall(rself,SI(send_out),2,INT2NUM(2),INT2NUM(blah[1]));
  } GRID_END
  
***************
*** 1144,1149 ****
  }
  
! \classinfo { IEVAL(rself,"install '#centroid2',1,1"); }
! \end class GridCentroid2
  
  //****************************************************************
--- 1150,1155 ----
  }
  
! \classinfo { IEVAL(rself,"install '#centroid',1,3"); }
! \end class GridCentroid
  
  //****************************************************************

Index: bitpacking.c
===================================================================
RCS file: /cvsroot/pure-data/externals/gridflow/base/bitpacking.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** bitpacking.c	4 Oct 2005 02:02:13 -0000	1.1
--- bitpacking.c	15 Mar 2006 04:37:06 -0000	1.2
***************
*** 27,42 ****
  #include <stdio.h>
  
  #define CONVERT1 t = \
! 	(((in[0] << hb[0]) >> 7) & mask[0]) | \
! 	(((in[1] << hb[1]) >> 7) & mask[1]) | \
! 	(((in[2] << hb[2]) >> 7) & mask[2])
  
  #define CONVERT2 \
! 	for (t=0,i=0; i<self->size; i++) t |= (((in[i] << hb[i]) >> 7) & mask[i]);
  
  #define CONVERT3 \
! 	for (t=0,i=0; i<self->size; i++) { \
! 		t |= ((in[i]>>(7-hb[i]))|(in[i]<<(hb[i]-7))) & mask[i]; \
! 	}
  
  #define WRITE_LE \
--- 27,42 ----
  #include <stdio.h>
  
+ //#define CONVERT0(z) (((in[z] << hb[z]) >> 7) & mask[z])
+ #define CONVERT0(z) ((in[z] >> chop[z]) << slide[z])
+ 
  #define CONVERT1 t = \
! 	CONVERT0(0) | CONVERT0(1) | CONVERT0(2)
  
  #define CONVERT2 \
! 	for (t=0,i=0; i<self->size; i++) t |= CONVERT0(i);
  
  #define CONVERT3 \
! 	for (t=0,i=0; i<self->size; i++) \
! 		t |= (((unsigned)in[i]>>(7-hb[i]))|(in[i]<<(hb[i]-7))) & mask[i];
  
  #define WRITE_LE \
***************
*** 75,90 ****
  	uint32 t;
  	int i;
- 	int hb[4];
- 	uint32 mask[4];
  	int sameorder = self->endian==2 || self->endian==::is_le();
  	int size = self->size;
! 
! 	for (i=0; i<self->size; i++) hb[i] = highest_bit(self->mask[i]);
! 	memcpy(mask,self->mask,size*sizeof(uint32));
! 
  	if (sameorder && size==3) {
  		switch(self->bytes) {
! 		case 2:	NTIMES(t=CONVERT1; *((int16 *)out)=t; out+=2; in+=3;) return;
! 		case 4:	NTIMES(t=CONVERT1; *((int32 *)out)=t; out+=4; in+=3;) return;
  		}
  	}
--- 75,90 ----
  	uint32 t;
  	int i;
  	int sameorder = self->endian==2 || self->endian==::is_le();
  	int size = self->size;
! 	uint32  mask[4]; memcpy(mask,self->mask,size*sizeof(uint32));
! 	uint32    hb[4]; for (i=0; i<size; i++) hb[i] = highest_bit(mask[i]);
! 	uint32  span[4]; for (i=0; i<size; i++) span[i] = hb[i] - lowest_bit(mask[i]);
! 	uint32  chop[4]; for (i=0; i<size; i++) chop[i] = 7-span[i];
! 	uint32 slide[4]; for (i=0; i<size; i++) slide[i] = hb[i]-span[i];
! 	
  	if (sameorder && size==3) {
  		switch(self->bytes) {
! 		case 2:	NTIMES(CONVERT1; *((int16 *)out)=t; out+=2; in+=3;) return;
! 		case 4:	NTIMES(CONVERT1; *((int32 *)out)=t; out+=4; in+=3;) return;
  		}
  	}
***************
*** 92,101 ****
  		switch (size) {
  		case 3: for (; n--; in+=3) {CONVERT1; WRITE_LE;} break;
! 		case 4:	for (; n--; in+=4) {CONVERT3; WRITE_LE;} break;
  		default:for (; n--; in+=size) {CONVERT2; WRITE_LE;}}
  	} else {
  		switch (size) {
  		case 3: for (; n--; in+=3) {CONVERT1; WRITE_BE;} break;
! 		case 4: for (; n--; in+=4) {CONVERT3; WRITE_BE;} break;
  		default:for (; n--; in+=size) {CONVERT2; WRITE_BE;}}
  	}
--- 92,101 ----
  		switch (size) {
  		case 3: for (; n--; in+=3) {CONVERT1; WRITE_LE;} break;
! 		case 4:	for (; n--; in+=4) {CONVERT1; WRITE_LE;} break;
  		default:for (; n--; in+=size) {CONVERT2; WRITE_LE;}}
  	} else {
  		switch (size) {
  		case 3: for (; n--; in+=3) {CONVERT1; WRITE_BE;} break;
! 		case 4: for (; n--; in+=4) {CONVERT1; WRITE_BE;} break;
  		default:for (; n--; in+=size) {CONVERT2; WRITE_BE;}}
  	}
***************
*** 133,138 ****
  	const int hb[3] = {15,10,4};
  	const uint32 mask[3] = {0x0000f800,0x000007e0,0x0000001f};
  	uint32 t;
! 	NTIMES( t=CONVERT1; *((short *)out)=t; out+=2; in+=3; )
  }
  
--- 133,141 ----
  	const int hb[3] = {15,10,4};
  	const uint32 mask[3] = {0x0000f800,0x000007e0,0x0000001f};
+ 	uint32 span[3] = {4,5,4};
+ 	uint32 chop[3] = {3,2,3};
+ 	uint32 slide[3] = {11,5,0};
  	uint32 t;
! 	NTIMES(CONVERT1; *((short *)out)=t; out+=2; in+=3;)
  }
  
***************
*** 188,192 ****
  }
  
! /* (R,G,B,?) -> B:8,G:8,R:8,0:8 */
  template <class T>
  static void pack3_bgrn8888(BitPacking *self, int n, Pt<T> in, Pt<uint8> out) {
--- 191,196 ----
  }
  
! // (R,G,B,?) -> B:8,G:8,R:8,0:8
! // fishy
  template <class T>
  static void pack3_bgrn8888(BitPacking *self, int n, Pt<T> in, Pt<uint8> out) {

Index: grid.h
===================================================================
RCS file: /cvsroot/pure-data/externals/gridflow/base/grid.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** grid.h	4 Oct 2005 02:02:13 -0000	1.1
--- grid.h	15 Mar 2006 04:37:08 -0000	1.2
***************
*** 3,7 ****
  
  	GridFlow
! 	Copyright (c) 2001,2002,2003,2004 by Mathieu Bouchard
  
  	This program is free software; you can redistribute it and/or
--- 3,7 ----
  
  	GridFlow
! 	Copyright (c) 2001,2002,2003,2004,2005 by Mathieu Bouchard
  
  	This program is free software; you can redistribute it and/or
***************
*** 26,30 ****
  
  // current version number as string literal
! #define GF_VERSION "0.8.0"
  #define GF_COMPILE_TIME __DATE__ ", " __TIME__
  
--- 26,30 ----
  
  // current version number as string literal
! #define GF_VERSION "0.8.1"
  #define GF_COMPILE_TIME __DATE__ ", " __TIME__
  
***************
*** 37,40 ****
--- 37,46 ----
  #include <math.h>
  
+ #ifdef __APPLE__
+ static inline void *memalign (size_t a, size_t n) {return malloc(n);}
+ #else
+ #include <malloc.h>
+ #endif
+ 
  extern "C" {
  #include <ruby.h>
***************
*** 59,67 ****
  
  #define BUG(s,args...) {fprintf(stderr,s "\nat: %s\n",args,__PRETTY_FUNCTION__); ::raise(11);}
! 
! // !@#$ what am I going to do about this? should this be changed?
! // should I wrap all of the Ruby API for C++-style convenience?
! typedef VALUE Ruby;
! // typedef struct Ruby { VALUE x };
  
  #ifdef IS_BRIDGE
--- 65,69 ----
  
  #define BUG(s,args...) {fprintf(stderr,s "\nat: %s\n",args,__PRETTY_FUNCTION__); ::raise(11);}
! #define L gfpost("%s:%d in %s",__FILE__,__LINE__,__PRETTY_FUNCTION__);
  
  #ifdef IS_BRIDGE
***************
*** 77,80 ****
--- 79,84 ----
  #endif
  
+ typedef VALUE Ruby;
+ 
  /* undocumented function from Ruby that is one thing we need to fix a very elusive bug
  that manifests itself when embedding ruby inside a plugin of another app. This exists
***************
*** 87,91 ****
  __attribute__ ((noreturn));
  };
- #define L fprintf(stderr,"%s:%d in %s\n",__FILE__,__LINE__,__PRETTY_FUNCTION__);
  #define SI(_sym_) (rb_intern(#_sym_))
  #define SYM(_sym_) (ID2SYM(SI(_sym_)))
--- 91,94 ----
***************
*** 105,123 ****
  static inline const char *rb_sym_name(Ruby sym) {return rb_id2name(SYM2ID(sym));}
  #define rb_str_pt(s,t) Pt<t>((t*)rb_str_ptr(s),rb_str_len(s))
- 
- // shorthands
  #define IEVAL(_self_,s) rb_funcall(_self_,SI(instance_eval),1,rb_str_new2(s))
  #define EVAL(s) rb_eval_string(s)
  #define rassert(_p_) if (!(_p_)) RAISE(#_p_);
- 
  // because of older versions of Ruby (1.6.?)
  #define rb_obj_class(o) rb_funcall((o),SI(class),0)
  
  #define WATCH(n,ar) { \
! 	char foo[16*1024], *p=foo; \
! 	p += sprintf(p,"%s: ",#ar); \
  	for (int q=0; q<n; q++) p += sprintf(p,"%lld ",(long long)ar[q]); \
! 	gfpost("%s",foo); \
! }
  
  // we're gonna override assert, so load it first, to avoid conflicts
--- 108,121 ----
  static inline const char *rb_sym_name(Ruby sym) {return rb_id2name(SYM2ID(sym));}
  #define rb_str_pt(s,t) Pt<t>((t*)rb_str_ptr(s),rb_str_len(s))
  #define IEVAL(_self_,s) rb_funcall(_self_,SI(instance_eval),1,rb_str_new2(s))
  #define EVAL(s) rb_eval_string(s)
  #define rassert(_p_) if (!(_p_)) RAISE(#_p_);
  // because of older versions of Ruby (1.6.?)
  #define rb_obj_class(o) rb_funcall((o),SI(class),0)
  
  #define WATCH(n,ar) { \
! 	char foo[16*1024], *p=foo; p += sprintf(p,"%s: ",#ar); \
  	for (int q=0; q<n; q++) p += sprintf(p,"%lld ",(long long)ar[q]); \
! 	gfpost("%s",foo);}
  
  // we're gonna override assert, so load it first, to avoid conflicts
***************
*** 149,153 ****
  static inline Ruby PTR2FIX (const void *ptr) {
  	long p = (long)ptr;
! 	if ((p&3)!=0) BUG("unaligned pointer: %08x\n",(long)(ptr));
  	return LONG2NUM(p>>2);
  }
--- 147,151 ----
  static inline Ruby PTR2FIX (const void *ptr) {
  	long p = (long)ptr;
! 	if ((p&3)!=0) BUG("unaligned pointer: %p\n",ptr);
  	return LONG2NUM(p>>2);
  }
***************
*** 185,189 ****
  template <class T> static inline T ipow(T a, T b) {
  	for(T r=1;;) {if (b&1) r*=a; b>>=1; if (!b) return r; a*=a;}
! }	
  
  // kludge
--- 183,187 ----
  template <class T> static inline T ipow(T a, T b) {
  	for(T r=1;;) {if (b&1) r*=a; b>>=1; if (!b) return r; a*=a;}
! }
  
  // kludge
***************
*** 197,201 ****
  template <class T> static inline T max(T a, T b) { return a>b?a:b; }
  //template <class T> inline T min(T a, T b) { T c = (a-b)>>31; return (a&c)|(b&~c); }
- //template <class T> inline T max(T a, T b) { T c = (a-b)>>31; return (a&c)|(b&~c); }
  
  // greatest common divisor, by euclid's algorithm
--- 195,198 ----
***************
*** 222,231 ****
  
  // returns the position (0..31) of highest bit set in a word, or 0 if none.
! #define FOO(N) if ((x>>N)&(((typeof(x))1<<N)-1)) { x>>=N; i+=N; }
! static int highest_bit(uint8  x) {int i=0;                    FOO(4)FOO(2)FOO(1)return i;}
! static int highest_bit(uint16 x) {int i=0;              FOO(8)FOO(4)FOO(2)FOO(1)return i;}
! static int highest_bit(uint32 x) {int i=0;       FOO(16)FOO(8)FOO(4)FOO(2)FOO(1)return i;}
! static int highest_bit(uint64 x) {int i=0;FOO(32)FOO(16)FOO(8)FOO(4)FOO(2)FOO(1)return i;}
! #undef FOO
  // returns the position (0..31) of lowest bit set in a word, or 0 if none.
  template <class T> static int lowest_bit(T n) { return highest_bit((~n+1)&n); }
--- 219,228 ----
  
  // returns the position (0..31) of highest bit set in a word, or 0 if none.
! #define Z(N) if ((x>>N)&(((typeof(x))1<<N)-1)) { x>>=N; i+=N; }
! static int highest_bit(uint8  x) {int i=0;              Z(4)Z(2)Z(1)return i;}
! static int highest_bit(uint16 x) {int i=0;          Z(8)Z(4)Z(2)Z(1)return i;}
! static int highest_bit(uint32 x) {int i=0;     Z(16)Z(8)Z(4)Z(2)Z(1)return i;}
! static int highest_bit(uint64 x) {int i=0;Z(32)Z(16)Z(8)Z(4)Z(2)Z(1)return i;}
! #undef Z
  // returns the position (0..31) of lowest bit set in a word, or 0 if none.
  template <class T> static int lowest_bit(T n) { return highest_bit((~n+1)&n); }
***************
*** 263,267 ****
  #define EACH_FLOAT_TYPE(MACRO) MACRO(float32) MACRO(float64)
  #endif
! #define EACH_NUMBER_TYPE(MACRO) EACH_INT_TYPE(MACRO) EACH_FLOAT_TYPE(MACRO)
  
  // note: loop unrolling macros assume N!=0
--- 260,264 ----
  #define EACH_FLOAT_TYPE(MACRO) MACRO(float32) MACRO(float64)
  #endif
! #define EACH_NUMBER_TYPE(MACRO) EACH_INT_TYPE(MACRO) EACH_FLOAT_TYPE(MACRO) MACRO(ruby)
  
  // note: loop unrolling macros assume N!=0
***************
*** 280,283 ****
--- 277,406 ----
  
  //****************************************************************
+ // my own little Ruby <-> C++ layer
+ 
+ //struct Arg { Ruby a; };
+ //struct ArgList { int n; Pt<Arg> v; };
+ static inline bool INTEGER_P(Ruby x) {return FIXNUM_P(x)||TYPE(x)==T_BIGNUM;}
+ static inline bool FLOAT_P(Ruby x)   {return TYPE(x)==T_FLOAT;}
+ #define INT(x) TO(int32,x)
+ #define TO(t,x) convert(x,(t*)0)
+ 
+ // not using NUM2INT because Ruby can convert Symbol to int
+ // (by compatibility with Ruby 1.4)
+ static inline int32 convert(Ruby x, int32 *foo) {
+ 	if (INTEGER_P(x)) return NUM2INT(x);
+ 	if (FLOAT_P(x)) return NUM2INT(rb_funcall(x,SI(round),0));
+ 	RAISE("expected Integer or Float (got %s)",
+ 		rb_str_ptr(rb_funcall(x,SI(inspect),0)));
+ }
+ static int16 convert(Ruby x, int16 *foo) {
+ 	int v = INT(x);
+ 	if (v<-0x8000 || v>=0x8000) RAISE("value %d is out of range",v);
+ 	return v;}
+ static uint16 convert(Ruby x, uint16 *foo) {
+ 	int v = INT(x);
+ 	if (v<0 || v>=0x10000) RAISE("value %d is out of range",v);
+ 	return v;}
+ static bool  convert(Ruby x, bool  *foo) {
+ 	if (x==Qtrue) return true;
+ 	if (x==Qfalse) return false;
+ 	switch (TYPE(x)) {
+ 		case T_FIXNUM: case T_BIGNUM: case T_FLOAT: return !!INT(x);
+ 		default: RAISE("can't convert to bool");
+ 	}
+ }
+ 
+ #ifdef HAVE_GCC64
+ static uint64 convert(Ruby val, uint64 *foo) { return NUM2ULONG(val); }
+ static  int64 convert(Ruby val,  int64 *foo) { return NUM2ULONG(val); }
+ static Ruby gf_ull2num(uint64 val) { return ULONG2NUM(val); }
+ static  Ruby gf_ll2num(uint64 val) { return  LONG2NUM(val); }
+ #else
+ static uint64 convert(Ruby val, uint64 *foo) {
+ 	if (FIXNUM_P(val)) return (uint64)FIX2LONG(val);
+ 	if (TYPE(val)!=T_BIGNUM) RAISE("type error");
+ 	uint64 v = (uint64)NUM2UINT(rb_funcall(val,SI(>>),1,INT2FIX(32))) << 32;
+ 	return v + NUM2UINT(rb_funcall(val,SI(&),1,UINT2NUM(0xffffffff)));}
+ static int64 convert(Ruby val, int64 *foo) {
+ 	if (FIXNUM_P(val)) return (int64)FIX2LONG(val);
+ 	if (TYPE(val)!=T_BIGNUM) RAISE("type error");
+ 	int64 v = (int64)NUM2INT(rb_funcall(val,SI(>>),1,INT2FIX(32))) << 32;
+ 	return v + NUM2UINT(rb_funcall(val,SI(&),1,UINT2NUM(0xffffffff)));}
+ static Ruby gf_ull2num(uint64 val) {
+     Ruby x = rb_funcall(UINT2NUM((uint32)(val>>32)),SI(<<),1,INT2FIX(32));
+     return rb_funcall(x,SI(+),1,UINT2NUM((uint32)val));}
+ static Ruby gf_ll2num(int64 val) {
+     Ruby x = rb_funcall( INT2NUM(( int32)(val>>32)),SI(<<),1,INT2FIX(32));
+     return rb_funcall(x,SI(+),1,UINT2NUM((uint32)val));}
+ #endif
+     
+ static long convert(Ruby x, long *foo) {
+ 	return sizeof(long)==sizeof(int32) ?
+ 		convert(x,(int32 *)0) :
+ 		convert(x,(int64 *)0);
+ }
+ 
+ static float64 convert(Ruby x, float64 *foo) {
+ 	if (INTEGER_P(x)) return INT(x);
+ 	if (TYPE(x)!=T_FLOAT) RAISE("not a Float");
+ 	return ((RFloat*)x)->value;}
+ static float32 convert(Ruby x, float32 *foo) {
+ 	return (float32) convert(x,(float64 *)0);}
+ typedef Ruby Symbol, Array, String, Integer;
+ static Ruby convert(Ruby x, Ruby *bogus) { return x; }
+ typedef Ruby (*RMethod)(...); /* !@#$ fishy */
+ 
+ #define BUILTIN_SYMBOLS(MACRO) \
+ 	MACRO(_grid,"grid") MACRO(_bang,"bang") MACRO(_float,"float") \
+ 	MACRO(_list,"list") MACRO(_sharp,"#") \
+ 	MACRO(iv_outlets,"@outlets") \
+ 	MACRO(iv_ninlets,"@ninlets") \
+ 	MACRO(iv_noutlets,"@noutlets")
+ extern struct BuiltinSymbols {
+ #define FOO(_sym_,_str_) Ruby _sym_;
+ BUILTIN_SYMBOLS(FOO)
+ #undef FOO
+ } bsym;
+ 
+ typedef struct R {
+ 	VALUE r;
+ 	R() {r=Qnil;}
+ 	R(int x) {r=INT2NUM(x);}
+ 	R(unsigned x) {r=UINT2NUM(x);}
+ 	R(long x) {r=LONG2NUM(x);}
+ 	R(unsigned long x) {r=ULONG2NUM(x);}
+ 	R(double x) {r=rb_float_new(x);}
+ 	R( int64 x) {r= gf_ll2num(x);}
+ 	R(uint64 x) {r=gf_ull2num(x);}
+ 	operator bool() {return !!INT2NUM(r);}
+ 	operator uint8 () {return INT2NUM(r);}
+ 	operator int16 () {return INT2NUM(r);}
+ 	operator int32 () {return INT2NUM(r);}
+ 	operator int64 () {return convert(r,(int64*)0);}
+ 	operator float32 () {return convert(r,(float32*)0);}
+ 	operator float64 () {return convert(r,(float64*)0);}
+ #define FOO(As,Op) \
+ 	R &operator As (int x) {r=rb_funcall(r, SI(Op),1,INT2NUM(x)); return *this;}
+ 	FOO(+=,+) FOO(-=,-) FOO(*=,*) FOO(/=,/) FOO(%=,%)
+ 	FOO(&=,&) FOO(|=,|) FOO(^=,^) FOO(<<=,<<) FOO(>>=,>>)
+ #undef FOO
+ //	bool operator  == (int x) {return rb_funcall(r,SI(==),1,INT2NUM(x));}
+ #define FOO(Op) \
+ 	R operator Op (R x)   {return rb_funcall(r,SI(Op),1,x.r);} \
+ 	R operator Op (int x) {return rb_funcall(r,SI(Op),1,INT2NUM(x));}
+ 	FOO(+) FOO(-) FOO(*) FOO(/) FOO(%)
+ 	FOO(&) FOO(|) FOO(^) FOO(<<) FOO(>>)
+ 	FOO(<) FOO(>) FOO(<=) FOO(>=) FOO(==) FOO(!=)
+ #undef FOO
+ 	static R value(VALUE r) {R x; x.r=r; return x;}
+ } ruby;
+ 
+ static R operator -(int a, R b) {return rb_funcall(a,SI(Op),1,INT2NUM(b.r));}
+ 
+ static inline R ipow(R a, R b) {return R::value(rb_funcall(a.r,SI(**),1,b.r));}
+ static inline R gf_abs(R a) { return R::value(rb_funcall(a.r,SI(abs),0)); }
+ static inline R cmp(R a, R b) { return R::value(rb_funcall(a.r,SI(<=>),1,b.r));}
+ 
+ //****************************************************************
  // hook into pointer manipulation. will help find memory corruption bugs.
  
***************
*** 378,385 ****
  extern "C" void *gfmalloc(size_t n);
  extern "C" void gffree(void *p);
! inline void *::operator new   (size_t n) { return gfmalloc(n); }
! inline void *::operator new[] (size_t n) { return gfmalloc(n); }
! inline void  ::operator delete   (void *p) { gffree(p); }
! inline void  ::operator delete[] (void *p) { gffree(p); }
  #endif
  
--- 501,509 ----
  extern "C" void *gfmalloc(size_t n);
  extern "C" void gffree(void *p);
! // note that C++ (GCC 3.4) now refuses the :: prefix so i removed it in the 4 following lines:
! inline void *operator new   (size_t n) { return gfmalloc(n); }
! inline void *operator new[] (size_t n) { return gfmalloc(n); }
! inline void  operator delete   (void *p) { gffree(p); }
! inline void  operator delete[] (void *p) { gffree(p); }
  #endif
  
***************
*** 401,486 ****
  
  //****************************************************************
- // my own little Ruby <-> C++ layer
- 
- struct Arg { Ruby a; };
- struct ArgList { int n; Pt<Arg> v; };
- static inline bool INTEGER_P(Ruby x) {return FIXNUM_P(x)||TYPE(x)==T_BIGNUM;}
- static inline bool FLOAT_P(Ruby x)   {return TYPE(x)==T_FLOAT;}
- #define INT(x) TO(int32,x)
- #define TO(t,x) convert(x,(t*)0)
- 
- // not using NUM2INT because Ruby can convert Symbol to int
- // (by compatibility with Ruby 1.4)
- static inline int32 convert(Ruby x, int32 *foo) {
- 	if (INTEGER_P(x)) return NUM2INT(x);
- 	if (FLOAT_P(x)) return NUM2INT(rb_funcall(x,SI(round),0));
- 	RAISE("expected Integer or Float (got %s)",
- 		rb_str_ptr(rb_funcall(x,SI(inspect),0)));
- }
- static int16 convert(Ruby x, int16 *foo) {
- 	int v = INT(x);
- 	if (v<-0x8000 || v>=0x8000) RAISE("value %d is out of range",v);
- 	return v;}
- static uint16 convert(Ruby x, uint16 *foo) {
- 	int v = INT(x);
- 	if (v<0 || v>=0x10000) RAISE("value %d is out of range",v);
- 	return v;}
- static bool  convert(Ruby x, bool  *foo) {
- 	if (x==Qtrue) return true;
- 	if (x==Qfalse) return false;
- 	switch (TYPE(x)) {
- 		case T_FIXNUM: case T_BIGNUM: case T_FLOAT: return !!INT(x);
- 		default: RAISE("can't convert to bool");
- 	}
- }
- 
- static uint64 convert(Ruby val, uint64 *foo) {
- 	if (FIXNUM_P(val)) return (uint64)FIX2LONG(val);
- 	if (TYPE(val)!=T_BIGNUM) RAISE("type error");
- 	uint64 v = (uint64)NUM2UINT(rb_funcall(val,SI(>>),1,INT2FIX(32))) << 32;
- 	return v + NUM2UINT(rb_funcall(val,SI(&),1,UINT2NUM(0xffffffff)));}
- static int64 convert(Ruby val, int64 *foo) {
- 	if (FIXNUM_P(val)) return (int64)FIX2LONG(val);
- 	if (TYPE(val)!=T_BIGNUM) RAISE("type error");
- 	int64 v = (int64)NUM2INT(rb_funcall(val,SI(>>),1,INT2FIX(32))) << 32;
- 	return v + NUM2UINT(rb_funcall(val,SI(&),1,UINT2NUM(0xffffffff)));}
- 
- static Ruby gf_ull2num(uint64 val) {
-     return rb_funcall(
- 	rb_funcall(UINT2NUM((uint32)(val>>32)),SI(<<),1,INT2FIX(32)),
- 	SI(+),1,UINT2NUM((uint32)val));}
- static Ruby gf_ll2num(int64 val) {
-     return rb_funcall(
- 	rb_funcall(INT2NUM((int32)(val>>32)),SI(<<),1,INT2FIX(32)),
- 	SI(+),1,UINT2NUM((uint32)val));}
- 
- static  long  convert(Ruby x,   long *foo) {
- 	return sizeof(long)==sizeof(int32) ?
- 		convert(x,(int32 *)0) :
- 		convert(x,(int64 *)0);
- }
- static float64 convert(Ruby x, float64 *foo) {
- 	if (INTEGER_P(x)) return INT(x);
- 	if (TYPE(x)!=T_FLOAT) RAISE("not a Float");
- 	return ((RFloat*)x)->value;}
- static float32 convert(Ruby x, float32 *foo) {
- 	return (float32) convert(x,(float64 *)0);}
- typedef Ruby Symbol, Array, String, Integer;
- static Ruby convert(Ruby x, Ruby *bogus) { return x; }
- typedef Ruby (*RMethod)(...); /* !@#$ fishy */
- 
- #define BUILTIN_SYMBOLS(MACRO) \
- 	MACRO(_grid,"grid") MACRO(_bang,"bang") MACRO(_float,"float") \
- 	MACRO(_list,"list") MACRO(_sharp,"#") \
- 	MACRO(iv_outlets,"@outlets") \
- 	MACRO(iv_ninlets,"@ninlets") \
- 	MACRO(iv_noutlets,"@noutlets")
- extern struct BuiltinSymbols {
- #define FOO(_sym_,_str_) Ruby _sym_;
- BUILTIN_SYMBOLS(FOO)
- #undef FOO
- } bsym;
- 
- //****************************************************************
  // CObject is the base class for C++ classes that get exported to Ruby.
  // BTW: It's quite convenient to have virtual-methods in the base class
--- 525,528 ----
***************
*** 510,514 ****
  struct MethodDecl { const char *selector; RMethod method; };
  void define_many_methods(Ruby rself, int n, MethodDecl *methods);
- 
  extern Ruby mGridFlow, cFObject, cGridObject, cFormat;
  
--- 552,555 ----
***************
*** 517,539 ****
  \class Dim < CObject
  struct Dim : CObject {
! 	static const int MAX_DIMENSIONS=16; // maximum number of dimensions in a grid
  	int n;
  	Pt<int32> v; // safe pointer
! 	int32 v2[MAX_DIMENSIONS]; // real stuff
  	void check(); // test invariants
! 	Dim(int n, Pt<int32> v) {
! 		this->v = Pt<int32>(v2,MAX_DIMENSIONS);
! 		this->n = n;
! 		COPY(this->v,v,n); check();
! 	}
! 	Dim(int n, int32* v) {
! 		this->v = Pt<int32>(v2,MAX_DIMENSIONS);
! 		this->n = n;
! 		COPY(this->v,Pt<int32>(v,n),n); check();
! 	}
! 	Dim()                 {v=Pt<int32>(v2,MAX_DIMENSIONS); n=0;                     check();}
! 	Dim(int a)            {v=Pt<int32>(v2,MAX_DIMENSIONS); n=1;v[0]=a;              check();}
! 	Dim(int a,int b)      {v=Pt<int32>(v2,MAX_DIMENSIONS); n=2;v[0]=a;v[1]=b;       check();}
! 	Dim(int a,int b,int c){v=Pt<int32>(v2,MAX_DIMENSIONS); n=3;v[0]=a;v[1]=b;v[2]=c;check();}
  	int count() {return n;}
  	int get(int i) { return v[i]; }
--- 558,572 ----
  \class Dim < CObject
  struct Dim : CObject {
! 	static const int MAX_DIM=16; // maximum number of dimensions in a grid
  	int n;
  	Pt<int32> v; // safe pointer
! 	int32 v2[MAX_DIM]; // real stuff
  	void check(); // test invariants
! 	Dim(int n, Pt<int32> v) { this->v = Pt<int32>(v2,MAX_DIM); this->n = n; COPY(this->v,v,n); check();}
! 	Dim(int n,    int32 *v) { this->v = Pt<int32>(v2,MAX_DIM); this->n = n; COPY(this->v,Pt<int32>(v,n),n); check();}
! 	Dim()                 {v=Pt<int32>(v2,MAX_DIM); n=0;                     check();}
! 	Dim(int a)            {v=Pt<int32>(v2,MAX_DIM); n=1;v[0]=a;              check();}
! 	Dim(int a,int b)      {v=Pt<int32>(v2,MAX_DIM); n=2;v[0]=a;v[1]=b;       check();}
! 	Dim(int a,int b,int c){v=Pt<int32>(v2,MAX_DIM); n=3;v[0]=a;v[1]=b;v[2]=c;check();}
  	int count() {return n;}
  	int get(int i) { return v[i]; }
***************
*** 611,614 ****
--- 644,648 ----
  NUMBER_TYPE_LIMITS(float32,-HUGE_VAL,+HUGE_VAL,(RAISE("all_ones"),0))
  NUMBER_TYPE_LIMITS(float64,-HUGE_VAL,+HUGE_VAL,(RAISE("all_ones"),0))
+ NUMBER_TYPE_LIMITS(   ruby,ruby(-HUGE_VAL),ruby(+HUGE_VAL),(RAISE("all_ones"),0))
  
  #ifdef HAVE_LITE
***************
*** 625,629 ****
  	MACRO( uint64,64,NT_UNSIGNED|NT_UNIMPL, "u64") MACRO(int64,64,NT_NOTLITE, "i64,l") \
  	MACRO(float32,32,NT_NOTLITE|NT_FLOAT, "f32,f") \
! 	MACRO(float64,64,NT_NOTLITE|NT_FLOAT, "f64,d")
  
  enum NumberTypeE {
--- 659,664 ----
  	MACRO( uint64,64,NT_UNSIGNED|NT_UNIMPL, "u64") MACRO(int64,64,NT_NOTLITE, "i64,l") \
  	MACRO(float32,32,NT_NOTLITE|NT_FLOAT, "f32,f") \
! 	MACRO(float64,64,NT_NOTLITE|NT_FLOAT, "f64,d") \
! 	MACRO(   ruby,sizeof(long),NT_NOTLITE,"r")
  
  enum NumberTypeE {
***************
*** 662,670 ****
    case uint8_e:   C(uint8) break;         case int16_e: C(int16) break; \
    case int32_e:   C(int32) break; NONLITE(case int64_e: C(int64) break; \
!   case float32_e: C(float32) break; case float64_e: C(float64) break;) \
    default: E; RAISE("type '%s' not available here",number_type_table[T].sym);}
! #define TYPESWITCH_NOFLOAT(T,C,E) switch (T) { \
    case uint8_e: C(uint8) break; case int16_e: C(int16) break; \
!   case int32_e: C(int32) break;   NONLITE(case int64_e: C(int64) break;)\
    default: E; RAISE("type '%s' not available here",number_type_table[T].sym);}
  
--- 697,706 ----
    case uint8_e:   C(uint8) break;         case int16_e: C(int16) break; \
    case int32_e:   C(int32) break; NONLITE(case int64_e: C(int64) break; \
!   case float32_e: C(float32) break; case float64_e: C(float64) break; \
!   case ruby_e: C(ruby) break;) \
    default: E; RAISE("type '%s' not available here",number_type_table[T].sym);}
! #define TYPESWITCH_JUSTINT(T,C,E) switch (T) { \
    case uint8_e: C(uint8) break; case int16_e: C(int16) break; \
!   case int32_e: C(int32) break;   NONLITE(case int64_e: C(int64) break;) \
    default: E; RAISE("type '%s' not available here",number_type_table[T].sym);}
  
***************
*** 684,696 ****
  	// neutral: right: forall y {f(x,y)=x}; left: forall x {f(x,y)=y};
  	// absorbent: right: exists a forall y {f(x,y)=a}; ...
  	AlgebraicCheck is_neutral, is_absorbent;
! 	NumopOn(Map m, Zip z, Fold f, Scan s, AlgebraicCheck n, AlgebraicCheck a) :
! 		op_map(m), op_zip(z), op_fold(f), op_scan(s),
! 		is_neutral(n), is_absorbent(a) {}
  	NumopOn() {}
  	NumopOn(const NumopOn &z) {
  		op_map  = z.op_map;  op_zip  = z.op_zip;
  		op_fold = z.op_fold; op_scan = z.op_scan;
! 		is_neutral = z.is_neutral; is_absorbent = z.is_absorbent; }
  };
  
--- 720,733 ----
  	// neutral: right: forall y {f(x,y)=x}; left: forall x {f(x,y)=y};
  	// absorbent: right: exists a forall y {f(x,y)=a}; ...
+ 	T (*neutral)(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, T (*neu)(LeftRight), AlgebraicCheck n, AlgebraicCheck a) :
! 		op_map(m), op_zip(z), op_fold(f), op_scan(s), neutral(neu), is_neutral(n), is_absorbent(a) {}
  	NumopOn() {}
  	NumopOn(const NumopOn &z) {
  		op_map  = z.op_map;  op_zip  = z.op_zip;
  		op_fold = z.op_fold; op_scan = z.op_scan;
! 		is_neutral = z.is_neutral; neutral = z.neutral;
! 		is_absorbent = z.is_absorbent; }
  };
  
***************
*** 698,702 ****
  #define OP_ASSOC (1<<0)
  // abelian property: commutativity: f(a,b)=f(b,a)
! #define OP_COMM  (1<<1)
  
  \class Numop < CObject
--- 735,739 ----
  #define OP_ASSOC (1<<0)
  // abelian property: commutativity: f(a,b)=f(b,a)
! #define OP_COMM (1<<1)
  
  \class Numop < CObject
***************
*** 774,778 ****
  	NumberTypeE nt;
  	void *data;
- 	void *rdata;
  	Grid(P<Dim> dim, NumberTypeE nt, bool clear=false) : dim(0), nt(int32_e), data(0) {
  		if (!dim) RAISE("hell");
--- 811,814 ----
***************
*** 796,807 ****
  		return foo;
  	}
! 	~Grid() {if (rdata) delete[] (uint8 *)rdata;}
  private:
  	void init(P<Dim> dim, NumberTypeE nt) {
  		this->dim = dim;
  		this->nt = nt;
! 		rdata = dim ? new int64[1+(bytes()+7)/8] : 0;
! 		int align = ((long)rdata) & 7;
! 		data = (char *)rdata + ((8-align)&7);
  		//fprintf(stderr,"rdata=%p data=%p align=%d\n",rdata,data,align);
  	}
--- 832,842 ----
  		return foo;
  	}
! 	~Grid() {if (data) free(data);}
  private:
  	void init(P<Dim> dim, NumberTypeE nt) {
  		this->dim = dim;
  		this->nt = nt;
! 		data = 0;
! 		if (dim) data = memalign(16,bytes()+16);
  		//fprintf(stderr,"rdata=%p data=%p align=%d\n",rdata,data,align);
  	}
***************
*** 938,953 ****
  // GRIN1 : int32 only
  // GRIN4 : all types
! // GRIN2 : integers only; no floats
  // GRINF : floats only; no integers
  #ifndef HAVE_LITE
! #define GRIN(TB,TS,TI,TL,TF,TD) {TB,TS,TI,TL,TF,TD}
  #else
! #define GRIN(TB,TS,TI,TL,TF,TD) {TB,TS,TI}
  #endif // HAVE_LITE
  
! #define GRIN1(C,I) GRIN(0,0,C::grinw_##I,0,0,0)
! #define GRIN4(C,I) GRIN(C::grinw_##I,C::grinw_##I,C::grinw_##I,C::grinw_##I,C::grinw_##I,C::grinw_##I)
! #define GRIN2(C,I) GRIN(C::grinw_##I,C::grinw_##I,C::grinw_##I,C::grinw_##I,0,0)
! #define GRINF(C,I) GRIN(0,0,0,0,C::grinw_##I,C::grinw_##I)
  
  struct FClass { // 0.7.8: removed all GridObject-specific stuff.
--- 973,988 ----
  // GRIN1 : int32 only
  // GRIN4 : all types
! // GRIN2 : integers only; no floats (no R either actually)
  // GRINF : floats only; no integers
  #ifndef HAVE_LITE
! #define GRIN(TB,TS,TI,TL,TF,TD,TR) {TB,TS,TI,TL,TF,TD,TR}
  #else
! #define GRIN(TB,TS,TI,TL,TF,TD,TR) {TB,TS,TI}
  #endif // HAVE_LITE
  
! #define GRIN1(C,I) GRIN(0,0,C::grinw_##I,0,0,0,0)
! #define GRIN4(C,I) GRIN(C::grinw_##I,C::grinw_##I,C::grinw_##I,C::grinw_##I,C::grinw_##I,C::grinw_##I,C::grinw_##I)
! #define GRIN2(C,I) GRIN(C::grinw_##I,C::grinw_##I,C::grinw_##I,C::grinw_##I,0,0,0)
! #define GRINF(C,I) GRIN(0,0,0,0,C::grinw_##I,C::grinw_##I,0)
  
  struct FClass { // 0.7.8: removed all GridObject-specific stuff.
***************
*** 1082,1085 ****
--- 1117,1122 ----
  // a stack for the profiler, etc.
  #define GF_STACK_MAX 256
+ //#define NO_INLINE(decl) decl __attribute__((noinline))
+ #define NO_INLINE(decl) decl
  struct GFStack {
  	struct GFStackFrame {
***************
*** 1091,1096 ****
  	int n;
  	GFStack() { n = 0; }
! 	void push (FObject *o) __attribute__((noinline));
! 	void pop () __attribute__((noinline));
  };
  extern GFStack gf_stack;
--- 1128,1133 ----
  	int n;
  	GFStack() { n = 0; }
! 	NO_INLINE(void push (FObject *o));
! 	NO_INLINE(void pop ());
  };
  extern GFStack gf_stack;

Index: main.c
===================================================================
RCS file: /cvsroot/pure-data/externals/gridflow/base/main.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** main.c	4 Oct 2005 02:02:13 -0000	1.1
--- main.c	15 Mar 2006 04:37:08 -0000	1.2
***************
*** 92,96 ****
  
  void Dim::check() {
! 	if (n>MAX_DIMENSIONS) RAISE("too many dimensions");
  	for (int i=0; i<n; i++) if (v[i]<0) RAISE("Dim: negative dimension");
  }
--- 92,96 ----
  
  void Dim::check() {
! 	if (n>MAX_DIM) RAISE("too many dimensions");
  	for (int i=0; i<n; i++) if (v[i]<0) RAISE("Dim: negative dimension");
  }
***************
*** 436,440 ****
  			}
  			const char *se = s+strlen(s);
! 			while (se[-1]==')' || se[-1]=='}') { se--; close++; }
  			if (s!=se) {
  				Ruby u = rb_str_new(s,se-s);
--- 436,440 ----
  			}
  			const char *se = s+strlen(s);
! 			while (se>s && (se[-1]==')' || se[-1]=='}')) { se--; close++; }
  			if (s!=se) {
  				Ruby u = rb_str_new(s,se-s);
***************
*** 496,500 ****
  void *gfmalloc(size_t n) {
  	uint64 t = rdtsc();
! 	void *p = malloc(n);
  	long align = (long)p & 7;
  	if (align) fprintf(stderr,"malloc alignment = %ld mod 8\n",align);
--- 496,501 ----
  void *gfmalloc(size_t n) {
  	uint64 t = rdtsc();
! //	void *p = malloc(n);
! 	void *p = memalign(16,n);
  	long align = (long)p & 7;
  	if (align) fprintf(stderr,"malloc alignment = %ld mod 8\n",align);
***************
*** 574,578 ****
  	rb_define_const(mGridFlow, "GF_VERSION", rb_str_new2(GF_VERSION));
  	rb_define_const(mGridFlow, "GF_COMPILE_TIME", rb_str_new2(GF_COMPILE_TIME));
! 
  	cFObject = rb_define_class_under(mGridFlow, "FObject", rb_cObject);
  	EVAL(
--- 575,579 ----
  	rb_define_const(mGridFlow, "GF_VERSION", rb_str_new2(GF_VERSION));
  	rb_define_const(mGridFlow, "GF_COMPILE_TIME", rb_str_new2(GF_COMPILE_TIME));
! 	rb_define_const(mGridFlow, "GCC_VERSION", rb_str_new2(GCC_VERSION));
  	cFObject = rb_define_class_under(mGridFlow, "FObject", rb_cObject);
  	EVAL(

Index: grid.c
===================================================================
RCS file: /cvsroot/pure-data/externals/gridflow/base/grid.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** grid.c	4 Oct 2005 02:02:13 -0000	1.1
--- grid.c	15 Mar 2006 04:37:08 -0000	1.2
***************
*** 33,40 ****
  
  /* copied from bridge/puredata.c (sorry: linkage issue) */
! struct Pointer : CObject { void *p; Pointer(void *_p) : p(_p) {}};
! Ruby Pointer_s_noo (void *ptr) {
! 	return Data_Wrap_Struct(EVAL("GridFlow::Pointer"), 0, 0, new Pointer(ptr));}
! static void *Pointer_gut (Ruby rself) {DGS(Pointer); return self->p;}
  
  //#define TRACE fprintf(stderr,"%s %s [%s:%d]\n",INFO(parent),__PRETTY_FUNCTION__,__FILE__,__LINE__);assert(this);
--- 33,54 ----
  
  /* copied from bridge/puredata.c (sorry: linkage issue) */
! struct Pointer : CObject {
! 	void *p;
! 	Pointer(void *_p) : p(_p) {}
! };
! 
! #define Pointer_s_new Pointer_s_new_2
! #define Pointer_get   Pointer_get_2
! 
! static Ruby Pointer_s_new (void *ptr) {
! 	Pointer *self = new Pointer(ptr);
! 	Ruby rself = Data_Wrap_Struct(EVAL("GridFlow::Pointer"), 0, CObject_free, self);
! 	self->rself = rself;
! 	return rself;
! }
! static void *Pointer_get (Ruby rself) {
! 	DGS(Pointer);
! 	return self->p;
! }
  
  //#define TRACE fprintf(stderr,"%s %s [%s:%d]\n",INFO(parent),__PRETTY_FUNCTION__,__FILE__,__LINE__);assert(this);
***************
*** 44,49 ****
  	if (NumberTypeE_type_of(d)!=this->nt) RAISE("%s(%s): " \
  		"type mismatch during transmission (got %s expecting %s)", \
! 		INFO(parent), \
! 		__PRETTY_FUNCTION__, \
  		number_type_table[NumberTypeE_type_of(d)].name, \
  		number_type_table[this->nt].name);
--- 58,62 ----
  	if (NumberTypeE_type_of(d)!=this->nt) RAISE("%s(%s): " \
  		"type mismatch during transmission (got %s expecting %s)", \
! 		INFO(parent), __PRETTY_FUNCTION__, \
  		number_type_table[NumberTypeE_type_of(d)].name, \
  		number_type_table[this->nt].name);
***************
*** 78,81 ****
--- 91,96 ----
  #undef FOO
  
+ static inline void NUM(Ruby x, ruby &y) { y.r=x; }
+ 
  void Grid::init_from_ruby_list(int n, Ruby *a, NumberTypeE nt) {
  	Ruby delim = SYM(#);
***************
*** 163,175 ****
  Ruby GridInlet::begin(int argc, Ruby *argv) {TRACE;
  	if (!argc) return PTR2FIX(this);
! 	GridOutlet *back_out = (GridOutlet *) Pointer_gut(argv[0]);
  	nt = (NumberTypeE) INT(argv[1]);
  	argc-=2, argv+=2;
  	PROF(parent) {
! 	if (dim) {
! 		gfpost("%s: grid inlet conflict; aborting %s in favour of %s",
  			INFO(parent), INFO(sender), INFO(back_out->parent));
- 		abort();
- 	}
  	sender = back_out->parent;
  	if ((int)nt<0 || (int)nt>=(int)number_type_table_end)
--- 178,187 ----
  Ruby GridInlet::begin(int argc, Ruby *argv) {TRACE;
  	if (!argc) return PTR2FIX(this);
! 	GridOutlet *back_out = (GridOutlet *) Pointer_get(argv[0]);
  	nt = (NumberTypeE) INT(argv[1]);
  	argc-=2, argv+=2;
  	PROF(parent) {
! 	if (dim) RAISE("%s: grid inlet conflict; aborting %s in favour of %s",
  			INFO(parent), INFO(sender), INFO(back_out->parent));
  	sender = back_out->parent;
  	if ((int)nt<0 || (int)nt>=(int)number_type_table_end)
***************
*** 329,333 ****
  	a[0] = INT2NUM(woutlet);
  	a[1] = bsym._grid;
! 	a[2] = Pointer_s_noo(this);
  	a[3] = INT2NUM(nt);
  	for(int i=0; i<n; i++) a[4+i] = INT2NUM(dim->get(i));
--- 341,345 ----
  	a[0] = INT2NUM(woutlet);
  	a[1] = bsym._grid;
! 	a[2] = Pointer_s_new(this);
  	a[3] = INT2NUM(nt);
  	for(int i=0; i<n; i++) a[4+i] = INT2NUM(dim->get(i));





More information about the Pd-cvs mailing list