Program Listing for File base_grid3D.hpp

Return to documentation for file (rcppsw/ds/base_grid3D.hpp)

#pragma once

/*******************************************************************************
 * Includes
 ******************************************************************************/
#include <algorithm>
#include <boost/multi_array.hpp>

#include "rcppsw/common/common.hpp"
#include "rcppsw/math/vector3.hpp"

/*******************************************************************************
 * Namespaces/Decls
 ******************************************************************************/
namespace rcppsw::ds {

/*******************************************************************************
 * Class Definitions
 ******************************************************************************/
template <typename T>
class base_grid3D {
 public:
  using value_type = T;
  using coord_type = rmath::vector3z;

  using grid_type = typename boost::multi_array<T, 3>;
  using grid_view = typename grid_type::template array_view<3>::type;
  using const_grid_view = typename grid_type::template const_array_view<3>::type;
  using index_range = typename grid_type::index_range;

  base_grid3D(void) = default;
  virtual ~base_grid3D(void) = default;

  virtual T& access(size_t i, size_t j, size_t k) = 0;

  virtual size_t xsize(void) const = 0;

  virtual size_t ysize(void) const = 0;

  virtual size_t zsize(void) const = 0;

  T& access(const coord_type& c) { return access(c.x(), c.y(), c.z()); }

  const T& access(const coord_type& c) const {
    return const_cast<base_grid3D*>(this)->access(c);
  }
  const T& access(size_t i, size_t j, size_t k) const {
    return const_cast<base_grid3D*>(this)->access(i, j, k);
  }

  bool contains(size_t i, size_t j, size_t k) {
    return i < xsize() && j < ysize() && k < zsize();
  }

  bool contains(const coord_type& pt) {
    return contains(pt.x(), pt.y(), pt.z());
  }

  RCPPSW_PURE T& operator[](const coord_type& c) { return access(c); }
  RCPPSW_PURE const T& operator[](const coord_type& c) const {
    return access(c);
  }

  grid_view layer(size_t z) {
    return subgrid(coord_type(0, ysize(), z),
                   coord_type(0, ysize(), z + 1));
  }

  const_grid_view layer(size_t z) const {
    return const_cast<base_grid3D<T>*>(this)->layer(z);
  }

  grid_view subgrid(const coord_type& ll, const coord_type& ur) {
    index_range x(ll.x(), ur.x(), 1);
    index_range y(ll.y(), ur.y(), 1);
    index_range z(ll.z(), ur.z(), 1);
    return grid_view(grid()[boost::indices[x][y][z]]);
  }

  const_grid_view subgrid(const coord_type& ll,
                          const coord_type& ur) const {
    index_range x(ll.x(), ur.x(), 1);
    index_range y(ll.y(), ur.y(), 1);
    index_range z(ll.z(), ur.z(), 1);
    return const_grid_view(grid()[boost::indices[x][y][z]]);
  }

  grid_view subcircle(const coord_type& c, size_t radius) {
    auto ll_x =
        std::max<int>(0, static_cast<int>(c.x()) - static_cast<int>(radius));
    auto ll_y =
        std::max<int>(0, static_cast<int>(c.y()) - static_cast<int>(radius));

    /*
     * boost uses half open interval for index ranges, and we want a closed
     * interval, so we +1.
     */
    auto ur_x = std::min(c.x() + radius + 1, xsize());
    auto ur_y = std::min(c.y() + radius + 1, ysize());

    coord_type ll(ll_x, ll_y, c.z());
    coord_type ur(ur_x, ur_y, c.z() + 1);

    return subgrid(ll, ur);
  }

  const_grid_view subcircle(const coord_type& c, size_t radius) const {
    auto ll_x =
        std::max<int>(0, static_cast<int>(c.x()) - static_cast<int>(radius));
    auto ll_y =
        std::max<int>(0, static_cast<int>(c.y()) - static_cast<int>(radius));

    /*
     * boost uses half open interval for index ranges, and we want a closed
     * interval, so we +1.
     */
    auto ur_x = std::min(c.x() + radius + 1, xsize());
    auto ur_y = std::min(c.y() + radius + 1, ysize());

    coord_type ll(ll_x, ll_y, c.z());
    coord_type ur(ur_x, ur_y, c.z() + 1);

    return subgrid(ll, ur);
  }

 protected:
  virtual const grid_type& grid(void) const = 0;
  virtual grid_type& grid(void) = 0;
};

} /* namespace rcppsw::ds */