Package Summary Overview Summary

### class:MemoryLayout [NONE]
All Known Subinterfaces: `AddressLayout`, `GroupLayout`, `PaddingLayout`, `SequenceLayout`, `StructLayout`, `UnionLayout`, `ValueLayout`, `ValueLayout.OfBoolean`, `ValueLayout.OfByte`, `ValueLayout.OfChar`, `ValueLayout.OfDouble`, `ValueLayout.OfFloat`, `ValueLayout.OfInt`, `ValueLayout.OfLong`, `ValueLayout.OfShort` public sealed interface MemoryLayout permits SequenceLayout, GroupLayout, PaddingLayout, ValueLayout A memory layout describes the contents of a memory segment. There are two leaves in the layout hierarchy, value layouts , which are used to represent values of given size and kind and padding layouts which are used, as the name suggests, to represent a portion of a memory segment whose contents should be ignored, and which are primarily present for alignment reasons. Some common value layout constants, such as `ValueLayout.JAVA_INT` and `ValueLayout.JAVA_FLOAT_UNALIGNED` are defined in the `ValueLayout` class. A special kind of value layout, namely an address layout , is used to model values that denote the address of a region of memory. More complex layouts can be derived from simpler ones: a sequence layout denotes a homogeneous repetition of zero or more occurrences of an element layout; a group layout denotes a heterogeneous aggregation of zero or more member layouts. Group layouts come in two flavors: struct layouts , where member layouts are laid out one after the other, and union layouts where member layouts are laid out at the same starting offset. Layouts can be optionally associated with a name. A layout name can be referred to when constructing layout paths . Consider the following struct declaration in C:
    typedef struct {
        char kind;
        int value;
    } TaggedValues[5];
The above declaration can be modelled using a layout object, as follows:
    SequenceLayout taggedValues = MemoryLayout.sequenceLayout(5,
        MemoryLayout.structLayout(
            ValueLayout.JAVA_BYTE.withName("kind"),
            MemoryLayout.paddingLayout(3),
            ValueLayout.JAVA_INT.withName("value")
        )
    ).withName("TaggedValues");
## Characteristics of memory layouts All layouts have a size (expressed in bytes), which is defined as follows: The size of a value layout is determined by the ValueLayout.carrier() associated with the value layout. That is, the constant `ValueLayout.JAVA_INT` has carrier `int`, and size of 4 bytes; The size of an address layout is platform-dependent. That is, the constant `ValueLayout.ADDRESS` has size of 8 bytes on a 64-bit platform; The size of a padding layout is always provided explicitly, on construction; The size of a sequence layout whose element layout is E and element count is L, is the size of E, multiplied by L; The size of a struct layout with member layouts M1, M2, ... Mn whose sizes are S1, S2, ... Sn, respectively, is S1 + S2 + ... + Sn ; The size of a union layout U with member layouts M1, M2, ... Mn whose sizes are S1, S2, ... Sn, respectively, is max(S1, S2, ... Sn). Furthermore, all layouts have a natural alignment (expressed in bytes) which is defined as follows: The natural alignment of a padding layout is 1; The natural alignment of a value layout whose size is N is N; The natural alignment of a sequence layout whose element layout is E is the alignment of E; The natural alignment of a group layout with member layouts M1, M2, ... Mn whose alignments are A1, A2, ... An, respectively, is max(A1, A2 ... An) . A layout's alignment can be overridden if needed (see `withByteAlignment(long)`), which can be useful to describe layouts with weaker or stronger alignment constraints. ## Layout paths A layout path is used to unambiguously select a layout that is nested in some other layout. Layout paths are typically expressed as a sequence of one or more path elements . (A more formal definition of layout paths is provided below). Layout paths can be used to: obtain offsets of arbitrarily nested layouts; obtain a var handle that can be used to access the value corresponding to the selected layout; select an arbitrarily nested layout. For instance, given the `taggedValues` sequence layout constructed above, we can obtain the offset, in bytes, of the member layout named `value` in the first sequence element, as follows:
    long valueOffset = taggedValues.byteOffset(PathElement.sequenceElement(0),
                                              PathElement.groupElement("value")); // yields 4
Similarly, we can select the member layout named `value`, as follows:
    MemoryLayout value = taggedValues.select(PathElement.sequenceElement(),
                                             PathElement.groupElement("value"));
### Open path elements Some layout path elements, said open path elements , can select multiple layouts at once. For instance, the open path elements `MemoryLayout.PathElement.sequenceElement()`, `MemoryLayout.PathElement.sequenceElement(long, long)` select an unspecified element in a sequence layout. A var handle derived from a layout path containing one or more open path element features additional coordinates of type `long`, which can be used by clients to bind the open elements in the path:
    VarHandle valueHandle = taggedValues.varHandle(PathElement.sequenceElement(),
                                                   PathElement.groupElement("value"));
    MemorySegment valuesSegment = ...
    int val = (int) valueHandle.get(valuesSegment, 2); // reads the "value" field of the third struct in the array
Open path elements also affects the creation of offset-computing method handles . Each open path element becomes an additional `long` parameter in the obtained method handle. This parameter can be used to specify the index of the sequence element whose offset is to be computed:
    MethodHandle offsetHandle = taggedValues.byteOffsetHandle(PathElement.sequenceElement(),
                                                              PathElement.groupElement("kind"));
    long offset1 = (long) offsetHandle.invokeExact(1L); // 8
    long offset2 = (long) offsetHandle.invokeExact(2L); // 16
### Dereference path elements A special kind of path element, called dereference path element , allows var handles obtained from memory layouts to follow pointers. Consider the following layout:
    StructLayout RECTANGLE = MemoryLayout.structLayout(
            ValueLayout.ADDRESS.withTargetLayout(
                    MemoryLayout.sequenceLayout(4,
                            MemoryLayout.structLayout(
                                    ValueLayout.JAVA_INT.withName("x"),
                                    ValueLayout.JAVA_INT.withName("y")
                            ).withName("point")
                     )
             ).withName("points")
    );
This layout is a struct layout which describe a rectangle. It contains a single field, namely `points`, an address layout whose target layout is a sequence layout of four struct layouts. Each struct layout describes a two-dimensional point, and is defined as a pair or `ValueLayout.JAVA_INT` coordinates, with names `x` and `y`, respectively. With dereference path elements, we can obtain a var handle which accesses the `y` coordinate of one of the point in the rectangle, as follows:
    VarHandle rectPointYs = RECTANGLE.varHandle(
            PathElement.groupElement("points"),
            PathElement.dereferenceElement(),
            PathElement.sequenceElement(),
            PathElement.groupElement("y")
    );

    MemorySegment rect = ...
    int rect_y_4 = (int) rectPointYs.get(rect, 2); // rect.points[2]->y
### Layout path well-formedness A layout path is applied to a layout `C_0`, also called the initial layout . Each path element in a layout path can be thought of as a function which updates the current layout `C_i-1` to some other layout `C_i`. That is, for each path element `E1, E2, ... En` , in a layout path `P`, we compute `C_i = f_i(C_i-1)` , where `f_i` is the selection function associated with the path element under consideration, denoted as `E_i`. The final layout `C_i` is also called the selected layout . A layout path `P` is considered well-formed for an initial layout `C_0` if all its path elements `E1, E2, ... En` are well-formed for their corresponding input layouts `C_0, C_1, ... C_n-1` . A path element `E` is considered well-formed for a layout `L` if any of the following is true: `L` is a sequence layout and `E` is a sequence path element (one of `MemoryLayout.PathElement.sequenceElement(long)`, `MemoryLayout.PathElement.sequenceElement(long, long)` or `MemoryLayout.PathElement.sequenceElement()`). Moreover, if `E` contains one or more sequence indices, such indices have to be compatible with the sequence layout's element count; `L` is a group layout and `E` is a group path element (one of `MemoryLayout.PathElement.groupElement(String)` or `MemoryLayout.PathElement.groupElement(long)`). Moreover, the group path element must refer to a valid member layout in `L`, either by name, or index; `L` is an address layout and `E` is a dereference path element . Moreover, `L` must define some target layout . Any attempt to provide a layout path `P` that is not well-formed for an initial layout `C_0` will result in an `IllegalArgumentException`. ## Access mode restrictions A var handle returned by `varHandle(PathElement...)` or `ValueLayout.varHandle()` features certain access characteristics, which are derived from the selected layout `L`: A carrier type `T`, derived from `L.carrier()` An alignment constraint `A`, derived from `L.byteAlignment()` An access size `S`, derived from `L.byteSize()` Depending on the above characteristics, the returned var handle might feature certain access mode restrictions . We say that a var handle is aligned if its alignment constraint `A` is compatible with the access size `S`, that is if `A >= S` . An aligned var handle is guaranteed to support the following access modes: read write access modes for all `T`. On 32-bit platforms, access modes `get` and `set` for `long`, `double` and `MemorySegment` are supported but might lead to word tearing, as described in Section . of The Java Language Specification . atomic update access modes for `int`, `long`, `float`, `double` and `MemorySegment`. (Future major platform releases of the JDK may support additional types for certain currently unsupported access modes.) numeric atomic update access modes for `int`, `long` and `MemorySegment`. (Future major platform releases of the JDK may support additional numeric types for certain currently unsupported access modes.) bitwise atomic update access modes for `int`, `long` and `MemorySegment`. (Future major platform releases of the JDK may support additional numeric types for certain currently unsupported access modes.) If `T` is `float`, `double` or `MemorySegment` then atomic update access modes compare values using their bitwise representation (see `Float.floatToRawIntBits(float)`, `Double.doubleToRawLongBits(double)` and `MemorySegment.address()`, respectively). Alternatively, a var handle is unaligned if its alignment constraint `A` is incompatible with the access size `S`, that is, if `A < S` . An unaligned var handle only supports the `get` and `set` access modes. All other access modes will result in `UnsupportedOperationException` being thrown. Moreover, while supported, access modes `get` and `set` might lead to word tearing. Since: 22 Implementation Requirements: Implementations of this interface are immutable, thread-safe and value-based. Sealed Graph:

### method:byteSize() [NONE]
### byteSize long byteSize() Returns the layout size, in bytes. Returns: the layout size, in bytes

### method:name() [NONE]
### name Optional<String> name() Returns the name (if any) associated with this layout. Returns: the name (if any) associated with this layout See Also: `withName(String)`

### method:withName(java.lang.String) [NONE]
### withName MemoryLayout withName (String name) Returns a memory layout with the same characteristics as this layout, but with the given name. Parameters: `name` - the layout name. Returns: a memory layout with the same characteristics as this layout, but with the given name See Also: `name()`

### method:withoutName() [NONE]
### withoutName MemoryLayout withoutName() Returns a memory layout with the same characteristics as this layout, but with no name. Returns: a memory layout with the same characteristics as this layout, but with no name See Also: `name()` API Note: This can be useful to compare two layouts that have different names, but are otherwise equal.

### method:byteAlignment() [NONE]
### byteAlignment long byteAlignment() Returns the alignment constraint associated with this layout, expressed in bytes. Layout alignment defines a power of two `A` which is the byte-wise alignment of the layout, where `A` is the number of bytes that must be aligned for any pointer that correctly points to this layout. Thus: `A=1` means unaligned (in the usual sense), which is common in packets. `A=8` means word aligned (on LP64), `A=4` int aligned, `A=2` short aligned, etc. `A=64` is the most strict alignment required by the x86/SV ABI (for AVX-512 data). If no explicit alignment constraint was set on this layout (see `withByteAlignment(long)`), then this method returns the natural alignment constraint (in bytes) associated with this layout. Returns: the alignment constraint associated with this layout, expressed in bytes

### method:withByteAlignment(long) [NONE]
### withByteAlignment MemoryLayout withByteAlignment (long byteAlignment) Returns a memory layout with the same characteristics as this layout, but with the given alignment constraint (in bytes). Parameters: `byteAlignment` - the layout alignment constraint, expressed in bytes. Returns: a memory layout with the same characteristics as this layout, but with the given alignment constraint (in bytes) Throws: `IllegalArgumentException` - if `byteAlignment` is not a power of two.

### method:scale(long,long) [NONE]
### scale default long scale (long offset, long index) Returns `offset + (byteSize() * index)` . Parameters: `offset` - the base offset `index` - the index to be scaled by the byte size of this layout Returns: `offset + (byteSize() * index)` Throws: `IllegalArgumentException` - if `offset` or `index` is negative `ArithmeticException` - if either the addition or multiplication overflows

### method:scaleHandle() [NONE]
### scaleHandle default MethodHandle scaleHandle() Returns a method handle that can be used to invoke `scale(long, long)` on this layout. Returns: a method handle that can be used to invoke `scale(long, long)` on this layout

### method:byteOffset(java.lang.foreign.MemoryLayout.PathElement...) [NONE]
### byteOffset default long byteOffset (MemoryLayout.PathElement... elements) Computes the offset, in bytes, of the layout selected by the given layout path, where the initial layout in the path is this layout. Parameters: `elements` - the layout path elements. Returns: The offset, in bytes, of the layout selected by the layout path in `elements`. Throws: `IllegalArgumentException` - if the layout path is not well-formed for this layout. `IllegalArgumentException` - if the layout path contains one or more open path elements . `IllegalArgumentException` - if the layout path contains one or more dereference path elements .

### method:byteOffsetHandle(java.lang.foreign.MemoryLayout.PathElement...) [NONE]
> ### byteOffsetHandle default MethodHandle byteOffsetHandle (MemoryLayout.PathElement... elements) Creates a method handle that computes the offset, in bytes, of the layout selected by the given layout path, where the initial layout in the path is this layout. The returned method handle has the following characteristics: its return type is `long`; it has one leading `long` parameter representing the base offset; it has as zero or more trailing parameters of type `long`, one for each open path element in the provided layout path. The order of these parameters corresponds to the order in which the open path elements occur in the provided layout path. The final offset returned by the method handle is computed as follows:
>      offset = b + c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n)
where `b` represents the base offset provided as a dynamic `long` argument, `x_1`, `x_2`, ... `x_n` represent indices into sequences provided as dynamic `long` arguments, whereas `s_1`, `s_2`, ... `s_n` are static stride constants derived from the size of the element layout of a sequence, and `c_1`, `c_2`, ... `c_m` are other static offset constants (such as field offsets) which are derived from the layout path. Parameters: `elements` - the layout path elements. Returns: a method handle that computes the offset, in bytes, of the layout selected by the given layout path. Throws: `IllegalArgumentException` - if the layout path is not well-formed for this layout. `IllegalArgumentException` - if the layout path contains one or more dereference path elements . API Note: The returned method handle can be used to compute a layout offset, similarly to `byteOffset(PathElement...)`, but more flexibly, as some indices can be specified when invoking the method handle.

### method:varHandle(java.lang.foreign.MemoryLayout.PathElement...) [CHANGED]
### varHandle default VarHandle varHandle (MemoryLayout.PathElement... elements) Creates a var handle that accesses a memory segment at the offset selected by the given layout path, where the initial layout in the path is this layout. The returned var handle has the following characteristics: its type is derived from the carrier of the selected value layout; it has a leading parameter of type `MemorySegment` representing the accessed segment a following `long` parameter, corresponding to the base offset, denoted as `B`; it has zero or more trailing access coordinates of type `long`, one for each open path element in the provided layout path, denoted as `I1, I2, ... In` , respectively. The order of these access coordinates corresponds to the order in which the open path elements occur in the provided layout path. If the provided layout path `P` contains no dereference elements, then the offset `O` of the access operation is computed as follows:
    O = this.offsetHandle(P).invokeExact(B, I1, I2, ... In);
Accessing a memory segment using the var handle returned by this method is subject to the following checks: The physical address of the accessed memory segment must be aligned according to the alignment constraint of the root layout (this layout), or an `IllegalArgumentException` will be issued. Note that the alignment constraint of the root layout can be more strict (but not less) than the alignment constraint of the selected value layout. The offset of the access operation (computed as above) must fall inside the spatial bounds of the accessed memory segment, or an `IndexOutOfBoundsException` is thrown. This is the case when `O + A <= S` , where `O` is the accessed offset (computed as above), `A` is the size of the selected layout and `S` is the size of the accessed memory segment. The accessed memory segment must be `accessible` from the thread performing the access operation, or a `WrongThreadException` is thrown. The scope associated with the accessed segment must be alive, or an `IllegalStateException` is thrown. If the selected layout is an address layout , calling `VarHandle.get(Object...)` on the returned var handle will return a new memory segment. The segment is associated with a fresh the global scope that is always alive. Moreover, the size of the segment depends on whether the address layout has a target layout . More specifically: If the address layout has a target layout `T`, then the size of the returned segment is `T.byteSize()`; Otherwise, the address layout has no target layout, and the size of the returned segment is zero. Moreover, if the selected layout is an address layout , calling `VarHandle.set(Object...)` can throw `IllegalArgumentException` if the memory segment representing the address to be written is not a native memory segment. If the provided layout path has size `m` and contains a dereference path element in position `k` (where `k <= m` ) then two layout paths `P` and `P'` are derived, where P contains all the path elements from 0 to `k - 1` and `P'` contains all the path elements from `k + 1` to `m` (if any). Then, the returned var handle is computed as follows:
    VarHandle baseHandle = this.varHandle(P);
    MemoryLayout target = ((AddressLayout)this.select(P)).targetLayout().get();
    VarHandle targetHandle = target.varHandle(P');
    targetHandle = MethodHandles.insertCoordinates(targetHandle, 1, 0L); // always access nested targets at offset 0
    targetHandle = MethodHandles.collectCoordinates(targetHandle, 0,
            baseHandle.toMethodHandle(VarHandle.AccessMode.GET));
(The above can be trivially generalized to cases where the provided layout path contains more than one dereference path elements). As an example, consider the memory layout expressed by a `GroupLayout` instance constructed as follows:
        GroupLayout grp = java.lang.foreign.MemoryLayout.structLayout(
                MemoryLayout.paddingLayout(4),
                ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN).withName("value")
        );
To access the member layout named `value`, we can construct a var handle as follows:
        VarHandle handle = grp.varHandle(PathElement.groupElement("value")); //(MemorySegment, long) -> int
Parameters: `elements` - the layout path elements. Returns: a var handle that accesses a memory segment at the offset selected by the given layout path. Throws: `IllegalArgumentException` - if the layout path is not well-formed for this layout. `IllegalArgumentException` - if the layout selected by the provided path is not a value layout . API Note: The resulting var handle features certain access mode restrictions , which are common to all var handles derived from memory layouts.
### varHandle default VarHandle varHandle (MemoryLayout.PathElement... elements) Creates a var handle that accesses a memory segment at the offset selected by the given layout path, where the initial layout in the path is this layout. The returned var handle has the following characteristics: its type is derived from the carrier of the selected value layout; it has a leading parameter of type `MemorySegment` representing the accessed segment a following `long` parameter, corresponding to the base offset, denoted as `B`; it has zero or more trailing access coordinates of type `long`, one for each open path element in the provided layout path, denoted as `I1, I2, ... In` , respectively. The order of these access coordinates corresponds to the order in which the open path elements occur in the provided layout path. If the provided layout path `P` contains no dereference elements, then the offset `O` of the access operation is computed as follows:
    O = this.offsetHandle(P).invokeExact(B, I1, I2, ... In);
Accessing a memory segment using the var handle returned by this method is subject to the following checks: The physical address of the accessed memory segment must be aligned according to the alignment constraint of the root layout (this layout), or an `IllegalArgumentException` will be issued. Note that the alignment constraint of the root layout can be more strict (but not less) than the alignment constraint of the selected value layout. The offset of the access operation (computed as above) must fall inside the spatial bounds of the accessed memory segment, or an `IndexOutOfBoundsException` is thrown. This is the case when `O + A <= S` , where `O` is the accessed offset (computed as above), `A` is the size of the selected layout and `S` is the size of the accessed memory segment. The accessed memory segment must be `accessible` from the thread performing the access operation, or a `WrongThreadException` is thrown. The scope associated with the accessed segment must be alive, or an `IllegalStateException` is thrown. If the selected layout is an address layout , calling `VarHandle.get(Object...)` on the returned var handle will return a new memory segment. The segment is associated with a fresh scope that is always alive. Moreover, the size of the segment depends on whether the address layout has a target layout . More specifically: If the address layout has a target layout `T`, then the size of the returned segment is `T.byteSize()`; Otherwise, the address layout has no target layout, and the size of the returned segment is zero. Moreover, if the selected layout is an address layout , calling `VarHandle.set(Object...)` can throw `IllegalArgumentException` if the memory segment representing the address to be written is not a native memory segment. If the provided layout path has size `m` and contains a dereference path element in position `k` (where `k <= m` ) then two layout paths `P` and `P'` are derived, where P contains all the path elements from 0 to `k - 1` and `P'` contains all the path elements from `k + 1` to `m` (if any). Then, the returned var handle is computed as follows:
    VarHandle baseHandle = this.varHandle(P);
    MemoryLayout target = ((AddressLayout)this.select(P)).targetLayout().get();
    VarHandle targetHandle = target.varHandle(P');
    targetHandle = MethodHandles.insertCoordinates(targetHandle, 1, 0L); // always access nested targets at offset 0
    targetHandle = MethodHandles.collectCoordinates(targetHandle, 0,
            baseHandle.toMethodHandle(VarHandle.AccessMode.GET));
(The above can be trivially generalized to cases where the provided layout path contains more than one dereference path elements). As an example, consider the memory layout expressed by a `GroupLayout` instance constructed as follows:
        GroupLayout grp = java.lang.foreign.MemoryLayout.structLayout(
                MemoryLayout.paddingLayout(4),
                ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN).withName("value")
        );
To access the member layout named `value`, we can construct a var handle as follows:
        VarHandle handle = grp.varHandle(PathElement.groupElement("value")); //(MemorySegment, long) -> int
Parameters: `elements` - the layout path elements. Returns: a var handle that accesses a memory segment at the offset selected by the given layout path. Throws: `IllegalArgumentException` - if the layout path is not well-formed for this layout. `IllegalArgumentException` - if the layout selected by the provided path is not a value layout . API Note: The resulting var handle features certain access mode restrictions , which are common to all var handles derived from memory layouts. | ### varHandle default VarHandle varHandle (MemoryLayout.PathElement... elements) Creates a var handle that accesses a memory segment at the offset selected by the given layout path, where the initial layout in the path is this layout. The returned var handle has the following characteristics: its type is derived from the carrier of the selected value layout; it has a leading parameter of type `MemorySegment` representing the accessed segment a following `long` parameter, corresponding to the base offset, denoted as `B`; it has zero or more trailing access coordinates of type `long`, one for each open path element in the provided layout path, denoted as `I1, I2, ... In` , respectively. The order of these access coordinates corresponds to the order in which the open path elements occur in the provided layout path. If the provided layout path `P` contains no dereference elements, then the offset `O` of the access operation is computed as follows:
    O = this.offsetHandle(P).invokeExact(B, I1, I2, ... In);
Accessing a memory segment using the var handle returned by this method is subject to the following checks: The physical address of the accessed memory segment must be aligned according to the alignment constraint of the root layout (this layout), or an `IllegalArgumentException` will be issued. Note that the alignment constraint of the root layout can be more strict (but not less) than the alignment constraint of the selected value layout. The offset of the access operation (computed as above) must fall inside the spatial bounds of the accessed memory segment, or an `IndexOutOfBoundsException` is thrown. This is the case when `O + A <= S` , where `O` is the accessed offset (computed as above), `A` is the size of the selected layout and `S` is the size of the accessed memory segment. The accessed memory segment must be `accessible` from the thread performing the access operation, or a `WrongThreadException` is thrown. The scope associated with the accessed segment must be alive, or an `IllegalStateException` is thrown. If the selected layout is an address layout , calling `VarHandle.get(Object...)` on the returned var handle will return a new memory segment. The segment is associated with the global scope. Moreover, the size of the segment depends on whether the address layout has a target layout . More specifically: If the address layout has a target layout `T`, then the size of the returned segment is `T.byteSize()`; Otherwise, the address layout has no target layout, and the size of the returned segment is zero. Moreover, if the selected layout is an address layout , calling `VarHandle.set(Object...)` can throw `IllegalArgumentException` if the memory segment representing the address to be written is not a native memory segment. If the provided layout path has size `m` and contains a dereference path element in position `k` (where `k <= m` ) then two layout paths `P` and `P'` are derived, where P contains all the path elements from 0 to `k - 1` and `P'` contains all the path elements from `k + 1` to `m` (if any). Then, the returned var handle is computed as follows:
    VarHandle baseHandle = this.varHandle(P);
    MemoryLayout target = ((AddressLayout)this.select(P)).targetLayout().get();
    VarHandle targetHandle = target.varHandle(P);
    targetHandle = MethodHandles.insertCoordinates(targetHandle, 1, 0L); // always access nested targets at offset 0
    targetHandle = MethodHandles.collectCoordinates(targetHandle, 0,
            baseHandle.toMethodHandle(VarHandle.AccessMode.GET));
(The above can be trivially generalized to cases where the provided layout path contains more than one dereference path elements). As an example, consider the memory layout expressed by a `GroupLayout` instance constructed as follows:
        GroupLayout grp = java.lang.foreign.MemoryLayout.structLayout(
                MemoryLayout.paddingLayout(4),
                ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN).withName("value")
        );
To access the member layout named `value`, we can construct a var handle as follows:
        VarHandle handle = grp.varHandle(PathElement.groupElement("value")); //(MemorySegment, long) -> int
Parameters: `elements` - the layout path elements. Returns: a var handle that accesses a memory segment at the offset selected by the given layout path. Throws: `IllegalArgumentException` - if the layout path is not well-formed for this layout. `IllegalArgumentException` - if the layout selected by the provided path is not a value layout . API Note: The resulting var handle features certain access mode restrictions , which are common to all var handles derived from memory layouts.

### method:sliceHandle(java.lang.foreign.MemoryLayout.PathElement...) [NONE]
### sliceHandle default MethodHandle sliceHandle (MemoryLayout.PathElement... elements) Creates a method handle which, given a memory segment, returns a slice corresponding to the layout selected by the given layout path, where the initial layout in the path is this layout. The returned method handle has the following characteristics: its return type is `MemorySegment`; it has a leading parameter of type `MemorySegment` corresponding to the memory segment to be sliced a following `long` parameter, corresponding to the base offset it has as zero or more trailing parameters of type `long`, one for each open path element in the provided layout path. The order of these parameters corresponds to the order in which the open path elements occur in the provided layout path. The offset `O` of the returned segment is computed as if by a call to a byte offset handle constructed using the given path elements. Computing a slice of a memory segment using the method handle returned by this method is subject to the following checks: The physical address of the accessed memory segment must be aligned according to the alignment constraint of the root layout (this layout), or an `IllegalArgumentException` will be issued. Note that the alignment constraint of the root layout can be more strict (but not less) than the alignment constraint of the selected layout. The start offset of the slicing operation (computed as above) must fall fall inside the spatial bounds of the accessed memory segment, or an `IndexOutOfBoundsException` is thrown. This is the case when `O + A <= S` , where `O` is the start offset of the slicing operation (computed as above), `A` is the size of the selected layout and `S` is the size of the accessed memory segment. Parameters: `elements` - the layout path elements. Returns: a method handle which is used to slice a memory segment at the offset selected by the given layout path. Throws: `IllegalArgumentException` - if the layout path is not well-formed for this layout. `IllegalArgumentException` - if the layout path contains one or more dereference path elements . API Note: The returned method handle can be used to obtain a memory segment slice, similarly to `MemorySegment.asSlice(long, long)` , but more flexibly, as some indices can be specified when invoking the method handle.

### method:select(java.lang.foreign.MemoryLayout.PathElement...) [NONE]
### select default MemoryLayout select (MemoryLayout.PathElement... elements) Returns the layout selected from the provided path, where the initial layout in the path is this layout. Parameters: `elements` - the layout path elements. Returns: the layout selected by the layout path in `elements`. Throws: `IllegalArgumentException` - if the layout path is not well-formed for this layout. `IllegalArgumentException` - if the layout path contains one or more dereference path elements . `IllegalArgumentException` - if the layout path contains one or more path elements that select one or more sequence element indices, such as `MemoryLayout.PathElement.sequenceElement(long)` and `MemoryLayout.PathElement.sequenceElement(long, long)` ).

### method:equals(java.lang.Object) [NONE]
### equals boolean equals (Object other) Compares the specified object with this layout for equality. Returns `true` if and only if the specified object is also a layout, and it is equal to this layout. Two layouts are considered equal if they are of the same kind, have the same size, name and alignment constraint. Furthermore, depending on the layout kind, additional conditions must be satisfied: two value layouts are considered equal if they have the same order, and carrier. Additionally, two address layouts are considered equal if they also have the same target layout ; two sequence layouts are considered equal if they have the same element count (see `SequenceLayout.elementCount()`), and if their element layouts (see `SequenceLayout.elementLayout()`) are also equal; two group layouts are considered equal if they are of the same type (see `StructLayout`, `UnionLayout`) and if their member layouts (see `GroupLayout.memberLayouts()`) are also equal. Overrides: `equals` in class `Object` Parameters: `other` - the object to be compared for equality with this layout. Returns: `true` if the specified object is equal to this layout. See Also: `Object.hashCode()` `HashMap`

### method:hashCode() [NONE]
### hashCode int hashCode() Returns the hash code value for this layout. Overrides: `hashCode` in class `Object` Returns: the hash code value for this layout See Also: `Object.equals(java.lang.Object)` `System.identityHashCode(java.lang.Object)`

### method:toString() [NONE]
### toString String toString() Returns the string representation of this layout. Overrides: `toString` in class `Object` Returns: the string representation of this layout

### method:paddingLayout(long) [NONE]
### paddingLayout static PaddingLayout paddingLayout (long byteSize) Creates a padding layout with the given byte size. The alignment constraint of the returned layout is 1. As such, regardless of its size, in the absence of an explicit alignment constraint, a padding layout does not affect the natural alignment of the group or sequence layout it is nested into. Parameters: `byteSize` - the padding size (expressed in bytes). Returns: the new selector layout. Throws: `IllegalArgumentException` - if `byteSize <= 0` .

### method:sequenceLayout(long,java.lang.foreign.MemoryLayout) [NONE]
### sequenceLayout static SequenceLayout sequenceLayout (long elementCount, MemoryLayout elementLayout) Creates a sequence layout with the given element layout and element count. Parameters: `elementCount` - the sequence element count. `elementLayout` - the sequence element layout. Returns: the new sequence layout with the given element layout and size. Throws: `IllegalArgumentException` - if `elementCount` is negative. `IllegalArgumentException` - if `elementLayout.byteSize() * elementCount` overflows. `IllegalArgumentException` - if `elementLayout.byteSize() % elementLayout.byteAlignment() != 0` .

### method:structLayout(java.lang.foreign.MemoryLayout...) [NONE]
  ### structLayout static StructLayout structLayout (MemoryLayout... elements) Creates a struct layout with the given member layouts. Parameters: `elements` - The member layouts of the struct layout. Returns: a struct layout with the given member layouts. Throws: `IllegalArgumentException` - if the sum of the byte sizes of the member layouts overflows. `IllegalArgumentException` - if a member layout in `elements` occurs at an offset (relative to the start of the struct layout) which is not compatible with its alignment constraint. API Note: This factory does not automatically align element layouts, by inserting additional padding layout elements. As such, the following struct layout creation will fail with an exception:
      structLayout(JAVA_SHORT, JAVA_INT);
  To avoid the exception, clients can either insert additional padding layout elements:
      structLayout(JAVA_SHORT, MemoryLayout.paddingLayout(2), JAVA_INT);
  Or, alternatively, they can use a member layout which features a smaller alignment constraint. This will result in a packed struct layout:
      structLayout(JAVA_SHORT, JAVA_INT.withByteAlignment(2));

### method:unionLayout(java.lang.foreign.MemoryLayout...) [NONE]
### unionLayout static UnionLayout unionLayout (MemoryLayout... elements) Creates a union layout with the given member layouts. Parameters: `elements` - The member layouts of the union layout. Returns: a union layout with the given member layouts.