forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSwiftPrivate.swift
98 lines (86 loc) · 2.68 KB
/
SwiftPrivate.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import SwiftShims
/// Convert the given numeric value to a hexidecimal string.
public func asHex<T : IntegerType>(x: T) -> String {
return "0x" + String(x.toIntMax(), radix: 16)
}
/// Convert the given sequence of numeric values to a string representing
/// their hexidecimal values.
public func asHex<
S: SequenceType
where
S.Generator.Element : IntegerType
>(x: S) -> String {
return "[ " + x.lazy.map { asHex($0) }.joinWithSeparator(", ") + " ]"
}
/// Compute the prefix sum of `seq`.
public func scan<
S : SequenceType, U
>(seq: S, _ initial: U, _ combine: (U, S.Generator.Element) -> U) -> [U] {
var result: [U] = []
result.reserveCapacity(seq.underestimateCount())
var runningResult = initial
for element in seq {
runningResult = combine(runningResult, element)
result.append(runningResult)
}
return result
}
public func randomShuffle<T>(a: [T]) -> [T] {
var result = a
for var i = a.count - 1; i != 0; --i {
// FIXME: 32 bits are not enough in general case!
let j = Int(rand32(exclusiveUpperBound: UInt32(i + 1)))
if i != j {
swap(&result[i], &result[j])
}
}
return result
}
public func gather<
C : CollectionType,
IndicesSequence : SequenceType
where
IndicesSequence.Generator.Element == C.Index
>(
collection: C, _ indices: IndicesSequence
) -> [C.Generator.Element] {
return Array(indices.map { collection[$0] })
}
public func scatter<T>(a: [T], _ idx: [Int]) -> [T] {
var result = a
for i in 0..<a.count {
result[idx[i]] = a[i]
}
return result
}
public func withArrayOfCStrings<R>(
args: [String], _ body: ([UnsafeMutablePointer<CChar>]) -> R
) -> R {
let argsLengths = Array(args.map { $0.utf8.count + 1 })
let argsOffsets = [ 0 ] + scan(argsLengths, 0, +)
let argsBufferSize = argsOffsets.last!
var argsBuffer: [UInt8] = []
argsBuffer.reserveCapacity(argsBufferSize)
for arg in args {
argsBuffer.appendContentsOf(arg.utf8)
argsBuffer.append(0)
}
return argsBuffer.withUnsafeBufferPointer {
(argsBuffer) in
let ptr = UnsafeMutablePointer<CChar>(argsBuffer.baseAddress)
var cStrings = argsOffsets.map { ptr + $0 }
cStrings[cStrings.count - 1] = nil
return body(cStrings)
}
}