Row.java

// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 **********************************************************************
 * Copyright (c) 2002-2014, Google, International Business Machines
 * Corporation and others.  All Rights Reserved.
 **********************************************************************
 * Author: Mark Davis
 **********************************************************************
 */
package com.ibm.icu.impl;

import com.ibm.icu.util.Freezable;
import java.util.Objects;

@SuppressWarnings({"unchecked", "rawtypes"})
public class Row<C0, C1, C2, C3, C4>
        implements java.lang.Comparable, Cloneable, Freezable<Row<C0, C1, C2, C3, C4>> {
    protected Object[] items;
    protected volatile boolean frozen;

    /** Convenience Methods */
    public static <C0, C1> R2<C0, C1> of(C0 p0, C1 p1) {
        return new R2<>(p0, p1);
    }

    public static <C0, C1, C2> R3<C0, C1, C2> of(C0 p0, C1 p1, C2 p2) {
        return new R3<>(p0, p1, p2);
    }

    public static <C0, C1, C2, C3> R4<C0, C1, C2, C3> of(C0 p0, C1 p1, C2 p2, C3 p3) {
        return new R4<>(p0, p1, p2, p3);
    }

    public static <C0, C1, C2, C3, C4> R5<C0, C1, C2, C3, C4> of(
            C0 p0, C1 p1, C2 p2, C3 p3, C4 p4) {
        return new R5<>(p0, p1, p2, p3, p4);
    }

    public static class R2<C0, C1> extends Row<C0, C1, C1, C1, C1> {
        public R2(C0 a, C1 b) {
            items = new Object[] {a, b};
        }
    }

    public static class R3<C0, C1, C2> extends Row<C0, C1, C2, C2, C2> {
        public R3(C0 a, C1 b, C2 c) {
            items = new Object[] {a, b, c};
        }
    }

    public static class R4<C0, C1, C2, C3> extends Row<C0, C1, C2, C3, C3> {
        public R4(C0 a, C1 b, C2 c, C3 d) {
            items = new Object[] {a, b, c, d};
        }
    }

    public static class R5<C0, C1, C2, C3, C4> extends Row<C0, C1, C2, C3, C4> {
        public R5(C0 a, C1 b, C2 c, C3 d, C4 e) {
            items = new Object[] {a, b, c, d, e};
        }
    }

    public Row<C0, C1, C2, C3, C4> set0(C0 item) {
        return set(0, item);
    }

    public C0 get0() {
        return (C0) items[0];
    }

    public Row<C0, C1, C2, C3, C4> set1(C1 item) {
        return set(1, item);
    }

    public C1 get1() {
        return (C1) items[1];
    }

    public Row<C0, C1, C2, C3, C4> set2(C2 item) {
        return set(2, item);
    }

    public C2 get2() {
        return (C2) items[2];
    }

    public Row<C0, C1, C2, C3, C4> set3(C3 item) {
        return set(3, item);
    }

    public C3 get3() {
        return (C3) items[3];
    }

    public Row<C0, C1, C2, C3, C4> set4(C4 item) {
        return set(4, item);
    }

    public C4 get4() {
        return (C4) items[4];
    }

    protected Row<C0, C1, C2, C3, C4> set(int i, Object item) {
        if (frozen) {
            throw new UnsupportedOperationException("Attempt to modify frozen object");
        }
        items[i] = item;
        return this;
    }

    @Override
    public int hashCode() {
        int sum = items.length;
        for (Object item : items) {
            sum = sum * 37 + Utility.checkHash(item);
        }
        return sum;
    }

    @Override
    public boolean equals(Object other) {
        if (other == null) {
            return false;
        }
        if (this == other) {
            return true;
        }
        try {
            Row<C0, C1, C2, C3, C4> that = (Row<C0, C1, C2, C3, C4>) other;
            if (items.length != that.items.length) {
                return false;
            }
            int i = 0;
            for (Object item : items) {
                if (!Objects.equals(item, that.items[i++])) {
                    return false;
                }
            }
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    @Override
    public int compareTo(Object other) {
        int result;
        Row<C0, C1, C2, C3, C4> that = (Row<C0, C1, C2, C3, C4>) other;
        result = items.length - that.items.length;
        if (result != 0) {
            return result;
        }
        int i = 0;
        for (Object item : items) {
            result = Utility.checkCompare(((Comparable) item), ((Comparable) that.items[i++]));
            if (result != 0) {
                return result;
            }
        }
        return 0;
    }

    @Override
    public String toString() {
        StringBuilder result = new StringBuilder("[");
        boolean first = true;
        for (Object item : items) {
            if (first) {
                first = false;
            } else {
                result.append(", ");
            }
            result.append(item);
        }
        return result.append("]").toString();
    }

    @Override
    public boolean isFrozen() {
        return frozen;
    }

    @Override
    public Row<C0, C1, C2, C3, C4> freeze() {
        frozen = true;
        return this;
    }

    @Override
    public Row<C0, C1, C2, C3, C4> clone() {
        if (frozen) return this;
        try {
            Row<C0, C1, C2, C3, C4> result = (Row<C0, C1, C2, C3, C4>) super.clone();
            result.items = items.clone();
            return result;
        } catch (CloneNotSupportedException e) {
            return null;
        }
    }

    @Override
    public Row<C0, C1, C2, C3, C4> cloneAsThawed() {
        try {
            Row<C0, C1, C2, C3, C4> result = (Row<C0, C1, C2, C3, C4>) super.clone();
            items = items.clone();
            result.frozen = false;
            return result;
        } catch (CloneNotSupportedException e) {
            return null;
        }
    }
}