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