Skip to content

Commit 9e5b246

Browse files
committed
[stdlib] add loads and stores for raw buffer slices
1 parent 39e2d13 commit 9e5b246

File tree

1 file changed

+46
-24
lines changed

1 file changed

+46
-24
lines changed

stdlib/public/core/UnsafeBufferPointerSlice.swift

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -297,9 +297,9 @@ extension Slice where Base == UnsafeMutableRawBufferPointer {
297297
}
298298

299299
/// Returns a new instance of the given type, read from the
300-
/// buffer pointer slice's raw memory.
300+
/// specified offset into the buffer pointer slice's raw memory.
301301
///
302-
/// The memory at the beginning of this buffer pointer slice
302+
/// The memory at `offset` bytes into this buffer pointer slice
303303
/// must be properly aligned for accessing `T` and initialized to `T` or
304304
/// another type that is layout compatible with `T`.
305305
///
@@ -314,28 +314,31 @@ extension Slice where Base == UnsafeMutableRawBufferPointer {
314314
///
315315
/// The memory to read for the new instance must not extend beyond the
316316
/// memory region represented by the buffer pointer slice---that is,
317-
/// `MemoryLayout<T>.size` must be less than or equal to the slice's `count`.
317+
/// `offset + MemoryLayout<T>.size` must be less than or equal
318+
/// to the slice's `count`.
318319
///
319320
/// - Parameters:
321+
/// - offset: The offset into the slice's memory, in bytes, at
322+
/// which to begin reading data for the new instance. The default is zero.
320323
/// - type: The type to use for the newly constructed instance. The memory
321324
/// must be initialized to a value of a type that is layout compatible
322325
/// with `type`.
323326
/// - Returns: A new instance of type `T`, copied from the buffer pointer
324327
/// slice's memory.
325328
@inlinable
326329
@_alwaysEmitIntoClient
327-
public func load<T>(as type: T.Type) -> T {
330+
public func load<T>(fromByteOffset offset: Int = 0, as type: T.Type) -> T {
328331
let buffer = Base(rebasing: self)
329-
return buffer.load(fromByteOffset: 0, as: T.self)
332+
return buffer.load(fromByteOffset: offset, as: T.self)
330333
}
331334

332335
/// Returns a new instance of the given type, read from the
333-
/// buffer pointer slice's raw memory.
336+
/// specified offset into the buffer pointer slice's raw memory.
334337
///
335338
/// This function only supports loading trivial types.
336339
/// A trivial type does not contain any reference-counted property
337340
/// within its in-memory stored representation.
338-
/// The memory at `offset` bytes into the buffer must be laid out
341+
/// The memory at `offset` bytes into the buffer slice must be laid out
339342
/// identically to the in-memory representation of `T`.
340343
///
341344
/// You can use this method to create new values from the buffer pointer's
@@ -349,32 +352,40 @@ extension Slice where Base == UnsafeMutableRawBufferPointer {
349352
///
350353
/// The memory to read for the new instance must not extend beyond the
351354
/// memory region represented by the buffer pointer slice---that is,
352-
/// `MemoryLayout<T>.size` must be less than or equal to the slice's `count`.
355+
/// `offset + MemoryLayout<T>.size` must be less than or equal
356+
/// to the slice's `count`.
353357
///
354358
/// - Parameters:
359+
/// - offset: The offset into the slice's memory, in bytes, at
360+
/// which to begin reading data for the new instance. The default is zero.
355361
/// - type: The type to use for the newly constructed instance. The memory
356362
/// must be initialized to a value of a type that is layout compatible
357363
/// with `type`.
358364
/// - Returns: A new instance of type `T`, copied from the buffer pointer's
359365
/// memory.
360366
@inlinable
361367
@_alwaysEmitIntoClient
362-
public func loadUnaligned<T>(as type: T.Type) -> T {
368+
public func loadUnaligned<T>(
369+
fromByteOffset offset: Int = 0,
370+
as type: T.Type
371+
) -> T {
363372
let buffer = Base(rebasing: self)
364-
return buffer.loadUnaligned(fromByteOffset: 0, as: T.self)
373+
return buffer.loadUnaligned(fromByteOffset: offset, as: T.self)
365374
}
366375

367-
/// Stores a value's bytes into the buffer pointer slice's raw memory.
376+
/// Stores a value's bytes into the buffer pointer slice's raw memory at the
377+
/// specified byte offset.
368378
///
369379
/// The type `T` to be stored must be a trivial type. The memory must also be
370380
/// uninitialized, initialized to `T`, or initialized to another trivial
371381
/// type that is layout compatible with `T`.
372382
///
373383
/// The memory written to must not extend beyond
374384
/// the memory region represented by the buffer pointer slice---that is,
375-
/// `MemoryLayout<T>.size` must be less than or equal to the slice's `count`.
385+
/// `offset + MemoryLayout<T>.size` must be less than or equal
386+
/// to the slice's `count`.
376387
///
377-
/// After calling `storeBytes(of:as:)`, the memory is
388+
/// After calling `storeBytes(of:toByteOffset:as:)`, the memory is
378389
/// initialized to the raw bytes of `value`. If the memory is bound to a
379390
/// type `U` that is layout compatible with `T`, then it contains a value of
380391
/// type `U`. Calling `storeBytes(of:toByteOffset:as:)` does not change the
@@ -386,12 +397,14 @@ extension Slice where Base == UnsafeMutableRawBufferPointer {
386397
/// forms of indirection are trivial, as are imported C structs and enums.
387398
///
388399
/// If you need to store into memory a copy of a value of a type that isn't
389-
/// trivial, you cannot use the `storeBytes(of:as:)` method.
400+
/// trivial, you cannot use the `storeBytes(of:toByteOffset:as:)` method.
390401
/// Instead, you must know either initialize the memory or,
391402
/// if you know the memory was already bound to `type`, assign to the memory.
392403
///
393404
/// - Parameters:
394405
/// - value: The value to store as raw bytes.
406+
/// - offset: The offset in bytes into the buffer pointer slice's memory
407+
/// to begin writing bytes from the value. The default is zero.
395408
/// - type: The type to use for the newly constructed instance. The memory
396409
/// must be initialized to a value of a type that is layout compatible
397410
/// with `type`.
@@ -509,9 +522,9 @@ extension Slice where Base == UnsafeRawBufferPointer {
509522
}
510523

511524
/// Returns a new instance of the given type, read from the
512-
/// buffer pointer slice's raw memory.
525+
/// specified offset into the buffer pointer slice's raw memory.
513526
///
514-
/// The memory at the beginning of this buffer pointer slice
527+
/// The memory at `offset` bytes into this buffer pointer slice
515528
/// must be properly aligned for accessing `T` and initialized to `T` or
516529
/// another type that is layout compatible with `T`.
517530
///
@@ -526,28 +539,31 @@ extension Slice where Base == UnsafeRawBufferPointer {
526539
///
527540
/// The memory to read for the new instance must not extend beyond the
528541
/// memory region represented by the buffer pointer slice---that is,
529-
/// `MemoryLayout<T>.size` must be less than or equal to the slice's `count`.
542+
/// `offset + MemoryLayout<T>.size` must be less than or equal
543+
/// to the slice's `count`.
530544
///
531545
/// - Parameters:
546+
/// - offset: The offset into the slice's memory, in bytes, at
547+
/// which to begin reading data for the new instance. The default is zero.
532548
/// - type: The type to use for the newly constructed instance. The memory
533549
/// must be initialized to a value of a type that is layout compatible
534550
/// with `type`.
535551
/// - Returns: A new instance of type `T`, copied from the buffer pointer
536552
/// slice's memory.
537553
@inlinable
538554
@_alwaysEmitIntoClient
539-
public func load<T>(as type: T.Type) -> T {
555+
public func load<T>(fromByteOffset offset: Int = 0, as type: T.Type) -> T {
540556
let buffer = Base(rebasing: self)
541-
return buffer.load(fromByteOffset: 0, as: T.self)
557+
return buffer.load(fromByteOffset: offset, as: T.self)
542558
}
543559

544560
/// Returns a new instance of the given type, read from the
545-
/// buffer pointer slice's raw memory.
561+
/// specified offset into the buffer pointer slice's raw memory.
546562
///
547563
/// This function only supports loading trivial types.
548564
/// A trivial type does not contain any reference-counted property
549565
/// within its in-memory stored representation.
550-
/// The memory at `offset` bytes into the buffer must be laid out
566+
/// The memory at `offset` bytes into the buffer slice must be laid out
551567
/// identically to the in-memory representation of `T`.
552568
///
553569
/// You can use this method to create new values from the buffer pointer's
@@ -561,19 +577,25 @@ extension Slice where Base == UnsafeRawBufferPointer {
561577
///
562578
/// The memory to read for the new instance must not extend beyond the
563579
/// memory region represented by the buffer pointer slice---that is,
564-
/// `MemoryLayout<T>.size` must be less than or equal to the slice's `count`.
580+
/// `offset + MemoryLayout<T>.size` must be less than or equal
581+
/// to the slice's `count`.
565582
///
566583
/// - Parameters:
584+
/// - offset: The offset into the slice's memory, in bytes, at
585+
/// which to begin reading data for the new instance. The default is zero.
567586
/// - type: The type to use for the newly constructed instance. The memory
568587
/// must be initialized to a value of a type that is layout compatible
569588
/// with `type`.
570589
/// - Returns: A new instance of type `T`, copied from the buffer pointer's
571590
/// memory.
572591
@inlinable
573592
@_alwaysEmitIntoClient
574-
public func loadUnaligned<T>(as type: T.Type) -> T {
593+
public func loadUnaligned<T>(
594+
fromByteOffset offset: Int = 0,
595+
as type: T.Type
596+
) -> T {
575597
let buffer = Base(rebasing: self)
576-
return buffer.loadUnaligned(fromByteOffset: 0, as: T.self)
598+
return buffer.loadUnaligned(fromByteOffset: offset, as: T.self)
577599
}
578600
}
579601

0 commit comments

Comments
 (0)