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

org.azolla.l.ling.collect.Tuple Maven / Gradle / Ivy

There is a newer version: 2.0.3
Show newest version
/*
 * @(#)Tuple.java		Created at 2013-5-2
 * 
 * Copyright (c) 2011-2013 azolla.org All rights reserved.
 * Azolla PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. 
 */
package org.azolla.l.ling.collect;

import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;

import javax.annotation.Nullable;

import com.google.common.base.Objects;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import org.azolla.l.ling.lang.Char0;

/**
 * Tuple
 * 
 * Quadruple<Integer, Integer, Integer, Integer> ip = Tuple.of(127, 0, 0, 1);
 * System.out.println(Tuple.joinWith(".").join(ip));	//127.0.0.1 
 *
 * @author 	[email protected]
 * @since 	ADK1.0
 */
public class Tuple implements Iterable
{
    public static final String BEGIN = String.valueOf(Char0.OPEN_PARENTHESIS);
    public static final String SEP   = String.valueOf(Char0.COMMA);
    public static final String END   = String.valueOf(Char0.CLOSE_PARENTHESIS);

    protected First first;
    protected Rest  rest;

    protected Tuple(First first, Rest rest)
    {
        this.first = first;
        this.rest = rest;
    }

    @Override
    public int hashCode()
    {
        return Objects.hashCode(Iterators.toArray(iterator(), Object.class));
    }

    @Override
    public boolean equals(@Nullable Object obj)
    {
        if (this == obj)
        {
            return true;
        }

        if ((null != obj) && (Tuple.class.isAssignableFrom(obj.getClass())))
        {
            return Iterables.elementsEqual(this, (Tuple) obj);
        }

        return false;
    }

    @Override
    public String toString()
    {
        return joinWith(BEGIN, SEP, END).join(this);
    }

    public String toString(String sep)
    {
        return toString(joinWith(sep));
    }

    public String toString(String begin, String sep, String end)
    {
        return toString(joinWith(begin, sep, end));
    }

    public String toString(TupleJoiner joiner)
    {
        return joiner.join(this);
    }

    public static TupleJoiner joinWith(String begin, String sep, String end)
    {
        return new TupleJoiner(begin, sep, end);
    }

    public static TupleJoiner joinWith(String sep)
    {
        return new TupleJoiner(BEGIN, sep, END);
    }

    @Override
    public Iterator iterator()
    {
        return Lists.newArrayList(first, rest).iterator();
    }

    public  Tuple> prepend(T t)
    {
        return new Tuple>(t, this);
    }

    public static Null of()
    {
        return new Null();
    }

    public static  Single of(T1 t1)
    {
        return new Single(t1);
    }

    public static  Pair of(T1 t1, T2 t2)
    {
        return new Pair(t1, t2);
    }

    public static  Triple of(T1 t1, T2 t2, T3 t3)
    {
        return new Triple(t1, t2, t3);
    }

    public static  Quadruple of(T1 t1, T2 t2, T3 t3, T4 t4)
    {
        return new Quadruple(t1, t2, t3, t4);
    }

    public static  Quintuple of(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
    {
        return new Quintuple(t1, t2, t3, t4, t5);
    }

    public static  Sextuple of(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
    {
        return new Sextuple(t1, t2, t3, t4, t5, t6);
    }

    public static  Septuple of(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
    {
        return new Septuple(t1, t2, t3, t4, t5, t6, t7);
    }

    public static  Octuple of(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
    {
        return new Octuple(t1, t2, t3, t4, t5, t6, t7, t8);
    }

    public static  Nonuple of(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9)
    {
        return new Nonuple(t1, t2, t3, t4, t5, t6, t7, t8, t9);
    }

    public static  Decuple of(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10)
    {
        return new Decuple(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10);
    }

    public static  DecuplePlus of(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, Object... rest)
    {
        return new DecuplePlus(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, rest);
    }

    public static  T1 getFirst(Tuple tuple)
    {
        return tuple.first;
    }

    public static  T2 getSecond(Tuple> tuple)
    {
        return tuple.rest.first;
    }

    public static  T3 getThird(Tuple>> tuple)
    {
        return tuple.rest.rest.first;
    }

    public static  T4 getFourth(Tuple>>> tuple)
    {
        return tuple.rest.rest.rest.first;
    }

    public static  T5 getFifth(Tuple>>>> tuple)
    {
        return tuple.rest.rest.rest.rest.first;
    }

    public static  T6 getSixth(Tuple>>>>> tuple)
    {
        return tuple.rest.rest.rest.rest.rest.first;
    }

    public static  T7 getSeventh(Tuple>>>>>> tuple)
    {
        return tuple.rest.rest.rest.rest.rest.rest.first;
    }

    public static  T8 getEighth(Tuple>>>>>>> tuple)
    {
        return tuple.rest.rest.rest.rest.rest.rest.rest.first;
    }

    public static  T9 getNinth(Tuple>>>>>>>> tuple)
    {
        return tuple.rest.rest.rest.rest.rest.rest.rest.rest.first;
    }

    public static  T10 getTenth(Tuple>>>>>>>>> tuple)
    {
        return tuple.rest.rest.rest.rest.rest.rest.rest.rest.rest.first;
    }

    @SuppressWarnings("unchecked")
    public static  T getN(Tuple tuple, int n)
    {
        return (T) Iterables.get(tuple, n);
    }

    private static enum End
    {
        SINGLETON;
    }

    public static class DecuplePlus extends Tuple>>>>>>>>>>
    {
        public DecuplePlus(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, Object[] rest)
        {
            super(t1, of(t2, t3, t4, t5, t6, t7, t8, t9, t10, rest));
        }

        @Override
        public Iterator iterator()
        {
            return Iterables.concat(Lists.newArrayList(new Object[] {first, rest.first, rest.rest.first, rest.rest.rest.first, rest.rest.rest.rest.first, rest.rest.rest.rest.rest.first, rest.rest.rest.rest.rest.rest.first, rest.rest.rest.rest.rest.rest.rest.first, rest.rest.rest.rest.rest.rest.rest.rest.first, rest.rest.rest.rest.rest.rest.rest.rest.rest.first}), Lists.newArrayList(rest.rest.rest.rest.rest.rest.rest.rest.rest.rest.first)).iterator();
        }
    }

    public static class Decuple extends Tuple>>>>>>>>>
    {
        public Decuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10)
        {
            super(t1, of(t2, t3, t4, t5, t6, t7, t8, t9, t10));
        }

        @Override
        public Iterator iterator()
        {
            return Lists.newArrayList(new Object[] {first, rest.first, rest.rest.first, rest.rest.rest.first, rest.rest.rest.rest.first, rest.rest.rest.rest.rest.first, rest.rest.rest.rest.rest.rest.first, rest.rest.rest.rest.rest.rest.rest.first, rest.rest.rest.rest.rest.rest.rest.rest.first, rest.rest.rest.rest.rest.rest.rest.rest.rest.first}).iterator();
        }
    }

    public static class Nonuple extends Tuple>>>>>>>>
    {
        public Nonuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9)
        {
            super(t1, of(t2, t3, t4, t5, t6, t7, t8, t9));
        }

        @Override
        public Iterator iterator()
        {
            return Lists.newArrayList(new Object[] {first, rest.first, rest.rest.first, rest.rest.rest.first, rest.rest.rest.rest.first, rest.rest.rest.rest.rest.first, rest.rest.rest.rest.rest.rest.first, rest.rest.rest.rest.rest.rest.rest.first, rest.rest.rest.rest.rest.rest.rest.rest.first}).iterator();
        }
    }

    public static class Octuple extends Tuple>>>>>>>
    {
        public Octuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
        {
            super(t1, of(t2, t3, t4, t5, t6, t7, t8));
        }

        @Override
        public Iterator iterator()
        {
            return Lists.newArrayList(new Object[] {first, rest.first, rest.rest.first, rest.rest.rest.first, rest.rest.rest.rest.first, rest.rest.rest.rest.rest.first, rest.rest.rest.rest.rest.rest.first, rest.rest.rest.rest.rest.rest.rest.first}).iterator();
        }
    }

    public static class Septuple extends Tuple>>>>>>
    {
        public Septuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
        {
            super(t1, of(t2, t3, t4, t5, t6, t7));
        }

        @Override
        public Iterator iterator()
        {
            return Lists.newArrayList(new Object[] {first, rest.first, rest.rest.first, rest.rest.rest.first, rest.rest.rest.rest.first, rest.rest.rest.rest.rest.first, rest.rest.rest.rest.rest.rest.first}).iterator();
        }
    }

    public static class Sextuple extends Tuple>>>>>
    {
        public Sextuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
        {
            super(t1, of(t2, t3, t4, t5, t6));
        }

        @Override
        public Iterator iterator()
        {
            return Lists.newArrayList(new Object[] {first, rest.first, rest.rest.first, rest.rest.rest.first, rest.rest.rest.rest.first, rest.rest.rest.rest.rest.first}).iterator();
        }
    }

    public static class Quintuple extends Tuple>>>>
    {
        public Quintuple(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
        {
            super(t1, of(t2, t3, t4, t5));
        }

        @Override
        public Iterator iterator()
        {
            return Lists.newArrayList(new Object[] {first, rest.first, rest.rest.first, rest.rest.rest.first, rest.rest.rest.rest.first}).iterator();
        }
    }

    public static class Quadruple extends Tuple>>>
    {
        public Quadruple(T1 t1, T2 t2, T3 t3, T4 t4)
        {
            super(t1, of(t2, t3, t4));
        }

        @Override
        public Iterator iterator()
        {
            return Lists.newArrayList(new Object[] {first, rest.first, rest.rest.first, rest.rest.rest.first}).iterator();
        }
    }

    public static class Triple extends Tuple>>
    {
        public Triple(T1 t1, T2 t2, T3 t3)
        {
            super(t1, of(t2, t3));
        }

        @Override
        public Iterator iterator()
        {
            return Lists.newArrayList(new Object[] {first, rest.first, rest.rest.first}).iterator();
        }
    }

    public static class Pair extends Tuple>
    {
        public Pair(T1 t1, T2 t2)
        {
            super(t1, of(t2));
        }

        @Override
        public Iterator iterator()
        {
            return Lists.newArrayList(new Object[] {first, rest.first}).iterator();
        }
    }

    public static class Single extends Tuple
    {
        public Single(T1 t1)
        {
            super(t1, End.SINGLETON);
        }

        @Override
        public Iterator iterator()
        {
            return Lists.newArrayList((Object) first).iterator();
        }
    }

    public static class Null extends Tuple
    {
        private Null()
        {
            super(End.SINGLETON, End.SINGLETON);
        }

        @Override
        public Iterator iterator()
        {
            return Collections.emptyIterator();
        }
    }

    public static class TupleJoiner
    {
        private final String open;
        private final String separator;
        private final String close;

        public TupleJoiner(String open, String separator, String close)
        {
            this.open = open;
            this.separator = separator;
            this.close = close;
        }

        public  A appendTo(A appender, Tuple tuple) throws IOException
        {
            appender.append(open);
            Iterator iterTerm = tuple.iterator();
            if(iterTerm.hasNext())
            {
                appender.append(toString(iterTerm.next()));
                while(iterTerm.hasNext())
                {
                    appender.append(separator);
                    appender.append(toString(iterTerm.next()));
                }
            }
            appender.append(close);

            return appender;
        }

        public StringBuilder appendTo(StringBuilder builder, Tuple tuple)
        {
            try
            {
                appendTo((Appendable) builder, tuple);
            }
            catch(IOException impossible)
            {
                throw new AssertionError(impossible);
            }

            return builder;
        }

        public StringBuilder appendTo(Tuple tuple)
        {
            return appendTo(new StringBuilder(), tuple);
        }

        public String join(Tuple tuple)
        {
            return appendTo(tuple).toString();
        }

        private CharSequence toString(Object term)
        {
            return (term instanceof CharSequence) ? (CharSequence) term : String.valueOf(term);
        }
    }
}