Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/dn-m/Structure
Browse files Browse the repository at this point in the history
  • Loading branch information
jsbean committed Aug 27, 2018
2 parents 60d646e + b179331 commit 15458ff
Show file tree
Hide file tree
Showing 13 changed files with 1,006 additions and 70 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// Fragmentable.swift
// DataStructures
//
// Created by James Bean on 8/22/18.
//

/// Interface for types which can be fragmented into smaller pieces.
public protocol Fragmentable {

// MARK: - Associated Types

/// Type of fragment that is created from this type.
associatedtype Fragment
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// Intervallic.swift
// DataStructures
//
// Created by James Bean on 8/22/18.
//

import Algebra

public protocol Intervallic: Measured {

// MARK - Associated Types

/// The type which is used to measure this type.
associatedtype Metric

// MARK: - Instance Properties

/// Length of the `Spanning` type in the given `Metric`.
var length: Metric { get }
}

extension Numeric where Self: Comparable {

/// - Returns: Self as its length.
public var length: Self {
return self
}
}

extension Int: Intervallic { }
extension Float: Intervallic { }
extension Double: Intervallic { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// IntervallicFragmentable.swift
// DataStructures
//
// Created by James Bean on 8/24/18.
//

import Algebra

/// Interface for types which are `Intervallic`, and can be fragmented into a type which shares its
/// `Metric` type.
public protocol IntervallicFragmentable: Intervallic, Fragmentable
where Fragment: Intervallic, Fragment.Metric == Metric
{

// MARK: - Associated Types

/// The fragment of an `IntervallicFragmentable` type.
associatedtype Fragment

// MARK: - Instance Methods

/// - Returns: The `Fragment` in the given `range`.
func fragment(in range: Range<Metric>) -> Fragment
}

extension IntervallicFragmentable where Metric: Zero {

/// - Returns: The `Fragment` of this `IntervallicFragmentable`-conforming type value in the
/// given `range`.
public func fragment(in range: PartialRangeUpTo<Metric>) -> Fragment {
return fragment(in: .zero ..< range.upperBound)
}

/// - Returns: The `Fragment` of this `IntervallicFragmentable`-conforming type value in the
/// given `range`.
public func fragment(in range: PartialRangeFrom<Metric>) -> Fragment {
return fragment(in: range.lowerBound ..< length)
}
}
15 changes: 15 additions & 0 deletions Sources/DataStructures/ContiguousSegmentCollection/Measured.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// Measured.swift
// DataStructures
//
// Created by James Bean on 8/22/18.
//

/// Interface for types which are measured by some `Metric` type.
public protocol Measured {

// MARK: - Associated Types

/// The type which is used to measure this type.
associatedtype Metric: SignedNumeric, Comparable
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// Totalizable.swift
// DataStructures
//
// Created by James Bean on 8/22/18.
//

import Algebra

/// Interface for fragment types which can create a fragment version of a whole instance of the
/// type.
public protocol Totalizable {

// MARK: - Associated Types

/// The type of the given `Whole`.
associatedtype Whole

// MARK: - Initializers

/// Creates a `Totalizable` fragment with an instance of the `Whole` type.
init(whole: Whole)
}
4 changes: 4 additions & 0 deletions Sources/DataStructures/DictionaryProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ public protocol DictionaryProtocol: Collection {

/// - Returns: `Value` for the given `key`, if present. Otherwise, `nil`.
subscript (key: Key) -> Value? { get set }

/// Reserves the required amount of memory to store the given `minimumCapacity` of key-value
/// pairs.
mutating func reserveCapacity(_ minimumCapacity: Int)
}

extension DictionaryProtocol {
Expand Down
43 changes: 21 additions & 22 deletions Sources/DataStructures/OrderedDictionary.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public struct OrderedDictionary <Key: Hashable, Value>: DictionaryProtocol {
public var keys: [Key] = []

/// Values.
public var values: [Key: Value] = [:]
public var unordered: [Key: Value] = [:]

// MARK: - Initializers

Expand All @@ -27,7 +27,7 @@ public struct OrderedDictionary <Key: Hashable, Value>: DictionaryProtocol {
public init(minimumCapacity: Int) {
self.keys = []
self.keys.reserveCapacity(minimumCapacity)
self.values = .init(minimumCapacity: minimumCapacity)
self.unordered = .init(minimumCapacity: minimumCapacity)
}

// MARK: - Subscripts
Expand All @@ -36,18 +36,18 @@ public struct OrderedDictionary <Key: Hashable, Value>: DictionaryProtocol {
public subscript(key: Key) -> Value? {

get {
return values[key]
return unordered[key]
}

set {

guard let newValue = newValue else {
values.removeValue(forKey: key)
unordered.removeValue(forKey: key)
keys = keys.filter { $0 != key }
return
}

let oldValue = values.updateValue(newValue, forKey: key)
let oldValue = unordered.updateValue(newValue, forKey: key)
if oldValue == nil {
keys.append(key)
}
Expand All @@ -59,31 +59,33 @@ public struct OrderedDictionary <Key: Hashable, Value>: DictionaryProtocol {
/// Append `value` for given `key`.
public mutating func append(_ value: Value, key: Key) {
keys.append(key)
values[key] = value
unordered[key] = value
}

/// Insert `value` for given `key` at `index`.
public mutating func insert(_ value: Value, key: Key, index: Int) {
keys.insert(key, at: index)
values[key] = value
unordered[key] = value
}

/// Append the contents of another `OrderedDictionary` structure.
public mutating func appendContents(of orderedDictionary: OrderedDictionary<Key,Value>) {
keys.append(contentsOf: orderedDictionary.keys)
for key in orderedDictionary.keys {
values.updateValue(orderedDictionary[key]!, forKey: key)
unordered.updateValue(orderedDictionary[key]!, forKey: key)
}
}

/// - returns: The value at the given `index`.
public func value(index: Int) -> Value? {

guard index >= 0 && index < keys.count else {
return nil
}
/// Reserves the amount of memory required to store the given `minimumCapacity` of elements.
public mutating func reserveCapacity(_ minimumCapacity: Int) {
keys.reserveCapacity(minimumCapacity)
unordered.reserveCapacity(minimumCapacity)
}

return values[keys[index]]
/// - Returns: The value at the given `index`.
public func value(index: Int) -> Value? {
guard index >= 0 && index < keys.count else { return nil }
return unordered[keys[index]]
}
}

Expand Down Expand Up @@ -114,24 +116,21 @@ extension OrderedDictionary: Collection {
/// - returns: Element at the given `index`.
public subscript (index: Int) -> (Key, Value) {
let key = keys[index]
let value = values[key]!
let value = unordered[key]!
return (key, value)
}
}

extension OrderedDictionary: Equatable where Value: Equatable { }
extension OrderedDictionary: Hashable where Value: Hashable { }

extension OrderedDictionary: ExpressibleByDictionaryLiteral {

// MARK: - ExpressibleByDictionaryLiteral

/// Create an `OrderedDictionary` with a `DictionaryLiteral`.
public init(dictionaryLiteral elements: (Key, Value)...) {

self.init()

elements.forEach { (k, v) in
append(v, key: k)
}
self.init(minimumCapacity: elements.count)
elements.forEach { (k, v) in append(v, key: k) }
}
}
35 changes: 30 additions & 5 deletions Sources/DataStructures/SortedArray.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,27 @@ public struct SortedArray <Element: Comparable>:
self.init(presorted: Array(elements).sorted())
}

/// Create a `SortedArray` with the given array of presorted elements.
/// Create a `SortedArray` with the given collection of presorted elements.
///
/// - Warning: You must be certain that `presorted` is sorted, otherwise undefined behavior is
/// certain.
public init <C> (presorted: C) where C: Collection, C.Element == Element {
self.base = Array(presorted)
}

/// Create a `SortedArray` with the given array of presorted elements.
///
/// - Warning: You must be certain that `presorted` is sorted, otherwise undefined behavior is
/// certain.
public init(presorted: [Element]) {
self.base = presorted
}

/// Creates a `SortedArray` with the contents of another one.
public init(_ sorted: SortedArray) {
self.init(presorted: sorted.base)
}

// MARK: - Instance Methods

/// Remove the given `element`, if it is contained herein.
Expand All @@ -62,12 +75,23 @@ public struct SortedArray <Element: Comparable>:
}

/// Insert the contents of another sequence of `T`.
public mutating func insert <S> (contentsOf elements: S)
where S: Sequence, S.Element == Element
{
public mutating func insert <S: Sequence> (contentsOf elements: S) where S.Element == Element {
elements.forEach { insert($0) }
}

/// Reserves the amount of memory to store the given `minimumCapacity` of elements.
public mutating func reserveCapacity(_ minimumCapacity: Int) {
base.reserveCapacity(minimumCapacity)
}

/// Appends the given `element`.
///
/// - Warning: This element _must_ be greater or equal to the current maximum, otherwise there
/// will be undefined behavior ahead.
public mutating func append(guaranteedMax element: Element) {
base.append(element)
}

/// - Returns: Index for the given `element`, if it exists. Otherwise, `nil`.
public func index(of element: Element) -> Int? {
let index = self.index(for: element)
Expand Down Expand Up @@ -95,6 +119,7 @@ public struct SortedArray <Element: Comparable>:
}

extension SortedArray: Equatable { }
extension SortedArray: Hashable where Element: Hashable { }

extension SortedArray {

Expand All @@ -109,7 +134,7 @@ extension SortedArray: Additive {
// MARK: - Additive

/// - Returns: Empty `SortedArray`.
public static var zero: SortedArray<Element> {
public static var zero: SortedArray {
return SortedArray()
}

Expand Down
Loading

0 comments on commit 15458ff

Please sign in to comment.