paiza POH ando #_poh ツリ目セットチャレンジ (withVaList() on Swift Linux)


## 181226
import CoreFoundationはだめになったらしいです。詳細は https://qiita.com/cielavenir/items/63df19f876b384c1e1f2 。

## 160408追記
AtCoderではCoreFoundationに対応しましたのでこの怪奇な場合分けは不要です。念のため。

## 160329追記
どうもCoreFoundationはOSXでしか使えないらしい？とりあえず現状はこうすれば良いです。

```swift
//import CoreFoundation
#if _runtime(_ObjC)
import Darwin
#else
import Glibc
#endif
```

この状態で、vscanf等、正常に使えます。paizaや[AtCoder](http://language-test-201603.contest.atcoder.jp/submissions/679822)が進化したのはわしのおかげじゃな(ふぉふぉふぉ)

もし`_runtime(_ObjC)`が弾かれるなら`os(OSX)`にする。まあ、Swift処理系がiOSに入っているわけはないので大きな問題にはならないかと。

## 151213追記
[withVaList()を追加するプルリク](https://github.com/apple/swift/pull/339)が本体にマージされましたので、Swift 2.3以降ではここで紹介するハックは不要です。

----

| |URL|
|:--|:--|
|解答集|http://qiita.com/cielavenir/items/2fd430a3468a068feef5|
|withVaList()を書いた話|http://qiita.com/cielavenir/items/2598d47b97a7c9caf970|
|水着チャレンジ(のrobustな解法)|http://qiita.com/cielavenir/items/46f873191b37736d5062|

まあ、Rubyだと`puts 'Ann'*gets.to_i`で瞬殺なのですが、今回はSwiftが主体らしいので。

しかし、Swift、入力がきつい。
`NSString(data:stdIn.availableData。 encoding:NSUTF8StringEncoding)`とNSScannerを組み合わせるとなると、入力を読み切る必要がある。
なので私は`withUnsafePointer(&n){vscanf("%d",getVaList([COpaquePointer($0)]))}`を使っている。なお、scanfは不可。

しかし。[オープンソース版](https://github.com/apple/swift)のSwiftには、 **getVaList()は存在しない。**
ソースコードのpublic/core/VarArgs.swiftによると、

>// Excluded due to use of dynamic casting and Builtin.autorelease, neither
>// of which correctly work without the ObjC Runtime right now.

だそうです。悲惨。

というわけで、ソースを適当に改変してwithVaList()だけでも活かせるようにした。かなり大変でした＾＾；；

<del>ただし、(autoreleaseについては気にしなくて良さそうですが)dynamic castingが怪しいので、競技プログラミング以外では使わないほうが良いかも。</del>

というわけでまだ1問しか解けていないわけですが、これからがんばります…

```swift:tyama_paizapoh7a1.swift
//usr/bin/env xcrun swift $0 $@;exit

#if os(OSX)
//_runtime(_ObjC)

#else

//import CoreFoundation
// even if not using ObjC runtime, withValist() is possible.

/// Instances of conforming types can be encoded, and appropriately
/// passed, as elements of a C `va_list`.
///
/// This protocol is useful in presenting C "varargs" APIs natively in
/// Swift.  It only works for APIs that have a `va_list` variant, so
/// for example, it isn't much use if all you have is:
///
///     int f(int n, ...)
///
/// Given a version like this, though,
///
///     int f(int, va_list arguments)
///
/// you can write:
///
///     func swiftF(x: Int, arguments: CVarArgType...) -> Int {
///       return withVaList(arguments) { f(x, $0) }
///     }
public protocol CVarArgType {
  // Note: the protocol is public, but its requirement is stdlib-private.
  // That's because there are APIs operating on CVarArgType instances, but
  // defining conformances to CVarArgType outside of the standard library is
  // not supported.

  /// Transform `self` into a series of machine words that can be
  /// appropriately interpreted by C varargs.
  var _cVarArgEncoding: [Int] { get }
}

/// Floating point types need to be passed differently on x86_64
/// systems.  CoreGraphics uses this to make CGFloat work properly.
public // SPI(CoreGraphics)
protocol _CVarArgPassedAsDouble : CVarArgType {}

/// Some types require alignment greater than Int on some architectures.
public // SPI(CoreGraphics)
protocol _CVarArgAlignedType : CVarArgType {
  /// Return the required alignment in bytes of 
  /// the value returned by `_cVarArgEncoding`.
  var _cVarArgAlignment: Int { get }
}

#if arch(x86_64)
let _x86_64CountGPRegisters = 6
let _x86_64CountSSERegisters = 8
let _x86_64SSERegisterWords = 2
let _x86_64RegisterSaveWords = _x86_64CountGPRegisters + _x86_64CountSSERegisters * _x86_64SSERegisterWords
#endif

/// Invoke `f` with a C `va_list` argument derived from `args`.
public func withVaList<R>(args: [CVarArgType],
  _ f: CVaListPointer -> R) -> R {
  let builder = VaListBuilder()
  for a in args {
    builder.append(a)
  }
  return withVaList(builder, f)
}

/// Invoke `f` with a C `va_list` argument derived from `builder`.
public func withVaList<R>(builder: VaListBuilder,
  _ f: CVaListPointer -> R) -> R {
#if arch(x86_64)
  builder.header.reg_save_area = builder.storage._baseAddressIfContiguous
  builder.header.overflow_arg_area
    = builder.storage._baseAddressIfContiguous + _x86_64RegisterSaveWords
  let result = withUnsafeMutablePointer(&builder.header) {
    return f(CVaListPointer(_fromUnsafeMutablePointer:$0))
  }
#else
  let result = withUnsafeMutablePointer(&builder.storage) {
    return f(CVaListPointer(_fromUnsafeMutablePointer:$0))
  }
#endif
  _fixLifetime(builder)
  return result
}

@warn_unused_result
public func _encodeBitsAsWords<T : CVarArgType>(x: T) -> [Int] {
  let result = [Int](
    count: (sizeof(T.self) + sizeof(Int.self) - 1) / sizeof(Int.self),
    repeatedValue: 0)
  var tmp = x
  withUnsafeMutablePointer(&tmp) {
    UnsafeMutablePointer(result._baseAddressIfContiguous).assignFrom($0,count:sizeof(T.self)/sizeof(Int.self))
  }
  return result
}

// CVarArgType conformances for the integer types.  Everything smaller
// than a CInt must be promoted to CInt or CUnsignedInt before
// encoding.

// Signed types
extension Int : CVarArgType {
  /// Transform `self` into a series of machine words that can be
  /// appropriately interpreted by C varargs.
  public var _cVarArgEncoding: [Int] {
    return _encodeBitsAsWords(self)
  }
}

extension Int64 : CVarArgType, _CVarArgAlignedType {
  /// Transform `self` into a series of machine words that can be
  /// appropriately interpreted by C varargs.
  public var _cVarArgEncoding: [Int] {
    return _encodeBitsAsWords(self)
  }

  /// Return the required alignment in bytes of 
  /// the value returned by `_cVarArgEncoding`.
  public var _cVarArgAlignment: Int {
    // FIXME: alignof differs from the ABI alignment on some architectures
    return alignofValue(self)
  }
}

extension Int32 : CVarArgType {
  /// Transform `self` into a series of machine words that can be
  /// appropriately interpreted by C varargs.
  public var _cVarArgEncoding: [Int] {
    return _encodeBitsAsWords(self)
  }
}

extension Int16 : CVarArgType {
  /// Transform `self` into a series of machine words that can be
  /// appropriately interpreted by C varargs.
  public var _cVarArgEncoding: [Int] {
    return _encodeBitsAsWords(CInt(self))
  }
}

extension Int8 : CVarArgType {
  /// Transform `self` into a series of machine words that can be
  /// appropriately interpreted by C varargs.
  public var _cVarArgEncoding: [Int] {
    return _encodeBitsAsWords(CInt(self))
  }
}

// Unsigned types
extension UInt : CVarArgType {
  /// Transform `self` into a series of machine words that can be
  /// appropriately interpreted by C varargs.
  public var _cVarArgEncoding: [Int] {
    return _encodeBitsAsWords(self)
  }
}

extension UInt64 : CVarArgType, _CVarArgAlignedType {
  /// Transform `self` into a series of machine words that can be
  /// appropriately interpreted by C varargs.
  public var _cVarArgEncoding: [Int] {
    return _encodeBitsAsWords(self)
  }

  /// Return the required alignment in bytes of 
  /// the value returned by `_cVarArgEncoding`.
  public var _cVarArgAlignment: Int {
    // FIXME: alignof differs from the ABI alignment on some architectures
    return alignofValue(self)
  }
}

extension UInt32 : CVarArgType {
  /// Transform `self` into a series of machine words that can be
  /// appropriately interpreted by C varargs.
  public var _cVarArgEncoding: [Int] {
    return _encodeBitsAsWords(self)
  }
}

extension UInt16 : CVarArgType {
  /// Transform `self` into a series of machine words that can be
  /// appropriately interpreted by C varargs.
  public var _cVarArgEncoding: [Int] {
    return _encodeBitsAsWords(CUnsignedInt(self))
  }
}

extension UInt8 : CVarArgType {
  /// Transform `self` into a series of machine words that can be
  /// appropriately interpreted by C varargs.
  public var _cVarArgEncoding: [Int] {
    return _encodeBitsAsWords(CUnsignedInt(self))
  }
}

extension COpaquePointer : CVarArgType {
  /// Transform `self` into a series of machine words that can be
  /// appropriately interpreted by C varargs.
  public var _cVarArgEncoding: [Int] {
    return _encodeBitsAsWords(self)
  }
}

extension UnsafePointer : CVarArgType {
  /// Transform `self` into a series of machine words that can be
  /// appropriately interpreted by C varargs.
  public var _cVarArgEncoding: [Int] {
    return _encodeBitsAsWords(self)
  }
}

extension UnsafeMutablePointer : CVarArgType {
  /// Transform `self` into a series of machine words that can be
  /// appropriately interpreted by C varargs.
  public var _cVarArgEncoding: [Int] {
    return _encodeBitsAsWords(self)
  }
}

extension Float : _CVarArgPassedAsDouble, _CVarArgAlignedType {
  /// Transform `self` into a series of machine words that can be
  /// appropriately interpreted by C varargs.
  public var _cVarArgEncoding: [Int] {
    return _encodeBitsAsWords(Double(self))
  }

  /// Return the required alignment in bytes of 
  /// the value returned by `_cVarArgEncoding`.
  public var _cVarArgAlignment: Int {
    // FIXME: alignof differs from the ABI alignment on some architectures
    return alignofValue(Double(self))
  }
}

extension Double : _CVarArgPassedAsDouble, _CVarArgAlignedType {
  /// Transform `self` into a series of machine words that can be
  /// appropriately interpreted by C varargs.
  public var _cVarArgEncoding: [Int] {
    return _encodeBitsAsWords(self)
  }

  /// Return the required alignment in bytes of 
  /// the value returned by `_cVarArgEncoding`.
  public var _cVarArgAlignment: Int {
    // FIXME: alignof differs from the ABI alignment on some architectures
    return alignofValue(self)
  }
}

#if !arch(x86_64)

/// An object that can manage the lifetime of storage backing a
/// `CVaListPointer`.
final public class VaListBuilder {

  func append(arg: CVarArgType) {
    // Write alignment padding if necessary.
    // This is needed on architectures where the ABI alignment of some 
    // supported vararg type is greater than the alignment of Int.
    // FIXME: this implementation is not portable because
    // alignof differs from the ABI alignment on some architectures
#if os(watchOS) && arch(arm)   // FIXME: rdar://21203036 should be arch(armv7k)
    if let arg = arg as? _CVarArgAlignedType {
      let alignmentInWords = arg._cVarArgAlignment / sizeof(Int)
      let misalignmentInWords = count % alignmentInWords
      if misalignmentInWords != 0 {
        let paddingInWords = alignmentInWords - misalignmentInWords
        appendWords([Int](count: paddingInWords, repeatedValue: -1))
      }
    }
#endif

    // Write the argument's value itself.
    appendWords(arg._cVarArgEncoding)
  }

  // Manage storage that is accessed as Words 
  // but possibly more aligned than that.
  // FIXME: this should be packaged into a better storage type

  func appendWords(words: [Int]) {
    let newCount = count + words.count
    if newCount > allocated {
      let oldAllocated = allocated
      let oldStorage = storage
      let oldCount = count

      allocated = max(newCount, allocated * 2)
      storage = allocStorage(wordCount: allocated)
      // count is updated below

      if oldStorage != nil {
        storage.moveInitializeFrom(oldStorage, count:oldCount)
        deallocStorage(wordCount: oldAllocated, 
          storage: oldStorage)
      }
    }

    for word in words {
      storage[count++] = word
    }
  }

  @warn_unused_result
  func rawSizeAndAlignment(wordCount: Int) -> (Builtin.Word, Builtin.Word) {
    return ((wordCount * strideof(Int.self))._builtinWordValue, 
      requiredAlignmentInBytes._builtinWordValue)
  }

  @warn_unused_result
  func allocStorage(wordCount wordCount: Int) -> UnsafeMutablePointer<Int> {
    let (rawSize, rawAlignment) = rawSizeAndAlignment(wordCount)
    let rawStorage = Builtin.allocRaw(rawSize, rawAlignment)
    return UnsafeMutablePointer<Int>(rawStorage)
  }

  func deallocStorage(
    wordCount wordCount: Int,
    storage: UnsafeMutablePointer<Int>
  ) {
    let (rawSize, rawAlignment) = rawSizeAndAlignment(wordCount)
    Builtin.deallocRaw(storage._rawValue, rawSize, rawAlignment)
  }

  deinit {
    if storage != nil {
      deallocStorage(wordCount: allocated, storage: storage)
    }
  }

  // FIXME: alignof differs from the ABI alignment on some architectures
  let requiredAlignmentInBytes = alignof(Double.self)
  var count = 0
  var allocated = 0
  var storage: UnsafeMutablePointer<Int> = nil
}

#else

/// An object that can manage the lifetime of storage backing a
/// `CVaListPointer`.
final public class VaListBuilder {

  struct Header {
    var gp_offset = CUnsignedInt(0)
    var fp_offset = CUnsignedInt(_x86_64CountGPRegisters * strideof(Int.self))
    var overflow_arg_area: UnsafeMutablePointer<Int> = nil
    var reg_save_area: UnsafeMutablePointer<Int> = nil
  }

  init() {
    // prepare the register save area
    storage = Array(count: _x86_64RegisterSaveWords, repeatedValue: 0)
  }

  func append(arg: CVarArgType) {
    var encoded = arg._cVarArgEncoding

    if arg is _CVarArgPassedAsDouble
      && sseRegistersUsed < _x86_64CountSSERegisters {
      var startIndex = _x86_64CountGPRegisters
           + (sseRegistersUsed * _x86_64SSERegisterWords)
      for w in encoded {
        storage[startIndex] = w
        ++startIndex
      }
      ++sseRegistersUsed
    }
    else if encoded.count == 1 && gpRegistersUsed < _x86_64CountGPRegisters {
      storage[gpRegistersUsed++] = encoded[0]
    }
    else {
      for w in encoded {
        storage.append(w)
      }
    }
  }

  var gpRegistersUsed = 0
  var sseRegistersUsed = 0

  final  // Property must be final since it is used by Builtin.addressof.
  var header = Header()
  var storage: [Int]
}

#endif

#endif // _runtime(_ObjC)

import CoreFoundation

var n=0;
for withUnsafeMutablePointer(&n){withVaList([COpaquePointer($0)]){vscanf("%d",$0)}};n>0;n-- {
    print("Ann",terminator:"")
}
```