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