Implement const dcel handles

This commit is contained in:
Nikita Lisitsa 2022-09-16 19:22:24 +03:00
parent 4c976272c5
commit b7e070a3a6

View file

@ -107,13 +107,14 @@ namespace psemek::cg
std::vector<edge_rec> edges;
std::vector<face_rec> faces;
// TODO: const handles
// TODO: iteration over handles
struct point_handle;
struct point_handle_const;
struct edge_handle;
struct edge_handle_const;
struct face_handle;
struct face_handle_const;
struct point_handle : detail::handle_base<dcel, Index, detail::point_tag>
{
@ -123,7 +124,7 @@ namespace psemek::cg
edge_handle edge() const;
void edge(edge_handle h);
void edge(edge_handle h) const;
protected:
point_rec & get() const
@ -134,6 +135,23 @@ namespace psemek::cg
}
};
struct point_handle_const : detail::handle_base<dcel const, Index, detail::point_tag>
{
using detail::handle_base<dcel const, Index, detail::point_tag>::handle_base;
Point const & data() const;
edge_handle_const edge() const;
protected:
point_rec const & get() const
{
assert(this->owner_ != nullptr);
assert(this->i_ < this->owner_->points.size());
return this->owner_->points[this->i_];
}
};
struct edge_handle : detail::handle_base<dcel, Index, detail::edge_tag>
{
using detail::handle_base<dcel, Index, detail::edge_tag>::handle_base;
@ -145,10 +163,10 @@ namespace psemek::cg
edge_handle twin() const;
face_handle face() const;
void origin(point_handle h);
void next(edge_handle h);
void twin(edge_handle h);
void face(face_handle h);
void origin(point_handle h) const;
void next(edge_handle h) const;
void twin(edge_handle h) const;
void face(face_handle h) const;
protected:
edge_rec & get() const
@ -159,6 +177,26 @@ namespace psemek::cg
}
};
struct edge_handle_const : detail::handle_base<dcel const, Index, detail::edge_tag>
{
using detail::handle_base<dcel const, Index, detail::edge_tag>::handle_base;
Edge const & data() const;
point_handle_const origin() const;
edge_handle_const next() const;
edge_handle_const twin() const;
face_handle_const face() const;
protected:
edge_rec const & get() const
{
assert(this->owner_ != nullptr);
assert(this->i_ < this->owner_->edges.size());
return this->owner_->edges[this->i_];
}
};
struct face_handle : detail::handle_base<dcel, Index, detail::face_tag>
{
using detail::handle_base<dcel, Index, detail::face_tag>::handle_base;
@ -167,7 +205,7 @@ namespace psemek::cg
edge_handle edge() const;
void edge(edge_handle h);
void edge(edge_handle h) const;
protected:
face_rec & get() const
@ -178,6 +216,23 @@ namespace psemek::cg
}
};
struct face_handle_const : detail::handle_base<dcel const, Index, detail::face_tag>
{
using detail::handle_base<dcel const, Index, detail::face_tag>::handle_base;
Face const & data() const;
edge_handle_const edge() const;
protected:
face_rec const & get() const
{
assert(this->owner_ != nullptr);
assert(this->i_ < this->owner_->faces.size());
return this->owner_->faces[this->i_];
}
};
point_handle point(Index i)
{
return {this, i};
@ -193,6 +248,21 @@ namespace psemek::cg
return {this, i};
}
point_handle_const point(Index i) const
{
return {this, i};
}
edge_handle_const edge(Index i) const
{
return {this, i};
}
face_handle_const face(Index i) const
{
return {this, i};
}
point_handle push_point(Point data = {})
{
auto i = static_cast<Index>(points.size());
@ -315,11 +385,23 @@ namespace psemek::cg
}
template <typename Point, typename Edge, typename Face, typename Index>
void dcel<Point, Edge, Face, Index>::point_handle::edge(edge_handle h)
void dcel<Point, Edge, Face, Index>::point_handle::edge(edge_handle h) const
{
get().edge = h.index();
}
template <typename Point, typename Edge, typename Face, typename Index>
Point const & dcel<Point, Edge, Face, Index>::point_handle_const::data() const
{
return get().data();
}
template <typename Point, typename Edge, typename Face, typename Index>
typename dcel<Point, Edge, Face, Index>::edge_handle_const dcel<Point, Edge, Face, Index>::point_handle_const::edge() const
{
return edge_handle_const{this->owner_, get().edge};
}
template <typename Point, typename Edge, typename Face, typename Index>
Edge & dcel<Point, Edge, Face, Index>::edge_handle::data() const
{
@ -351,29 +433,59 @@ namespace psemek::cg
}
template <typename Point, typename Edge, typename Face, typename Index>
void dcel<Point, Edge, Face, Index>::edge_handle::origin(point_handle h)
void dcel<Point, Edge, Face, Index>::edge_handle::origin(point_handle h) const
{
get().origin = h.index();
}
template <typename Point, typename Edge, typename Face, typename Index>
void dcel<Point, Edge, Face, Index>::edge_handle::next(edge_handle h)
void dcel<Point, Edge, Face, Index>::edge_handle::next(edge_handle h) const
{
get().next = h.index();
}
template <typename Point, typename Edge, typename Face, typename Index>
void dcel<Point, Edge, Face, Index>::edge_handle::twin(edge_handle h)
void dcel<Point, Edge, Face, Index>::edge_handle::twin(edge_handle h) const
{
get().twin = h.index();
}
template <typename Point, typename Edge, typename Face, typename Index>
void dcel<Point, Edge, Face, Index>::edge_handle::face(face_handle h)
void dcel<Point, Edge, Face, Index>::edge_handle::face(face_handle h) const
{
get().face = h.index();
}
template <typename Point, typename Edge, typename Face, typename Index>
Edge const & dcel<Point, Edge, Face, Index>::edge_handle_const::data() const
{
return get().data();
}
template <typename Point, typename Edge, typename Face, typename Index>
typename dcel<Point, Edge, Face, Index>::point_handle_const dcel<Point, Edge, Face, Index>::edge_handle_const::origin() const
{
return point_handle_const{this->owner_, get().origin};
}
template <typename Point, typename Edge, typename Face, typename Index>
typename dcel<Point, Edge, Face, Index>::edge_handle_const dcel<Point, Edge, Face, Index>::edge_handle_const::next() const
{
return edge_handle_const{this->owner_, get().next};
}
template <typename Point, typename Edge, typename Face, typename Index>
typename dcel<Point, Edge, Face, Index>::edge_handle_const dcel<Point, Edge, Face, Index>::edge_handle_const::twin() const
{
return edge_handle_const{this->owner_, get().twin};
}
template <typename Point, typename Edge, typename Face, typename Index>
typename dcel<Point, Edge, Face, Index>::face_handle_const dcel<Point, Edge, Face, Index>::edge_handle_const::face() const
{
return face_handle_const{this->owner_, get().face};
}
template <typename Point, typename Edge, typename Face, typename Index>
Face & dcel<Point, Edge, Face, Index>::face_handle::data() const
{
@ -387,11 +499,23 @@ namespace psemek::cg
}
template <typename Point, typename Edge, typename Face, typename Index>
void dcel<Point, Edge, Face, Index>::face_handle::edge(edge_handle h)
void dcel<Point, Edge, Face, Index>::face_handle::edge(edge_handle h) const
{
get().edge = h.index();
}
template <typename Point, typename Edge, typename Face, typename Index>
Face const & dcel<Point, Edge, Face, Index>::face_handle_const::data() const
{
return get().data();
}
template <typename Point, typename Edge, typename Face, typename Index>
typename dcel<Point, Edge, Face, Index>::edge_handle_const dcel<Point, Edge, Face, Index>::face_handle_const::edge() const
{
return edge_handle_const{this->owner_, get().edge};
}
template <
typename Point2, typename Edge2 = util::empty, typename Face2 = util::empty, typename Index2 = std::size_t,
typename Point, typename Edge, typename Face, typename Index,