Blame projects/neural/layout.inc.cpp

e865c9
#ifndef LAYOUT_INC_CPP
e865c9
#define LAYOUT_INC_CPP
e865c9
e865c9
e865c9
#include <cassert></cassert>
e865c9
#include <cstdio></cstdio>
e865c9
e865c9
#include <vector></vector>
e865c9
#include <algorithm></algorithm>
e865c9
e865c9
e865c9
struct Layout {
e865c9
  typedef std::vector<layout> List;</layout>
e865c9
e865c9
  int sx, sy, sz;
e865c9
  int x0, x1;
e865c9
  int y0, y1;
e865c9
  int z0, z1;
e865c9
e865c9
  inline Layout(): sx(), sy(), sz(), x0(), x1(), y0(), y1(), z0(), z1() { }
e865c9
e865c9
  explicit inline Layout(int sx, int sy = 1, int sz = 1):
e865c9
    sx(sx), sy(sy), sz(sz), x0(), x1(sx), y0(), y1(sy), z0(), z1(sz) { }
e865c9
e865c9
e865c9
  inline Layout& expandX  (int e0, int e1) { return sx += e0+e1, x0 += e0, x1 += e0, *this; }
e865c9
  inline Layout& expandY  (int e0, int e1) { return sy += e0+e1, y0 += e0, y1 += e0, *this; }
e865c9
  inline Layout& expandZ  (int e0, int e1) { return sz += e0+e1, z0 += e0, z1 += e0, *this; }
e865c9
  inline Layout& expandXY (int e0, int e1) { return expandX (e0, e1).expandY(e0, e1); }
e865c9
  inline Layout& expandXYZ(int e0, int e1) { return expandXY(e0, e1).expandZ(e0, e1); }
e865c9
  inline Layout& expandX  (int e)          { return expandX  (e, e); }
e865c9
  inline Layout& expandY  (int e)          { return expandY  (e, e); }
e865c9
  inline Layout& expandZ  (int e)          { return expandX  (e, e); }
e865c9
  inline Layout& expandXY (int e)          { return expandXY (e, e); }
e865c9
  inline Layout& expandXYZ(int e)          { return expandXYZ(e, e); }
e865c9
e865c9
  inline Layout& padX  (int p0, int p1) { return x0 += p0, x1 -= p0, *this; }
e865c9
  inline Layout& padY  (int p0, int p1) { return y0 += p0, y1 -= p0, *this; }
e865c9
  inline Layout& padZ  (int p0, int p1) { return z0 += p0, z1 -= p0, *this; }
e865c9
  inline Layout& padXY (int p0, int p1) { return padX (p0, p1).padY(p0, p1); }
e865c9
  inline Layout& padXYZ(int p0, int p1) { return padXY(p0, p1).padZ(p0, p1); }
e865c9
  inline Layout& padX  (int p)          { return padX  (p, p); }
e865c9
  inline Layout& padY  (int p)          { return padY  (p, p); }
e865c9
  inline Layout& padZ  (int p)          { return padX  (p, p); }
e865c9
  inline Layout& padXY (int p)          { return padXY (p, p); }
e865c9
  inline Layout& padXYZ(int p)          { return padXYZ(p, p); }
e865c9
b579b3
  inline bool hasPadX() const { return x0 > 0 || x1 < sx; }
b579b3
  inline bool hasPadY() const { return y0 > 0 || y1 < sy; }
b579b3
  inline bool hasPadZ() const { return z0 > 0 || z1 < sz; }
b579b3
  inline bool hasPad()  const { return hasPadX() || hasPadY() || hasPadZ(); }
e865c9
e865c9
  inline int getW() const { return x1 - x0; }
e865c9
  inline int getH() const { return y1 - y0; }
e865c9
  inline int getD() const { return z1 - z0; }
e865c9
e865c9
  inline int getCount() const { return sx*sy*sz; }
e865c9
  inline int getActiveCount() const { return getW()*getH()*getD(); }
e865c9
e865c9
e865c9
  inline operator bool() const {
e865c9
    return x0 >= 0 && x0 < x1 && x1 <= sx
e865c9
        && y0 >= 0 && y0 < y1 && y1 <= sy
e865c9
        && z0 >= 0 && z0 < z1 && z1 <= sz;
e865c9
  }
e865c9
e865c9
  
e865c9
  inline bool isSameSizeWith(const Layout &b) const
e865c9
    { return sx == b.sx && sy == b.sy && sz == b.sz; }
e865c9
  inline bool isSameActiveSizeWith(const Layout &b) const
e865c9
    { return getW() == b.getW() && getH() == b.getH() && getD() == b.getD(); }
e865c9
e865c9
  inline bool isSubLayoutOf(const Layout &b) const
e865c9
    { return isSameSizeWith(b) && b.x0 <= x0 && x0 < x1 && x1 <= b.x1; }
e865c9
  inline bool isParentLayoutOf(const Layout &b) const
e865c9
    { return b.isSubLayoutOf(*this); }
e865c9
  
e865c9
e865c9
  void splitX(List &list, int count) const {
e865c9
    if (count <= 0) return list.clear();
e865c9
    list.resize(count);
e865c9
    int v = x0, s = x1 - v;
e865c9
    for(int i = 0; i < count; ++i) {
e865c9
      Layout &l = list[i] = *this;
e865c9
      l.x0 = v;
e865c9
      l.x1 = (v += s/count + (i < s%count));
e865c9
    }
e865c9
  }
e865c9
e865c9
  void splitY(List &list, int count) const {
e865c9
    if (count <= 0) return list.clear();
e865c9
    list.resize(count);
e865c9
    int v = y0, s = y1 - v;
e865c9
    for(int i = 0; i < count; ++i) {
e865c9
      Layout &l = list[i] = *this;
e865c9
      l.y0 = v;
e865c9
      l.y1 = (v += s/count + (i < s%count));
e865c9
    }
e865c9
  }
e865c9
e865c9
  void splitZ(List &list, int count) const {
e865c9
    if (count <= 0) return list.clear();
e865c9
    list.resize(count);
e865c9
    int v = z0, s = z1 - v;
e865c9
    for(int i = 0; i < count; ++i) {
e865c9
      Layout &l = list[i] = *this;
e865c9
      l.z0 = v;
e865c9
      l.z1 = (v += s/count + (i < s%count));
e865c9
    }
e865c9
  }
e865c9
e865c9
  void split(List &list, int count) const {
e865c9
    int h = getH(), w = getW(), d = getD();
e865c9
    if (h >= w && h >= d) splitY(list, count); else
e865c9
              if (w >= d) splitX(list, count); else
e865c9
                          splitZ(list, count);
e865c9
  }
e865c9
e865c9
  void print(const char *prefix = nullptr) const {
e865c9
    if (prefix && *prefix) printf("%s: ", prefix);
e865c9
    printf("x: %d (%d-%d), y: %d (%d-%d), z: %d (%d-%d)\n", sx, x0, x1, sy, y0, y1, sz, z0, z1);
e865c9
  }
e865c9
  void printYXZ(const char *prefix = nullptr) const {
e865c9
    if (prefix && *prefix) printf("%s: ", prefix);
e865c9
    printf("y: %d (%d-%d), x: %d (%d-%d), z: %d (%d-%d)\n", sy, y0, y1, sx, x0, x1, sz, z0, z1);
e865c9
  }
e865c9
};
e865c9
e865c9
e865c9
e865c9
e865c9
e865c9
#endif