Skip to content

Commit f4cc407

Browse files
committed
---
yaml --- r: 151305 b: refs/heads/try2 c: 4a122a3 h: refs/heads/master i: 151303: 4815d78 v: v3
1 parent b436f25 commit f4cc407

File tree

3 files changed

+97
-27
lines changed

3 files changed

+97
-27
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: b7374182f7298183f261a0905ac10f5c8c9701ad
8+
refs/heads/try2: 4a122a3185d77cf716dc52d2f54a0595cbccf861
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/libgraphviz/lib.rs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
/*! Generate files suitable for use with [Graphviz](http://www.graphviz.org/)
1212
13-
The `render` function generates output (e.g. a `output.dot` file) for
13+
The `render` function generates output (e.g. an `output.dot` file) for
1414
use with [Graphviz](http://www.graphviz.org/) by walking a labelled
1515
graph. (Graphviz can then automatically lay out the nodes and edges
1616
of the graph, and also optionally render the graph as an image or
@@ -37,16 +37,18 @@ pairs of ints, representing the edges (the node set is implicit).
3737
Each node label is derived directly from the int representing the node,
3838
while the edge labels are all empty strings.
3939
40-
This example also illustrates how to use the `Borrowed` variant of
41-
`MaybeOwnedVector` to return a slice into the edge list, rather than
42-
constructing a copy from scratch.
40+
This example also illustrates how to use `MaybeOwnedVector` to return
41+
an owned vector or a borrowed slice as appropriate: we construct the
42+
node vector from scratch, but borrow the edge list (rather than
43+
constructing a copy of all the edges from scratch).
4344
4445
The output from this example renders five nodes, with the first four
4546
forming a diamond-shaped acyclic graph and then pointing to the fifth
4647
which is cyclic.
4748
4849
```rust
4950
use dot = graphviz;
51+
use graphviz::maybe_owned_vec::IntoMaybeOwnedVector;
5052
5153
type Nd = int;
5254
type Ed = (int,int);
@@ -77,12 +79,12 @@ impl<'a> dot::GraphWalk<'a, Nd, Ed> for Edges {
7779
}
7880
nodes.sort();
7981
nodes.dedup();
80-
nodes.move_iter().collect()
82+
nodes.into_maybe_owned()
8183
}
8284
8385
fn edges(&'a self) -> dot::Edges<'a,Ed> {
8486
let &Edges(ref edges) = self;
85-
dot::maybe_owned_vec::Borrowed(edges.as_slice())
87+
edges.as_slice().into_maybe_owned()
8688
}
8789
8890
fn source(&self, e: &Ed) -> Nd { let &(s,_) = e; s }
@@ -119,9 +121,16 @@ This example also illustrates how to use a type (in this case the edge
119121
type) that shares substructure with the graph: the edge type here is a
120122
direct reference to the `(source,target)` pair stored in the graph's
121123
internal vector (rather than passing around a copy of the pair
122-
itself). Note that in this case, this implies that `fn edges(&'a
123-
self)` must construct a fresh `Vec<&'a (uint,uint)>` from the
124-
`Vec<(uint,uint)>` edges stored in `self`.
124+
itself). Note that this implies that `fn edges(&'a self)` must
125+
construct a fresh `Vec<&'a (uint,uint)>` from the `Vec<(uint,uint)>`
126+
edges stored in `self`.
127+
128+
Since both the set of nodes and the set of edges are always
129+
constructed from scratch via iterators, we use the `collect()` method
130+
from the `Iterator` trait to collect the nodes and edges into freshly
131+
constructed growable `Vec` values (rather use the `into_maybe_owned`
132+
from the `IntoMaybeOwnedVector` trait as was used in the first example
133+
above).
125134
126135
The output from this example renders four nodes that make up the
127136
Hasse-diagram for the subsets of the set `{x, y}`. Each edge is

branches/try2/src/libgraphviz/maybe_owned_vec.rs

Lines changed: 78 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,44 +8,69 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use std::container::Container;
11+
use std::fmt;
1212
use std::iter::FromIterator;
1313
use std::slice;
1414

15-
// Note: Once Dynamically Sized Types (DST) lands, this should be
16-
// replaced with something like `enum Owned<'a, Sized? U>{ Owned(~U),
17-
// Borrowed(&'a U) }`; and then `U` could be instantiated with `[T]`
18-
// or `str`, etc.
15+
// Note 1: It is not clear whether the flexibility of providing both
16+
// the `Growable` and `FixedLen` variants is sufficiently useful.
17+
// Consider restricting to just a two variant enum.
1918

20-
/// MaybeOwnedVector<'a,T> abstracts over `Vec<T>` and `&'a [T]`.
19+
// Note 2: Once Dynamically Sized Types (DST) lands, it might be
20+
// reasonable to replace this with something like `enum MaybeOwned<'a,
21+
// Sized? U>{ Owned(~U), Borrowed(&'a U) }`; and then `U` could be
22+
// instantiated with `[T]` or `str`, etc. Of course, that would imply
23+
// removing the `Growable` variant, which relates to note 1 above.
24+
// Alternatively, we might add `MaybeOwned` for the general case but
25+
// keep some form of `MaybeOwnedVector` to avoid unnecessary copying
26+
// of the contents of `Vec<T>`, since we anticipate that to be a
27+
// frequent way to dynamically construct a vector.
28+
29+
/// MaybeOwnedVector<'a,T> abstracts over `Vec<T>`, `~[T]`, `&'a [T]`.
2130
///
2231
/// Some clients will have a pre-allocated vector ready to hand off in
2332
/// a slice; others will want to create the set on the fly and hand
24-
/// off ownership.
25-
#[deriving(Eq)]
33+
/// off ownership, via either `Growable` or `FixedLen` depending on
34+
/// which kind of vector they have constucted. (The `FixedLen`
35+
/// variant is provided for interoperability with `std::slice` methods
36+
/// that return `~[T]`.)
2637
pub enum MaybeOwnedVector<'a,T> {
2738
Growable(Vec<T>),
39+
FixedLen(~[T]),
2840
Borrowed(&'a [T]),
2941
}
3042

43+
/// Trait for moving into a `MaybeOwnedVector`
44+
pub trait IntoMaybeOwnedVector<'a,T> {
45+
/// Moves self into a `MaybeOwnedVector`
46+
fn into_maybe_owned(self) -> MaybeOwnedVector<'a,T>;
47+
}
48+
49+
impl<'a,T> IntoMaybeOwnedVector<'a,T> for Vec<T> {
50+
#[inline]
51+
fn into_maybe_owned(self) -> MaybeOwnedVector<'a,T> { Growable(self) }
52+
}
53+
54+
impl<'a,T> IntoMaybeOwnedVector<'a,T> for ~[T] {
55+
#[inline]
56+
fn into_maybe_owned(self) -> MaybeOwnedVector<'a,T> { FixedLen(self) }
57+
}
58+
59+
impl<'a,T> IntoMaybeOwnedVector<'a,T> for &'a [T] {
60+
#[inline]
61+
fn into_maybe_owned(self) -> MaybeOwnedVector<'a,T> { Borrowed(self) }
62+
}
63+
3164
impl<'a,T> MaybeOwnedVector<'a,T> {
3265
pub fn iter(&'a self) -> slice::Items<'a,T> {
3366
match self {
3467
&Growable(ref v) => v.iter(),
68+
&FixedLen(ref v) => v.iter(),
3569
&Borrowed(ref v) => v.iter(),
3670
}
3771
}
3872
}
3973

40-
impl<'a,T> Container for MaybeOwnedVector<'a,T> {
41-
fn len(&self) -> uint {
42-
match self {
43-
&Growable(ref v) => v.len(),
44-
&Borrowed(ref v) => v.len(),
45-
}
46-
}
47-
}
48-
4974
// The `Vector` trait is provided in the prelude and is implemented on
5075
// both `&'a [T]` and `Vec<T>`, so it makes sense to try to support it
5176
// seamlessly. The other vector related traits from the prelude do
@@ -59,13 +84,49 @@ impl<'b,T> slice::Vector<T> for MaybeOwnedVector<'b,T> {
5984
fn as_slice<'a>(&'a self) -> &'a [T] {
6085
match self {
6186
&Growable(ref v) => v.as_slice(),
87+
&FixedLen(ref v) => v.as_slice(),
6288
&Borrowed(ref v) => v.as_slice(),
6389
}
6490
}
6591
}
6692

6793
impl<'a,T> FromIterator<T> for MaybeOwnedVector<'a,T> {
6894
fn from_iter<I:Iterator<T>>(iterator: I) -> MaybeOwnedVector<T> {
95+
// If we are building from scratch, might as well build the
96+
// most flexible variant.
6997
Growable(FromIterator::from_iter(iterator))
7098
}
7199
}
100+
101+
impl<'a,T:fmt::Show> fmt::Show for MaybeOwnedVector<'a,T> {
102+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
103+
self.as_slice().fmt(f)
104+
}
105+
}
106+
107+
impl<'a,T:Clone> CloneableVector<T> for MaybeOwnedVector<'a,T> {
108+
/// Returns a copy of `self`.
109+
fn to_owned(&self) -> ~[T] {
110+
self.as_slice().to_owned()
111+
}
112+
113+
/// Convert `self` into an owned slice, not making a copy if possible.
114+
fn into_owned(self) -> ~[T] {
115+
match self {
116+
Growable(v) => v.as_slice().to_owned(),
117+
FixedLen(v) => v,
118+
Borrowed(v) => v.to_owned(),
119+
}
120+
}
121+
}
122+
123+
impl<'a,T:Clone> MaybeOwnedVector<'a,T> {
124+
/// Convert `self` into a growable `Vec`, not making a copy if possible.
125+
pub fn into_vec(self) -> Vec<T> {
126+
match self {
127+
Growable(v) => v,
128+
FixedLen(v) => Vec::from_slice(v.as_slice()),
129+
Borrowed(v) => Vec::from_slice(v),
130+
}
131+
}
132+
}

0 commit comments

Comments
 (0)