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 * 'g * 'h}.
026 *
027 * @author <a href="mailto:xclerc@ocamljava.org">Xavier Clerc</a>
028 * @version 2.0
029 * @since 2.0
030 */
031public final class OCamlTuple8<T0 extends OCamlValue,
032                               T1 extends OCamlValue,
033                               T2 extends OCamlValue,
034                               T3 extends OCamlValue,
035                               T4 extends OCamlValue,
036                               T5 extends OCamlValue,
037                               T6 extends OCamlValue,
038                               T7 extends OCamlValue> extends OCamlValue {
039
040    /** Wrapper for nested value. */
041    private final Wrapper<T0> wrapper0;
042
043    /** Wrapper for nested value. */
044    private final Wrapper<T1> wrapper1;
045
046    /** Wrapper for nested value. */
047    private final Wrapper<T2> wrapper2;
048
049    /** Wrapper for nested value. */
050    private final Wrapper<T3> wrapper3;
051
052    /** Wrapper for nested value. */
053    private final Wrapper<T4> wrapper4;
054
055    /** Wrapper for nested value. */
056    private final Wrapper<T5> wrapper5;
057
058    /** Wrapper for nested value. */
059    private final Wrapper<T6> wrapper6;
060
061    /** Wrapper for nested value. */
062    private final Wrapper<T7> wrapper7;
063
064    /**
065     * Constructs a new instance wrapping the passed value.
066     * @param w0 wrapper for nested value - should not be {@code null}
067     * @param w1 wrapper for nested value - should not be {@code null}
068     * @param w2 wrapper for nested value - should not be {@code null}
069     * @param w3 wrapper for nested value - should not be {@code null}
070     * @param w4 wrapper for nested value - should not be {@code null}
071     * @param w5 wrapper for nested value - should not be {@code null}
072     * @param w6 wrapper for nested value - should not be {@code null}
073     * @param w7 wrapper for nested value - should not be {@code null}
074     * @param v value to wrap - should not be {@code null}
075     */
076    private OCamlTuple8(final Wrapper<T0> w0,
077                        final Wrapper<T1> w1,
078                        final Wrapper<T2> w2,
079                        final Wrapper<T3> w3,
080                        final Wrapper<T4> w4,
081                        final Wrapper<T5> w5,
082                        final Wrapper<T6> w6,
083                        final Wrapper<T7> w7,
084                        final Value v) {
085        super(v);
086        assert w0 != null : "null w0";
087        assert w1 != null : "null w1";
088        assert w2 != null : "null w2";
089        assert w3 != null : "null w3";
090        assert w4 != null : "null w4";
091        assert w5 != null : "null w5";
092        assert w6 != null : "null w6";
093        assert w7 != null : "null w7";
094        this.wrapper0 = w0;
095        this.wrapper1 = w1;
096        this.wrapper2 = w2;
097        this.wrapper3 = w3;
098        this.wrapper4 = w4;
099        this.wrapper5 = w5;
100        this.wrapper6 = w6;
101        this.wrapper7 = w7;
102    } // end constructor(Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>, Wrapper<T6>, Wrapper<T7>, Value)
103
104    /**
105     * {@inheritDoc}
106     */
107    @Override
108    public Wrapper<? extends OCamlTuple8<T0, T1, T2, T3, T4, T5, T6, T7>> getWrapper() {
109        return OCamlTuple8.wrapper(this.wrapper0,
110                                   this.wrapper1,
111                                   this.wrapper2,
112                                   this.wrapper3,
113                                   this.wrapper4,
114                                   this.wrapper5,
115                                   this.wrapper6,
116                                   this.wrapper7);
117    } // end method 'getWrapper()'
118
119    /**
120     * {@inheritDoc}
121     */
122    @Override
123    public Wrapper<? extends OCamlValue> getWrapper(final int idx) {
124        switch (idx) {
125        case 0: return this.wrapper0;
126        case 1: return this.wrapper1;
127        case 2: return this.wrapper2;
128        case 3: return this.wrapper3;
129        case 4: return this.wrapper4;
130        case 5: return this.wrapper5;
131        case 6: return this.wrapper6;
132        case 7: return this.wrapper7;
133        default: return OCamlUnit.WRAPPER;
134        } // end switch
135    } // end method 'getWrapper(int)'
136
137    /**
138     * Returns the first element of the wrapped value.
139     * @return the first element of the wrapped value
140     */
141    public T0 get0() {
142        return this.wrapper0.wrap(this.value.get0());
143    } // end method 'get0()'
144
145    /**
146     * Returns the second element of the wrapped value.
147     * @return the second element of the wrapped value
148     */
149    public T1 get1() {
150        return this.wrapper1.wrap(this.value.get1());
151    } // end method 'get1()'
152
153    /**
154     * Returns the third element of the wrapped value.
155     * @return the third element of the wrapped value
156     */
157    public T2 get2() {
158        return this.wrapper2.wrap(this.value.get2());
159    } // end method 'get2()'
160
161    /**
162     * Returns the fourth element of the wrapped value.
163     * @return the fourth element of the wrapped value
164     */
165    public T3 get3() {
166        return this.wrapper3.wrap(this.value.get3());
167    } // end method 'get3()'
168
169    /**
170     * Returns the fifth element of the wrapped value.
171     * @return the fifth element of the wrapped value
172     */
173    public T4 get4() {
174        return this.wrapper4.wrap(this.value.get4());
175    } // end method 'get4()'
176
177    /**
178     * Returns the sixth element of the wrapped value.
179     * @return the sixth element of the wrapped value
180     */
181    public T5 get5() {
182        return this.wrapper5.wrap(this.value.get5());
183    } // end method 'get5()'
184
185    /**
186     * Returns the seventh element of the wrapped value.
187     * @return the seventh element of the wrapped value
188     */
189    public T6 get6() {
190        return this.wrapper6.wrap(this.value.get6());
191    } // end method 'get6()'
192
193    /**
194     * Returns the eighth element of the wrapped value.
195     * @return the eighth element of the wrapped value
196     */
197    public T7 get7() {
198        return this.wrapper7.wrap(this.value.get7());
199    } // end method 'get7()'
200
201    /**
202     * {@inheritDoc}
203     */
204    @Override
205    public int hashCode() {
206        return this.value.get0().hashCode()
207            + this.value.get1().hashCode()
208            + this.value.get2().hashCode()
209            + this.value.get3().hashCode()
210            + this.value.get4().hashCode()
211            + this.value.get5().hashCode()
212            + this.value.get6().hashCode()
213            + this.value.get7().hashCode();
214    } // end method 'hashCode()'
215
216    /**
217     * {@inheritDoc}
218     */
219    @Override
220    public boolean equals(final Object obj) {
221        if (obj instanceof OCamlTuple8) {
222            final OCamlTuple8<?, ?, ?, ?, ?, ?, ?, ?> that = (OCamlTuple8) obj;
223            return this.value.get0().equals(that.value.get0())
224                && this.value.get1().equals(that.value.get1())
225                && this.value.get2().equals(that.value.get2())
226                && this.value.get3().equals(that.value.get3())
227                && this.value.get4().equals(that.value.get4())
228                && this.value.get5().equals(that.value.get5())
229                && this.value.get6().equals(that.value.get6())
230                && this.value.get7().equals(that.value.get7());
231        } else {
232            return false;
233        } // end if/else
234    } // end method 'equals(Object)'
235
236    /**
237     * {@inheritDoc}
238     */
239    @Override
240    public String toString() {
241        final StringBuilder sb = new StringBuilder();
242        sb.append("OCamlTuple8(");
243        sb.append(this.wrapper0.wrap(this.value.get0()).toString());
244        sb.append(", ");
245        sb.append(this.wrapper1.wrap(this.value.get1()).toString());
246        sb.append(", ");
247        sb.append(this.wrapper2.wrap(this.value.get2()).toString());
248        sb.append(", ");
249        sb.append(this.wrapper3.wrap(this.value.get3()).toString());
250        sb.append(", ");
251        sb.append(this.wrapper4.wrap(this.value.get4()).toString());
252        sb.append(", ");
253        sb.append(this.wrapper5.wrap(this.value.get5()).toString());
254        sb.append(", ");
255        sb.append(this.wrapper6.wrap(this.value.get6()).toString());
256        sb.append(", ");
257        sb.append(this.wrapper7.wrap(this.value.get7()).toString());
258        sb.append(")");
259        return sb.toString();
260    } // end method 'toString()'
261
262    /**
263     * Constructs a new {@code 'a * 'b * 'c * 'c * 'd * 'e * 'f * 'g * 'h} value, and wraps it.
264     * @param v0 first element of value to wrap
265     * @param v1 second element of value to wrap
266     * @param v2 third element of value to wrap
267     * @param v3 fourth element of value to wrap
268     * @param v4 fifth element of value to wrap
269     * @param v5 sixth element of value to wrap
270     * @param v6 seventh element of value to wrap
271     * @param v7 eighth element of value to wrap
272     * @return a new {@code OCamlTuple8} instance wrapping the passed values
273     */
274    @SuppressWarnings("unchecked")
275    public static <T0 extends OCamlValue,
276                   T1 extends OCamlValue,
277                   T2 extends OCamlValue,
278                   T3 extends OCamlValue,
279                   T4 extends OCamlValue,
280                   T5 extends OCamlValue,
281                   T6 extends OCamlValue,
282                   T7 extends OCamlValue>
283        OCamlTuple8<T0, T1, T2, T3, T4, T5, T6, T7> create(final T0 v0,
284                                                           final T1 v1,
285                                                           final T2 v2,
286                                                           final T3 v3,
287                                                           final T4 v4,
288                                                           final T5 v5,
289                                                           final T6 v6,
290                                                           final T7 v7) {
291        assert v0 != null : "null v0";
292        assert v1 != null : "null v1";
293        assert v2 != null : "null v2";
294        assert v3 != null : "null v3";
295        assert v4 != null : "null v4";
296        assert v5 != null : "null v5";
297        assert v6 != null : "null v6";
298        assert v7 != null : "null v7";
299        return new OCamlTuple8<T0, T1, T2, T3, T4, T5, T6, T7>((Wrapper<T0>) v0.getWrapper(),
300                                                               (Wrapper<T1>) v1.getWrapper(),
301                                                               (Wrapper<T2>) v2.getWrapper(),
302                                                               (Wrapper<T3>) v3.getWrapper(),
303                                                               (Wrapper<T4>) v4.getWrapper(),
304                                                               (Wrapper<T5>) v5.getWrapper(),
305                                                               (Wrapper<T6>) v6.getWrapper(),
306                                                               (Wrapper<T7>) v7.getWrapper(),
307                                                               Value.createBlock(0,
308                                                                                 v0.value(),
309                                                                                 v1.value(),
310                                                                                 v2.value(),
311                                                                                 v3.value(),
312                                                                                 v4.value(),
313                                                                                 v5.value(),
314                                                                                 v6.value(),
315                                                                                 v7.value()));
316    } // end method 'create(T0, T1, T2, T3, T4, T5, T6, T7)'
317
318    /**
319     * Wraps the passed value.
320     * @param w0 wrapper for nested value - should not be {@code null}
321     * @param w1 wrapper for nested value - should not be {@code null}
322     * @param w2 wrapper for nested value - should not be {@code null}
323     * @param w3 wrapper for nested value - should not be {@code null}
324     * @param w4 wrapper for nested value - should not be {@code null}
325     * @param w5 wrapper for nested value - should not be {@code null}
326     * @param w6 wrapper for nested value - should not be {@code null}
327     * @param w7 wrapper for nested value - should not be {@code null}
328     * @param v value to wrap - should not be {@code null}
329     * @return a new {@code OCamlTuple8} instance wrapping the passed value
330     */
331    public static <T0 extends OCamlValue,
332                   T1 extends OCamlValue,
333                   T2 extends OCamlValue,
334                   T3 extends OCamlValue,
335                   T4 extends OCamlValue,
336                   T5 extends OCamlValue,
337                   T6 extends OCamlValue,
338                   T7 extends OCamlValue>
339        OCamlTuple8<T0, T1, T2, T3, T4, T5, T6, T7> wrap(final Wrapper<T0> w0,
340                                                         final Wrapper<T1> w1,
341                                                         final Wrapper<T2> w2,
342                                                         final Wrapper<T3> w3,
343                                                         final Wrapper<T4> w4,
344                                                         final Wrapper<T5> w5,
345                                                         final Wrapper<T6> w6,
346                                                         final Wrapper<T7> w7,
347                                                         final Value v) {
348        assert w0 != null : "null w0";
349        assert w1 != null : "null w1";
350        assert w2 != null : "null w2";
351        assert w3 != null : "null w3";
352        assert w4 != null : "null w4";
353        assert w5 != null : "null w5";
354        assert w6 != null : "null w6";
355        assert w7 != null : "null w7";
356        assert v != null : "null v";
357        return new OCamlTuple8<T0, T1, T2, T3, T4, T5, T6, T7>(w0, w1, w2, w3, w4, w5, w6, w7, v);
358    } // end method 'wrap(Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>, Wrapper<T6>, Wrapper<T7>, Value)'
359
360    /**
361     * Returns a wrapper for {@code OCamlTuple8} values.
362     * @param w0 wrapper for nested value - should not be {@code null}
363     * @param w1 wrapper for nested value - should not be {@code null}
364     * @param w2 wrapper for nested value - should not be {@code null}
365     * @param w3 wrapper for nested value - should not be {@code null}
366     * @param w4 wrapper for nested value - should not be {@code null}
367     * @param w5 wrapper for nested value - should not be {@code null}
368     * @param w6 wrapper for nested value - should not be {@code null}
369     * @param w7 wrapper for nested value - should not be {@code null}
370     * @return a wrapper for {@code OCamlTuple8} values
371     */
372    @SuppressWarnings("unchecked")
373    public static <T0 extends OCamlValue,
374                   T1 extends OCamlValue,
375                   T2 extends OCamlValue,
376                   T3 extends OCamlValue,
377                   T4 extends OCamlValue,
378                   T5 extends OCamlValue,
379                   T6 extends OCamlValue,
380                   T7 extends OCamlValue>
381        Wrapper<? extends OCamlTuple8<T0, T1, T2, T3, T4, T5, T6, T7>> wrapper(final Wrapper<T0> w0,
382                                                                               final Wrapper<T1> w1,
383                                                                               final Wrapper<T2> w2,
384                                                                               final Wrapper<T3> w3,
385                                                                               final Wrapper<T4> w4,
386                                                                               final Wrapper<T5> w5,
387                                                                               final Wrapper<T6> w6,
388                                                                               final Wrapper<T7> w7) {
389        return new ComposedWrapper<OCamlTuple8<T0, T1, T2, T3, T4, T5, T6, T7>>(w0, w1, w2, w3, w4, w5, w6, w7) {
390            /**
391             * {@inheritDoc}
392             */
393            @Override
394                public OCamlTuple8<T0, T1, T2, T3, T4, T5, T6, T7> wrap(final Value v) {
395                return new OCamlTuple8<T0, T1, T2, T3, T4, T5, T6, T7>(w0, w1, w2, w3, w4, w5, w6, w7, v);
396            } // end method 'wrap(Value)'
397        }; // end anonymous inner-class
398    } // end method 'wrapper(Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>, Wrapper<T6>, Wrapper<T7>)'
399
400} // end class 'OCamlTuple8'