Charj: New 2D multi-dimensional array support in C++.
authorJonathan Lifflander <jliffl2@illinois.edu>
Thu, 19 Aug 2010 01:55:39 +0000 (20:55 -0500)
committerJonathan Lifflander <jliffl2@illinois.edu>
Thu, 19 Aug 2010 02:14:25 +0000 (21:14 -0500)
src/langs/charj/src/charj/libs/Array.h

index 36de6660247afcb7bb5f614855ced74af361e1b1..59c44c2a1e1dc2830ac43d1cb6c025c57104f436 100644 (file)
@@ -1,14 +1,23 @@
 #ifndef ARRAY_H
 #define ARRAY_H
 
+#include <cstdarg>
+#include <cstdio>
+#include <cstdlib>
+#include <cassert>
+#include <iostream>
 #include <charm++.h>
 
 namespace CharjArray {
   class Range {
   public:
-    int size, offset;
+    int size, start, stop;
     Range() {}
-    Range(int size_) : size(size_) {}
+    Range(int size_) : size(size_), start(0), stop(size) {}
+    Range(int start_, int stop_) :
+      start(start_), stop(stop_), size(stop_ - start_) {
+      assert(stop >= start);
+    }
   };
 
   template<int dims>
@@ -27,6 +36,12 @@ namespace CharjArray {
       ranges[0] = range;
     }
 
+    Domain(Range range1, Range range2) {
+      // TODO: fix Charj generator so it uses the array
+      ranges[0] = range1;
+      ranges[1] = range2;
+    }
+
     int size() {
       int total = 0;
       for (int i = 0; i < dims; i++)
@@ -38,52 +53,99 @@ namespace CharjArray {
   };
 
   template<int dims>
-  class Point : public Domain<dims> {
+  class RowMajor {
+  public:
+    static int access(const int i, const Domain<dims> &d) {
+      return i - d.ranges[0].start;
+    }
+    static int access(const int i, const int j, const Domain<dims> &d) {
+      return (i - d.ranges[0].start) * d.ranges[1].size + j -
+        d.ranges[1].start;
+    }
+    // Generic access method, not used right now.
+    // static int access(const int *i, const Domain<dims> &d) {
+    //   int off = i[0];
+    //   int dimoff = 1;
+    //   for (int j = ndims-1; j > 0; --j) {
+    //     dimoff *= d.ranges[j].size;
+    //     off += dimoff * (i[j] - d.ranges[j].start);
+    //   }
+    //   return off;
+    // }
+  };
+
+  template<int dims>
+  class ColMajor {
   public:
-    Point(int dim) : Domain<dims>() {
-      this->ranges[0].size = dim;
+    static int access(const int i, const Domain<dims> &d) {
+      return i - d.ranges[0].start;
+    }
+    static int access(const int i, const int j, const Domain<dims> &d) {
+      return (j - d.ranges[1].start) * d.ranges[1].size + i -
+        d.ranges[0].start;
     }
   };
 
-  enum ArrayType { RECT, JAGGED, ROW_MAJOR, COL_MAJOR };
-  template<class type, int dims = 1, ArrayType atype = RECT>
+  template<class type, int dims = 1, class atype = RowMajor<dims> >
   class Array {
   private:
     Domain<dims> domain;
     type *block;
+    int ref_cout;
+    Array* ref_parent;
 
   public:
-    Array(Domain<dims> domain_) {
+    Array(Domain<dims> domain_) : ref_parent(0) {
       init(domain_);
     }
 
+    Array(type **block_) {
+      block = *block_;
+    }
+
+    Array() : ref_parent(0) {
+
+    }
+
+    Array(Array* parent, Domain<dims> domain_) : ref_parent(parent) {
+      domain = domain_;
+      block = parent->block;
+    }
+
     void init(Domain<dims> &domain_) {
       domain = domain_;
-      if (atype == RECT)
-       block = new type[domain.size()];
+      //if (atype == ROW_MAJOR)
+      block = new type[domain.size()];
     }
 
     ~Array() {
       delete block;
     }
-    
-    type* operator[] (const Domain<dims> &domain) {
+
+    /*type* operator[] (const Domain<dims> &domain) {
       return block[domain.ranges[0].size];
+      }*/
+
+    type& operator[] (const int i) {
+      return block[atype::access(i, domain)];
     }
 
-    type& operator[] (const Point<dims> &point) {
-      return block[point.ranges[0].size];
+    type& access(const int i, const int j) {
+      return block[atype::access(i, j, domain)];
     }
 
-    type& operator[] (const int index) {
-      return block[index];
+    Array<type, dims, atype>* operator[] (const Domain<dims> &domain) {
+      return new Array<type, dims, atype>(this, domain);
     }
 
     int size() {
       return domain.size();
     }
 
+    int size(int dim) {
+      return domain.ranges[dim].size;
+    }
+
     void pup(PUP::er& p) { }
   };
 }