fera_graph/
ext.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5//! Extension traits for std types.
6//!
7//! The traits is this module are included in the [prelude].
8//!
9//! # Examples
10//!
11//! ```
12//! extern crate fera_fun;
13//! extern crate fera_graph;
14//!
15//! use fera_graph::prelude::*;
16//! use fera_fun::vec;
17//!
18//! # fn main() {
19//! let g = CompleteGraph::new(4);
20//! let mut w = g.default_vertex_prop(0);
21//! w[0] = 1;
22//! w[1] = 2;
23//! w[2] = 3;
24//! w[3] = 0;
25//!
26//! let mut vertices = vec(g.vertices());
27//! assert!(!vertices.is_sorted_by_prop(&w));
28//!
29//! vertices.sort_by_prop(&w);
30//! assert!(vertices.is_sorted_by_prop(&w));
31//! assert_eq!(vec![3, 0, 1, 2], vertices);
32//!
33//! // returns the index of the vertex with w = 2,
34//! // that is, the index of vertex 1
35//! assert_eq!(Ok(2), vertices.binary_search_by_prop(&2, &w));
36//!
37//! // returns the index that a vertex with w = 5
38//! // could be inserted while maintaining sorted order
39//! assert_eq!(Err(4), vertices.binary_search_by_prop(&5, &w));
40//! # }
41//! ```
42//!
43//! [prelude]: ../prelude/index.html
44
45use params::IntoOwned;
46use prelude::*;
47
48/// Extension trait for slices.
49///
50/// See the [module documentation] for examples.
51///
52/// [module documentation]: index.html
53pub trait GraphsSliceExt<T> {
54    /// Returns `true` if a slice is sorted according to a [property], otherwise, returns `false`.
55    ///
56    /// [property]: ../props/index.html
57    fn is_sorted_by_prop<P, K>(&self, prop: P) -> bool
58    where
59        P: PropGet<K>,
60        for<'a> &'a T: IntoOwned<K>,
61        P::Output: Ord;
62
63    /// Sort a slice using a [property].
64    ///
65    /// This functions calls [`slice::sort_by_key`].
66    ///
67    /// [property]: ../props/index.html
68    /// [`slice::sort_by_key`]:
69    /// https://doc.rust-lang.org/stable/std/primitive.slice.html#method.sort_by_key
70    fn sort_by_prop<P, K>(&mut self, prop: P)
71    where
72        P: PropGet<K>,
73        for<'a> &'a T: IntoOwned<K>,
74        P::Output: Ord;
75
76    /// Sort a slice using a [property].
77    ///
78    /// This functions calls [`slice::sort_unstable_by_key`].
79    ///
80    /// [property]: ../props/index.html
81    /// [`slice::sort_unstable_by_key`]:
82    /// https://doc.rust-lang.org/stable/std/primitive.slice.html#method.sort_unstable_by_key
83    fn sort_unstable_by_prop<P, K>(&mut self, prop: P)
84    where
85        P: PropGet<K>,
86        for<'a> &'a T: IntoOwned<K>,
87        P::Output: Ord;
88
89    /// Binary searches a slice that is sorted by a [property].
90    ///
91    /// This functions calls [`slice::binary_search_by_key`].
92    ///
93    /// [property]: ../props/index.html
94    /// [`slice::binary_search_by_key`]:
95    /// https://doc.rust-lang.org/stable/std/primitive.slice.html#method.binary_search_by_key
96    fn binary_search_by_prop<P, K>(&self, prop_value: &P::Output, prop: P) -> Result<usize, usize>
97    where
98        P: PropGet<K>,
99        for<'a> &'a T: IntoOwned<K>,
100        P::Output: Ord;
101}
102
103impl<T> GraphsSliceExt<T> for [T] {
104    fn is_sorted_by_prop<P, K>(&self, prop: P) -> bool
105    where
106        P: PropGet<K>,
107        for<'a> &'a T: IntoOwned<K>,
108        P::Output: Ord,
109    {
110        let mut iter = self.iter();
111        if let Some(item) = iter.next() {
112            let mut p = prop.get(item.into_owned());
113            for item in iter {
114                let q = prop.get(item.into_owned());
115                if p > q {
116                    return false;
117                }
118                p = q;
119            }
120        }
121        true
122    }
123
124    #[inline]
125    fn sort_by_prop<P, K>(&mut self, prop: P)
126    where
127        P: PropGet<K>,
128        for<'a> &'a T: IntoOwned<K>,
129        P::Output: Ord,
130    {
131        self.sort_by_key(|item| prop.get(item.into_owned()))
132    }
133
134    #[inline]
135    fn sort_unstable_by_prop<P, K>(&mut self, prop: P)
136    where
137        P: PropGet<K>,
138        for<'a> &'a T: IntoOwned<K>,
139        P::Output: Ord,
140    {
141        self.sort_unstable_by_key(|item| prop.get(item.into_owned()))
142    }
143
144    #[inline]
145    fn binary_search_by_prop<P, K>(&self, prop_value: &P::Output, prop: P) -> Result<usize, usize>
146    where
147        P: PropGet<K>,
148        for<'a> &'a T: IntoOwned<K>,
149        P::Output: Ord,
150    {
151        self.binary_search_by_key(prop_value, |item| prop.get(item.into_owned()))
152    }
153}
154
155/// Extension trait for vectors.
156///
157/// See the [module documentation] for examples.
158///
159/// [module documentation]: index.html
160pub trait GraphsVecExt<T> {
161    /// Returns a vector sorted by a [property].
162    ///
163    /// This functions calls [`GraphsSliceExt::sort_by_prop`].
164    ///
165    /// [property]: ../props/index.html
166    /// [`GraphsSliceExt::sort_by_prop`]: trait.GraphsSliceExt.html#tymethod.sort_by_prop
167    fn sorted_by_prop<P, K>(self, prop: P) -> Self
168    where
169        P: PropGet<K>,
170        for<'a> &'a T: IntoOwned<K>,
171        P::Output: Ord;
172
173    /// Returns a vector sorted by a [property].
174    ///
175    /// This functions calls [`GraphsSliceExt::sort_unstable_by_prop`].
176    ///
177    /// [property]: ../props/index.html
178    /// [`GraphsSliceExt::sort_unstable_by_prop`]: trait.GraphsSliceExt.html#tymethod.sort_unstable_by_prop
179    fn sorted_unstable_by_prop<P, K>(self, prop: P) -> Self
180    where
181        P: PropGet<K>,
182        for<'a> &'a T: IntoOwned<K>,
183        P::Output: Ord;
184}
185
186impl<T> GraphsVecExt<T> for Vec<T> {
187    #[inline]
188    fn sorted_by_prop<P, K>(mut self, prop: P) -> Self
189    where
190        P: PropGet<K>,
191        for<'a> &'a T: IntoOwned<K>,
192        P::Output: Ord,
193    {
194        self.sort_by_prop(prop);
195        self
196    }
197
198    #[inline]
199    fn sorted_unstable_by_prop<P, K>(mut self, prop: P) -> Self
200    where
201        P: PropGet<K>,
202        for<'a> &'a T: IntoOwned<K>,
203        P::Output: Ord,
204    {
205        self.sort_unstable_by_prop(prop);
206        self
207    }
208}