<commit_before>//
//  OrderedSet.swift
//  Yomu
//
//  Created by <NAME> on 8/23/16.
//  Copyright © 2016 <NAME>. All rights reserved.
//

import Foundation

struct OrderedSet<T: Hashable> {
  var indexByElement: [T: Int]
  var contents: Array<T>
  var count: Int {
    return contents.count
  }

  init() {
    indexByElement = [:]
    contents = []
  }

  subscript(index: Int) -> T {
    return contents[index]
  }

  mutating func append(element: T) {
    if indexByElement[element] != nil {
      return
    }

    indexByElement[element] = contents.count
    contents.append(element)
  }

  mutating func remove(element: T) -> Bool {
    guard let index = indexByElement[element] else {
      return false
    }

    indexByElement[element] = nil
    contents.removeAtIndex(index)

    return true
  }

  func has(element: T) -> Bool {
    return indexByElement[element] != nil
  }
}<commit_msg>Implement CustomStringConvertible, ArrayLiteralConvertible and SequenceType for OrderedSet<commit_after>//
//  OrderedSet.swift
//  Yomu
//
//  Created by <NAME> on 8/23/16.
//  Copyright © 2016 <NAME>. All rights reserved.
//

import Foundation

struct OrderedSet<T: Hashable>: ArrayLiteralConvertible {
  private var indexByElement: [T: Int] = [:]
  private var elements: Array<T> = []

  var count: Int {
    return elements.count
  }

  init(arrayLiteral elements: T...) {
    for element in elements {
      append(element)
    }
  }

  mutating func append(element: T) {
    if indexByElement[element] != nil {
      return
    }

    indexByElement[element] = elements.count
    elements.append(element)
  }

  mutating func remove(element: T) -> Bool {
    guard let index = indexByElement[element] else {
      return false
    }

    indexByElement[element] = nil
    elements.removeAtIndex(index)

    return true
  }

  func has(element: T) -> Bool {
    return indexByElement[element] != nil
  }
}

extension OrderedSet: CustomStringConvertible {
  var description: String {
    return elements.reduce("OrderedSet \(count) objects: ") {
      "\($0), $1"
    }
  }
}

extension OrderedSet: MutableCollectionType {
  typealias Index = Int

  var startIndex: Int {
    return 0
  }

  var endIndex: Int {
    return elements.count
  }

  subscript(index: Index) -> T {
    get {
      return elements[index]
    }

    set {
      if has(newValue) {
        return
      }

      let oldValue = elements[index]
      indexByElement[oldValue] = nil
      indexByElement[newValue] = index
      elements[index] = newValue
    }
  }
}

extension OrderedSet: SequenceType {
  typealias Generator = OrderedSetGenerator<T>

  func generate() -> Generator {
    return OrderedSetGenerator(set: self)
  }
}

struct OrderedSetGenerator<T: Hashable>: GeneratorType {
  typealias Element = T

  var generator: IndexingGenerator<Array<T>>

  init(set: OrderedSet<T>) {
    generator = set.elements.generate()
  }

  mutating func next() -> T? {
    return generator.next()
  }
}
{'fraction_non_alphanumeric': 0.11316319677635997, 'fraction_numerical': 0.007051712558764272, 'mean_word_length': 2.8045977011494254, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 24, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '635001', 'n_tokens_mistral': 989, 'n_tokens_neox': 936, 'n_words': 238}