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 java.lang.invoke.MethodHandle;
022import java.lang.invoke.MethodHandles;
023import java.lang.invoke.MethodType;
024
025import org.ocamljava.runtime.values.Value;
026
027/**
028 * The {@code OCamlFunction10} class represent an OCaml function taking ten
029 * parameter.
030 *
031 * @author <a href="mailto:xclerc@ocamljava.org">Xavier Clerc</a>
032 * @version 2.0
033 * @since 2.0
034 */
035public abstract class OCamlFunction10<T0 extends OCamlValue,
036                                      T1 extends OCamlValue,
037                                      T2 extends OCamlValue,
038                                      T3 extends OCamlValue,
039                                      T4 extends OCamlValue,
040                                      T5 extends OCamlValue,
041                                      T6 extends OCamlValue,
042                                      T7 extends OCamlValue,
043                                      T8 extends OCamlValue,
044                                      T9 extends OCamlValue,
045                                      TR extends OCamlValue> extends OCamlValue {
046
047    /** Wrapper for first parameter. */
048    protected final Wrapper<T0> wrapper0;
049
050    /** Wrapper for second parameter. */
051    protected final Wrapper<T1> wrapper1;
052
053    /** Wrapper for third parameter. */
054    protected final Wrapper<T2> wrapper2;
055
056    /** Wrapper for fourth parameter. */
057    protected final Wrapper<T3> wrapper3;
058
059    /** Wrapper for fifth parameter. */
060    protected final Wrapper<T4> wrapper4;
061
062    /** Wrapper for sixth parameter. */
063    protected final Wrapper<T5> wrapper5;
064
065    /** Wrapper for seventh parameter. */
066    protected final Wrapper<T6> wrapper6;
067
068    /** Wrapper for eighth parameter. */
069    protected final Wrapper<T7> wrapper7;
070
071    /** Wrapper for ninth parameter. */
072    protected final Wrapper<T8> wrapper8;
073
074    /** Wrapper for tenth parameter. */
075    protected final Wrapper<T9> wrapper9;
076
077    /** Wrapper for return value. */
078    protected final Wrapper<TR> wrapperr;
079
080    /** Method handle for function actually called from the OCaml runtime. */
081    private static final MethodHandle METHOD_HANDLE;
082
083    static {
084        MethodHandle mh;
085        try {
086            final MethodHandles.Lookup lookup = MethodHandles.lookup();
087            final MethodType mt = MethodType.methodType(Value.class,
088                                                        Value.class,
089                                                        Value.class,
090                                                        Value.class,
091                                                        Value.class,
092                                                        Value.class,
093                                                        Value.class,
094                                                        Value.class,
095                                                        Value.class,
096                                                        Value.class,
097                                                        Value.class);
098            mh = lookup.findVirtual(OCamlFunction10Caller.class, "called", mt);
099        } catch (final NoSuchMethodException | IllegalAccessException e) {
100            assert false : "OCamlFunction10: unable to get method handle";
101            mh = null;
102        } // end try/catch
103        METHOD_HANDLE = mh;
104    } // end static block
105
106    /**
107     * Constructs a new instance. <br/>
108     * To be used by Java implementations.
109     * @param w0 wrapper for first parameter - should not be {@code null}
110     * @param w1 wrapper for second parameter - should not be {@code null}
111     * @param w2 wrapper for third parameter - should not be {@code null}
112     * @param w3 wrapper for fourth parameter - should not be {@code null}
113     * @param w4 wrapper for fifth parameter - should not be {@code null}
114     * @param w5 wrapper for sixth parameter - should not be {@code null}
115     * @param w6 wrapper for seventh parameter - should not be {@code null}
116     * @param w7 wrapper for eigth parameter - should not be {@code null}
117     * @param w8 wrapper for ninth parameter - should not be {@code null}
118     * @param w9 wrapper for tenth parameter - should not be {@code null}
119     * @param wr wrapper for result - should not be {@code null}
120     */
121    public OCamlFunction10(final Wrapper<T0> w0,
122                           final Wrapper<T1> w1,
123                           final Wrapper<T2> w2,
124                           final Wrapper<T3> w3,
125                           final Wrapper<T4> w4,
126                           final Wrapper<T5> w5,
127                           final Wrapper<T6> w6,
128                           final Wrapper<T7> w7,
129                           final Wrapper<T8> w8,
130                           final Wrapper<T9> w9,
131                           final Wrapper<TR> wr) {
132        super(Value.UNIT);
133        assert w0 != null : "null w0";
134        assert w1 != null : "null w1";
135        assert w2 != null : "null w2";
136        assert w3 != null : "null w3";
137        assert w4 != null : "null w4";
138        assert w5 != null : "null w5";
139        assert w6 != null : "null w6";
140        assert w7 != null : "null w7";
141        assert w8 != null : "null w8";
142        assert w8 != null : "null w9";
143        assert wr != null : "null wr";
144        this.wrapper0 = w0;
145        this.wrapper1 = w1;
146        this.wrapper2 = w2;
147        this.wrapper3 = w3;
148        this.wrapper4 = w4;
149        this.wrapper5 = w5;
150        this.wrapper6 = w6;
151        this.wrapper7 = w7;
152        this.wrapper8 = w8;
153        this.wrapper9 = w9;
154        this.wrapperr = wr;
155    } // end constructor(Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>, Wrapper<T6>, Wrapper<T7>, Wrapper<T8>, Wrapper<T9>, Wrapper<TR>)
156
157    /**
158     * Constructs a new instance. <br/>
159     * To be used by Java implementations.
160     */
161    @SuppressWarnings("unchecked")
162    public OCamlFunction10() {
163        this((Wrapper<T0>) OCamlValue.WRAPPER,
164             (Wrapper<T1>) OCamlValue.WRAPPER,
165             (Wrapper<T2>) OCamlValue.WRAPPER,
166             (Wrapper<T3>) OCamlValue.WRAPPER,
167             (Wrapper<T4>) OCamlValue.WRAPPER,
168             (Wrapper<T5>) OCamlValue.WRAPPER,
169             (Wrapper<T6>) OCamlValue.WRAPPER,
170             (Wrapper<T7>) OCamlValue.WRAPPER,
171             (Wrapper<T8>) OCamlValue.WRAPPER,
172             (Wrapper<T9>) OCamlValue.WRAPPER,
173             (Wrapper<TR>) OCamlValue.WRAPPER);
174    } // end empty constructor
175
176    /**
177     * Constructs a new instance from a value. <br/>
178     * To be used by OCaml implementations.
179     * @param w0 wrapper for first parameter - should not be {@code null}
180     * @param w1 wrapper for second parameter - should not be {@code null}
181     * @param w2 wrapper for third parameter - should not be {@code null}
182     * @param w3 wrapper for fourth parameter - should not be {@code null}
183     * @param w4 wrapper for fifth parameter - should not be {@code null}
184     * @param w5 wrapper for fifth parameter - should not be {@code null}
185     * @param w6 wrapper for fifth parameter - should not be {@code null}
186     * @param w7 wrapper for fifth parameter - should not be {@code null}
187     * @param w8 wrapper for fifth parameter - should not be {@code null}
188     * @param w9 wrapper for fifth parameter - should not be {@code null}
189     * @param wr wrapper for result - should not be {@code null}
190     */
191    OCamlFunction10(final Value v,
192                    final Wrapper<T0> w0,
193                    final Wrapper<T1> w1,
194                    final Wrapper<T2> w2,
195                    final Wrapper<T3> w3,
196                    final Wrapper<T4> w4,
197                    final Wrapper<T5> w5,
198                    final Wrapper<T6> w6,
199                    final Wrapper<T7> w7,
200                    final Wrapper<T8> w8,
201                    final Wrapper<T9> w9,
202                    final Wrapper<TR> wr) {
203        super(v);
204        assert w0 != null : "null w0";
205        assert w1 != null : "null w1";
206        assert w2 != null : "null w2";
207        assert w3 != null : "null w3";
208        assert w4 != null : "null w4";
209        assert w5 != null : "null w5";
210        assert w6 != null : "null w6";
211        assert w7 != null : "null w7";
212        assert w8 != null : "null w8";
213        assert w9 != null : "null w9";
214        assert wr != null : "null wr";
215        this.wrapper0 = w0;
216        this.wrapper1 = w1;
217        this.wrapper2 = w2;
218        this.wrapper3 = w3;
219        this.wrapper4 = w4;
220        this.wrapper5 = w5;
221        this.wrapper6 = w6;
222        this.wrapper7 = w7;
223        this.wrapper8 = w8;
224        this.wrapper9 = w9;
225        this.wrapperr = wr;
226    } // end constructor(Value, Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>, Wrapper<T6>, Wrapper<T7>, Wrapper<T8>, Wrapper<T9>, Wrapper<TR>)
227
228    /**
229     * {@inheritDoc}
230     */
231    @Override
232    public final Wrapper<? extends OCamlFunction10<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, TR>> getWrapper() {
233        return OCamlFunction10.wrapper(this.wrapper0,
234                                       this.wrapper1,
235                                       this.wrapper2,
236                                       this.wrapper3,
237                                       this.wrapper4,
238                                       this.wrapper5,
239                                       this.wrapper6,
240                                       this.wrapper7,
241                                       this.wrapper8,
242                                       this.wrapper9,
243                                       this.wrapperr);
244    } // end method 'getWrapper()'
245
246    /**
247     * {@inheritDoc}
248     */
249    @Override
250    public Wrapper<? extends OCamlValue> getWrapper(final int idx) {
251        switch (idx) {
252        case 0: return this.wrapper0;
253        case 1: return this.wrapper1;
254        case 2: return this.wrapper2;
255        case 3: return this.wrapper3;
256        case 4: return this.wrapper4;
257        case 5: return this.wrapper5;
258        case 6: return this.wrapper6;
259        case 7: return this.wrapper7;
260        case 8: return this.wrapper8;
261        case 9: return this.wrapper9;
262        case 10: return this.wrapperr;
263        default: return OCamlUnit.WRAPPER;
264        } // end switch
265    } // end method 'getWrapper(int)'
266
267    /**
268     * Returns the closure to be executed from the OCaml runtime.
269     * @param w0 wrapper for first parameter - should not be {@code null}
270     * @param w1 wrapper for second parameter - should not be {@code null}
271     * @param w2 wrapper for third parameter - should not be {@code null}
272     * @param w3 wrapper for fourth parameter - should not be {@code null}
273     * @param w4 wrapper for fifth parameter - should not be {@code null}
274     * @param w5 wrapper for sixth parameter - should not be {@code null}
275     * @param w6 wrapper for seventh parameter - should not be {@code null}
276     * @param w7 wrapper for eighth parameter - should not be {@code null}
277     * @param w8 wrapper for ninth parameter - should not be {@code null}
278     * @param w9 wrapper for tenth parameter - should not be {@code null}
279     * @return the closure to be executed on the OCaml side
280     */
281    public Value getClosure(final Wrapper<T0> w0,
282                            final Wrapper<T1> w1,
283                            final Wrapper<T2> w2,
284                            final Wrapper<T3> w3,
285                            final Wrapper<T4> w4,
286                            final Wrapper<T5> w5,
287                            final Wrapper<T6> w6,
288                            final Wrapper<T7> w7,
289                            final Wrapper<T8> w8,
290                            final Wrapper<T9> w9) {
291        assert w0 != null : "null w0";
292        assert w1 != null : "null w1";
293        assert w2 != null : "null w2";
294        assert w3 != null : "null w3";
295        assert w4 != null : "null w4";
296        assert w5 != null : "null w5";
297        assert w6 != null : "null w6";
298        assert w7 != null : "null w7";
299        assert w8 != null : "null w8";
300        assert w9 != null : "null w9";
301        final OCamlFunction10Caller<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, TR> ofc = new OCamlFunction10Caller<>(w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, this);
302        return Value.createClosure(OCamlFunction10.METHOD_HANDLE.bindTo(ofc), 10);
303    } // end method 'getClosure(Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>, Wrapper<T6>, Wrapper<T7>, Wrapper<T8>, Wrapper<T9>)'
304
305    /**
306     * The actual implementation of the function
307     * @param p0 first parameter - should not be {@code null}
308     * @param p1 second parameter - should not be {@code null}
309     * @param p2 third parameter - should not be {@code null}
310     * @param p3 fourth parameter - should not be {@code null}
311     * @param p4 fifth parameter - should not be {@code null}
312     * @param p5 sixth parameter - should not be {@code null}
313     * @param p6 seventh parameter - should not be {@code null}
314     * @param p7 eighth parameter - should not be {@code null}
315     * @param p8 ninth parameter - should not be {@code null}
316     * @param p9 tenth parameter - should not be {@code null}
317     * @throws OCamlException if function fails
318     */
319    public abstract TR execute(final T0 p0,
320                               final T1 p1,
321                               final T2 p2,
322                               final T3 p3,
323                               final T4 p4,
324                               final T5 p5,
325                               final T6 p6,
326                               final T7 p7,
327                               final T8 p8,
328                               final T9 p9)
329        throws OCamlException;
330
331    /**
332     * {@inheritDoc}
333     */
334    @Override
335    public final int hashCode() {
336        return super.hashCode();
337    } // end method 'hashCode()'
338
339    /**
340     * {@inheritDoc}
341     */
342    @Override
343    public final boolean equals(final Object obj) {
344        if (obj instanceof OCamlFunction10) {
345            final OCamlFunction10<?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?> that = (OCamlFunction10) obj;
346            return this == that;
347        } else {
348            return false;
349        } // end if/else
350    } // end method 'equals(Object)'
351
352    /**
353     * {@inheritDoc}
354     */
355    @Override
356    public final String toString() {
357        return "OCamlFunction10(...)";
358    } // end method 'toString()'
359
360    /**
361     * Wraps the passed value.
362     * @param w0 wrapper for first parameter - should not be {@code null}
363     * @param w1 wrapper for second parameter - should not be {@code null}
364     * @param w2 wrapper for third parameter - should not be {@code null}
365     * @param w3 wrapper for fourth parameter - should not be {@code null}
366     * @param w4 wrapper for fifth parameter - should not be {@code null}
367     * @param w5 wrapper for sixth parameter - should not be {@code null}
368     * @param w6 wrapper for seventh parameter - should not be {@code null}
369     * @param w7 wrapper for eighth parameter - should not be {@code null}
370     * @param w8 wrapper for ninth parameter - should not be {@code null}
371     * @param w9 wrapper for tenth parameter - should not be {@code null}
372     * @param wr wrapper for result - should not be {@code null}
373     * @param v value to wrap - should not be {@code null}
374     * @return a new {@code OCamlFunction10} instance wrapping the passed value
375     */
376    public static <T0 extends OCamlValue,
377                   T1 extends OCamlValue,
378                   T2 extends OCamlValue,
379                   T3 extends OCamlValue,
380                   T4 extends OCamlValue,
381                   T5 extends OCamlValue,
382                   T6 extends OCamlValue,
383                   T7 extends OCamlValue,
384                   T8 extends OCamlValue,
385                   T9 extends OCamlValue,
386                   TR extends OCamlValue>
387        OCamlFunction10<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, TR> wrap(final Wrapper<T0> w0,
388                                                                         final Wrapper<T1> w1,
389                                                                         final Wrapper<T2> w2,
390                                                                         final Wrapper<T3> w3,
391                                                                         final Wrapper<T4> w4,
392                                                                         final Wrapper<T5> w5,
393                                                                         final Wrapper<T6> w6,
394                                                                         final Wrapper<T7> w7,
395                                                                         final Wrapper<T8> w8,
396                                                                         final Wrapper<T9> w9,
397                                                                         final Wrapper<TR> wr,
398                                                                         final Value v) {
399        assert w0 != null : "null w0";
400        assert w1 != null : "null w1";
401        assert w2 != null : "null w2";
402        assert w3 != null : "null w3";
403        assert w4 != null : "null w4";
404        assert w5 != null : "null w5";
405        assert w6 != null : "null w6";
406        assert w7 != null : "null w7";
407        assert w8 != null : "null w8";
408        assert w9 != null : "null w9";
409        assert wr != null : "null wr";
410        assert v != null : "null v";
411        return new OCamlFunction10Impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, TR>(w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, wr, v);
412    } // end method 'wrap(Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>, Wrapper<T6>, Wrapper<T7>, Wrapper<T8>, Wrapper<T9>, Wrapper<TR>, Value)'
413
414    /**
415     * Returns a wrapper for {@code OCamlFunction10} values.
416     * @param w0 wrapper for first parameter - should not be {@code null}
417     * @param w1 wrapper for second parameter - should not be {@code null}
418     * @param w2 wrapper for third parameter - should not be {@code null}
419     * @param w3 wrapper for fourth parameter - should not be {@code null}
420     * @param w4 wrapper for fifth parameter - should not be {@code null}
421     * @param w5 wrapper for sixth parameter - should not be {@code null}
422     * @param w6 wrapper for seventh parameter - should not be {@code null}
423     * @param w7 wrapper for eighth parameter - should not be {@code null}
424     * @param w8 wrapper for ninth parameter - should not be {@code null}
425     * @param w9 wrapper for tenth parameter - should not be {@code null}
426     * @param wr wrapper for result - should not be {@code null}
427     * @return a wrapper for {@code OCamlFunction5} values
428     */
429    @SuppressWarnings("unchecked")
430    public static <T0 extends OCamlValue,
431                   T1 extends OCamlValue,
432                   T2 extends OCamlValue,
433                   T3 extends OCamlValue,
434                   T4 extends OCamlValue,
435                   T5 extends OCamlValue,
436                   T6 extends OCamlValue,
437                   T7 extends OCamlValue,
438                   T8 extends OCamlValue,
439                   T9 extends OCamlValue,
440                   TR extends OCamlValue>
441        Wrapper<? extends OCamlFunction10<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, TR>> wrapper(final Wrapper<T0> w0,
442                                                                                               final Wrapper<T1> w1,
443                                                                                               final Wrapper<T2> w2,
444                                                                                               final Wrapper<T3> w3,
445                                                                                               final Wrapper<T4> w4,
446                                                                                               final Wrapper<T5> w5,
447                                                                                               final Wrapper<T6> w6,
448                                                                                               final Wrapper<T7> w7,
449                                                                                               final Wrapper<T8> w8,
450                                                                                               final Wrapper<T9> w9,
451                                                                                               final Wrapper<TR> wr) {
452        assert w0 != null : "null w0";
453        assert w1 != null : "null w1";
454        assert w2 != null : "null w2";
455        assert w3 != null : "null w3";
456        assert w4 != null : "null w4";
457        assert w5 != null : "null w5";
458        assert w6 != null : "null w6";
459        assert w7 != null : "null w7";
460        assert w8 != null : "null w8";
461        assert w9 != null : "null w9";
462        assert wr != null : "null wr";
463        return new ComposedWrapper<OCamlFunction10<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, TR>>(w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, wr) {
464            /**
465             * {@inheritDoc}
466             */
467            @Override
468                public OCamlFunction10<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, TR> wrap(final Value v) {
469                return new OCamlFunction10Impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, TR>(w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, wr, v);
470            } // end method 'wrap(Value)'
471        }; // end anonymous inner-class
472    } // end method 'wrapper(Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>, Wrapper<T6>, Wrapper<T7>, Wrapper<T8>, Wrapper<T9>, Wrapper<TR>)'
473
474} // end class 'OCamlFunction10'