//===--- UnsafePointer.swift.gyb ------------------------------*- swift -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

%import gyb

% for mutable in (True, False):
%  Self = 'UnsafeMutablePointer' if mutable else 'UnsafePointer'
%  a_Self = 'an `UnsafeMutablePointer`' if mutable else 'an `UnsafePointer`'
%  Mutable = 'Mutable' if mutable else ''
/// A pointer for accessing ${'and manipulating' if mutable else ''} data of a
/// specific type.
///
/// You use instances of the `Unsafe${Mutable}Pointer` type to access data of a
/// specific type in memory. The type of data that a pointer can access is the
/// pointer's `Pointee` type. `Unsafe${Mutable}Pointer` provides no automated
/// memory management or alignment guarantees. You are responsible for
/// handling the life cycle of any memory you work with through unsafe
/// pointers to avoid leaks or undefined behavior.
///
/// Memory that you manually manage can be either *untyped* or *bound* to a
/// specific type. You use the `Unsafe${Mutable}Pointer` type to access and
/// manage memory that has been bound to a specific type.
///
/// Understanding a Pointer's Memory State
/// ======================================
///
/// The memory referenced by an `Unsafe${Mutable}Pointer` instance can be in
/// one of several states. Many pointer operations must only be applied to
/// pointers with memory in a specific state---you must keep track of the
/// state of the memory you are working with and understand the changes to
/// that state that different operations perform. Memory can be untyped and
/// uninitialized, bound to a type and uninitialized, or bound to a type and
/// initialized to a value. Finally, memory that was allocated previously may
/// have been deallocated, leaving existing pointers referencing unallocated
/// memory.
///
/// Uninitialized Memory
/// --------------------
///
/// Memory that has just been allocated through a typed pointer or has been
/// deinitialized is in an *uninitialized* state. Uninitialized memory must be
/// initialized before it can be accessed for reading.
///
%if mutable:
/// You can use methods like `initialize(to:count:)`, `initialize(from:count:)`,
/// and `moveInitialize(from:count:)` to initialize the memory referenced by a
/// pointer with a value or series of values.
///
% end
/// Initialized Memory
/// ------------------
///
/// *Initialized* memory has a value that can be read using a pointer's
/// `pointee` property or through subscript notation. In the following
/// example, `ptr` is a pointer to memory initialized with a value of `23`:
///
///     let ptr: Unsafe${Mutable}Pointer<Int> = ...
///     // ptr.pointee == 23
///     // ptr[0] == 23
///
/// Accessing a Pointer's Memory as a Different Type
/// ================================================
///
/// When you access memory through an `Unsafe${Mutable}Pointer` instance, the
/// `Pointee` type must be consistent with the bound type of the memory. If
/// you do need to access memory that is bound to one type as a different
/// type, Swift's pointer types provide type-safe ways to temporarily or
/// permanently change the bound type of the memory, or to load typed
/// instances directly from raw memory.
///
/// An `Unsafe${Mutable}Pointer<UInt8>` instance allocated with eight bytes of
/// memory, `uint8Pointer`, will be used for the examples below.
///
% if mutable:
///     var bytes: [UInt8] = [39, 77, 111, 111, 102, 33, 39, 0]
///     let uint8Pointer = UnsafeMutablePointer<UInt8>.allocate(capacity: 8)
///     uint8Pointer.initialize(from: &bytes, count: 8)
% else:
///     let uint8Pointer: UnsafePointer<UInt8> = fetchEightBytes()
% end
///
/// When you only need to temporarily access a pointer's memory as a different
/// type, use the `withMemoryRebound(to:capacity:)` method. For example, you
/// can use this method to call an API that expects a pointer to a different
/// type that is layout compatible with your pointer's `Pointee`. The following
/// code temporarily rebinds the memory that `uint8Pointer` references from
/// `UInt8` to `Int8` to call the imported C `strlen` function.
///
///     // Imported from C
///     func strlen(_ __s: UnsafePointer<Int8>!) -> UInt
///
///     let length = uint8Pointer.withMemoryRebound(to: Int8.self, capacity: 8) {
///         return strlen($0)
///     }
///     // length == 7
///
/// When you need to permanently rebind memory to a different type, first
/// obtain a raw pointer to the memory and then call the
/// `bindMemory(to:capacity:)` method on the raw pointer. The following
/// example binds the memory referenced by `uint8Pointer` to one instance of
/// the `UInt64` type:
///
///     let uint64Pointer = Unsafe${Mutable}RawPointer(uint8Pointer)
///                               .bindMemory(to: UInt64.self, capacity: 1)
///
/// After rebinding the memory referenced by `uint8Pointer` to `UInt64`,
/// accessing that pointer's referenced memory as a `UInt8` instance is
/// undefined.
///
///     var fullInteger = uint64Pointer.pointee          // OK
///     var firstByte = uint8Pointer.pointee             // undefined
///
% if mutable:
/// Alternatively, you can access the same memory as a different type without
/// rebinding through untyped memory access, so long as the bound type and the
/// destination type are trivial types. Convert your pointer to an
/// `UnsafeMutableRawPointer` instance and then use the raw pointer's
/// `load(fromByteOffset:as:)` and `storeBytes(of:toByteOffset:as:)` methods
/// to read and write values.
% else:
/// Alternatively, you can access the same memory as a different type without
/// rebinding through untyped memory access, so long as the bound type and the
/// destination type are trivial types. Convert your pointer to an
/// `UnsafeRawPointer` instance and then use the raw pointer's
/// `load(fromByteOffset:as:)` method to read values.
% end
///
///     let rawPointer = Unsafe${Mutable}RawPointer(uint64Pointer)
///     fullInteger = rawPointer.load(as: UInt64.self)   // OK
///     firstByte = rawPointer.load(as: UInt8.self)      // OK
///
/// Performing Typed Pointer Arithmetic
/// ===================================
///
/// Pointer arithmetic with a typed pointer is counted in strides of the
/// pointer's `Pointee` type. When you add to or subtract from an `${Self}`
/// instance, the result is a new pointer of the same type, offset by that
/// number of instances of the `Pointee` type.
///
///     // 'intPointer' points to memory initialized with [10, 20, 30, 40]
///     let intPointer: ${Self}<Int> = ...
///
///     // Load the first value in memory
///     let x = intPointer.pointee
///     // x == 10
///
///     // Load the third value in memory
///     let offsetPointer = intPointer + 2
///     let y = offsetPointer.pointee
///     // y == 30
///
/// You can also use subscript notation to access the value in memory at a
/// specific offset.
///
///     let z = intPointer[2]
///     // z == 30
///
/// Implicit Casting and Bridging
/// =============================
///
%if mutable:
/// When calling a function or method with an `${Self}` parameter, you can pass
/// an instance of that specific pointer type or use Swift's implicit bridging
/// to pass a compatible pointer.
///
/// For example, the `printInt(atAddress:)` function in the following code
/// sample expects an `${Self}<Int>` instance as its first parameter:
///
///     func printInt(atAddress p: ${Self}<Int>) {
///         print(p.pointee)
///     }
///
/// As is typical in Swift, you can call the `printInt(atAddress:)` function
/// with an `${Self}` instance. This example passes `intPointer`, a mutable
/// pointer to an `Int` value, to `print(address:)`.
///
///     printInt(atAddress: intPointer)
///     // Prints "42"
///
/// Alternatively, you can use Swift's *implicit bridging* to pass a pointer to
/// an instance or to the elements of an array. The following example passes a
/// pointer to the `value` variable by using inout syntax:
///
///     var value: Int = 23
///     printInt(atAddress: &value)
///     // Prints "23"
///
/// A mutable pointer to the elements of an array is implicitly created when
/// you pass the array using inout syntax. This example uses implicit bridging
/// to pass a pointer to the elements of `numbers` when calling
/// `printInt(atAddress:)`.
///
///     var numbers = [5, 10, 15, 20]
///     printInt(atAddress: &numbers)
///     // Prints "5"
///
/// No matter which way you call `printInt(atAddress:)`, Swift's type safety
/// guarantees that you can only pass a pointer to the type required by the
/// function---in this case, a pointer to an `Int`.
%else:
/// When calling a function or method with an `${Self}` parameter, you can pass
/// an instance of that specific pointer type, pass an instance of a
/// compatible pointer type, or use Swift's implicit bridging to pass a
/// compatible pointer.
///
/// For example, the `printInt(atAddress:)` function in the following code
/// sample expects an `${Self}<Int>` instance as its first parameter:
///
///     func printInt(atAddress p: ${Self}<Int>) {
///         print(p.pointee)
///     }
///
/// As is typical in Swift, you can call the `printInt(atAddress:)` function
/// with an `${Self}` instance. This example passes `intPointer`, a pointer to
/// an `Int` value, to `print(address:)`.
///
///     printInt(atAddress: intPointer)
///     // Prints "42"
///
/// Because a mutable typed pointer can be implicitly cast to an immutable
/// pointer with the same `Pointee` type when passed as a parameter, you can
/// also call `printInt(atAddress:)` with an `UnsafeMutablePointer` instance.
///
///     let mutableIntPointer = UnsafeMutablePointer(mutating: intPointer)
///     printInt(atAddress: mutableIntPointer)
///     // Prints "42"
///
/// Alternatively, you can use Swift's *implicit bridging* to pass a pointer to
/// an instance or to the elements of an array. The following example passes a
/// pointer to the `value` variable by using inout syntax:
///
///     var value: Int = 23
///     printInt(atAddress: &value)
///     // Prints "23"
///
/// An immutable pointer to the elements of an array is implicitly created when
/// you pass the array as an argument. This example uses implicit bridging to
/// pass a pointer to the elements of `numbers` when calling
/// `printInt(atAddress:)`.
///
///     let numbers = [5, 10, 15, 20]
///     printInt(atAddress: numbers)
///     // Prints "5"
///
/// You can also use inout syntax to pass a mutable pointer to the elements of
/// an array. Because `printInt(atAddress:)` requires an immutable pointer,
/// although this is syntactically valid, it isn't necessary.
///
///     var mutableNumbers = numbers
///     printInt(atAddress: &mutableNumbers)
///
/// No matter which way you call `printInt(atAddress:)`, Swift's type safety
/// guarantees that you can only pass a pointer to the type required by the
/// function---in this case, a pointer to an `Int`.
%end
///
/// - Important: The pointer created through implicit bridging of an instance
///   or of an array's elements is only valid during the execution of the
///   called function. Escaping the pointer to use after the execution of the
///   function is undefined behavior. In particular, do not use implicit
///   bridging when calling an `${Self}` initializer.
///
///       var number = 5
///       let numberPointer = Unsafe${Mutable}Pointer<Int>(&number)
///       // Accessing 'numberPointer' is undefined behavior.
@_fixed_layout
public struct ${Self}<Pointee>: _Pointer {

  /// A type that represents the distance between two pointers.
  public typealias Distance = Int

  /// The underlying raw (untyped) pointer.
  public let _rawValue: Builtin.RawPointer

  /// Creates ${a_Self} from a builtin raw pointer.
  @inlinable // FIXME(sil-serialize-all)
  @_transparent
  public init(_ _rawValue : Builtin.RawPointer) {
    self._rawValue = _rawValue
  }

  /// Creates a new typed pointer from the given opaque pointer.
  ///
  /// - Parameter from: The opaque pointer to convert to a typed pointer.
  @inlinable // FIXME(sil-serialize-all)
  @_transparent
  public init(_ from : OpaquePointer) {
    _rawValue = from._rawValue
  }

  /// Creates a new typed pointer from the given opaque pointer.
  ///
  /// - Parameter from: The opaque pointer to convert to a typed pointer. If
  ///   `from` is `nil`, the result of this initializer is `nil`.
  @inlinable // FIXME(sil-serialize-all)
  @_transparent
  public init?(_ from : OpaquePointer?) {
    guard let unwrapped = from else { return nil }
    self.init(unwrapped)
  }

  /// Creates a new typed pointer from the given address, specified as a bit
  /// pattern.
  ///
  /// The address passed as `bitPattern` must have the correct alignment for
  /// the pointer's `Pointee` type. That is,
  /// `bitPattern % MemoryLayout<Pointee>.alignment` must be `0`.
  ///
  /// - Parameter bitPattern: A bit pattern to use for the address of the new
  ///   pointer. If `bitPattern` is zero, the result is `nil`.
  @inlinable // FIXME(sil-serialize-all)
  @_transparent
  public init?(bitPattern: Int) {
    if bitPattern == 0 { return nil }
    self._rawValue = Builtin.inttoptr_Word(bitPattern._builtinWordValue)
  }

  /// Creates a new typed pointer from the given address, specified as a bit
  /// pattern.
  ///
  /// The address passed as `bitPattern` must have the correct alignment for
  /// the pointer's `Pointee` type. That is,
  /// `bitPattern % MemoryLayout<Pointee>.alignment` must be `0`.
  ///
  /// - Parameter bitPattern: A bit pattern to use for the address of the new
  ///   pointer. If `bitPattern` is zero, the result is `nil`.
  @inlinable // FIXME(sil-serialize-all)
  @_transparent
  public init?(bitPattern: UInt) {
    if bitPattern == 0 { return nil }
    self._rawValue = Builtin.inttoptr_Word(bitPattern._builtinWordValue)
  }

  /// Creates a new pointer from the given typed pointer.
  ///
  /// - Parameter other: The typed pointer to convert.
  @inlinable // FIXME(sil-serialize-all)
  @_transparent
  public init(_ other: ${Self}<Pointee>) {
    self = other
  }

  /// Creates a new pointer from the given typed pointer.
  ///
  /// - Parameter other: The typed pointer to convert. If `other` is `nil`, the
  ///   result is `nil`.
  @inlinable // FIXME(sil-serialize-all)
  @_transparent
  public init?(_ other: ${Self}<Pointee>?) {
    guard let unwrapped = other else { return nil }
    self = unwrapped
  }

%  if mutable:
  /// Creates a mutable typed pointer referencing the same memory as the given
  /// immutable pointer.
  ///
  /// - Parameter other: The immutable pointer to convert.
  @inlinable // FIXME(sil-serialize-all)
  @_transparent
  public init(mutating other: UnsafePointer<Pointee>) {
    self._rawValue = other._rawValue
  }

  /// Creates a mutable typed pointer referencing the same memory as the given
  /// immutable pointer.
  ///
  /// - Parameter other: The immutable pointer to convert. If `other` is `nil`,
  ///   the result is `nil`.
  @inlinable // FIXME(sil-serialize-all)
  @_transparent
  public init?(mutating other: UnsafePointer<Pointee>?) {
    guard let unwrapped = other else { return nil }
    self.init(mutating: unwrapped)
  }
% else:
  /// Creates an immutable typed pointer referencing the same memory as the
  /// given mutable pointer.
  ///
  /// - Parameter other: The pointer to convert.
  @inlinable // FIXME(sil-serialize-all)
  @_transparent
  public init(_ other: UnsafeMutablePointer<Pointee>) {
    self._rawValue = other._rawValue
  }

  /// Creates an immutable typed pointer referencing the same memory as the
  /// given mutable pointer.
  ///
  /// - Parameter other: The pointer to convert. If `other` is `nil`, the
  ///   result is `nil`.
  @inlinable // FIXME(sil-serialize-all)
  @_transparent
  public init?(_ other: UnsafeMutablePointer<Pointee>?) {
    guard let unwrapped = other else { return nil }
    self.init(unwrapped)
  }
%  end

%  if mutable:
  /// Allocates uninitialized memory for the specified number of instances of
  /// type `Pointee`.
  ///
  /// The resulting pointer references a region of memory that is bound to
  /// `Pointee` and is `count * MemoryLayout<Pointee>.stride` bytes in size.
  ///
  /// The following example allocates enough new memory to store four `Int`
  /// instances and then initializes that memory with the elements of a range.
  ///
  ///     let intPointer = UnsafeMutablePointer<Int>.allocate(capacity: 4)
  ///     for i in 0..<4 {
  ///         (intPointer + i).initialize(to: i)
  ///     }
  ///     print(intPointer.pointee)
  ///     // Prints "0"
  ///
  /// When you allocate memory, always remember to deallocate once you're
  /// finished.
  ///
  ///     intPointer.deallocate()
  ///
  /// - Parameter count: The amount of memory to allocate, counted in instances
  ///   of `Pointee`.
  @inlinable
  public static func allocate(capacity count: Int)
    -> UnsafeMutablePointer<Pointee> {
    let size = MemoryLayout<Pointee>.stride * count
    let rawPtr =
      Builtin.allocRaw(size._builtinWordValue, Builtin.alignof(Pointee.self))
    Builtin.bindMemory(rawPtr, count._builtinWordValue, Pointee.self)
    return UnsafeMutablePointer(rawPtr)
  }
  
  @available(swift, deprecated: 4.1, obsoleted: 5.0.0, message: "Swift currently only supports freeing entire heap blocks, use deallocate() instead")
  public func deallocate(capacity _: Int) { 
    self.deallocate()
  }

%  end

  /// Deallocates the memory block previously allocated at this pointer.
  ///
  /// This pointer must be a pointer to the start of a previously allocated memory 
  /// block. The memory must not be initialized or `Pointee` must be a trivial type.
  @inlinable
  public func deallocate() {
    Builtin.deallocRaw(_rawValue, (-1)._builtinWordValue, (-1)._builtinWordValue)
  }

  /// Accesses the instance referenced by this pointer.
  ///
%  if mutable:
  /// When reading from the `pointee` property, the instance referenced by this
  /// pointer must already be initialized. When `pointee` is used as the left
  /// side of an assignment, the instance must be initialized or this
  /// pointer's `Pointee` type must be a trivial type.
  ///
  /// Do not assign an instance of a nontrivial type through `pointee` to
  /// uninitialized memory. Instead, use an initializing method, such as
  /// `initialize(to:count:)`.
%  else:
  /// When reading from the `pointee` property, the instance referenced by
  /// this pointer must already be initialized.
%  end
  @inlinable // FIXME(sil-serialize-all)
  public var pointee: Pointee {
%  if mutable:
    @_transparent unsafeAddress {
      return UnsafePointer(self)
    }
    @_transparent nonmutating unsafeMutableAddress {
      return self
    }
%  else:
    @_transparent unsafeAddress {
      return self
    }
%  end
  }

%  if mutable:
  @available(swift, deprecated: 4.1, obsoleted: 5.0.0, renamed: "initialize(repeating:count:)")
  public func initialize(to newValue: Pointee, count: Int = 1) { 
    initialize(repeating: newValue, count: count)
  }

  /// Initializes this pointer's memory with the specified number of
  /// consecutive copies of the given value.
  ///
  /// The destination memory must be uninitialized or the pointer's `Pointee`
  /// must be a trivial type. After a call to `initialize(repeating:count:)`, the
  /// memory referenced by this pointer is initialized.
  ///
  /// - Parameters:
  ///   - repeatedValue: The instance to initialize this pointer's memory with.
  ///   - count: The number of consecutive copies of `newValue` to initialize.
  ///     `count` must not be negative. 
  @inlinable
  public func initialize(repeating repeatedValue: Pointee, count: Int) {
    // FIXME: add tests (since the `count` has been added)
    _debugPrecondition(count >= 0,
      "${Self}.initialize(repeating:count:): negative count")
    // Must not use `initializeFrom` with a `Collection` as that will introduce
    // a cycle.
    for offset in 0..<count {
      Builtin.initialize(repeatedValue, (self + offset)._rawValue)
    }
  }
  
  /// Initializes this pointer's memory with a single instance of the given value.
  ///
  /// The destination memory must be uninitialized or the pointer's `Pointee`
  /// must be a trivial type. After a call to `initialize(to:)`, the
  /// memory referenced by this pointer is initialized. Calling this method is 
  /// roughly equivalent to calling `initialize(repeating:count:)` with a 
  /// `count` of 1.
  ///
  /// - Parameters:
  ///   - value: The instance to initialize this pointer's pointee to.
  @inlinable
  public func initialize(to value: Pointee) {
    Builtin.initialize(value, self._rawValue)
  }

  /// Retrieves and returns the referenced instance, returning the pointer's
  /// memory to an uninitialized state.
  ///
  /// Calling the `move()` method on a pointer `p` that references memory of
  /// type `T` is equivalent to the following code, aside from any cost and
  /// incidental side effects of copying and destroying the value:
  ///
  ///     let value: T = {
  ///         defer { p.deinitialize(count: 1) }
  ///         return p.pointee
  ///     }()
  ///
  /// The memory referenced by this pointer must be initialized. After calling
  /// `move()`, the memory is uninitialized.
  ///
  /// - Returns: The instance referenced by this pointer.
  @inlinable
  public func move() -> Pointee {
    return Builtin.take(_rawValue)
  }

  /// Replaces this pointer's memory with the specified number of
  /// consecutive copies of the given value.
  ///
  /// The region of memory starting at this pointer and covering `count`
  /// instances of the pointer's `Pointee` type must be initialized or
  /// `Pointee` must be a trivial type. After calling
  /// `assign(repeating:count:)`, the region is initialized.
  ///
  /// - Parameters:
  ///   - repeatedValue: The instance to assign this pointer's memory to.
  ///   - count: The number of consecutive copies of `newValue` to assign.
  ///     `count` must not be negative. 
  @inlinable
  public func assign(repeating repeatedValue: Pointee, count: Int) {
    _debugPrecondition(count >= 0, "${Self}.assign(repeating:count:) with negative count")
    for i in 0..<count {
      self[i] = repeatedValue
    }
  }
  
  /// Replaces this pointer's initialized memory with the specified number of
  /// instances from the given pointer's memory.
  ///
  /// The region of memory starting at this pointer and covering `count`
  /// instances of the pointer's `Pointee` type must be initialized or
  /// `Pointee` must be a trivial type. After calling
  /// `assign(from:count:)`, the region is initialized.
  ///
  /// - Note: Returns without performing work if `self` and `source` are equal.
  ///
  /// - Parameters:
  ///   - source: A pointer to at least `count` initialized instances of type
  ///     `Pointee`. The memory regions referenced by `source` and this
  ///     pointer may overlap.
  ///   - count: The number of instances to copy from the memory referenced by
  ///     `source` to this pointer's memory. `count` must not be negative.
  @inlinable
  public func assign(from source: UnsafePointer<Pointee>, count: Int) {
    _debugPrecondition(
      count >= 0, "${Self}.assign with negative count")
    if UnsafePointer(self) < source || UnsafePointer(self) >= source + count {
      // assign forward from a disjoint or following overlapping range.
      Builtin.assignCopyArrayFrontToBack(
        Pointee.self, self._rawValue, source._rawValue, count._builtinWordValue)
      // This builtin is equivalent to:
      // for i in 0..<count {
      //   self[i] = source[i]
      // }
    }
    else if UnsafePointer(self) != source {
      // assign backward from a non-following overlapping range.
      Builtin.assignCopyArrayBackToFront(
        Pointee.self, self._rawValue, source._rawValue, count._builtinWordValue)
      // This builtin is equivalent to:
      // var i = count-1
      // while i >= 0 {
      //   self[i] = source[i]
      //   i -= 1
      // }
    }
  }

  /// Moves instances from initialized source memory into the uninitialized
  /// memory referenced by this pointer, leaving the source memory
  /// uninitialized and the memory referenced by this pointer initialized.
  ///
  /// The region of memory starting at this pointer and covering `count`
  /// instances of the pointer's `Pointee` type must be uninitialized or
  /// `Pointee` must be a trivial type. After calling
  /// `moveInitialize(from:count:)`, the region is initialized and the memory
  /// region `source..<(source + count)` is uninitialized.
  ///
  /// - Parameters:
  ///   - source: A pointer to the values to copy. The memory region
  ///     `source..<(source + count)` must be initialized. The memory regions
  ///     referenced by `source` and this pointer may overlap.
  ///   - count: The number of instances to move from `source` to this
  ///     pointer's memory. `count` must not be negative.
  @inlinable
  public func moveInitialize(from source: ${Self}, count: Int) {
    _debugPrecondition(
      count >= 0, "${Self}.moveInitialize with negative count")
    if self < source || self >= source + count {
      // initialize forward from a disjoint or following overlapping range.
      Builtin.takeArrayFrontToBack(
        Pointee.self, self._rawValue, source._rawValue, count._builtinWordValue)
      // This builtin is equivalent to:
      // for i in 0..<count {
      //   (self + i).initialize(to: (source + i).move())
      // }
    }
    else {
      // initialize backward from a non-following overlapping range.
      Builtin.takeArrayBackToFront(
        Pointee.self, self._rawValue, source._rawValue, count._builtinWordValue)
      // This builtin is equivalent to:
      // var src = source + count
      // var dst = self + count
      // while dst != self {
      //   (--dst).initialize(to: (--src).move())
      // }
    }
  }

  /// Initializes the memory referenced by this pointer with the values
  /// starting at the given pointer.
  ///
  /// The region of memory starting at this pointer and covering `count`
  /// instances of the pointer's `Pointee` type must be uninitialized or
  /// `Pointee` must be a trivial type. After calling
  /// `initialize(from:count:)`, the region is initialized.
  ///
  /// - Parameters:
  ///   - source: A pointer to the values to copy. The memory region
  ///     `source..<(source + count)` must be initialized. The memory regions
  ///     referenced by `source` and this pointer must not overlap.
  ///   - count: The number of instances to move from `source` to this
  ///     pointer's memory. `count` must not be negative.
  @inlinable
  public func initialize(from source: UnsafePointer<Pointee>, count: Int) {
    _debugPrecondition(
      count >= 0, "${Self}.initialize with negative count")
    _debugPrecondition(
      UnsafePointer(self) + count <= source ||
      source + count <= UnsafePointer(self),
      "${Self}.initialize overlapping range")
    Builtin.copyArray(
      Pointee.self, self._rawValue, source._rawValue, count._builtinWordValue)
    // This builtin is equivalent to:
    // for i in 0..<count {
    //   (self + i).initialize(to: source[i])
    // }
  }

  /// Initializes memory starting at this pointer's address with the elements
  /// of the given collection.
  ///
  /// The region of memory starting at this pointer and covering `source.count`
  /// instances of the pointer's `Pointee` type must be uninitialized or
  /// `Pointee` must be a trivial type. After calling `initialize(from:)`, the
  /// region is initialized.
  ///
  /// - Parameter source: A collection of elements of the pointer's `Pointee`
  ///   type.
  // This is fundamentally unsafe since collections can underreport their count.
  @inlinable
  @available(*, deprecated, message: "it will be removed in Swift 4.0.  Please use 'UnsafeMutableBufferPointer.initialize(from:)' instead")
  public func initialize<C : Collection>(from source: C)
    where C.Element == Pointee {
    let buf = UnsafeMutableBufferPointer(start: self, count: numericCast(source.count))
    var (remainders,writtenUpTo) = source._copyContents(initializing: buf)
    // ensure that exactly rhs.count elements were written
    _precondition(remainders.next() == nil, "rhs underreported its count")
    _precondition(writtenUpTo == buf.endIndex, "rhs overreported its count")
  }

  /// Replaces the memory referenced by this pointer with the values
  /// starting at the given pointer, leaving the source memory uninitialized.
  ///
  /// The region of memory starting at this pointer and covering `count`
  /// instances of the pointer's `Pointee` type must be initialized or
  /// `Pointee` must be a trivial type. After calling
  /// `moveAssign(from:count:)`, the region is initialized and the memory
  /// region `source..<(source + count)` is uninitialized.
  ///
  /// - Parameters:
  ///   - source: A pointer to the values to copy. The memory region
  ///     `source..<(source + count)` must be initialized. The memory regions
  ///     referenced by `source` and this pointer must not overlap.
  ///   - count: The number of instances to move from `source` to this
  ///     pointer's memory. `count` must not be negative.
  @inlinable
  public func moveAssign(from source: ${Self}, count: Int) {
    _debugPrecondition(
      count >= 0, "${Self}.moveAssign(from:) with negative count")
    _debugPrecondition(
      self + count <= source || source + count <= self,
      "moveAssign overlapping range")
    Builtin.assignTakeArray(
      Pointee.self, self._rawValue, source._rawValue, count._builtinWordValue)
    // These builtins are equivalent to:
    // for i in 0..<count {
    //   self[i] = (source + i).move()
    // }
  }
  
  @available(swift, deprecated: 4.1, obsoleted: 5.0.0, message: "the default argument to deinitialize(count:) has been removed, please specify the count explicitly") 
  @inlinable
  @discardableResult
  public func deinitialize() -> UnsafeMutableRawPointer {
    return deinitialize(count: 1)
  }
  
  /// Deinitializes the specified number of values starting at this pointer.
  ///
  /// The region of memory starting at this pointer and covering `count`
  /// instances of the pointer's `Pointee` type must be initialized. After
  /// calling `deinitialize(count:)`, the memory is uninitialized, but still
  /// bound to the `Pointee` type.
  ///
  /// - Parameter count: The number of instances to deinitialize. `count` must
  ///   not be negative. 
  /// - Returns: A raw pointer to the same address as this pointer. The memory
  ///   referenced by the returned raw pointer is still bound to `Pointee`.
  @inlinable
  @discardableResult
  public func deinitialize(count: Int) -> UnsafeMutableRawPointer {
    _debugPrecondition(count >= 0, "${Self}.deinitialize with negative count")
    // FIXME: optimization should be implemented, where if the `count` value
    // is 1, the `Builtin.destroy(Pointee.self, _rawValue)` gets called.
    Builtin.destroyArray(Pointee.self, _rawValue, count._builtinWordValue)
    return UnsafeMutableRawPointer(self)
  }
%  end

  /// Executes the given closure while temporarily binding the specified number
  /// of instances to the given type.
  ///
  /// Use this method when you have a pointer to memory bound to one type and
  /// you need to access that memory as instances of another type. Accessing
  /// memory as a type `T` requires that the memory be bound to that type. A
  /// memory location may only be bound to one type at a time, so accessing
  /// the same memory as an unrelated type without first rebinding the memory
  /// is undefined.
  ///
  /// The region of memory starting at this pointer and covering `count`
  /// instances of the pointer's `Pointee` type must be initialized.
  ///
  /// The following example temporarily rebinds the memory of a `UInt64`
  /// pointer to `Int64`, then accesses a property on the signed integer.
  ///
  ///     let uint64Pointer: Unsafe${Mutable}Pointer<UInt64> = fetchValue()
  ///     let isNegative = uint64Pointer.withMemoryRebound(to: Int64.self) { ptr in
  ///         return ptr.pointee < 0
  ///     }
  ///
  /// Because this pointer's memory is no longer bound to its `Pointee` type
  /// while the `body` closure executes, do not access memory using the
  /// original pointer from within `body`. Instead, use the `body` closure's
  /// pointer argument to access the values in memory as instances of type
  /// `T`.
  ///
  /// After executing `body`, this method rebinds memory back to the original
  /// `Pointee` type.
  ///
  /// - Note: Only use this method to rebind the pointer's memory to a type
  ///   with the same size and stride as the currently bound `Pointee` type.
  ///   To bind a region of memory to a type that is a different size, convert
  ///   the pointer to a raw pointer and use the `bindMemory(to:capacity:)`
  ///   method.
  ///
  /// - Parameters:
  ///   - type: The type to temporarily bind the memory referenced by this
  ///     pointer. The type `T` must be the same size and be layout compatible
  ///     with the pointer's `Pointee` type.
  ///   - count: The number of instances of `Pointee` to bind to `type`.
  ///   - body: A closure that takes a ${Mutable.lower()} typed pointer to the
  ///     same memory as this pointer, only bound to type `T`. The closure's
  ///     pointer argument is valid only for the duration of the closure's
  ///     execution. If `body` has a return value, that value is also used as
  ///     the return value for the `withMemoryRebound(to:capacity:_:)` method.
  /// - Returns: The return value, if any, of the `body` closure parameter.
  @inlinable
  public func withMemoryRebound<T, Result>(to type: T.Type, capacity count: Int,
    _ body: (${Self}<T>) throws -> Result
  ) rethrows -> Result {
    Builtin.bindMemory(_rawValue, count._builtinWordValue, T.self)
    defer {
      Builtin.bindMemory(_rawValue, count._builtinWordValue, Pointee.self)
    }
    return try body(${Self}<T>(_rawValue))
  }

  /// Accesses the pointee at the specified offset from this pointer.
  ///
%  if mutable:
  /// For a pointer `p`, the memory at `p + i` must be initialized when reading
  /// the value by using the subscript. When the subscript is used as the left
  /// side of an assignment, the memory at `p + i` must be initialized or
  /// the pointer's `Pointee` type must be a trivial type.
  ///
  /// Do not assign an instance of a nontrivial type through the subscript to
  /// uninitialized memory. Instead, use an initializing method, such as
  /// `initialize(to:count:)`.
%  else:
  ///
  /// For a pointer `p`, the memory at `p + i` must be initialized.
%  end
  ///
  /// - Parameter i: The offset from this pointer at which to access an
  ///   instance, measured in strides of the pointer's `Pointee` type.
  @inlinable
  public subscript(i: Int) -> Pointee {
%  if mutable:
    @_transparent
    unsafeAddress {
      return UnsafePointer(self + i)
    }
    @_transparent
    nonmutating unsafeMutableAddress {
      return self + i
    }
%  else:
    @_transparent
    unsafeAddress {
      return self + i
    }
%  end
  }
}

extension ${Self}: Equatable {
  // - Note: Strideable's implementation is potentially less efficient and cannot
  //   handle misaligned pointers.
  /// Returns a Boolean value indicating whether two pointers are equal.
  ///
  /// - Parameters:
  ///   - lhs: A pointer.
  ///   - rhs: Another pointer.
  /// - Returns: `true` if `lhs` and `rhs` reference the same memory address;
  ///   otherwise, `false`.
  @inlinable // FIXME(sil-serialize-all)
  @_transparent
  public static func == (lhs: ${Self}<Pointee>, rhs: ${Self}<Pointee>) -> Bool {
    return Bool(Builtin.cmp_eq_RawPointer(lhs._rawValue, rhs._rawValue))
  }
}

extension ${Self}: Comparable {
  // - Note: Strideable's implementation is potentially less efficient and
  // cannot handle misaligned pointers.
  //
  // - Note: This is an unsigned comparison unlike Strideable's implementation.
  /// Returns a Boolean value indicating whether the first pointer references
  /// an earlier memory location than the second pointer.
  ///
  /// - Parameters:
  ///   - lhs: A pointer.
  ///   - rhs: Another pointer.
  /// - Returns: `true` if `lhs` references a memory address earlier than
  ///   `rhs`; otherwise, `false`.
  @inlinable // FIXME(sil-serialize-all)
  @_transparent
  public static func < (lhs: ${Self}<Pointee>, rhs: ${Self}<Pointee>) -> Bool {
    return Bool(Builtin.cmp_ult_RawPointer(lhs._rawValue, rhs._rawValue))
  }
}
extension ${Self}: Hashable {
  /// Hashes the essential components of this value by feeding them into the
  /// given hasher.
  ///
  /// - Parameter hasher: The hasher to use when combining the components
  ///   of this instance.
  @inlinable // FIXME(sil-serialize-all)
  public func hash(into hasher: inout Hasher) {
    hasher.combine(Int(bitPattern: self))
  }
}

extension ${Self}: Strideable {
  /// Returns a pointer to the next consecutive instance.
  ///
  /// The resulting pointer must be within the bounds of the same allocation as
  /// this pointer.
  ///
  /// - Returns: A pointer advanced from this pointer by
  ///   `MemoryLayout<Pointee>.stride` bytes.
  @inlinable
  public func successor() -> ${Self} {
    return advanced(by: 1)
  }

  /// Returns a pointer to the previous consecutive instance.
  ///
  /// The resulting pointer must be within the bounds of the same allocation as
  /// this pointer.
  ///
  /// - Returns: A pointer shifted backward from this pointer by
  ///   `MemoryLayout<Pointee>.stride` bytes.
  @inlinable
  public func predecessor() -> ${Self} {
    return self - 1
  }

  /// Returns the distance from this pointer to the given pointer, counted as
  /// instances of the pointer's `Pointee` type.
  ///
  /// With pointers `p` and `q`, the result of `p.distance(to: q)` is
  /// equivalent to `q - p`.
  ///
  /// Typed pointers are required to be properly aligned for their `Pointee`
  /// type. Proper alignment ensures that the result of `distance(to:)`
  /// accurately measures the distance between the two pointers, counted in
  /// strides of `Pointee`. To find the distance in bytes between two
  /// pointers, convert them to `UnsafeRawPointer` instances before calling
  /// `distance(to:)`.
  ///
  /// - Parameter end: The pointer to calculate the distance to.
  /// - Returns: The distance from this pointer to `end`, in strides of the
  ///   pointer's `Pointee` type. To access the stride, use
  ///   `MemoryLayout<Pointee>.stride`.
  @inlinable
  public func distance(to end: ${Self}) -> Int {
    return
      Int(Builtin.sub_Word(Builtin.ptrtoint_Word(end._rawValue),
                           Builtin.ptrtoint_Word(_rawValue)))
      / MemoryLayout<Pointee>.stride
  }

  /// Returns a pointer offset from this pointer by the specified number of
  /// instances.
  ///
  /// With pointer `p` and distance `n`, the result of `p.advanced(by: n)` is
  /// equivalent to `p + n`.
  ///
  /// The resulting pointer must be within the bounds of the same allocation as
  /// this pointer.
  ///
  /// - Parameter n: The number of strides of the pointer's `Pointee` type to
  ///   offset this pointer. To access the stride, use
  ///   `MemoryLayout<Pointee>.stride`. `n` may be positive, negative, or
  ///   zero.
  /// - Returns: A pointer offset from this pointer by `n` instances of the
  ///   `Pointee` type.
  @inlinable
  public func advanced(by n: Int) -> ${Self} {
    return ${Self}(Builtin.gep_Word(
      self._rawValue, n._builtinWordValue, Pointee.self))
  }
}

extension ${Self} : CustomDebugStringConvertible {
  /// A textual representation of the pointer, suitable for debugging.
  @inlinable // FIXME(sil-serialize-all)
  public var debugDescription: String {
    return _rawPointerToString(_rawValue)
  }
}

extension ${Self} : CustomReflectable {
  @inlinable // FIXME(sil-serialize-all)
  public var customMirror: Mirror {
    let ptrValue = UInt64(bitPattern: Int64(Int(Builtin.ptrtoint_Word(_rawValue))))
    return Mirror(self, children: ["pointerValue": ptrValue])
  }
}

extension ${Self} : CustomPlaygroundQuickLookable {
  @inlinable // FIXME(sil-serialize-all)
  internal var summary: String {
    let selfType = "${Self}"
    let ptrValue = UInt64(bitPattern: Int64(Int(Builtin.ptrtoint_Word(_rawValue))))
    return ptrValue == 0 ? "\(selfType)(nil)" : "\(selfType)(0x\(_uint64ToString(ptrValue, radix:16, uppercase:true)))"
  }

  @inlinable // FIXME(sil-serialize-all)
  @available(*, deprecated, message: "${Self}.customPlaygroundQuickLook will be removed in a future Swift version")
  public var customPlaygroundQuickLook: PlaygroundQuickLook {
    return .text(summary)
  }
}

extension Int {
  /// Creates a new value with the bit pattern of the given pointer.
  ///
  /// The new value represents the address of the pointer passed as `pointer`.
  /// If `pointer` is `nil`, the result is `0`.
  ///
  /// - Parameter pointer: The pointer to use as the source for the new
  ///   integer.
  @inlinable
  public init<U>(bitPattern pointer: ${Self}<U>?) {
    if let pointer = pointer {
      self = Int(Builtin.ptrtoint_Word(pointer._rawValue))
    } else {
      self = 0
    }
  }
}

extension UInt {
  /// Creates a new value with the bit pattern of the given pointer.
  ///
  /// The new value represents the address of the pointer passed as `pointer`.
  /// If `pointer` is `nil`, the result is `0`.
  ///
  /// - Parameter pointer: The pointer to use as the source for the new
  ///   integer.
  @inlinable
  public init<U>(bitPattern pointer: ${Self}<U>?) {
    if let pointer = pointer {
      self = UInt(Builtin.ptrtoint_Word(pointer._rawValue))
    } else {
      self = 0
    }
  }
}

extension ${Self} {
  @inlinable // FIXME(sil-serialize-all)
  internal static var _max : ${Self} {
    return ${Self}(
      bitPattern: 0 as Int &- MemoryLayout<Pointee>.stride
    )._unsafelyUnwrappedUnchecked
  }
}
% end # for mutable

// ${'Local Variables'}:
// eval: (read-only-mode 1)
// End:
