001/*
002 * This file is part of OCaml-Java runtime.
003 * Copyright (C) 2007-2013 Xavier Clerc.
004 *
005 * OCaml-Java runtime is free software; you can redistribute it and/or modify
006 * it under the terms of the GNU Lesser General Public License as published by
007 * the Free Software Foundation; either version 3 of the License, or
008 * (at your option) any later version.
009 *
010 * OCaml-Java runtime is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU Lesser General Public License for more details.
014 *
015 * You should have received a copy of the GNU Lesser General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018
019package org.ocamljava.runtime.wrappers;
020
021import org.ocamljava.runtime.values.Value;
022
023/**
024 * The {@code OCamlOption} class is the wrapper class for OCaml values of
025 * type {@code 'a * 'b * 'c * 'd * 'e * 'f}.
026 *
027 * @author <a href="mailto:xclerc@ocamljava.org">Xavier Clerc</a>
028 * @version 2.0
029 * @since 2.0
030 */
031public final class OCamlTuple6<T0 extends OCamlValue,
032                               T1 extends OCamlValue,
033                               T2 extends OCamlValue,
034                               T3 extends OCamlValue,
035                               T4 extends OCamlValue,
036                               T5 extends OCamlValue> extends OCamlValue {
037
038    /** Wrapper for nested value. */
039    private final Wrapper<T0> wrapper0;
040
041    /** Wrapper for nested value. */
042    private final Wrapper<T1> wrapper1;
043
044    /** Wrapper for nested value. */
045    private final Wrapper<T2> wrapper2;
046
047    /** Wrapper for nested value. */
048    private final Wrapper<T3> wrapper3;
049
050    /** Wrapper for nested value. */
051    private final Wrapper<T4> wrapper4;
052
053    /** Wrapper for nested value. */
054    private final Wrapper<T5> wrapper5;
055
056    /**
057     * Constructs a new instance wrapping the passed value.
058     * @param w0 wrapper for nested value - should not be {@code null}
059     * @param w1 wrapper for nested value - should not be {@code null}
060     * @param w2 wrapper for nested value - should not be {@code null}
061     * @param w3 wrapper for nested value - should not be {@code null}
062     * @param w4 wrapper for nested value - should not be {@code null}
063     * @param w5 wrapper for nested value - should not be {@code null}
064     * @param v value to wrap - should not be {@code null}
065     */
066    private OCamlTuple6(final Wrapper<T0> w0,
067                        final Wrapper<T1> w1,
068                        final Wrapper<T2> w2,
069                        final Wrapper<T3> w3,
070                        final Wrapper<T4> w4,
071                        final Wrapper<T5> w5,
072                        final Value v) {
073        super(v);
074        assert w0 != null : "null w0";
075        assert w1 != null : "null w1";
076        assert w2 != null : "null w2";
077        assert w3 != null : "null w3";
078        assert w4 != null : "null w4";
079        assert w5 != null : "null w5";
080        this.wrapper0 = w0;
081        this.wrapper1 = w1;
082        this.wrapper2 = w2;
083        this.wrapper3 = w3;
084        this.wrapper4 = w4;
085        this.wrapper5 = w5;
086    } // end constructor(Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>, Value)
087
088    /**
089     * {@inheritDoc}
090     */
091    @Override
092    public Wrapper<? extends OCamlTuple6<T0, T1, T2, T3, T4, T5>> getWrapper() {
093        return OCamlTuple6.wrapper(this.wrapper0,
094                                   this.wrapper1,
095                                   this.wrapper2,
096                                   this.wrapper3,
097                                   this.wrapper4,
098                                   this.wrapper5);
099    } // end method 'getWrapper()'
100
101    /**
102     * {@inheritDoc}
103     */
104    @Override
105    public Wrapper<? extends OCamlValue> getWrapper(final int idx) {
106        switch (idx) {
107        case 0: return this.wrapper0;
108        case 1: return this.wrapper1;
109        case 2: return this.wrapper2;
110        case 3: return this.wrapper3;
111        case 4: return this.wrapper4;
112        case 5: return this.wrapper5;
113        default: return OCamlUnit.WRAPPER;
114        } // end switch
115    } // end method 'getWrapper(int)'
116
117    /**
118     * Returns the first element of the wrapped value.
119     * @return the first element of the wrapped value
120     */
121    public T0 get0() {
122        return this.wrapper0.wrap(this.value.get0());
123    } // end method 'get0()'
124
125    /**
126     * Returns the second element of the wrapped value.
127     * @return the second element of the wrapped value
128     */
129    public T1 get1() {
130        return this.wrapper1.wrap(this.value.get1());
131    } // end method 'get1()'
132
133    /**
134     * Returns the third element of the wrapped value.
135     * @return the third element of the wrapped value
136     */
137    public T2 get2() {
138        return this.wrapper2.wrap(this.value.get2());
139    } // end method 'get2()'
140
141    /**
142     * Returns the fourth element of the wrapped value.
143     * @return the fourth element of the wrapped value
144     */
145    public T3 get3() {
146        return this.wrapper3.wrap(this.value.get3());
147    } // end method 'get3()'
148
149    /**
150     * Returns the fifth element of the wrapped value.
151     * @return the fifth element of the wrapped value
152     */
153    public T4 get4() {
154        return this.wrapper4.wrap(this.value.get4());
155    } // end method 'get4()'
156
157    /**
158     * Returns the sixth element of the wrapped value.
159     * @return the sixth element of the wrapped value
160     */
161    public T5 get5() {
162        return this.wrapper5.wrap(this.value.get5());
163    } // end method 'get5()'
164
165    /**
166     * {@inheritDoc}
167     */
168    @Override
169    public int hashCode() {
170        return this.value.get0().hashCode()
171            + this.value.get1().hashCode()
172            + this.value.get2().hashCode()
173            + this.value.get3().hashCode()
174            + this.value.get4().hashCode()
175            + this.value.get5().hashCode();
176    } // end method 'hashCode()'
177
178    /**
179     * {@inheritDoc}
180     */
181    @Override
182    public boolean equals(final Object obj) {
183        if (obj instanceof OCamlTuple6) {
184            final OCamlTuple6<?, ?, ?, ?, ?, ?> that = (OCamlTuple6) obj;
185            return this.value.get0().equals(that.value.get0())
186                && this.value.get1().equals(that.value.get1())
187                && this.value.get2().equals(that.value.get2())
188                && this.value.get3().equals(that.value.get3())
189                && this.value.get4().equals(that.value.get4())
190                && this.value.get5().equals(that.value.get5());
191        } else {
192            return false;
193        } // end if/else
194    } // end method 'equals(Object)'
195
196    /**
197     * {@inheritDoc}
198     */
199    @Override
200    public String toString() {
201        final StringBuilder sb = new StringBuilder();
202        sb.append("OCamlTuple6(");
203        sb.append(this.wrapper0.wrap(this.value.get0()).toString());
204        sb.append(", ");
205        sb.append(this.wrapper1.wrap(this.value.get1()).toString());
206        sb.append(", ");
207        sb.append(this.wrapper2.wrap(this.value.get2()).toString());
208        sb.append(", ");
209        sb.append(this.wrapper3.wrap(this.value.get3()).toString());
210        sb.append(", ");
211        sb.append(this.wrapper4.wrap(this.value.get4()).toString());
212        sb.append(", ");
213        sb.append(this.wrapper5.wrap(this.value.get5()).toString());
214        sb.append(")");
215        return sb.toString();
216    } // end method 'toString()'
217
218    /**
219     * Constructs a new {@code 'a * 'b * 'c * 'c * 'd * 'e * 'f} value, and wraps it.
220     * @param v0 first element of value to wrap
221     * @param v1 second element of value to wrap
222     * @param v2 third element of value to wrap
223     * @param v3 fourth element of value to wrap
224     * @param v4 fifth element of value to wrap
225     * @param v5 sixth element of value to wrap
226     * @return a new {@code OCamlTuple6} instance wrapping the passed values
227     */
228    @SuppressWarnings("unchecked")
229    public static <T0 extends OCamlValue,
230                   T1 extends OCamlValue,
231                   T2 extends OCamlValue,
232                   T3 extends OCamlValue,
233                   T4 extends OCamlValue,
234                   T5 extends OCamlValue>
235        OCamlTuple6<T0, T1, T2, T3, T4, T5> create(final T0 v0,
236                                                   final T1 v1,
237                                                   final T2 v2,
238                                                   final T3 v3,
239                                                   final T4 v4,
240                                                   final T5 v5) {
241        assert v0 != null : "null v0";
242        assert v1 != null : "null v1";
243        assert v2 != null : "null v2";
244        assert v3 != null : "null v3";
245        assert v4 != null : "null v4";
246        assert v5 != null : "null v5";
247        return new OCamlTuple6<T0, T1, T2, T3, T4, T5>((Wrapper<T0>) v0.getWrapper(),
248                                                       (Wrapper<T1>) v1.getWrapper(),
249                                                       (Wrapper<T2>) v2.getWrapper(),
250                                                       (Wrapper<T3>) v3.getWrapper(),
251                                                       (Wrapper<T4>) v4.getWrapper(),
252                                                       (Wrapper<T5>) v5.getWrapper(),
253                                                       Value.createBlock(0,
254                                                                         v0.value(),
255                                                                         v1.value(),
256                                                                         v2.value(),
257                                                                         v3.value(),
258                                                                         v4.value(),
259                                                                         v5.value()));
260    } // end method 'create(T0, T1, T2, T3, T4, T5)'
261
262    /**
263     * Wraps the passed value.
264     * @param w0 wrapper for nested value - should not be {@code null}
265     * @param w1 wrapper for nested value - should not be {@code null}
266     * @param w2 wrapper for nested value - should not be {@code null}
267     * @param w3 wrapper for nested value - should not be {@code null}
268     * @param w4 wrapper for nested value - should not be {@code null}
269     * @param w5 wrapper for nested value - should not be {@code null}
270     * @param v value to wrap - should not be {@code null}
271     * @return a new {@code OCamlTuple6} instance wrapping the passed value
272     */
273    public static <T0 extends OCamlValue,
274                   T1 extends OCamlValue,
275                   T2 extends OCamlValue,
276                   T3 extends OCamlValue,
277                   T4 extends OCamlValue,
278                   T5 extends OCamlValue>
279        OCamlTuple6<T0, T1, T2, T3, T4, T5> wrap(final Wrapper<T0> w0,
280                                                 final Wrapper<T1> w1,
281                                                 final Wrapper<T2> w2,
282                                                 final Wrapper<T3> w3,
283                                                 final Wrapper<T4> w4,
284                                                 final Wrapper<T5> w5,
285                                                 final Value v) {
286        assert w0 != null : "null w0";
287        assert w1 != null : "null w1";
288        assert w2 != null : "null w2";
289        assert w3 != null : "null w3";
290        assert w4 != null : "null w4";
291        assert w5 != null : "null w5";
292        assert v != null : "null v";
293        return new OCamlTuple6<T0, T1, T2, T3, T4, T5>(w0, w1, w2, w3, w4, w5, v);
294    } // end method 'wrap(Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>, Value)'
295
296    /**
297     * Returns a wrapper for {@code OCamlTuple6} values.
298     * @param w0 wrapper for nested value - should not be {@code null}
299     * @param w1 wrapper for nested value - should not be {@code null}
300     * @param w2 wrapper for nested value - should not be {@code null}
301     * @param w3 wrapper for nested value - should not be {@code null}
302     * @param w4 wrapper for nested value - should not be {@code null}
303     * @param w5 wrapper for nested value - should not be {@code null}
304     * @return a wrapper for {@code OCamlTuple6} values
305     */
306    @SuppressWarnings("unchecked")
307    public static <T0 extends OCamlValue,
308                   T1 extends OCamlValue,
309                   T2 extends OCamlValue,
310                   T3 extends OCamlValue,
311                   T4 extends OCamlValue,
312                   T5 extends OCamlValue>
313        Wrapper<? extends OCamlTuple6<T0, T1, T2, T3, T4, T5>> wrapper(final Wrapper<T0> w0,
314                                                                       final Wrapper<T1> w1,
315                                                                       final Wrapper<T2> w2,
316                                                                       final Wrapper<T3> w3,
317                                                                       final Wrapper<T4> w4,
318                                                                       final Wrapper<T5> w5) {
319        return new ComposedWrapper<OCamlTuple6<T0, T1, T2, T3, T4, T5>>(w0, w1, w2, w3, w4, w5) {
320            /**
321             * {@inheritDoc}
322             */
323            @Override
324                public OCamlTuple6<T0, T1, T2, T3, T4, T5> wrap(final Value v) {
325                return new OCamlTuple6<T0, T1, T2, T3, T4, T5>(w0, w1, w2, w3, w4, w5, v);
326            } // end method 'wrap(Value)'
327        }; // end anonymous inner-class
328    } // end method 'wrapper(Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>)'
329
330} // end class 'OCamlTuple6'