7961 private static MethodType tableSwitchChecks(MethodHandle defaultCase, MethodHandle[] caseActions) {
7962 if (caseActions.length == 0)
7963 throw new IllegalArgumentException("Not enough cases: " + Arrays.toString(caseActions));
7964
7965 MethodType expectedType = defaultCase.type();
7966
7967 if (!(expectedType.parameterCount() >= 1) || expectedType.parameterType(0) != int.class)
7968 throw new IllegalArgumentException(
7969 "Case actions must have int as leading parameter: " + Arrays.toString(caseActions));
7970
7971 for (MethodHandle mh : caseActions) {
7972 Objects.requireNonNull(mh);
7973 if (mh.type() != expectedType)
7974 throw new IllegalArgumentException(
7975 "Case actions must have the same type: " + Arrays.toString(caseActions));
7976 }
7977
7978 return expectedType;
7979 }
7980
7981 /**
7982 * Creates a var handle object, which can be used to dereference a {@linkplain java.lang.foreign.MemorySegment memory segment}
7983 * at a given byte offset, using the provided value layout.
7984 *
7985 * <p>The provided layout specifies the {@linkplain ValueLayout#carrier() carrier type},
7986 * the {@linkplain ValueLayout#byteSize() byte size},
7987 * the {@linkplain ValueLayout#byteAlignment() byte alignment} and the {@linkplain ValueLayout#order() byte order}
7988 * associated with the returned var handle.
7989 *
7990 * <p>The list of coordinate types associated with the returned var handle is {@code (MemorySegment, long)},
7991 * where the {@code long} coordinate type corresponds to byte offset into the given memory segment coordinate.
7992 * Thus, the returned var handle accesses bytes at an offset in a given memory segment, composing bytes to or from
7993 * a value of the var handle type. Moreover, the access operation will honor the endianness and the
7994 * alignment constraints expressed in the provided layout.
7995 *
7996 * <p>As an example, consider the memory layout expressed by a {@link GroupLayout} instance constructed as follows:
7997 * {@snippet lang="java" :
7998 * GroupLayout seq = java.lang.foreign.MemoryLayout.structLayout(
7999 * MemoryLayout.paddingLayout(4),
8000 * ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN).withName("value")
8001 * );
8002 * }
8003 * To access the member layout named {@code value}, we can construct a memory segment view var handle as follows:
8004 * {@snippet lang="java" :
8005 * VarHandle handle = MethodHandles.memorySegmentViewVarHandle(ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN)); //(MemorySegment, long) -> int
8006 * handle = MethodHandles.insertCoordinates(handle, 1, 4); //(MemorySegment) -> int
8007 * }
8008 *
8009 * @apiNote The resulting var handle features certain <i>access mode restrictions</i>,
8010 * which are common to all memory segment view var handles. A memory segment view var handle is associated
8011 * with an access size {@code S} and an alignment constraint {@code B}
8012 * (both expressed in bytes). We say that a memory access operation is <em>fully aligned</em> if it occurs
8013 * at a memory address {@code A} which is compatible with both alignment constraints {@code S} and {@code B}.
8014 * If access is fully aligned then following access modes are supported and are
8015 * guaranteed to support atomic access:
8016 * <ul>
8017 * <li>read write access modes for all {@code T}, with the exception of
8018 * access modes {@code get} and {@code set} for {@code long} and
8019 * {@code double} on 32-bit platforms.
8020 * <li>atomic update access modes for {@code int}, {@code long},
8021 * {@code float}, {@code double} or {@link MemorySegment}.
8022 * (Future major platform releases of the JDK may support additional
8023 * types for certain currently unsupported access modes.)
8024 * <li>numeric atomic update access modes for {@code int}, {@code long} and {@link MemorySegment}.
8025 * (Future major platform releases of the JDK may support additional
8026 * numeric types for certain currently unsupported access modes.)
8027 * <li>bitwise atomic update access modes for {@code int}, {@code long} and {@link MemorySegment}.
8028 * (Future major platform releases of the JDK may support additional
8029 * numeric types for certain currently unsupported access modes.)
8030 * </ul>
8031 *
8032 * If {@code T} is {@code float}, {@code double} or {@link MemorySegment} then atomic
8033 * update access modes compare values using their bitwise representation
8034 * (see {@link Float#floatToRawIntBits},
8035 * {@link Double#doubleToRawLongBits} and {@link MemorySegment#address()}, respectively).
8036 * <p>
8037 * Alternatively, a memory access operation is <em>partially aligned</em> if it occurs at a memory address {@code A}
8038 * which is only compatible with the alignment constraint {@code B}; in such cases, access for anything other than the
8039 * {@code get} and {@code set} access modes will result in an {@code IllegalStateException}. If access is partially aligned,
8040 * atomic access is only guaranteed with respect to the largest power of two that divides the GCD of {@code A} and {@code S}.
8041 * <p>
8042 * In all other cases, we say that a memory access operation is <em>misaligned</em>; in such cases an
8043 * {@code IllegalStateException} is thrown, irrespective of the access mode being used.
8044 * <p>
8045 * Finally, if {@code T} is {@code MemorySegment} all write access modes throw {@link IllegalArgumentException}
8046 * unless the value to be written is a {@linkplain MemorySegment#isNative() native} memory segment.
8047 *
8048 * @param layout the value layout for which a memory access handle is to be obtained.
8049 * @return the new memory segment view var handle.
8050 * @throws NullPointerException if {@code layout} is {@code null}.
8051 * @see MemoryLayout#varHandle(MemoryLayout.PathElement...)
8052 * @since 19
8053 */
8054 @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
8055 public static VarHandle memorySegmentViewVarHandle(ValueLayout layout) {
8056 Objects.requireNonNull(layout);
8057 return Utils.makeSegmentViewVarHandle(layout);
8058 }
8059
8060 /**
8061 * Adapts a target var handle by pre-processing incoming and outgoing values using a pair of filter functions.
8062 * <p>
8063 * When calling e.g. {@link VarHandle#set(Object...)} on the resulting var handle, the incoming value (of type {@code T}, where
8064 * {@code T} is the <em>last</em> parameter type of the first filter function) is processed using the first filter and then passed
8065 * to the target var handle.
8066 * Conversely, when calling e.g. {@link VarHandle#get(Object...)} on the resulting var handle, the return value obtained from
8067 * the target var handle (of type {@code T}, where {@code T} is the <em>last</em> parameter type of the second filter function)
8068 * is processed using the second filter and returned to the caller. More advanced access mode types, such as
8069 * {@link VarHandle.AccessMode#COMPARE_AND_EXCHANGE} might apply both filters at the same time.
8070 * <p>
8071 * For the boxing and unboxing filters to be well-formed, their types must be of the form {@code (A... , S) -> T} and
8072 * {@code (A... , T) -> S}, respectively, where {@code T} is the type of the target var handle. If this is the case,
8073 * the resulting var handle will have type {@code S} and will feature the additional coordinates {@code A...} (which
8074 * will be appended to the coordinates of the target var handle).
8075 * <p>
8076 * If the boxing and unboxing filters throw any checked exceptions when invoked, the resulting var handle will
8077 * throw an {@link IllegalStateException}.
8078 * <p>
8079 * The resulting var handle will feature the same access modes (see {@link VarHandle.AccessMode}) and
8080 * atomic access guarantees as those featured by the target var handle.
8081 *
8082 * @param target the target var handle
8083 * @param filterToTarget a filter to convert some type {@code S} into the type of {@code target}
8084 * @param filterFromTarget a filter to convert the type of {@code target} to some type {@code S}
8085 * @return an adapter var handle which accepts a new type, performing the provided boxing/unboxing conversions.
8086 * @throws IllegalArgumentException if {@code filterFromTarget} and {@code filterToTarget} are not well-formed, that is, they have types
8087 * other than {@code (A... , S) -> T} and {@code (A... , T) -> S}, respectively, where {@code T} is the type of the target var handle,
8088 * or if it's determined that either {@code filterFromTarget} or {@code filterToTarget} throws any checked exceptions.
8089 * @throws NullPointerException if any of the arguments is {@code null}.
8090 * @since 19
8091 */
8092 @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
8093 public static VarHandle filterValue(VarHandle target, MethodHandle filterToTarget, MethodHandle filterFromTarget) {
8094 return VarHandles.filterValue(target, filterToTarget, filterFromTarget);
8095 }
8096
8097 /**
8098 * Adapts a target var handle by pre-processing incoming coordinate values using unary filter functions.
8099 * <p>
8100 * When calling e.g. {@link VarHandle#get(Object...)} on the resulting var handle, the incoming coordinate values
8101 * starting at position {@code pos} (of type {@code C1, C2 ... Cn}, where {@code C1, C2 ... Cn} are the return types
8102 * of the unary filter functions) are transformed into new values (of type {@code S1, S2 ... Sn}, where {@code S1, S2 ... Sn} are the
8103 * parameter types of the unary filter functions), and then passed (along with any coordinate that was left unaltered
8104 * by the adaptation) to the target var handle.
8105 * <p>
8106 * For the coordinate filters to be well-formed, their types must be of the form {@code S1 -> T1, S2 -> T1 ... Sn -> Tn},
8107 * where {@code T1, T2 ... Tn} are the coordinate types starting at position {@code pos} of the target var handle.
8108 * <p>
8109 * If any of the filters throws a checked exception when invoked, the resulting var handle will
8110 * throw an {@link IllegalStateException}.
8111 * <p>
8112 * The resulting var handle will feature the same access modes (see {@link VarHandle.AccessMode}) and
8113 * atomic access guarantees as those featured by the target var handle.
8114 *
8115 * @param target the target var handle
8116 * @param pos the position of the first coordinate to be transformed
8117 * @param filters the unary functions which are used to transform coordinates starting at position {@code pos}
8118 * @return an adapter var handle which accepts new coordinate types, applying the provided transformation
8119 * to the new coordinate values.
8120 * @throws IllegalArgumentException if the handles in {@code filters} are not well-formed, that is, they have types
8121 * other than {@code S1 -> T1, S2 -> T2, ... Sn -> Tn} where {@code T1, T2 ... Tn} are the coordinate types starting
8122 * at position {@code pos} of the target var handle, if {@code pos} is not between 0 and the target var handle coordinate arity, inclusive,
8123 * or if more filters are provided than the actual number of coordinate types available starting at {@code pos},
8124 * or if it's determined that any of the filters throws any checked exceptions.
8125 * @throws NullPointerException if any of the arguments is {@code null} or {@code filters} contains {@code null}.
8126 * @since 19
8127 */
8128 @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
8129 public static VarHandle filterCoordinates(VarHandle target, int pos, MethodHandle... filters) {
8130 return VarHandles.filterCoordinates(target, pos, filters);
8131 }
8132
8133 /**
8134 * Provides a target var handle with one or more <em>bound coordinates</em>
8135 * in advance of the var handle's invocation. As a consequence, the resulting var handle will feature less
8136 * coordinate types than the target var handle.
8137 * <p>
8138 * When calling e.g. {@link VarHandle#get(Object...)} on the resulting var handle, incoming coordinate values
8139 * are joined with bound coordinate values, and then passed to the target var handle.
8140 * <p>
8141 * For the bound coordinates to be well-formed, their types must be {@code T1, T2 ... Tn },
8142 * where {@code T1, T2 ... Tn} are the coordinate types starting at position {@code pos} of the target var handle.
8143 * <p>
8144 * The resulting var handle will feature the same access modes (see {@link VarHandle.AccessMode}) and
8145 * atomic access guarantees as those featured by the target var handle.
8146 *
8147 * @param target the var handle to invoke after the bound coordinates are inserted
8148 * @param pos the position of the first coordinate to be inserted
8149 * @param values the series of bound coordinates to insert
8150 * @return an adapter var handle which inserts additional coordinates,
8151 * before calling the target var handle
8152 * @throws IllegalArgumentException if {@code pos} is not between 0 and the target var handle coordinate arity, inclusive,
8153 * or if more values are provided than the actual number of coordinate types available starting at {@code pos}.
8154 * @throws ClassCastException if the bound coordinates in {@code values} are not well-formed, that is, they have types
8155 * other than {@code T1, T2 ... Tn }, where {@code T1, T2 ... Tn} are the coordinate types starting at position {@code pos}
8156 * of the target var handle.
8157 * @throws NullPointerException if any of the arguments is {@code null} or {@code values} contains {@code null}.
8158 * @since 19
8159 */
8160 @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
8161 public static VarHandle insertCoordinates(VarHandle target, int pos, Object... values) {
8162 return VarHandles.insertCoordinates(target, pos, values);
8163 }
8164
8165 /**
8166 * Provides a var handle which adapts the coordinate values of the target var handle, by re-arranging them
8167 * so that the new coordinates match the provided ones.
8168 * <p>
8169 * The given array controls the reordering.
8170 * Call {@code #I} the number of incoming coordinates (the value
8171 * {@code newCoordinates.size()}), and call {@code #O} the number
8172 * of outgoing coordinates (the number of coordinates associated with the target var handle).
8173 * Then the length of the reordering array must be {@code #O},
8174 * and each element must be a non-negative number less than {@code #I}.
8175 * For every {@code N} less than {@code #O}, the {@code N}-th
8176 * outgoing coordinate will be taken from the {@code I}-th incoming
8177 * coordinate, where {@code I} is {@code reorder[N]}.
8178 * <p>
8179 * No coordinate value conversions are applied.
8180 * The type of each incoming coordinate, as determined by {@code newCoordinates},
8181 * must be identical to the type of the corresponding outgoing coordinate
8182 * in the target var handle.
8183 * <p>
8184 * The reordering array need not specify an actual permutation.
8185 * An incoming coordinate will be duplicated if its index appears
8186 * more than once in the array, and an incoming coordinate will be dropped
8187 * if its index does not appear in the array.
8188 * <p>
8189 * The resulting var handle will feature the same access modes (see {@link VarHandle.AccessMode}) and
8190 * atomic access guarantees as those featured by the target var handle.
8191 * @param target the var handle to invoke after the coordinates have been reordered
8192 * @param newCoordinates the new coordinate types
8193 * @param reorder an index array which controls the reordering
8194 * @return an adapter var handle which re-arranges the incoming coordinate values,
8195 * before calling the target var handle
8196 * @throws IllegalArgumentException if the index array length is not equal to
8197 * the number of coordinates of the target var handle, or if any index array element is not a valid index for
8198 * a coordinate of {@code newCoordinates}, or if two corresponding coordinate types in
8199 * the target var handle and in {@code newCoordinates} are not identical.
8200 * @throws NullPointerException if any of the arguments is {@code null} or {@code newCoordinates} contains {@code null}.
8201 * @since 19
8202 */
8203 @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
8204 public static VarHandle permuteCoordinates(VarHandle target, List<Class<?>> newCoordinates, int... reorder) {
8205 return VarHandles.permuteCoordinates(target, newCoordinates, reorder);
8206 }
8207
8208 /**
8209 * Adapts a target var handle by pre-processing
8210 * a sub-sequence of its coordinate values with a filter (a method handle).
8211 * The pre-processed coordinates are replaced by the result (if any) of the
8212 * filter function and the target var handle is then called on the modified (usually shortened)
8213 * coordinate list.
8214 * <p>
8215 * If {@code R} is the return type of the filter, then:
8216 * <ul>
8217 * <li>if {@code R} <em>is not</em> {@code void}, the target var handle must have a coordinate of type {@code R} in
8218 * position {@code pos}. The parameter types of the filter will replace the coordinate type at position {@code pos}
8219 * of the target var handle. When the returned var handle is invoked, it will be as if the filter is invoked first,
8220 * and its result is passed in place of the coordinate at position {@code pos} in a downstream invocation of the
8221 * target var handle.</li>
8222 * <li> if {@code R} <em>is</em> {@code void}, the parameter types (if any) of the filter will be inserted in the
8223 * coordinate type list of the target var handle at position {@code pos}. In this case, when the returned var handle
8225 * downstream invocation of the target var handle.</li>
8226 * </ul>
8227 * <p>
8228 * If any of the filters throws a checked exception when invoked, the resulting var handle will
8229 * throw an {@link IllegalStateException}.
8230 * <p>
8231 * The resulting var handle will feature the same access modes (see {@link VarHandle.AccessMode}) and
8232 * atomic access guarantees as those featured by the target var handle.
8233 *
8234 * @param target the var handle to invoke after the coordinates have been filtered
8235 * @param pos the position in the coordinate list of the target var handle where the filter is to be inserted
8236 * @param filter the filter method handle
8237 * @return an adapter var handle which filters the incoming coordinate values,
8238 * before calling the target var handle
8239 * @throws IllegalArgumentException if the return type of {@code filter}
8240 * is not void, and it is not the same as the {@code pos} coordinate of the target var handle,
8241 * if {@code pos} is not between 0 and the target var handle coordinate arity, inclusive,
8242 * if the resulting var handle's type would have <a href="MethodHandle.html#maxarity">too many coordinates</a>,
8243 * or if it's determined that {@code filter} throws any checked exceptions.
8244 * @throws NullPointerException if any of the arguments is {@code null}.
8245 * @since 19
8246 */
8247 @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
8248 public static VarHandle collectCoordinates(VarHandle target, int pos, MethodHandle filter) {
8249 return VarHandles.collectCoordinates(target, pos, filter);
8250 }
8251
8252 /**
8253 * Returns a var handle which will discard some dummy coordinates before delegating to the
8254 * target var handle. As a consequence, the resulting var handle will feature more
8255 * coordinate types than the target var handle.
8256 * <p>
8257 * The {@code pos} argument may range between zero and <i>N</i>, where <i>N</i> is the arity of the
8258 * target var handle's coordinate types. If {@code pos} is zero, the dummy coordinates will precede
8259 * the target's real arguments; if {@code pos} is <i>N</i> they will come after.
8260 * <p>
8261 * The resulting var handle will feature the same access modes (see {@link VarHandle.AccessMode}) and
8262 * atomic access guarantees as those featured by the target var handle.
8263 *
8264 * @param target the var handle to invoke after the dummy coordinates are dropped
8265 * @param pos position of the first coordinate to drop (zero for the leftmost)
8266 * @param valueTypes the type(s) of the coordinate(s) to drop
8267 * @return an adapter var handle which drops some dummy coordinates,
8268 * before calling the target var handle
8269 * @throws IllegalArgumentException if {@code pos} is not between 0 and the target var handle coordinate arity, inclusive.
8270 * @throws NullPointerException if any of the arguments is {@code null} or {@code valueTypes} contains {@code null}.
8271 * @since 19
8272 */
8273 @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
8274 public static VarHandle dropCoordinates(VarHandle target, int pos, Class<?>... valueTypes) {
8275 return VarHandles.dropCoordinates(target, pos, valueTypes);
8276 }
8277 }
|
7961 private static MethodType tableSwitchChecks(MethodHandle defaultCase, MethodHandle[] caseActions) {
7962 if (caseActions.length == 0)
7963 throw new IllegalArgumentException("Not enough cases: " + Arrays.toString(caseActions));
7964
7965 MethodType expectedType = defaultCase.type();
7966
7967 if (!(expectedType.parameterCount() >= 1) || expectedType.parameterType(0) != int.class)
7968 throw new IllegalArgumentException(
7969 "Case actions must have int as leading parameter: " + Arrays.toString(caseActions));
7970
7971 for (MethodHandle mh : caseActions) {
7972 Objects.requireNonNull(mh);
7973 if (mh.type() != expectedType)
7974 throw new IllegalArgumentException(
7975 "Case actions must have the same type: " + Arrays.toString(caseActions));
7976 }
7977
7978 return expectedType;
7979 }
7980
7981 /**
7982 * Adapts a target var handle by pre-processing incoming and outgoing values using a pair of filter functions.
7983 * <p>
7984 * When calling e.g. {@link VarHandle#set(Object...)} on the resulting var handle, the incoming value (of type {@code T}, where
7985 * {@code T} is the <em>last</em> parameter type of the first filter function) is processed using the first filter and then passed
7986 * to the target var handle.
7987 * Conversely, when calling e.g. {@link VarHandle#get(Object...)} on the resulting var handle, the return value obtained from
7988 * the target var handle (of type {@code T}, where {@code T} is the <em>last</em> parameter type of the second filter function)
7989 * is processed using the second filter and returned to the caller. More advanced access mode types, such as
7990 * {@link VarHandle.AccessMode#COMPARE_AND_EXCHANGE} might apply both filters at the same time.
7991 * <p>
7992 * For the boxing and unboxing filters to be well-formed, their types must be of the form {@code (A... , S) -> T} and
7993 * {@code (A... , T) -> S}, respectively, where {@code T} is the type of the target var handle. If this is the case,
7994 * the resulting var handle will have type {@code S} and will feature the additional coordinates {@code A...} (which
7995 * will be appended to the coordinates of the target var handle).
7996 * <p>
7997 * If the boxing and unboxing filters throw any checked exceptions when invoked, the resulting var handle will
7998 * throw an {@link IllegalStateException}.
7999 * <p>
8000 * The resulting var handle will feature the same access modes (see {@link VarHandle.AccessMode}) and
8001 * atomic access guarantees as those featured by the target var handle.
8002 *
8003 * @param target the target var handle
8004 * @param filterToTarget a filter to convert some type {@code S} into the type of {@code target}
8005 * @param filterFromTarget a filter to convert the type of {@code target} to some type {@code S}
8006 * @return an adapter var handle which accepts a new type, performing the provided boxing/unboxing conversions.
8007 * @throws IllegalArgumentException if {@code filterFromTarget} and {@code filterToTarget} are not well-formed, that is, they have types
8008 * other than {@code (A... , S) -> T} and {@code (A... , T) -> S}, respectively, where {@code T} is the type of the target var handle,
8009 * or if it's determined that either {@code filterFromTarget} or {@code filterToTarget} throws any checked exceptions.
8010 * @throws NullPointerException if any of the arguments is {@code null}.
8011 * @since 22
8012 */
8013 public static VarHandle filterValue(VarHandle target, MethodHandle filterToTarget, MethodHandle filterFromTarget) {
8014 return VarHandles.filterValue(target, filterToTarget, filterFromTarget);
8015 }
8016
8017 /**
8018 * Adapts a target var handle by pre-processing incoming coordinate values using unary filter functions.
8019 * <p>
8020 * When calling e.g. {@link VarHandle#get(Object...)} on the resulting var handle, the incoming coordinate values
8021 * starting at position {@code pos} (of type {@code C1, C2 ... Cn}, where {@code C1, C2 ... Cn} are the return types
8022 * of the unary filter functions) are transformed into new values (of type {@code S1, S2 ... Sn}, where {@code S1, S2 ... Sn} are the
8023 * parameter types of the unary filter functions), and then passed (along with any coordinate that was left unaltered
8024 * by the adaptation) to the target var handle.
8025 * <p>
8026 * For the coordinate filters to be well-formed, their types must be of the form {@code S1 -> T1, S2 -> T1 ... Sn -> Tn},
8027 * where {@code T1, T2 ... Tn} are the coordinate types starting at position {@code pos} of the target var handle.
8028 * <p>
8029 * If any of the filters throws a checked exception when invoked, the resulting var handle will
8030 * throw an {@link IllegalStateException}.
8031 * <p>
8032 * The resulting var handle will feature the same access modes (see {@link VarHandle.AccessMode}) and
8033 * atomic access guarantees as those featured by the target var handle.
8034 *
8035 * @param target the target var handle
8036 * @param pos the position of the first coordinate to be transformed
8037 * @param filters the unary functions which are used to transform coordinates starting at position {@code pos}
8038 * @return an adapter var handle which accepts new coordinate types, applying the provided transformation
8039 * to the new coordinate values.
8040 * @throws IllegalArgumentException if the handles in {@code filters} are not well-formed, that is, they have types
8041 * other than {@code S1 -> T1, S2 -> T2, ... Sn -> Tn} where {@code T1, T2 ... Tn} are the coordinate types starting
8042 * at position {@code pos} of the target var handle, if {@code pos} is not between 0 and the target var handle coordinate arity, inclusive,
8043 * or if more filters are provided than the actual number of coordinate types available starting at {@code pos},
8044 * or if it's determined that any of the filters throws any checked exceptions.
8045 * @throws NullPointerException if any of the arguments is {@code null} or {@code filters} contains {@code null}.
8046 * @since 22
8047 */
8048 public static VarHandle filterCoordinates(VarHandle target, int pos, MethodHandle... filters) {
8049 return VarHandles.filterCoordinates(target, pos, filters);
8050 }
8051
8052 /**
8053 * Provides a target var handle with one or more <em>bound coordinates</em>
8054 * in advance of the var handle's invocation. As a consequence, the resulting var handle will feature less
8055 * coordinate types than the target var handle.
8056 * <p>
8057 * When calling e.g. {@link VarHandle#get(Object...)} on the resulting var handle, incoming coordinate values
8058 * are joined with bound coordinate values, and then passed to the target var handle.
8059 * <p>
8060 * For the bound coordinates to be well-formed, their types must be {@code T1, T2 ... Tn },
8061 * where {@code T1, T2 ... Tn} are the coordinate types starting at position {@code pos} of the target var handle.
8062 * <p>
8063 * The resulting var handle will feature the same access modes (see {@link VarHandle.AccessMode}) and
8064 * atomic access guarantees as those featured by the target var handle.
8065 *
8066 * @param target the var handle to invoke after the bound coordinates are inserted
8067 * @param pos the position of the first coordinate to be inserted
8068 * @param values the series of bound coordinates to insert
8069 * @return an adapter var handle which inserts additional coordinates,
8070 * before calling the target var handle
8071 * @throws IllegalArgumentException if {@code pos} is not between 0 and the target var handle coordinate arity, inclusive,
8072 * or if more values are provided than the actual number of coordinate types available starting at {@code pos}.
8073 * @throws ClassCastException if the bound coordinates in {@code values} are not well-formed, that is, they have types
8074 * other than {@code T1, T2 ... Tn }, where {@code T1, T2 ... Tn} are the coordinate types starting at position {@code pos}
8075 * of the target var handle.
8076 * @throws NullPointerException if any of the arguments is {@code null} or {@code values} contains {@code null}.
8077 * @since 22
8078 */
8079 public static VarHandle insertCoordinates(VarHandle target, int pos, Object... values) {
8080 return VarHandles.insertCoordinates(target, pos, values);
8081 }
8082
8083 /**
8084 * Provides a var handle which adapts the coordinate values of the target var handle, by re-arranging them
8085 * so that the new coordinates match the provided ones.
8086 * <p>
8087 * The given array controls the reordering.
8088 * Call {@code #I} the number of incoming coordinates (the value
8089 * {@code newCoordinates.size()}), and call {@code #O} the number
8090 * of outgoing coordinates (the number of coordinates associated with the target var handle).
8091 * Then the length of the reordering array must be {@code #O},
8092 * and each element must be a non-negative number less than {@code #I}.
8093 * For every {@code N} less than {@code #O}, the {@code N}-th
8094 * outgoing coordinate will be taken from the {@code I}-th incoming
8095 * coordinate, where {@code I} is {@code reorder[N]}.
8096 * <p>
8097 * No coordinate value conversions are applied.
8098 * The type of each incoming coordinate, as determined by {@code newCoordinates},
8099 * must be identical to the type of the corresponding outgoing coordinate
8100 * in the target var handle.
8101 * <p>
8102 * The reordering array need not specify an actual permutation.
8103 * An incoming coordinate will be duplicated if its index appears
8104 * more than once in the array, and an incoming coordinate will be dropped
8105 * if its index does not appear in the array.
8106 * <p>
8107 * The resulting var handle will feature the same access modes (see {@link VarHandle.AccessMode}) and
8108 * atomic access guarantees as those featured by the target var handle.
8109 * @param target the var handle to invoke after the coordinates have been reordered
8110 * @param newCoordinates the new coordinate types
8111 * @param reorder an index array which controls the reordering
8112 * @return an adapter var handle which re-arranges the incoming coordinate values,
8113 * before calling the target var handle
8114 * @throws IllegalArgumentException if the index array length is not equal to
8115 * the number of coordinates of the target var handle, or if any index array element is not a valid index for
8116 * a coordinate of {@code newCoordinates}, or if two corresponding coordinate types in
8117 * the target var handle and in {@code newCoordinates} are not identical.
8118 * @throws NullPointerException if any of the arguments is {@code null} or {@code newCoordinates} contains {@code null}.
8119 * @since 22
8120 */
8121 public static VarHandle permuteCoordinates(VarHandle target, List<Class<?>> newCoordinates, int... reorder) {
8122 return VarHandles.permuteCoordinates(target, newCoordinates, reorder);
8123 }
8124
8125 /**
8126 * Adapts a target var handle by pre-processing
8127 * a sub-sequence of its coordinate values with a filter (a method handle).
8128 * The pre-processed coordinates are replaced by the result (if any) of the
8129 * filter function and the target var handle is then called on the modified (usually shortened)
8130 * coordinate list.
8131 * <p>
8132 * If {@code R} is the return type of the filter, then:
8133 * <ul>
8134 * <li>if {@code R} <em>is not</em> {@code void}, the target var handle must have a coordinate of type {@code R} in
8135 * position {@code pos}. The parameter types of the filter will replace the coordinate type at position {@code pos}
8136 * of the target var handle. When the returned var handle is invoked, it will be as if the filter is invoked first,
8137 * and its result is passed in place of the coordinate at position {@code pos} in a downstream invocation of the
8138 * target var handle.</li>
8139 * <li> if {@code R} <em>is</em> {@code void}, the parameter types (if any) of the filter will be inserted in the
8140 * coordinate type list of the target var handle at position {@code pos}. In this case, when the returned var handle
8142 * downstream invocation of the target var handle.</li>
8143 * </ul>
8144 * <p>
8145 * If any of the filters throws a checked exception when invoked, the resulting var handle will
8146 * throw an {@link IllegalStateException}.
8147 * <p>
8148 * The resulting var handle will feature the same access modes (see {@link VarHandle.AccessMode}) and
8149 * atomic access guarantees as those featured by the target var handle.
8150 *
8151 * @param target the var handle to invoke after the coordinates have been filtered
8152 * @param pos the position in the coordinate list of the target var handle where the filter is to be inserted
8153 * @param filter the filter method handle
8154 * @return an adapter var handle which filters the incoming coordinate values,
8155 * before calling the target var handle
8156 * @throws IllegalArgumentException if the return type of {@code filter}
8157 * is not void, and it is not the same as the {@code pos} coordinate of the target var handle,
8158 * if {@code pos} is not between 0 and the target var handle coordinate arity, inclusive,
8159 * if the resulting var handle's type would have <a href="MethodHandle.html#maxarity">too many coordinates</a>,
8160 * or if it's determined that {@code filter} throws any checked exceptions.
8161 * @throws NullPointerException if any of the arguments is {@code null}.
8162 * @since 22
8163 */
8164 public static VarHandle collectCoordinates(VarHandle target, int pos, MethodHandle filter) {
8165 return VarHandles.collectCoordinates(target, pos, filter);
8166 }
8167
8168 /**
8169 * Returns a var handle which will discard some dummy coordinates before delegating to the
8170 * target var handle. As a consequence, the resulting var handle will feature more
8171 * coordinate types than the target var handle.
8172 * <p>
8173 * The {@code pos} argument may range between zero and <i>N</i>, where <i>N</i> is the arity of the
8174 * target var handle's coordinate types. If {@code pos} is zero, the dummy coordinates will precede
8175 * the target's real arguments; if {@code pos} is <i>N</i> they will come after.
8176 * <p>
8177 * The resulting var handle will feature the same access modes (see {@link VarHandle.AccessMode}) and
8178 * atomic access guarantees as those featured by the target var handle.
8179 *
8180 * @param target the var handle to invoke after the dummy coordinates are dropped
8181 * @param pos position of the first coordinate to drop (zero for the leftmost)
8182 * @param valueTypes the type(s) of the coordinate(s) to drop
8183 * @return an adapter var handle which drops some dummy coordinates,
8184 * before calling the target var handle
8185 * @throws IllegalArgumentException if {@code pos} is not between 0 and the target var handle coordinate arity, inclusive.
8186 * @throws NullPointerException if any of the arguments is {@code null} or {@code valueTypes} contains {@code null}.
8187 * @since 22
8188 */
8189 public static VarHandle dropCoordinates(VarHandle target, int pos, Class<?>... valueTypes) {
8190 return VarHandles.dropCoordinates(target, pos, valueTypes);
8191 }
8192 }
|