1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use std::fmt;
12 use std::iter::FromIterator;
13 use std::slice;
14
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.
18
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(Box<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]`.
30 ///
31 /// Some clients will have a pre-allocated vector ready to hand off in
32 /// a slice; others will want to create the set on the fly and hand
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]`.)
37 pub enum MaybeOwnedVector<'a,T> {
38 Growable(Vec<T>),
39 FixedLen(~[T]),
40 Borrowed(&'a [T]),
41 }
42
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
64 impl<'a,T> MaybeOwnedVector<'a,T> {
65 pub fn iter(&'a self) -> slice::Items<'a,T> {
66 match self {
67 &Growable(ref v) => v.iter(),
68 &FixedLen(ref v) => v.iter(),
69 &Borrowed(ref v) => v.iter(),
70 }
71 }
72 }
73
74 // The `Vector` trait is provided in the prelude and is implemented on
75 // both `&'a [T]` and `Vec<T>`, so it makes sense to try to support it
76 // seamlessly. The other vector related traits from the prelude do
77 // not appear to be implemented on both `&'a [T]` and `Vec<T>`. (It
78 // is possible that this is an oversight in some cases.)
79 //
80 // In any case, with `Vector` in place, the client can just use
81 // `as_slice` if they prefer that over `match`.
82
83 impl<'b,T> slice::Vector<T> for MaybeOwnedVector<'b,T> {
84 fn as_slice<'a>(&'a self) -> &'a [T] {
85 match self {
86 &Growable(ref v) => v.as_slice(),
87 &FixedLen(ref v) => v.as_slice(),
88 &Borrowed(ref v) => v.as_slice(),
89 }
90 }
91 }
92
93 impl<'a,T> FromIterator<T> for MaybeOwnedVector<'a,T> {
94 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.
97 Growable(FromIterator::from_iter(iterator))
98 }
99 }
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 }
libgraphviz/maybe_owned_vec.rs:36:25-36:25 -enum- definition:
/// that return `~[T]`.)
pub enum MaybeOwnedVector<'a,T> {
Growable(Vec<T>),
references:- 13123: impl<'a,T:Clone> MaybeOwnedVector<'a,T> {
124: /// Convert `self` into a growable `Vec`, not making a copy if possible.
libgraphviz/lib.rs:
444: pub type Nodes<'a,N> = MaybeOwnedVector<'a,N>;
445: pub type Edges<'a,E> = MaybeOwnedVector<'a,E>;
libgraphviz/maybe_owned_vec.rs:
93: impl<'a,T> FromIterator<T> for MaybeOwnedVector<'a,T> {
94: fn from_iter<I:Iterator<T>>(iterator: I) -> MaybeOwnedVector<T> {
95: // If we are building from scratch, might as well build the
libgraphviz/maybe_owned_vec.rs:43:47-43:47 -trait- definition:
/// Trait for moving into a `MaybeOwnedVector`
pub trait IntoMaybeOwnedVector<'a,T> {
/// Moves self into a `MaybeOwnedVector`
references:- 359: impl<'a,T> IntoMaybeOwnedVector<'a,T> for &'a [T] {
60: #[inline]