Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initial version of DictionaryProtocol #304

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,8 @@ let targets: [CustomTarget] = [
kind: .test,
name: "DequeTests",
dependencies: ["DequeModule", "_CollectionsTestSupport"]),

.target(kind: .exported, name: "DictionaryProtocol"),

.target(
kind: .exported,
Expand All @@ -251,7 +253,7 @@ let targets: [CustomTarget] = [
.target(
kind: .exported,
name: "OrderedCollections",
dependencies: ["_CollectionsUtilities"],
dependencies: ["_CollectionsUtilities", "DictionaryProtocol"],
exclude: ["CMakeLists.txt"]),
.target(
kind: .test,
Expand Down
4 changes: 4 additions & 0 deletions Sources/DictionaryProtocol/DictionaryConformance.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
extension Dictionary: DictionaryProtocol {
public typealias Elements = Self
public var elements: Elements { self }
}
48 changes: 48 additions & 0 deletions Sources/DictionaryProtocol/DictionaryProtocol.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
public protocol DictionaryProtocol<Key, Value>: Sequence, ExpressibleByDictionaryLiteral where Element == (key: Key, value: Value), Key: Hashable {
associatedtype Key
associatedtype Value

associatedtype Keys: Collection where Keys.Element == Key
associatedtype Values: Collection where Values.Element == Value
associatedtype Elements: Collection where Elements.Element == Element

var keys: Keys { get }
var values: Values { get }
var elements: Elements { get }

subscript(key: Key) -> Value? { get }

init()

// Cannot implement since stdlib's Dictionary has a different signature (unlabelled tuple)
//init<S: Sequence>(uniqueKeysWithValues keysAndValues: S) where S.Element == (key: Key, value: Value)

init<S: Sequence>(uniqueKeysWithValues keysAndValues: S) where S.Element == (Key, Value)

init<S: Sequence>(
_ keysAndValues: S,
uniquingKeysWith combine: (Value, Value) throws -> Value
) rethrows where S.Element == (Key, Value)

// OrderedDictionary also has a more generic version of this with the where clause: `where Value: RangeReplaceableCollection, Value.Element == S.Element` instead of `Value == [S.Element]`
init<S: Sequence>(
grouping values: S,
by keyForValue: (S.Element) throws -> Key
) rethrows where Value == [S.Element]

init(_ other: some DictionaryProtocol<Key, Value>)

// does not work for stdlib Dictionary. Not sure how to capture stdlib Dictionary signature for this method in protocol
//func mapValues<T, Result: DictionaryProtocol>(_ transform: (Value) throws -> T) rethrows -> Result where Result.Value == T
// func compactMapValues<T> // same as above

func filter(_ isIncluded: (Element) throws -> Bool) rethrows -> Self
}

extension DictionaryProtocol {
// This does not guarantee any sort of ordering when using `OrderedDictionary` however...
public init(_ other: some DictionaryProtocol<Key, Value>) {
// .lazy.map in order to remove labels from tuple
self.init(uniqueKeysWithValues: other.elements.lazy.map { $0 })
}
}
7 changes: 7 additions & 0 deletions Sources/DictionaryProtocol/MutableDictionaryProtocol.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
protocol MutableDictionaryProtocol<Key, Value>: DictionaryProtocol {
var values: Values { get set }
var elements: Elements { get set }

mutating func updateValue(_ value: Value, forKey key: Key) -> Value?
mutating func removeValue(forKey key: Key) -> Value?
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
//
//===----------------------------------------------------------------------===//

import DictionaryProtocol

/// An ordered collection of key-value pairs.
///
/// Like the standard `Dictionary`, ordered dictionaries use a hash table to
Expand Down Expand Up @@ -218,6 +220,8 @@ public struct OrderedDictionary<Key: Hashable, Value> {
}
}

extension OrderedDictionary: DictionaryProtocol { }

extension OrderedDictionary {
/// A read-only ordered collection view for the keys contained in this dictionary, as
/// an `OrderedSet`.
Expand Down