using Invercargill.DataStructures; using Invercargill.Mapping; namespace Invercargill { public class Attempts : Proxy>, Promotion> { public Enumerable> wrap (Enumerable> enumerable) { inner = enumerable; results = inner.where(a => a.success).select(a => a.result); errors = inner.where(a => !a.success).select(a => a.error); return this; } public bool can_wrap (GLib.Type element_type) { return element_type.is_a (typeof(Attempt)); } public Enumerable results { get; private set; } public Enumerable errors { get; private set; } public bool fully_successful() { return inner.all(a => a.success); } public new bool iterate_if(PredicateDelegate handler) throws Error { var tracker = get_tracker(); while(tracker.has_next()) { var item = tracker.get_next(); if(item.success) { if(!handler(item.result)) { return false; } } else { throw item.error; } } return true; } public new void iterate(ItemDelegate handler) throws Error { iterate_if(i => { handler(i); return true; }); } public new Series to_series() throws Error { var series = new Series(); iterate(i => series.add(i)); return series; } public new T[] to_array() throws Error { var array = new T[1024]; var index = 0; foreach (var item in this) { if(!item.success) { throw item.error; } if(index >= array.length) { array.resize(array.length*2); } safely_assign_to_array(array, index, item.result); index++; } array.resize(index); return array; } public new Vector to_vector() throws Error { var vector = new Vector(); iterate(i => vector.add(i)); return vector; } public new Dictionary to_dictionary(TransformDelegate key_selecter, HashDelegate? key_hash_func = null, EqualityDelegate? key_equal_func = null) throws Error { var dict = new Dictionary(key_hash_func, key_equal_func); iterate(i => dict.set(key_selecter(i), i)); return dict; } public new Dictionary select_to_dictionary(TransformDelegate key_selecter, TransformDelegate value_selecter, HashDelegate? key_hash_func = null, EqualityDelegate? key_equal_func = null) throws Error { var dict = new Dictionary(key_hash_func, key_equal_func); iterate(i => dict.set(key_selecter(i), value_selecter(i))); return dict; } public new Set to_set(HashDelegate? hash_func = null, EqualityDelegate? equal_func = null) throws Error { var @set = new HashSet(hash_func, equal_func); iterate(i => @set.add(i)); return @set; } public new Elements to_elements() throws Error { var series = new ElementSeries(); if(typeof(T).is_a(typeof(Element))) { iterate(i => series.add((Element)i)); } else { iterate(i => series.add(new NativeElement(i))); } return series; } public new Object[] to_object_array() throws Error { return to_vector().to_object_array(); } // New Functions public new bool any(PredicateDelegate predicate = (i) => true) throws Error { var result = false; var p = resolve_nullable_predicate(predicate); iterate_if(i => { if(p(i)) { result = true; return false; } return true; }); return result; } public new bool all(PredicateDelegate predicate) throws Error { return !any(i => !predicate(i)); } public new bool no(PredicateDelegate? predicate = null) throws Error { var p = resolve_nullable_predicate(predicate); return all(i => !p(i)); } public new Attempts where(owned PredicateDelegate predicate) { return inner.where(i => !i.success || predicate(i)).assert_promotion>(); } public new Attempts select(owned TransformDelegate transform) { return inner.select>(a => a.success ? new Attempt.successful(transform(a.result)) : new Attempt.unsuccessful(a.error)).assert_promotion>(); } public new Attempts select_many(owned TransformDelegate> transform) { return inner.select_many>(a => a.success ? transform(a.result).select>(i => new Attempt.successful(i)) : Iterate.single>(new Attempt.unsuccessful(a.error))).assert_promotion>(); } public new Attempts concat(Enumerable> other) { return inner.concat(other).assert_promotion(); } public new Attempts cast() { return select(i => (TOut)i); } public new Attempts> contextualised_select(owned TransformDelegate transform) { return select>((i) => new SelectionContext(i, transform(i))); } public new TOut aggregate(TOut initial, AggregateDelegate aggregate_func) throws Error { var aggregate = initial; iterate(i => { aggregate = aggregate_func(aggregate, i); }); return aggregate; } public new T max(TransformDelegate int_delegate) throws Error{ T item = null; var first = true; var value = 0; foreach (var a in this) { var i = a.unwrap(); if(first) { first = false; item = i; value = int_delegate(i); continue; } var item_value = int_delegate(i); if(item_value > value) { value = item_value; item = i; } } return item; } public new T min(TransformDelegate int_delegate) throws Error { T item = null; var first = true; var value = 0; foreach (var a in this) { var i = a.unwrap(); if(first) { first = false; item = i; value = int_delegate(i); continue; } var item_value = int_delegate(i); if(item_value < value) { value = item_value; item = i; } } return item; } public new bool contains(T item) throws Error { return any(i => i == item); } public Type attempt_element_type { get { return typeof(T); } } public new Attempts select_where(owned FilterTransformDelegate transform) { return inner.select_where((a, out o) => !a.success || transform(a.result, out o)).assert_promotion>(); } public new Attempts attempt_select(owned AttemptTransformDelegate transform) { return inner.attempt_select(a => a.success ? new Attempt(() => transform(a.result)) : new Attempt.unsuccessful(a.error)); } public new Attempts attempt_select_nested(owned AttemptTransformDelegate>> transform) { return attempt_select>>((owned)transform) .as_enumerable() .select_many>(a => a.success ? a.result : Iterate.single>(new Attempt.unsuccessful(a.error))) .assert_promotion>(); } public new Attempts attempt_map_with(Mapper mapper) { return attempt_select(o => mapper.materialise(o)); } private PredicateDelegate resolve_nullable_predicate(PredicateDelegate? predicate) { if(predicate == null) { return (p) => true; } return predicate; } } }