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