Program Listing for File base_grid2D.hpp
↰ Return to documentation for file (rcppsw/ds/base_grid2D.hpp
)
#pragma once
/*******************************************************************************
* Includes
******************************************************************************/
#include <algorithm>
#include <boost/multi_array.hpp>
#include "rcppsw/math/vector2.hpp"
/*******************************************************************************
* Namespaces/Decls
******************************************************************************/
namespace rcppsw::ds {
/*******************************************************************************
* Class Definitions
******************************************************************************/
template <typename T>
class base_grid2D {
public:
using value_type = T;
using coord_type = math::vector2z;
using grid_type = typename boost::multi_array<T, 2>;
using grid_view = typename grid_type::template array_view<2>::type;
using const_grid_view = typename grid_type::template const_array_view<2>::type;
using index_range = typename grid_type::index_range;
base_grid2D(void) = default;
virtual ~base_grid2D(void) = default;
virtual size_t xsize(void) const = 0;
virtual size_t ysize(void) const = 0;
virtual T& access(size_t i, size_t j) = 0;
T& access(const coord_type& c) { return access(c.x(), c.y()); }
RCPPSW_PURE T& operator[](const coord_type& c) { return access(c); }
RCPPSW_PURE const T& operator[](const coord_type& c) const {
return access(c);
}
const T& access(const coord_type& c) const {
return const_cast<base_grid2D*>(this)->access(c);
}
const T& access(size_t i, size_t j) const {
return const_cast<base_grid2D*>(this)->access(i, j);
}
bool contains(size_t i, size_t j) {
return i < xsize() && j < ysize();
}
bool contains(const coord_type& pt) {
return contains(pt.x(), pt.y());
}
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() - 1);
auto ur_y = std::min(c.y() + radius + 1, ysize() - 1);
coord_type ll(ll_x, ll_y);
coord_type ur(ur_x, ur_y);
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);
coord_type ur(ur_x, ur_y);
return subgrid(ll, ur);
}
grid_view subgrid(const coord_type& ll, const coord_type& ur) {
/*
* boost uses half open interval for index ranges, and we want a closed
* interval, so we +1.
*/
index_range x(ll.x(), ur.x() + 1, 1);
index_range y(ll.y(), ur.y() + 1, 1);
return grid_view(grid()[boost::indices[x][y]]);
}
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);
return const_grid_view(grid()[boost::indices[x][y]]);
}
protected:
virtual const grid_type& grid(void) const = 0;
virtual grid_type& grid(void) = 0;
};
} /* namespace rcppsw::ds */