[libgee] Add flat_map function
- From: Maciej Marcin Piechotka <mpiechotka src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgee] Add flat_map function
- Date: Sat, 6 Jul 2013 17:55:03 +0000 (UTC)
commit cb45df8faa5679e4defcaafe986a7ddae01eed68
Author: Maciej Piechotka <uzytkownik2 gmail com>
Date: Sat Jul 6 16:46:30 2013 +0200
Add flat_map function
gee/traversable.vala | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 57 insertions(+), 0 deletions(-)
---
diff --git a/gee/traversable.vala b/gee/traversable.vala
index 24ff08f..0ab1b52 100644
--- a/gee/traversable.vala
+++ b/gee/traversable.vala
@@ -380,12 +380,69 @@ public interface Gee.Traversable<G> : Object {
*/
public virtual Type element_type { get { return typeof (G); } }
+ /**
+ * A fused concatinate and map. The function is applied to each element
+ * of iteration and the resulting values are concatinated.
+ *
+ * The iterator is lazy evaluated but value is force-evaluated when
+ * iterator is moved to next value.
+ *
+ * Note: Default implementation uses { link stream}.
+ *
+ * Note: In { link Iterator} implementation if the parent iterator is
+ * { link Iterator.valid} and function returns a valid iterator the
+ * resulting iterator is also valid. Using the parent iterator is not
+ * allowed before the inner iterator { link Iterator.next}
+ * return false and then it points on its last element.
+ *
+ * @since 0.11.1
+ * @param f mapping function
+ * @return Iterator over returned values
+ */
+ public Iterator<A> flat_map<A>(owned FlatMapFunc<A, G> f) {
+ Iterator<A>? current = null;
+ return stream<A> ((state, item, out val) => {
+ switch (state) {
+ case Stream.YIELD:
+ if (current == null || !current.next ()) {
+ return Stream.CONTINUE;
+ } else {
+ val = new Lazy<A> (() => {return current.get ();});
+ return Stream.YIELD;
+ }
+ case Stream.CONTINUE:
+ current = f (item.get ());
+ if (current.valid) {
+ val = new Lazy<A> (() => {return current.get ();});
+ return Stream.YIELD;
+ } else {
+ return Stream.WAIT;
+ }
+ case Stream.WAIT:
+ if (current.next()) {
+ val = new Lazy<A> (() => {return current.get ();});
+ return Stream.YIELD;
+ } else {
+ return Stream.CONTINUE;
+ }
+ case Stream.END:
+ return Stream.END;
+ default:
+ assert_not_reached ();
+ }
+ });
+ }
+
public enum Stream {
YIELD,
CONTINUE,
END,
WAIT
}
+}
+namespace Gee {
+ // Placed here to workaround bug #703710
+ public delegate Iterator<A> FlatMapFunc<A, G>(owned G g);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]