@@ -345,6 +345,99 @@ extension EmbeddedIntegerCollectionIndices: Equatable, Hashable, Codable,
345
345
Sendable , BitwiseCopyable
346
346
{ }
347
347
348
+ // MARK: More Initializers
349
+
350
+ extension EmbeddedIntegerCollection {
351
+ /// Creates a collection wrapping an instance of the given integer type,
352
+ /// where the integer's initial value embeds elements taken from
353
+ /// the given iterator's virtual sequence,
354
+ /// notating which bit range cap stores the first element.
355
+ ///
356
+ /// - Precondition: The bit length of `Wrapped` needs to be a multiple of
357
+ /// the bit length of `Element`.
358
+ ///
359
+ /// - Parameters:
360
+ /// - iterator: The source for the embedded elements' values.
361
+ /// - type: A metatype specifier for the `Wrapped` type.
362
+ /// It does not need to be specified if the surrounding context already
363
+ /// locks it in.
364
+ /// - bitRange: Whether the collection's first element should be embedded at
365
+ /// the most- or least-significant bit range of the wrapping integer.
366
+ /// - Postcondition: This initializer fails if the `iterator` cannot
367
+ /// supply enough elements.
368
+ /// The count of elements extracted from the `iterator` will be the
369
+ /// minimum between its virtual sequence's length and the number of
370
+ /// elements supported by this collection type.
371
+ @inlinable
372
+ public init ? < T: IteratorProtocol < Element > > (
373
+ extractingFrom iterator: inout T ,
374
+ embeddingInto type: Wrapped . Type = Wrapped . self,
375
+ fillingFrom bitRange: EmbeddedIteratorDirection
376
+ ) {
377
+ self . init ( iteratingFrom: bitRange)
378
+
379
+ // Fill up the wrapping word from the most-significant element down.
380
+ var remainingElements = count
381
+ while remainingElements > 0 , let nextEmbeddedElement = iterator. next ( ) {
382
+ word <<= Element . bitWidth
383
+ word |= Wrapped ( nextEmbeddedElement)
384
+ remainingElements -= 1
385
+ }
386
+ guard remainingElements == 0 else { return nil }
387
+
388
+ // Flip the elements if the starting bit range is wrong.
389
+ if bitRange == . leastSignificantFirst, !isEmpty {
390
+ var first = startIndex
391
+ var last = index ( before: endIndex)
392
+ while first < last {
393
+ swapAt ( first, last)
394
+ formIndex ( after: & first)
395
+ formIndex ( before: & last)
396
+ }
397
+ }
398
+ }
399
+
400
+ /// Creates a collection wrapping an instance of the given integer type,
401
+ /// where the integer's initial value embeds elements taken from
402
+ /// the prefix of the given sequence,
403
+ /// notating which bit range cap stores the first element.
404
+ ///
405
+ /// - Precondition: The bit length of `Wrapped` needs to be a multiple of
406
+ /// the bit length of `Element`.
407
+ ///
408
+ /// If access to the elements of the `sequence` after what's needed to
409
+ /// fill this collection is required,
410
+ /// use the iterator-based `init(extractingFrom:embeddingInto:fillingFrom:)`
411
+ /// instead.
412
+ ///
413
+ /// - Parameters:
414
+ /// - sequence: The source for the embedded elements' values.
415
+ /// - type: A metatype specifier for the `Wrapped` type.
416
+ /// It does not need to be specified if the surrounding context already
417
+ /// locks it in.
418
+ /// - readAll: Whether every element of the `sequence` needs to
419
+ /// be copied into this collection (i.e. not a strict prefix).
420
+ /// - bitRange: Whether the collection's first element should be embedded at
421
+ /// the most- or least-significant bit range of the wrapping integer.
422
+ /// - Postcondition: This initializer fails if the `sequence` cannot
423
+ /// supply enough elements.
424
+ /// It also fails if `readAll` is `true` while the `sequence` has extra
425
+ /// elements after filling this collection.
426
+ @inlinable
427
+ public init ? < T: Sequence < Element > > (
428
+ readingFrom sequence: T ,
429
+ embeddingInto type: Wrapped . Type = Wrapped . self,
430
+ requireEverythingRead readAll: Bool ,
431
+ fillingFrom bitRange: EmbeddedIteratorDirection
432
+ ) {
433
+ var iterator = sequence. makeIterator ( )
434
+ self . init (
435
+ extractingFrom: & iterator, embeddingInto: type, fillingFrom: bitRange
436
+ )
437
+ guard !readAll || iterator. next ( ) == nil else { return nil }
438
+ }
439
+ }
440
+
348
441
// MARK: - Bit Manipulation Helpers
349
442
350
443
extension EmbeddedIntegerCollection {
0 commit comments