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