aboutsummaryrefslogtreecommitdiff
path: root/externals/gridflow/gridflow.h
diff options
context:
space:
mode:
Diffstat (limited to 'externals/gridflow/gridflow.h')
-rw-r--r--externals/gridflow/gridflow.h926
1 files changed, 0 insertions, 926 deletions
diff --git a/externals/gridflow/gridflow.h b/externals/gridflow/gridflow.h
deleted file mode 100644
index 85eeefd2..00000000
--- a/externals/gridflow/gridflow.h
+++ /dev/null
@@ -1,926 +0,0 @@
-/*
- $Id$
-
- GridFlow
- Copyright (c) 2001-2007 by Mathieu Bouchard
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- See file ../COPYING for further informations on licensing terms.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#ifndef __GRIDFLOW_H
-#define __GRIDFLOW_H
-
-#define GF_VERSION "0.9.4"
-
-#include "m_pd.h"
-#include "config.h"
-#include <vector>
-#include <string>
-#include <sstream>
-#include <map>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <math.h>
-#ifdef __APPLE__
-static inline void *memalign (size_t a, size_t n) {return malloc(n);}
-#else
-#include <malloc.h>
-#endif
-
-#ifndef a_float
-#define a_float a_w.w_float
-#define a_symbol a_w.w_symbol
-#define a_gpointer a_w.w_gpointer
-#endif
-
-#define gensym(s) gensym(const_cast<char *>(s))
-#define sys_vgui(FMT,ARGS...) sys_vgui(const_cast<char *>(FMT),ARGS)
-#define sys_gui(s) sys_gui(const_cast<char *>(s));
-
-#ifndef DESIREDATA
-#define A_LIST t_atomtype(13) /* (t_binbuf *) */
-#endif
-// the use of w_gpointer here is fake, just because there's no suitable member in the union
-static inline void SETLIST(t_atom *a, t_binbuf *b) {a->a_type = A_LIST; a->a_gpointer = (t_gpointer *)b;}
-static inline void SETNULL(t_atom *a) {a->a_type = A_NULL; a->a_gpointer = 0;}
-
-typedef char int8; typedef unsigned char uint8;
-typedef short int16; typedef unsigned short uint16;
-typedef int int32; typedef unsigned int uint32;
-typedef long long int64; typedef unsigned long long uint64;
-typedef float float32;
-typedef double float64;
-
-// three-way comparison (T is assumed Comparable)
-template <class T> static inline T cmp(T a, T b) { return a<b ? -1 : a>b; }
-
-// a remainder function such that div2(a,b)*b+mod(a,b) = a and for which mod(a,b) is in [0;b) or (b;0].
-// in contrast to C-language builtin a%b, this one has uniform behaviour around zero,
-// that is, the same as around any other whole number.
-static inline int mod(int a, int b) {int c=a%b; c+=b&-(c&&(a<0)^(b<0)); return c;}
-
-// counterpart of mod(a,b), just like a/b and a%b are counterparts
-static inline int div2(int a, int b) {return (a/b)-((a<0)&&!!(a%b));}
-
-static inline int32 gf_abs( int32 a) {return a>0?a:-a;}
-static inline int64 gf_abs( int64 a) {return a>0?a:-a;}
-static inline float32 gf_abs(float32 a) {return fabs(a);}
-static inline float64 gf_abs(float64 a) {return fabs(a);}
-
-// integer powers in log(b) time. T is assumed Integer
-template <class T> static inline T ipow(T a, T b) {T r=1; for(;;) {if (b&1) r*=a; b>>=1; if (!b) return r; a*=a;}}
-static inline float32 ipow(float32 a, float32 b) {return pow(a,b);}
-static inline float64 ipow(float64 a, float64 b) {return pow(a,b);}
-
-#undef min
-#undef max
-// minimum/maximum functions; T is assumed to be Comparable
-template <class T> static inline T min(T a, T b) {return a<b?a:b;}
-template <class T> static inline T max(T a, T b) {return a>b?a:b;}
-template <class T> static inline T clip(T a, T lower, T upper) {return a<lower?lower:a>upper?upper:a;}
-//template <class T> inline T min(T a, T b) { T c = (a-b)>>31; return (a&c)|(b&~c); }
-
-// greatest common divisor, by euclid's algorithm
-// this runs in log(a+b) number operations
-template <class T> static T gcd (T a, T b) {
- while (b) {T c=mod(a,b); a=b; b=c;}
- return a;
-}
-
-// greatest common divisor, the binary algorithm. haven't tried yet.
-template <class T> static T gcd2 (T a, T b) {
- int s=0;
- while (((a|b)&1)==0) { a>>=1; b>>=1; s++; }
- while (a) {
- if ((a&1)==0) a>>=1;
- else if ((b&1)==0) b>>=1;
- else {T t=abs(a-b); if (a<b) b=t; else a=t;}
- }
- return b<<s;
-}
-
-// least common multiple; this runs in log(a+b) like gcd.
-template <class T> static inline T lcm (T a, T b) {return a*b/gcd(a,b);}
-
-// returns the position (0..63) 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..63) 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); }
-
-static double drand() { return 1.0*rand()/(RAND_MAX+1.0); }
-
-// is little-endian
-static inline bool is_le() {int x=1; return ((char *)&x)[0];}
-
-static inline uint64 rdtsc()
-#if defined(HAVE_PENTIUM)
-{uint64 x; __asm__ volatile (".byte 0x0f, 0x31":"=A"(x)); return x;}
-#else
-{return 0;}
-#endif
-
-#ifdef HAVE_LITE
-#define EACH_INT_TYPE(MACRO) MACRO(uint8) MACRO(int16) MACRO(int32)
-#define EACH_FLOAT_TYPE(MACRO) MACRO(float32)
-#else
-#define EACH_INT_TYPE(MACRO) MACRO(uint8) MACRO(int16) MACRO(int32) MACRO(int64)
-#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
-// btw this may cause alignment problems when 8 does not divide N
-#define UNROLL_8(MACRO,N,PTR,ARGS...) \
- int n__=(-N)&7; PTR-=n__; N+=n__; \
- switch (n__) { start: \
- case 0:MACRO(0); case 1:MACRO(1); case 2:MACRO(2); case 3:MACRO(3); \
- case 4:MACRO(4); case 5:MACRO(5); case 6:MACRO(6); case 7:MACRO(7); \
- PTR+=8; N-=8; ARGS; if (N) goto start; }
-#define UNROLL_4(MACRO,N,PTR,ARGS...) \
- int n__=(-N)&3; PTR-=n__; N+=n__; \
- switch (n__) { start: \
- case 0:MACRO(0); case 1:MACRO(1); case 2:MACRO(2); case 3:MACRO(3); \
- PTR+=4; N-=4; ARGS; if (N) goto start; }
-
-struct Barf {
- char *text;
- Barf(const char *s, ...);
- Barf(const char *file, int line, const char *func, const char *s, ...);
- ~Barf() {free(text);}
-};
-
-#include <stdio.h>
-extern "C" void *gfmalloc(size_t n);
-extern "C" void gffree(void *p);
-#if __GNUC__<4
-#define ALLOCPREFIX static inline
-#else
-#define ALLOCPREFIX inline
-#endif
-#include "base/new.h"
-ALLOCPREFIX void *operator new (size_t n) throw (std::bad_alloc) {return gfmalloc(n);}
-ALLOCPREFIX void *operator new[] (size_t n) throw (std::bad_alloc) {return gfmalloc(n);}
-ALLOCPREFIX void *operator new (size_t n, const std::nothrow_t&) throw () {return gfmalloc(n);}
-ALLOCPREFIX void *operator new[] (size_t n, const std::nothrow_t&) throw () {return gfmalloc(n);}
-ALLOCPREFIX void operator delete (void*p) throw() {gffree(p);}
-ALLOCPREFIX void operator delete[](void*p) throw() {gffree(p);}
-ALLOCPREFIX void operator delete (void*p, const std::nothrow_t&) throw() {gffree(p);}
-ALLOCPREFIX void operator delete[](void*p, const std::nothrow_t&) throw() {gffree(p);}
-
-#define NEWBUF(T,N) (new T[N])
-#define DELBUF(A) (delete[] A)
-
-#ifdef __WIN32__
-#define INT winINT
-#define random rand
-#undef send
-#undef close
-#define sigjmp_buf jmp_buf
-#define siglongjmp longjmp
-#endif
-
-//#define _L_ post("%s:%d in %s",__FILE__,__LINE__,__PRETTY_FUNCTION__);
-#define _L_ fprintf(stderr,"%s:%d in %s\n",__FILE__,__LINE__,__PRETTY_FUNCTION__);
-#define RAISE(args...) throw Barf(__FILE__,__LINE__,__PRETTY_FUNCTION__,args)
-#define VA int argc, t_atom2 *argv
-// returns the size of a statically defined array
-#define COUNT(_array_) ((int)(sizeof(_array_) / sizeof((_array_)[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]); \
- post("%s",foo);}
-
-//****************************************************************
-
-struct FObject;
-struct t_atom2;
-typedef void (*FMethod)(FObject *, int, t_atom2 *);
-typedef std::string string;
-
-#define BUILTIN_SYMBOLS(MACRO) \
- MACRO(_grid,"grid") MACRO(_bang,"bang") MACRO(_float,"float") \
- MACRO(_list,"list") MACRO(_sharp,"#") \
- MACRO(_in,"in") MACRO(_out,"out")
-
-extern struct BuiltinSymbols {
-#define FOO(_sym_,_str_) t_symbol *_sym_;
-BUILTIN_SYMBOLS(FOO)
-#undef FOO
-} bsym;
-
-struct Numop;
-struct Pointer;
-#define INT(x) convert(x,(int32*)0)
-#define TO(T,x) convert(x,(T*)0)
-
-// trick to be able to define methods in t_atom
-struct t_atom2 : t_atom {
- bool operator == (t_symbol *b) {return this->a_type==A_SYMBOL && this->a_symbol==b;}
- bool operator != (t_symbol *b) {return !(*this==b);}
- operator float32 () const {
- if (a_type!=A_FLOAT) RAISE("expected float");
- return a_float;}
- operator bool () const {float f = round(float32(*this));
- if (f<0 || f>=2) RAISE("value %f is out of range",f);
- return (bool)f;}
- operator uint8 () const {float f = round(float32(*this));
- if (f<0 || f>=0x100) RAISE("value %f is out of range",f);
- return (uint8)f;}
- operator int16 () const {float f = round(float32(*this));
- if (f<-0x8000 || f>=0x8000) RAISE("value %f is out of range",f);
- return (int16)f;}
- operator uint16 () const {float f = round(float32(*this));
- if (f<0 || f>=0x10000) RAISE("value %f is out of range",f);
- return (uint16)f;}
- operator int32 () const {float f = round(float32(*this));
- if (f<-0x80000000LL || f>=0x80000000LL) RAISE("value %f is out of range",f);
- return (int32)f;}
- operator uint32 () const {float f = round(float32(*this));
- if (f<0 || f>=0x100000000LL) RAISE("value %f is out of range",f);
- return (uint32)f;}
- operator long () const {
- return sizeof(long)==sizeof(int32) ? (int32)*this : (int64)*this;}
- operator uint64 () const {
- if (a_type!=A_FLOAT) RAISE("expected float");
- return (uint64)round(a_float);}
- operator int64 () const {
- if (a_type!=A_FLOAT) RAISE("expected float");
- return (int64)round(a_float);}
- operator float64 () const {
- if (a_type!=A_FLOAT) RAISE("expected float");
- return a_float;}
- operator t_symbol * () const {
- if (a_type!=A_SYMBOL) RAISE("expected symbol");
- return a_symbol;}
- operator std::string () const {
- if (a_type!=A_SYMBOL) RAISE("expected symbol");
- return std::string(a_symbol->s_name);}
- operator void * () const {
- if (a_type!=A_POINTER) RAISE("expected pointer");
- return a_gpointer;}
- operator t_binbuf * () const {
- if (a_type!=A_LIST) RAISE("expected nested list");
- return (t_binbuf *)a_gpointer;}
-};
-
-template <class T> T convert(const t_atom &x, T *foo) {const t_atom2 *xx = (const t_atom2 *)&x; return (T)*xx;}
-
-//****************************************************************
-
-//template <class T> class P : T * {};
-//a reference counting pointer class
-template <class T> class P {
-public:
-#define INCR if (p) p->refcount++;
-#define DECR if (p) {p->refcount--; if (!p->refcount) delete p;}
- T *p;
- P() {p=0;}
- P(T *_p) {p=_p ; INCR;}
- P(const P<T> &_p) {p=_p.p; INCR;}
- P<T> &operator = (T * _p) {DECR; p=_p; INCR; return *this;}
- P<T> &operator = (P<T> _p) {DECR; p=_p.p; INCR; return *this;}
- bool operator == (P<T> _p) {return p==_p.p;}
- bool operator != (P<T> _p) {return p!=_p.p;}
- ~P() {DECR;}
- bool operator !() {return !p;}
- operator bool() {return !!p;}
- T &operator *() {return *p;}
- T *operator ->() {return p;}
- operator T *() {return p;}
-//#undef INCR
-//#undef DECR
-};
-
-void gfmemcopy(uint8 *out, const uint8 *in, long n);
-template <class T> inline void COPY(T *dest, T *src, long n) {
- gfmemcopy((uint8*)dest,(const uint8*)src,n*sizeof(T));
-}
-template <class T> inline void CLEAR(T *dest, long n) {
- memset(dest,0,n*sizeof(T));
-}
-template <class T> static void memswap (T *a, T *b, long n) {
- T c[n]; COPY(c,a,n); COPY(a,b,n); COPY(b,c,n);
-}
-
-//****************************************************************
-
-struct CObject {
- int32 refcount;
- CObject() : refcount(0) {}
- virtual ~CObject() {}
- virtual void changed (t_symbol *s=0) {}
-};
-
-// you shouldn't use MethodDecl directly (used by source_filter.rb)
-struct MethodDecl {const char *selector; FMethod method;};
-
-#undef check
-
-//****************************************************************
-// a Dim is a list of dimensions that describe the shape of a grid
-typedef int32 Card; /* should be switched to long int soon */
-struct Dim : CObject {
- static const Card MAX_DIM=16; // maximum number of dimensions in a grid
- Card n;
- Card v[MAX_DIM]; // real stuff
- void check(); // test invariants
- Dim(Card n, Card *v){this->n=n; COPY(this->v,v,n); check();}
- Dim() {n=0; check();}
- Dim(Card a) {n=1;v[0]=a; check();}
- Dim(Card a,Card b) {n=2;v[0]=a;v[1]=b; check();}
- Dim(Card a,Card b,Card c){n=3;v[0]=a;v[1]=b;v[2]=c;check();}
- Dim(Dim *a, Dim *b, Dim *c=0) {
- n=a->n+b->n; if(c) n+=c->n;
- if (n>Dim::MAX_DIM) RAISE("too many dims");
- COPY(v ,a->v,a->n);
- COPY(v+a->n,b->v,b->n);
- if(c) COPY(v+a->n+b->n,c->v,c->n);
- }
- Card count() {return n;}
- Card get(Card i) {return v[i];}
-/* Dim *range(Card i, Card j) {return new Dim(...);} */
- Card prod(Card start=0, Card end=-1) {
- if (end<0) end+=n;
- Card tot=1;
- for (Card i=start; i<=end; i++) tot *= v[i];
- return tot;
- }
- char *to_s();
- bool equal(P<Dim> o) {
- if (n!=o->n) return false;
- for (Card i=0; i<n; i++) if (v[i]!=o->v[i]) return false;
- return true;
- }
-};
-
-//****************************************************************
-//NumberTypeE is a very small int identifying the type of the (smallest) elements of a grid
-
-#define NT_UNSIGNED (1<<0)
-#define NT_FLOAT (1<<1)
-#define NT_UNIMPL (1<<2)
-#define NUMBER_TYPE_LIMITS(T,a,b,c) \
- inline T nt_smallest(T *bogus) {return a;} \
- inline T nt_greatest(T *bogus) {return b;} \
- inline T nt_all_ones(T *bogus) {return c;}
-
-NUMBER_TYPE_LIMITS( uint8,0,255,255)
-NUMBER_TYPE_LIMITS( int16,-0x8000,0x7fff,-1)
-NUMBER_TYPE_LIMITS( int32,-0x80000000,0x7fffffff,-1)
-NUMBER_TYPE_LIMITS( int64,-0x8000000000000000LL,0x7fffffffffffffffLL,-1)
-NUMBER_TYPE_LIMITS(float32,-HUGE_VAL,+HUGE_VAL,(RAISE("all_ones"),0))
-NUMBER_TYPE_LIMITS(float64,-HUGE_VAL,+HUGE_VAL,(RAISE("all_ones"),0))
-
-#ifdef HAVE_LITE
-#define NT_NOTLITE NT_UNIMPL
-#define NONLITE(x...)
-#else
-#define NT_NOTLITE 0
-#define NONLITE(x...) x
-#endif
-#define NUMBER_TYPES(MACRO) \
- MACRO(uint8, 8,NT_UNSIGNED, "u8,b") \
- MACRO(int16,16,0, "i16,s") \
- MACRO(int32,32,0, "i32,i") \
- MACRO(int64,64,NT_NOTLITE, "i64,l") \
- MACRO(float32,32,NT_FLOAT, "f32,f") \
- MACRO(float64,64,NT_NOTLITE|NT_FLOAT, "f64,d")
-
-enum NumberTypeE {
-#define FOO(_sym_,args...) _sym_##_e,
-NUMBER_TYPES(FOO)
-#undef FOO
-number_type_table_end
-};
-
-#define FOO(_type_) \
-inline NumberTypeE NumberTypeE_type_of(_type_ *x) { \
- return _type_##_e; }
-EACH_NUMBER_TYPE(FOO)
-#undef FOO
-
-struct NumberType : CObject {
- const char *name;
- int size;
- int flags;
- const char *aliases;
- NumberTypeE index;
- NumberType(const char *name_, int size_, int flags_, const char *aliases_) :
- name(name_), size(size_), flags(flags_), aliases(aliases_) {}
-};
-
-NumberTypeE NumberTypeE_find (string sym);
-NumberTypeE NumberTypeE_find (const t_atom &sym);
-
-#define TYPESWITCH(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;) \
- case float32_e: C(float32) break; NONLITE(case float64_e: C(float64) break;) \
- default: E; RAISE("type '%s' not available here",number_type_table[T].name);}
-#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].name);}
-
-//****************************************************************
-//BitPacking objects encapsulate optimised loops of bitfield conversion (mostly for I/O)
-struct BitPacking;
-// those are the types of the optimised loops of conversion; inputs are const
-struct Packer {
-#define FOO(S) void (*as_##S)(BitPacking *self, long n, S *in, uint8 *out);
-EACH_INT_TYPE(FOO)
-#undef FOO
-};
-struct Unpacker {
-#define FOO(S) void (*as_##S)(BitPacking *self, long n, uint8 *in, S *out);
-EACH_INT_TYPE(FOO)
-#undef FOO
-};
-
-struct BitPacking : CObject {
- Packer * packer;
- Unpacker *unpacker;
- unsigned int endian; // 0=big, 1=little, 2=same, 3=different
- int bytes;
- int size;
- uint32 mask[4];
- BitPacking(){::abort();} // don't call, but don't remove. sorry.
- BitPacking(int endian, int bytes, int size, uint32 *mask,
- Packer *packer=0, Unpacker *unpacker=0);
- bool is_le();
- bool eq(BitPacking *o);
-// main entrances to Packers/Unpackers
- template <class T> void pack(long n, T *in, uint8 *out);
- template <class T> void unpack(long n, uint8 *in, T *out);
-};
-
-int high_bit(uint32 n);
-int low_bit(uint32 n);
-void swap16(long n, uint16 *data);
-void swap32(long n, uint32 *data);
-void swap64(long n, uint64 *data);
-inline void swap_endian(long n, uint8 *data) {}
-inline void swap_endian(long n, int16 *data) {swap16(n,(uint16 *)data);}
-inline void swap_endian(long n, int32 *data) {swap32(n,(uint32 *)data);}
-inline void swap_endian(long n, int64 *data) {swap64(n,(uint64 *)data);}
-inline void swap_endian(long n, float32 *data) {swap32(n,(uint32 *)data);}
-inline void swap_endian(long n, float64 *data) {swap64(n,(uint64 *)data);}
-
-//****************************************************************
-// Numop objects encapsulate optimised loops of simple operations
-
-enum LeftRight { at_left, at_right };
-
-template <class T>
-struct NumopOn {
- // Function Vectorisations
- typedef void (*Map )( long n, T *as, T b ); Map map;
- typedef void (*Zip )( long n, T *as, T *bs); Zip zip;
- typedef void (*Fold)(long an, long n, T *as, T *bs); Fold fold;
- typedef void (*Scan)(long an, long n, T *as, T *bs); Scan scan;
- // Algebraic Properties (those involving simply numeric types)
- typedef bool (*AlgebraicCheck)(T x, LeftRight side);
- // 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}; ...
- 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,
- 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) {
- 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 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
- 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;
- if (!f) RAISE("operator %s does not support fold",name);
- f(an,n,(T *)as,(T *)bs);}
- template <class T> inline void scan(long an, long n, T *as, T *bs) {
- typename NumopOn<T>::Scan f = on(*as)->scan;
- if (!f) RAISE("operator %s does not support scan",name);
- f(an,n,(T *)as,(T *)bs);}
-
- 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
- sym=gensym((char *)name);
- }
-};
-
-extern NumberType number_type_table[];
-extern std::map<string,NumberType *> number_type_dict;
-extern std::map<string,Numop *> op_dict;
-extern std::map<string,Numop *> vop_dict;
-
-static inline NumberTypeE convert(const t_atom &x, NumberTypeE *bogus) {
- if (x.a_type!=A_SYMBOL) RAISE("expected number-type"); return NumberTypeE_find(string(x.a_symbol->s_name));}
-
-
-static Numop *convert(const t_atom &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];
-}
-
-// ****************************************************************
-struct Grid : CObject {
- P<Dim> dim;
- NumberTypeE nt;
- void *data;
- int state; /* 0:borrowing 1:owning -1:expired(TODO) */
- Grid(P<Dim> dim, NumberTypeE nt, bool clear=false) {
- state=1;
- if (!dim) RAISE("hell");
- init(dim,nt);
- if (clear) {long size = bytes(); CLEAR((char *)data,size);}
- }
- Grid(const t_atom &x) {state=1; init_from_atom(x);}
- Grid(int n, t_atom *a, NumberTypeE nt_=int32_e) {state=1; init_from_list(n,a,nt_);}
- template <class T> Grid(P<Dim> dim, T *data) {
- state=0; this->dim=dim;
- this->nt=NumberTypeE_type_of((T *)0);
- this->data = data;
- }
- // parens are necessary to prevent overflow at 1/16th of the word size (256 megs)
- long bytes() { return dim->prod()*(number_type_table[nt].size/8); }
- P<Dim> to_dim () { return new Dim(dim->prod(),(int32 *)*this); }
-#define FOO(T) operator T *() { return (T *)data; }
-EACH_NUMBER_TYPE(FOO)
-#undef FOO
- Grid *dup () { /* always produce an owning grid even if from a borrowing grid */
- Grid *foo=new Grid(dim,nt);
- memcpy(foo->data,data,bytes());
- return foo;
- }
- ~Grid() {if (state==1 && 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);
- if (!data) RAISE("out of memory (?) trying to get %ld bytes",bytes());
- }
- //fprintf(stderr,"rdata=%p data=%p align=%d\n",rdata,data,align);
- }
- void init_from_atom(const t_atom &x);
- void init_from_list( int n, t_atom *a, NumberTypeE nt=int32_e);
-};
-static inline Grid *convert (const t_atom &r, Grid **bogus) {return new Grid(r);}
-
-// DimConstraint interface:
-// return if d is acceptable
-// else RAISE with proper descriptive message
-typedef void (*DimConstraint)(P<Dim> d);
-
-struct PtrGrid : public P<Grid> {
- DimConstraint dc;
- void constrain(DimConstraint dc_) { dc=dc_; }
- P<Grid> next;
- PtrGrid() : P<Grid>(), dc(0), next(0) {}
- PtrGrid(const PtrGrid &_p) : P<Grid>(), dc(0), next(0) {dc=_p.dc; p=_p.p; INCR;}
-// PtrGrid( P<Grid> _p) : P<Grid>(), dc(0), next(0) {dc=_p.dc; p=_p.p; INCR;}
- PtrGrid( Grid *_p) : P<Grid>(), dc(0), next(0) {
- p=_p;
-INCR;}
- PtrGrid &operator =( Grid *_p) {if(dc&&_p)dc(_p->dim);
-DECR; p=_p; INCR;
-return *this;}
- PtrGrid &operator =(P<Grid> _p) {if(dc&&_p)dc(_p->dim); DECR; p=_p.p; INCR; return *this;}
- PtrGrid &operator =(PtrGrid _p) {if(dc&&_p)dc(_p->dim); DECR; p=_p.p; INCR; return *this;}
-};
-#undef INCR
-#undef DECR
-
-static inline P<Dim> convert(const t_atom &x, P<Dim> *foo) {
- Grid *d = convert(x,(Grid **)0);
- if (!d) RAISE("urgh");
- if (d->dim->n!=1) RAISE("dimension list must have only one dimension itself");
- return new Dim(d->dim->v[0],(int32 *)(d->data));
-}
-static inline PtrGrid convert(const t_atom &x, PtrGrid *foo) {return PtrGrid(convert(x,(Grid **)0));}
-
-//****************************************************************
-// GridInlet represents a grid-aware inlet
-
-// four-part macro for defining the behaviour of a gridinlet in a class
-// C:Class I:Inlet
-#define GRID_INLET(C,I) \
- template <class T> void C::grinw_##I (GridInlet *in, long n, T *data) { \
- ((C*)(in->parent))->grin_##I(in,n,data); } \
- template <class T> void C::grin_##I (GridInlet *in, long n, T *data) { \
- if (n==-1)
-#define GRID_ALLOC else if (n==-3)
-#define GRID_FLOW else if (n>=0)
-#define GRID_FINISH else if (n==-2)
-#define GRID_END }
-
-/* macro for defining a gridinlet's behaviour as just storage (no backstore) */
-// V is a PtrGrid instance-var
-#define GRID_INPUT(C,I,V) \
-GRID_INLET(C,I) { V=new Grid(in->dim,NumberTypeE_type_of(data)); } \
-GRID_FLOW { COPY((T *)*(V)+in->dex, data, n); } GRID_FINISH
-
-// macro for defining a gridinlet's behaviour as just storage (with backstore)
-// V is a PtrGrid instance-var
-#define GRID_INPUT2(C,I,V) \
- GRID_INLET(C,I) { \
- if (is_busy_except(in)) { \
- V.next = new Grid(in->dim,NumberTypeE_type_of(data)); \
- } else V= new Grid(in->dim,NumberTypeE_type_of(data)); \
- } GRID_FLOW { \
- COPY(((T *)*(V.next?V.next.p:&*V.p))+in->dex, data, n); \
- } GRID_FINISH
-
-typedef struct GridInlet GridInlet;
-typedef struct GridHandler {
-#define FOO(T) \
- void (*flow_##T)(GridInlet *in, long n, T *data); \
- void flow(GridInlet *in, long n, T *data) const {flow_##T(in,n,data);}
-EACH_NUMBER_TYPE(FOO)
-#undef FOO
-} GridHandler;
-
-struct FObject;
-struct GridInlet : CObject {
- FObject *parent;
- const GridHandler *gh;
-private:
- FObject *sender;
-public:
- P<Dim> dim;
- NumberTypeE nt;
- long dex;
-private:
- PtrGrid buf;// factor-chunk buffer
- long bufi; // buffer index: how much of buf is filled
-public:
- int mode; // 0=ignore; 4=ro; 6=rw
-// long allocfactor,allocmin,allocmax,allocn;
-// uint8 *alloc;
-
- GridInlet(FObject *parent_, const GridHandler *gh_) :
- parent(parent_), gh(gh_), sender(0),
- dim(0), nt(int32_e), dex(0), bufi(0), mode(4) {}
- ~GridInlet() {}
- void set_factor(long factor); // obsolete
- void set_chunk(long whichdim);
- void set_mode(int mode_) { mode=mode_; }
- int32 factor() {return buf?buf->dim->prod():1;}
- void begin(int argc, t_atom2 *argv);
- void finish(); /* i thought this should be private but maybe it shouldn't. */
-
- // n=-1 is begin, and n=-2 is finish; GF-0.9 may have n=-3 meaning alloc (?).
- template <class T> void flow(int mode, long n, T *data);
- void from_list(VA, NumberTypeE nt=int32_e) {Grid t(argc,argv,nt); from_grid(&t);}
- void from_atom(VA) {Grid t(argv[0]); from_grid(&t);}
- void from_grid(Grid *g);
- bool supports_type(NumberTypeE nt);
-private:
- template <class T> void from_grid2(Grid *g, T foo);
-};
-
-//****************************************************************
-// for use by source_filter.rb ONLY (for \grin)
-#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,TF}
-#endif // HAVE_LITE
-#define MESSAGE t_symbol *sel, int argc, t_atom2 *argv
-#define MESSAGE2 sel,argc,argv
-#define MESSAGE3 t_symbol *, int, t_atom2 *
-struct AttrDecl {
- string name;
- string type;
- AttrDecl(string name_, string type_) {name=name_; type=type_;}
-};
-struct BFObject;
-typedef FObject *(*t_allocator)(BFObject *,MESSAGE3);
-struct FClass {
- t_allocator allocator; // returns a new C++ object
- void (*startup)(FClass *);
- const char *cname; // C++ name (not PD name)
- int methodsn; MethodDecl *methods;
- FClass *super;
- int ninlets;
- int noutlets;
- t_class *bfclass;
- string name;
- size_t bytes;
- std::map<string,AttrDecl *> attrs;
-};
-
-void fclass_install(FClass *fc, FClass *super, size_t bytes);
-
-//****************************************************************
-// GridOutlet represents a grid-aware outlet
-struct GridOutlet : CObject {
-// number of (minimum,maximum) BYTES to send at once
-// starting with version 0.8, this is amount of BYTES, not amount of NUMBERS.
- static const long MIN_PACKET_SIZE = 1<<8;
- static const long MAX_PACKET_SIZE = 1<<12;
-// those are set only once
- FObject *parent; // not a P<> because of circular refs
- P<Dim> dim; // dimensions of the grid being sent
- NumberTypeE nt;
- std::vector<GridInlet *> inlets; // which inlets are we connected to
-// those are updated during transmission
- long dex; // how many numbers were already sent in this connection
-
- GridOutlet(FObject *parent_, int woutlet, P<Dim> dim_, NumberTypeE nt_=int32_e);
- ~GridOutlet() {}
- void callback(GridInlet *in);
-
- // send/send_direct: data belongs to caller, may be stack-allocated,
- // receiver doesn't modify the data; in send(), there is buffering;
- // in send_direct(), there is not. When switching from buffered to
- // unbuffered mode, flush() must be called
- template <class T> void send(long n, T *data);
- void flush(); // goes with send();
-
- // give: data must be dynamically allocated as a whole: the data
- // will be deleted eventually, and should not be used by the caller
- // beyond the call to give().
- template <class T> void give(long n, T *data);
-
- // third way to send (upcoming, in GF-1.1.??) is called "ask".
- template <class T> void ask(int &n, T *&data, long factor, long min, long max);
-
-private:
- bool frozen; // is the "begin" phase finished?
- PtrGrid buf; // temporary buffer
- long bufi; // number of bytes used in the buffer
- void begin(int woutlet, P<Dim> dim, NumberTypeE nt=int32_e);
- template <class T> void send_direct(long n, T *data);
- void finish() {
- flush();
- for (uint32 i=0; i<inlets.size(); i++) inlets[i]->finish();
- dim=0;
- }
-};
-
-//****************************************************************
-
-#define CHECK_GRIN(class,i) \
- if (in.size()<=i) in.resize(i+1); \
- if (!in[i]) in[i]=new GridInlet((FObject *)this,&class##_grid_##i##_hand);
-
-#define CHECK_ALIGN16(d,nt) \
- {int bytes = 16; \
- int align = ((ulong)(void*)d)%bytes; \
- if (align) {_L_;post("%s(%s): Alignment Warning: %s=%p is not %d-aligned: %d", \
- ARGS(this), __PRETTY_FUNCTION__,#d,(void*)d,bytes,align);}}
-
-struct BFProxy;
-struct BFObject : t_object {
- void *gemself; // this absolutely needs to be the first field, to make GEM happy
- FObject *self;
- int ninlets,noutlets; // per object settings (not class)
- BFProxy **inlets; // direct access to inlets (not linked lists)
- t_outlet **outlets; // direct access to outlets (not linked lists)
- t_canvas *mom;
- void ninlets_set(int n, bool draw=true);
- void noutlets_set(int n, bool draw=true);
-};
-
-// represents objects that have inlets/outlets
-\class FObject : CObject {
- BFObject *bself; // point to PD peer
- std::vector<P<GridInlet> > in;
- P<GridOutlet> out;
- FObject(BFObject *bself, MESSAGE) : bself(bself) {bself->self = this;}
- template <class T> void send_out(int outlet, int argc, T *argv) {
- t_atom foo[argc];
- for (int i=0; i<argc; i++) SETFLOAT(&foo[i],argv[i]);
- outlet_list(bself->outlets[outlet],&s_list,argc,foo);
- }
- bool is_busy_except(P<GridInlet> gin) {
- for (uint32 i=0; i<in.size(); i++) if (in[i] && in[i]!=gin && in[i]->dim) return true;
- return false;
- }
- \decl 0 get (t_symbol *s=0);
- \decl 0 help ();
-};
-\end class
-
-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;
-
-#define ARGS(OBJ) "(some object...)"
-#define NOTEMPTY(_a_) if (!(_a_)) RAISE("in [%s], '%s' is empty",ARGS(this), #_a_);
-#define SAME_TYPE(_a_,_b_) \
- if ((_a_)->nt != (_b_)->nt) RAISE("%s: same type please (%s has %s; %s has %s)", ARGS(this), \
- #_a_, number_type_table[(_a_)->nt].name, \
- #_b_, number_type_table[(_b_)->nt].name);
-static void SAME_DIM(int n, P<Dim> a, int ai, P<Dim> b, int bi) {
- if (ai+n > a->n) RAISE("left hand: not enough dimensions");
- if (bi+n > b->n) RAISE("right hand: not enough dimensions");
- for (int i=0; i<n; i++) {
- if (a->v[ai+i] != b->v[bi+i]) {
- RAISE("mismatch: left dim #%d is %d, right dim #%d is %d",
- ai+i, a->v[ai+i],
- bi+i, b->v[bi+i]);}}}
-
-void suffixes_are (const char *name, const char *suffixes);
-#define install(name,inlets,outlets) install2(fclass,name,inlets,outlets)
-void install2(FClass *fclass, const char *name, int inlets, int outlets);
-#define add_creator(name) add_creator2(fclass,name)
-void add_creator2(FClass *fclass, const char *name);
-#define install_format(name,mode,suffixes) do {install(name,1,1); suffixes_are(name,suffixes);} while(0)
-void call_super(int argc, t_atom *argv);
-#define SUPER call_super(argc,argv);
-
-\class Format : FObject {
- int mode;
- int fd;
- FILE *f;
- NumberTypeE cast;
- long frame;
- Format(BFObject *, MESSAGE);
- \decl 0 open (t_symbol *mode, string filename);
- \decl 0 close ();
- \decl 0 cast (NumberTypeE nt);
- \decl 0 seek(int frame);
- \decl 0 rewind ();
- ~Format ();
-};
-
-extern std::vector<string> gf_data_path;
-string gf_find_file (string x);
-void pd_oprintf (std::ostream &o, const char *s, int argc, t_atom *argv);
-void pd_oprint (std::ostream &o, int argc, t_atom *argv);
-void pd_post (const char *s, int argc, t_atom *argv);
-
-inline void set_atom (t_atom *a, uint8 v) {SETFLOAT(a,(float)v);}
-inline void set_atom (t_atom *a, int16 v) {SETFLOAT(a,(float)v);}
-inline void set_atom (t_atom *a, int32 v) {SETFLOAT(a,(float)v);}
-inline void set_atom (t_atom *a, uint32 v) {SETFLOAT(a,(float)v);}
-inline void set_atom (t_atom *a, long v) {SETFLOAT(a,(float)v);}
-inline void set_atom (t_atom *a, float32 v) {SETFLOAT(a,v);}
-inline void set_atom (t_atom *a, float64 v) {SETFLOAT(a,v);}
-inline void set_atom (t_atom *a, t_symbol *v) {SETSYMBOL(a,v);}
-inline void set_atom (t_atom *a, Numop *v) {SETSYMBOL(a,v->sym);}
-inline void set_atom (t_atom *a, t_binbuf *v) {SETLIST(a,v);}
-
-extern std::map<string,FClass *> fclasses;
-int handle_braces(int ac, t_atom *av);
-
-extern FClass ciFObject, ciFormat;
-
-#endif // __GF_GRID_H