All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.unit16.z.indexed.DSL Maven / Gradle / Ivy

package com.unit16.z.indexed;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;

import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.google.common.collect.UnmodifiableIterator;

public abstract class DSL
implements Indexed, Iterable
{
	private static final class ListBacked
	extends DSL
	{
		private final List _list;

		ListBacked(List i)
		{
			_list = i;
		}
		
		ListBacked(DSL i)
		{
			_list = new ArrayList<>(i.size());
			for (C c : i) { _list.add(c); }
		}
		
		@Override public C get(int i) { return _list.get(i); }
		
		@Override public int size() { return _list.size(); }	
		
		@Override public Iterator iterator() { return _list.iterator(); }
	}

	private static final class IndexedBacked
	extends DSL
	{
		private final Indexed _i;
		
		IndexedBacked(Indexed i) {
			_i = i;
		}

		@Override
		public C get(int i) { return _i.get(i); }

		@Override
		public int size() { return _i.size(); }

		@Override
		public Iterator iterator() {
			return new UnmodifiableIterator() {

				private int _j = 0;
				
				@Override
				public boolean hasNext() { return _j < size(); }

				@Override
				public C next() { _j++; return get(_j - 1);}
			};
		}
	}
	
	public static  DSL from(List c)
	{
		return new ListBacked<>(c);
	}
	
	public static  DSL from(Indexed c)
	{
		return (c instanceof DSL) ? (DSL) c : new IndexedBacked<>(c); 
	}
	
	public final  DSL map(Function f)
	{
		return new OnResultOf<>(this, f);
	}
	
	public final DSL head(final int max)
	{
		final Indexed w = this;
		return new IndexedBacked<>(new Indexed(){

			@Override
			public B get(int i) { return w.get(i); }

			@Override
			public int size() { return max; }});
	}
	
	public final DSL tail(final int min)
	{
		final Indexed w = this;
		return new IndexedBacked<>(new Indexed(){

			@Override
			public B get(int i) { return w.get(i + min); }

			@Override
			public int size() { return w.size() - min; }});
	}
	
	public final DSL filter(Predicate p)
	{
		if (size() > 0)
		{
			final Iterator i = Iterators.filter(this.iterator(), x -> p.test(x));
			if (i.hasNext())
			{
				return new ListBacked<>(Lists.newArrayList(i));
			}
		}
		
		return new Empty<>();
	}
	
	public final DSL strict()
	{
		return new ListBacked<>(this);
	}
	
	public final DSL append(Indexed snd)
	{
		return new Concat<>(this, snd);
	}
	
	private static final class Concat
	extends DSL
	{
		private final DSL fst_;
		private final DSL snd_;
		private final int sf;
		private final int ss;
		
		Concat(Indexed fst, Indexed snd) { 
			fst_ = from(fst); 
			snd_ = from(snd);
			sf = fst_.size(); 
			ss = snd_.size();
		}
		@Override
		public C get(int i) { 
			return i < sf ? fst_.get(i) : snd_.get(i - sf);
		}

		@Override
		public int size() { return sf + ss; }

		@Override
		public Iterator iterator() { 
			return Iterators.concat(fst_.iterator(), snd_.iterator()); }
	}
}