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