diff options
Diffstat (limited to 'Build/source/utils/asymptote/arrayop.h')
-rw-r--r-- | Build/source/utils/asymptote/arrayop.h | 77 |
1 files changed, 71 insertions, 6 deletions
diff --git a/Build/source/utils/asymptote/arrayop.h b/Build/source/utils/asymptote/arrayop.h index dd21a80a1d6..378b313627e 100644 --- a/Build/source/utils/asymptote/arrayop.h +++ b/Build/source/utils/asymptote/arrayop.h @@ -297,16 +297,16 @@ void searchArray(vm::stack *s) { T key=pop<T>(s); array *a=pop<array*>(s); - Int size=(Int) a->size(); + size_t size= a->size(); if(size == 0 || key < read<T>(a,0)) {s->push(-1); return;} - Int u=size-1; - if(key >= read<T>(a,u)) {s->push(u); return;} - Int l=0; + size_t u=size-1; + if(key >= read<T>(a,u)) {s->push((Int) u); return;} + size_t l=0; while (l < u) { - Int i=(l+u)/2; - if(read<T>(a,i) <= key && key < read<T>(a,i+1)) {s->push(i); return;} + size_t i=(l+u)/2; if(key < read<T>(a,i)) u=i; + else if(key < read<T>(a,i+1)) {s->push((Int) i); return;} else l=i+1; } s->push(0); @@ -507,6 +507,71 @@ camp::triple multshiftless(const vm::array& t, const camp::triple& v); double norm(double *a, size_t n); double norm(camp::triple *a, size_t n); +inline size_t checkdimension(const vm::array *a, size_t dim) +{ + size_t size=checkArray(a); + if(dim && size != dim) { + ostringstream buf; + buf << "array of length " << dim << " expected"; + vm::error(buf); + } + return size; +} + +template<class T> +inline void copyArrayC(T* &dest, const vm::array *a, size_t dim=0, + GCPlacement placement=NoGC) +{ + size_t size=checkdimension(a,dim); + dest=(placement == NoGC) ? new T[size] : new(placement) T[size]; + for(size_t i=0; i < size; i++) + dest[i]=vm::read<T>(a,i); +} + +template<class T, class A> +inline void copyArrayC(T* &dest, const vm::array *a, T (*cast)(A), + size_t dim=0, GCPlacement placement=NoGC) +{ + size_t size=checkdimension(a,dim); + dest=(placement == NoGC) ? new T[size] : new(placement) T[size]; + for(size_t i=0; i < size; i++) + dest[i]=cast(vm::read<A>(a,i)); +} + +template<typename T> +inline vm::array* copyCArray(const size_t n, const T* p, + GCPlacement placement=NoGC) +{ + vm::array* a = new vm::array(n); + for(size_t i=0; i < n; ++i) (*a)[i] = p[i]; + return a; +} + +template<class T> +inline void copyArray2C(T* &dest, const vm::array *a, bool square=true, + size_t dim2=0, GCPlacement placement=NoGC) +{ + size_t n=checkArray(a); + size_t m=(square || n == 0) ? n : checkArray(vm::read<vm::array*>(a,0)); + if(n > 0 && dim2 && m != dim2) { + ostringstream buf; + buf << "second matrix dimension must be " << dim2; + vm::error(buf); + } + + dest=(placement == NoGC) ? new T[n*m] : new(placement) T[n*m]; + for(size_t i=0; i < n; i++) { + vm::array *ai=vm::read<vm::array*>(a,i); + size_t aisize=checkArray(ai); + if(aisize == m) { + T *desti=dest+i*m; + for(size_t j=0; j < m; j++) + desti[j]=vm::read<T>(ai,j); + } else + vm::error(square ? "matrix must be square" : "matrix must be rectangular"); + } +} + } // namespace run #endif // ARRAYOP_H |