Skip to content

Commit 87da7f2

Browse files
committed
add initial implementation of crate
1 parent 02915cf commit 87da7f2

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,5 @@
1818
Proxy GAT: Abstractions for generic proxy views with GAT to enable generic container types
1919

2020
The purpose of this crate is to make it possible to construct containers that allow comparing internal data which may be represented entirely differently than its original form to views of that data that may exist in an entirely different form and have to be constructed from lifetimes. The specific example that forced the creation of this crate was the use of ndarray using Array2 as a storage structure for Array1 values. A container might wish to store clusters of Array2 or use a single Array2 to store a set of Array1 values, but in doing so it makes it impossible to get a reference to the underlying Array1. When inserting or adding new Array1 values, most container types need to be able to compare the underlying data in some way, and this crate provides abstractions to create unifying view types from internal and external data for comparison. Because the [`ProxyView`] type created by this crate has no associated lifetime, it makes it possible to compare data through views of the underlying data that can be created arbitrarily and with their own lifetimes. No reference type is needed. This enables abstracting downstream code over the container type and also allows abstracting containers over the intermediary view type the user wishes.
21+
22+
A trivial implementation that allows the view to be a basic reference &T is provided as [`ReferenceProxy`]. It is recommended for container authors to use this proxy as a default type argument for the majority of users. For containers that need to use specific proxies, they can create their own proxy, such as a wrapper around ArrayView1, and then downstream users can override the defaults on containers that are permissive to match their view to yours. Users which require specific proxies for their own uses may also override them for permissive containers. Containers that use specialized storage methods might not store the owned version of the value directly, and so those are encouraged to create unique views for their type.

src/lib.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,65 @@
22
33
#![no_std]
44
doc_comment::doctest!("../README.md");
5+
6+
use core::marker::PhantomData;
7+
8+
/// A convenience type alias to get a view from a proxy and a lifetime.
9+
pub type View<'a, P> = <P as ProxyView>::View<'a>;
10+
11+
/// A type generator that produces a view type for a given lifetime.
12+
///
13+
/// The owned value associated with the proxy is required to outlive any borrow lifetime,
14+
/// so it's type must be known when this trait is implemented.
15+
///
16+
/// It also provides a static method to generate a view from a reference to an owned value,
17+
/// though views may be generated in alternative ways. The view must always be generatable
18+
/// from a reference to the owned value. An example is ndarray arrays, which can be viewed
19+
/// as sub-slices, but you can always create a view from a single owned array. For instance,
20+
/// you might store multiple Array1 using Array2 and create views using rows/columns, but
21+
/// it is important that new points being added to the space can be viewed using an ArrayView1
22+
/// just like you can for points stored in the Array2 so that they can be compared.
23+
pub trait ProxyView {
24+
/// The concrete type that this proxy borrows from.
25+
type Owned;
26+
27+
/// The borrowed view type for a given lifetime.
28+
/// `Self::Owned` must outlive the borrow lifetime to ensure safety.
29+
type View<'a>
30+
where
31+
Self::Owned: 'a;
32+
33+
fn view<'a>(owned: &'a Self::Owned) -> Self::View<'a>;
34+
}
35+
36+
/// Provides a generic way to clone owned values from arbitrary proxies.
37+
pub trait ProxyToOwned: ProxyView {
38+
fn to_owned_proxy<'a>(view: Self::View<'a>) -> Self::Owned;
39+
}
40+
41+
/// A proxy that simply returns a reference to the owned value.
42+
pub struct ReferenceProxy<T>(pub PhantomData<T>);
43+
44+
impl<T> ReferenceProxy<T> {
45+
pub fn new() -> Self {
46+
ReferenceProxy(PhantomData)
47+
}
48+
}
49+
50+
impl<T> Default for ReferenceProxy<T> {
51+
fn default() -> Self {
52+
Self::new()
53+
}
54+
}
55+
56+
impl<T> ProxyView for ReferenceProxy<T> {
57+
type Owned = T;
58+
type View<'a>
59+
= &'a T
60+
where
61+
Self::Owned: 'a;
62+
63+
fn view<'a>(owned: &'a Self::Owned) -> Self::View<'a> {
64+
owned
65+
}
66+
}

0 commit comments

Comments
 (0)