Skip to content

Instantly share code, notes, and snippets.

@olson-sean-k
Last active March 28, 2020 22:17
Show Gist options
  • Save olson-sean-k/e9d66b13d54a42f889fc0c217b020b30 to your computer and use it in GitHub Desktop.
Save olson-sean-k/e9d66b13d54a42f889fc0c217b020b30 to your computer and use it in GitHub Desktop.
Eliminate geometry type parameters and reorganize graph types and traits.
use std::hash::Hash;
use std::ops::Deref;
pub trait Reborrow {
type Target;
fn reborrow(&self) -> &Self::Target;
}
impl<'a, T> Reborrow for &'a T {
type Target = T;
fn reborrow(&self) -> &Self::Target {
*self
}
}
impl<'a, T> Reborrow for &'a mut T {
type Target = T;
fn reborrow(&self) -> &Self::Target {
&**self
}
}
pub struct MeshGraph<G>
where
G: GraphGeometry,
{
vertices: <Vertex<G> as Entity>::Storage,
}
impl<G> Geometric for MeshGraph<G>
where
G: GraphGeometry,
{
type Geometry = G;
}
impl<G> AsStorage<Vertex<G>> for MeshGraph<G>
where
G: GraphGeometry,
{
fn as_storage(&self) -> &<Vertex<G> as Entity>::Storage {
unimplemented!()
}
}
pub trait AsPosition {
type Position;
fn as_position(&self) -> &Self::Position;
}
pub trait GraphGeometry {
type Vertex: Copy;
}
pub trait Geometric {
type Geometry: GraphGeometry;
}
impl<B> Geometric for B
where
B: Reborrow,
B::Target: Geometric,
{
type Geometry = <B::Target as Geometric>::Geometry;
}
pub type Geometry<M> = <M as Geometric>::Geometry;
pub type VertexPosition<M> = <<Geometry<M> as GraphGeometry>::Vertex as AsPosition>::Position;
pub trait Entity: Sized {
type Key: Copy + Eq + Hash;
type Attribute: Copy;
type Storage: Get<Self>;
}
pub trait AsStorage<E>
where
E: Entity,
{
fn as_storage(&self) -> &E::Storage;
}
pub trait Get<E>
where
E: Entity,
{
fn get(&self, key: E::Key) -> Option<&E>;
}
impl<E> Get<E> for Vec<E>
where
E: Entity<Key = usize>,
{
fn get(&self, key: E::Key) -> Option<&E> {
self.deref().get(key)
}
}
pub struct Vertex<G>
where
G: GraphGeometry,
{
pub geometry: G::Vertex,
}
impl<G> Entity for Vertex<G>
where
G: GraphGeometry,
{
type Key = usize;
type Attribute = G::Vertex;
type Storage = Vec<Self>;
}
pub trait ClosedView: Deref<Target = <Self as ClosedView>::Entity> + Sized {
type Key: Copy + Eq + Hash;
type Entity: Entity<Key = Self::Key>;
fn key(&self) -> Self::Key;
}
pub trait Rebind: ClosedView {
fn rebind<K, T>(self, key: K) -> Option<T>
where
K: Copy + Eq + Hash,
T: ClosedView<Key = K>;
}
pub struct View<B, E>
where
B: Reborrow,
B::Target: AsStorage<E>,
E: Entity,
{
key: E::Key,
storage: B,
}
impl<B, M, E> View<B, E>
where
B: Reborrow<Target = M>,
M: AsStorage<E>,
E: Entity,
{
pub fn interior_reborrow(&self) -> View<&M, E> {
let storage = self.storage.reborrow();
View {
key: self.key,
storage,
}
}
}
pub struct VertexView<B>
where
B: Reborrow,
B::Target: AsStorage<Vertex<Geometry<B>>> + Geometric,
{
inner: View<B, Vertex<Geometry<B>>>,
}
impl<B, M> VertexView<B>
where
B: Reborrow<Target = M>,
M: AsStorage<Vertex<Geometry<M>>> + Geometric,
{
pub fn into_identity(self) -> VertexView<B> {
VertexView { inner: self.inner }
}
pub fn identity(&self) -> VertexView<&M> {
self.interior_reborrow().into_identity()
}
pub fn position<'a>(&'a self) -> &'a VertexPosition<M>
where
M::Geometry: 'a,
<M::Geometry as GraphGeometry>::Vertex: AsPosition,
{
self.deref().geometry.as_position()
}
pub fn neighboring_vertices(&self) -> VertexCirculator<&M> {
VertexCirculator::from(self.interior_reborrow())
}
fn interior_reborrow(&self) -> VertexView<&M> {
VertexView {
inner: self.inner.interior_reborrow(),
}
}
}
impl<B, M, G> ClosedView for VertexView<B>
where
B: Reborrow<Target = M>,
M: AsStorage<Vertex<G>> + Geometric<Geometry = G>,
G: GraphGeometry,
{
type Key = <Vertex<G> as Entity>::Key;
type Entity = Vertex<G>;
fn key(&self) -> Self::Key {
self.inner.key
}
}
impl<B, M, G> Deref for VertexView<B>
where
B: Reborrow<Target = M>,
M: AsStorage<Vertex<G>> + Geometric<Geometry = G>,
G: GraphGeometry,
{
type Target = Vertex<G>;
fn deref(&self) -> &Self::Target {
unimplemented!()
}
}
impl<B, M, G> From<View<B, Vertex<G>>> for VertexView<B>
where
B: Reborrow<Target = M>,
M: AsStorage<Vertex<G>> + Geometric<Geometry = G>,
G: GraphGeometry,
{
fn from(inner: View<B, Vertex<G>>) -> Self {
VertexView { inner }
}
}
pub struct VertexCirculator<B> {
storage: B,
}
impl<B, M> From<VertexView<B>> for VertexCirculator<B>
where
B: Reborrow<Target = M>,
M: AsStorage<Vertex<Geometry<M>>> + Geometric,
{
fn from(vertex: VertexView<B>) -> Self {
let storage = vertex.inner.storage;
VertexCirculator { storage }
}
}
impl<'a, M> Iterator for VertexCirculator<&'a M>
where
M: AsStorage<Vertex<Geometry<M>>> + Geometric,
{
type Item = VertexView<&'a M>;
fn next(&mut self) -> Option<Self::Item> {
None
}
}
fn test<'a, G>(vertex: VertexView<&'a MeshGraph<G>>)
where
G: GraphGeometry,
G::Vertex: AsPosition,
{
let identity = vertex.into_identity();
let position = identity.position();
for vertex in identity.neighboring_vertices() {
let identity = vertex.into_identity();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment