@@ -264,31 +264,69 @@ fileprivate enum ConstantBuffers {
264264 } ( )
265265}
266266
267+ fileprivate extension BinaryInteger {
268+
269+ var numberOfDecimalDigits : Int {
270+ @inline ( __always) get {
271+ var value = self
272+ var count = 0
273+
274+ repeat {
275+ value /= 10
276+ count += 1
277+ }
278+ while value != 0
279+
280+ return count
281+ }
282+ }
283+ }
284+
267285extension ByteBuffer {
268286
269287 @discardableResult
270- public mutating func write< T: FixedWidthInteger > ( integerAsString integer: T ,
271- as: T . Type = T . self) -> Int
288+ public mutating func write< T: SignedInteger > ( integerAsString integer: T ,
289+ as: T . Type = T . self) -> Int
272290 {
273291 let bytesWritten = set ( integerAsString: integer, at: self . writerIndex)
274292 moveWriterIndex ( forwardBy: bytesWritten)
275293 return Int ( bytesWritten)
276294 }
277295
278296 @discardableResult
279- public mutating func set< T: FixedWidthInteger > ( integerAsString integer: T ,
280- at index: Int ,
281- as: T . Type = T . self) -> Int
297+ public mutating func set< T: SignedInteger > ( integerAsString integer: T ,
298+ at index: Int ,
299+ as: T . Type = T . self) -> Int
282300 {
283- var value = integer
301+ let charCount = integer. numberOfDecimalDigits + ( integer < 0 ? 1 : 0 )
302+ let avail = capacity - index
284303
285- #if true // slow, fixme
286- let len = String ( value, radix: 10 )
287- return set ( string: len, at: index) ! // TBD: why is this returning an Opt?
288- #else
289- return Swift . withUnsafeBytes ( of: & value) { ptr in
290- // TODO: do the itoa thing to make it fast
304+ if avail < charCount {
305+ changeCapacity ( to: capacity + ( charCount - avail) )
306+ }
307+
308+ self . withVeryUnsafeBytes { rbpp in
309+ let mrbpp = UnsafeMutableRawBufferPointer ( mutating: rbpp)
310+ let base = mrbpp. baseAddress!. assumingMemoryBound ( to: UInt8 . self)
311+ . advanced ( by: index)
312+ var cursor = base. advanced ( by: charCount)
313+
314+ let c0 : T = 48
315+ var negativeAbsoluteValue = integer < 0 ? integer : - integer
316+ repeat {
317+ cursor -= 1
318+ cursor. pointee = UInt8 ( c0 - ( negativeAbsoluteValue % 10 ) )
319+ negativeAbsoluteValue /= 10 ;
291320 }
292- #endif
321+ while negativeAbsoluteValue != 0
322+
323+ if integer < 0 {
324+ cursor -= 1
325+ cursor. pointee = 45 // -
326+ }
327+
328+ }
329+
330+ return charCount
293331 }
294332}
0 commit comments