Repository: apple/swift-nio
File: Sources/NIOCore/ByteBuffer-int.swift (Swift)

Code before:
        guard self != 0 else {
            return 1
        }
        return 1 << (Self.bitWidth - (self - 1).leadingZeroBitCount)
    }

    /// Returns the previous power of 2, or self if it already is.
    @inlinable
    func previousPowerOf2() -> Self {
        guard self != 0 else {
            return 0
        }

        return 1 << ((Self.bitWidth - 1) - self.leadingZeroBitCount)
    }

    /// Initialize an integer from a ByteBuffer. The buffer must contain enough bytes to represent the integer.
    /// The bytes will be read using the host system's endianness.
    /// If the buffer doesn't contain enough bytes to represent the integer, the program will crash.
    ///
    /// - Parameters:
    ///   - buffer: The ByteBuffer to read from
    ///
    /// - Returns: The integer value read from the buffer
    @inlinable
    public init(buffer: ByteBuffer) {
        var buffer = buffer
        self = buffer.readInteger(endianness: .host, as: Self.self)!
    }
}

extension UInt32 {
    /// Returns the next power of two unless that would overflow, in which case UInt32.max (on 64-bit systems) or
    /// Int32.max (on 32-bit systems) is returned. The returned value is always safe to be cast to Int and passed
    /// to malloc on all platforms.
    @inlinable
    func nextPowerOf2ClampedToMax() -> UInt32 {
        guard self > 0 else {
            return 1
        }

        var n = self

        #if arch(arm) || arch(i386) || arch(arm64_32)
        // on 32-bit platforms we can't make use of a whole UInt32.max (as it doesn't fit in an Int)
        let max = UInt32(Int.max)
        #else
        // on 64-bit platforms we're good
        let max = UInt32.max
        #endif


Review comment (bug):
This should definitely be failable, so that we can avoid the force-unwrap. We also want to add tests.

There's a separate question about whether this should be _exactly_ the right size.

Code after:
    func nextPowerOf2() -> Self {
        guard self != 0 else {
            return 1
        }
        return 1 << (Self.bitWidth - (self - 1).leadingZeroBitCount)
    }

    /// Returns the previous power of 2, or self if it already is.
    @inlinable
    func previousPowerOf2() -> Self {
        guard self != 0 else {
            return 0
        }

        return 1 << ((Self.bitWidth - 1) - self.leadingZeroBitCount)
    }

    /// Initialize an integer from a byte buffer of exactly the right size.
    /// The bytes will be read using the host system's endianness.
    ///
    /// - Parameters:
    ///   - buffer: The ByteBuffer to read from
    ///   - endianness: The endianness to use when reading the integer, defaults to the host system's endianness.
    @inlinable
    public init?(buffer: ByteBuffer, endianness: Endianness = .host) {
        var buffer = buffer
        guard let value = buffer.readInteger(endianness: endianness, as: Self.self), buffer.readableBytes == 0 else {
            return nil
        }
        self = value
    }
}

extension UInt32 {
    /// Returns the next power of two unless that would overflow, in which case UInt32.max (on 64-bit systems) or
    /// Int32.max (on 32-bit systems) is returned. The returned value is always safe to be cast to Int and passed
    /// to malloc on all platforms.
    @inlinable
    func nextPowerOf2ClampedToMax() -> UInt32 {
        guard self > 0 else {
            return 1
        }

        var n = self

        #if arch(arm) || arch(i386) || arch(arm64_32)
        // on 32-bit platforms we can't make use of a whole UInt32.max (as it doesn't fit in an Int)
        let max = UInt32(Int.max)
        #else
        // on 64-bit platforms we're good
        let max = UInt32.max