summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/arrayop.h
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/asymptote/arrayop.h')
-rw-r--r--Build/source/utils/asymptote/arrayop.h77
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