| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- namespace Invercargill.DataStructures {
- public class Series<T> : Enumerable<T>, Lot<T>, ReadOnlyCollection<T>, Collection<T> {
-
- [Compact]
- internal class SeriesItem<T> {
- public SeriesItem<T>* next;
- public T value;
- public SeriesItem(owned T value) {
- this.value = (owned)value;
- }
- }
- internal SeriesItem<T>* root;
- internal SeriesItem<T>* end;
- private int n_items = 0;
- public Series() {}
- public override uint? peek_count() {
- return n_items;
- }
- public override EnumerableInfo get_info() {
- return new EnumerableInfo.infer_ultimate (this, EnumerableCategory.IN_MEMORY);
- }
- public override Tracker<T> get_tracker() {
- return new SeriesTracker<T>(root);
- }
- public override uint length { get { return n_items; }}
- public override T[] to_array () {
- var arr = new T[n_items];
- var count = 0;
- iterate(i => {
- arr[count] = i;
- count++;
- });
- return arr;
- }
- public void add(T item) {
- lock(root) {
- n_items++;
- SeriesItem<T>* si = new SeriesItem<T>(item);
- if(root == null) {
- root = si;
- end = si;
- return;
- }
- end->next = si;
- end = si;
- }
- }
- public void add_all(Enumerable<T> items) {
- lock(root) {
- SeriesItem<T>* chain_start = null;
- SeriesItem<T>* chain_end = null;
- foreach (var item in items) {
- n_items++;
- SeriesItem<T>* si = new SeriesItem<T>(item);
- if(chain_start == null) {
- chain_start = si;
- chain_end = si;
- continue;
- }
- chain_end->next = si;
- chain_end = si;
- }
- if(root == null) {
- root = chain_start;
- end = chain_end;
- return;
- }
- end->next = chain_start;
- end = chain_end;
- }
- }
- public void add_start(T item) {
- lock(root) {
- n_items++;
- SeriesItem<T>* si = new SeriesItem<T>(item);
- if(root == null) {
- end = si;
- }
- si->next = root;
- root = si;
- }
- }
- public void add_all_start(Enumerable<T> items) {
- lock(root) {
- SeriesItem<T>* chain_start = null;
- SeriesItem<T>* chain_end = null;
- foreach (var item in items) {
- n_items++;
- SeriesItem<T>* si = new SeriesItem<T>(item);
- if(chain_start == null) {
- chain_start = si;
- chain_end = si;
- continue;
- }
- chain_end->next = si;
- chain_end = si;
- }
- if(root == null) {
- end = chain_end;
- }
- chain_end->next = root;
- root = chain_start;
- }
- }
- public T pop_start() throws SequenceError {
- SequenceError? e = null;
- T? item = null;
- lock(root) {
- if(root == null) {
- e = new SequenceError.NO_ELEMENTS("Series contains no elements");
- }
- else {
- var old_root = root;
- root = root->next;
- item = old_root->value;
- delete old_root;
- if(root == null) {
- end = null;
- }
- }
- }
- if(e != null) {
- throw e;
- }
- return item;
- }
- public void remove_first_where(Invercargill.PredicateDelegate<T> predicate) {
- remove_items(predicate, true);
- }
- public void remove_all_where(Invercargill.PredicateDelegate<T> predicate) {
- remove_items(predicate, false);
- }
- private void remove_items(Invercargill.PredicateDelegate<T> predicate, bool first_only) {
- lock(root) {
- SeriesItem<T>* previous = null;
- SeriesItem<T>* node = root;
- while(node != null) {
- if(predicate(node->value)) {
- if(previous == null) {
- root = node->next;
- }
- else {
- previous->next = node->next;
- }
- delete node;
- if(first_only) {
- break;
- }
- }
- previous = node;
- node = node->next;
- }
- }
- }
- public void clear() {
- lock(root) {
- n_items = 0;
- SeriesItem<T>* node = root;
- while(node != null) {
- SeriesItem<T>* removed = node;
- node = node->next;
- // Delete won't unref the value so explicitly set to null before deleting
- removed->value = null;
- delete removed;
- }
- root = null;
- end = null;
- }
- }
- ~Series() {
- clear();
- }
- private class SeriesTracker<T> : Tracker<T> {
- private weak SeriesItem<T>* current;
- public SeriesTracker(SeriesItem<T>* root) {
- current = root;
- }
- public override bool has_next() {
- return current != null;
- }
- public override T get_next() {
- var value = current->value;
- current = current->next;
- return value;
- }
- }
- }
- }
|