Skip to content

Commit d58943a

Browse files
mohanadkandilmkandil
andauthored
Add filter method for ordered and unordered map (#67501)
Co-authored-by: mkandil <[email protected]>
1 parent 0b07c34 commit d58943a

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

stdlib/public/Cxx/CxxDictionary.swift

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@ public protocol CxxDictionary<Key, Value> {
2525
associatedtype Size: BinaryInteger
2626
associatedtype InsertionResult
2727

28+
init()
29+
2830
/// Do not implement this function manually in Swift.
2931
func __findUnsafe(_ key: Key) -> RawIterator
30-
3132
/// Do not implement this function manually in Swift.
3233
mutating func __findMutatingUnsafe(_ key: Key) -> RawMutableIterator
3334

@@ -39,6 +40,9 @@ public protocol CxxDictionary<Key, Value> {
3940
@discardableResult
4041
mutating func erase(_ key: Key) -> Size
4142

43+
/// Do not implement this function manually in Swift.
44+
func __beginUnsafe() -> RawIterator
45+
4246
/// Do not implement this function manually in Swift.
4347
func __endUnsafe() -> RawIterator
4448

@@ -72,4 +76,22 @@ extension CxxDictionary {
7276
}
7377
}
7478
}
79+
80+
public func filter(_ isIncluded: (_ key: Key, _ value: Value) throws -> Bool) rethrows -> Self {
81+
var filteredDictionary = Self.init()
82+
var iterator = __beginUnsafe()
83+
let endIterator = __endUnsafe()
84+
85+
while iterator != endIterator {
86+
let pair = iterator.pointee
87+
88+
if try isIncluded(pair.first, pair.second) {
89+
filteredDictionary.__insertUnsafe(pair)
90+
}
91+
92+
iterator = iterator.successor()
93+
}
94+
95+
return filteredDictionary
96+
}
7597
}

test/Interop/Cxx/stdlib/Inputs/std-map.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
#define TEST_INTEROP_CXX_STDLIB_INPUTS_STD_MAP_H
33

44
#include <map>
5-
#include <unordered_map>
65
#include <string>
6+
#include <unordered_map>
77

88
using Map = std::map<int, int>;
99
using MapStrings = std::map<std::string, std::string>;
@@ -12,5 +12,7 @@ using UnorderedMap = std::unordered_map<int, int>;
1212

1313
inline Map initMap() { return {{1, 3}, {2, 2}, {3, 3}}; }
1414
inline UnorderedMap initUnorderedMap() { return {{1, 3}, {3, 3}, {2, 2}}; }
15+
inline Map initEmptyMap() { return {}; }
16+
inline UnorderedMap initEmptyUnorderedMap() { return {}; }
1517

1618
#endif // TEST_INTEROP_CXX_STDLIB_INPUTS_STD_MAP_H

test/Interop/Cxx/stdlib/use-std-map.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,38 @@ StdMapTestSuite.test("UnorderedMap.subscript") {
8888
expectNil(m[-1])
8989
}
9090

91+
StdMapTestSuite.test("Map.filter") {
92+
var m = initMap()
93+
var n = initEmptyMap()
94+
95+
expectNotNil(m[1])
96+
expectEqual(n.size(), 0)
97+
98+
m = m.filter { k, v in k != 1 }
99+
n = n.filter { k, v in false }
100+
101+
expectNil(m[1])
102+
expectEqual(m[2], 2)
103+
expectEqual(m[3], 3)
104+
expectTrue(n.empty())
105+
}
106+
107+
StdMapTestSuite.test("UnorderedMap.filter") {
108+
var m = initUnorderedMap()
109+
var n = initEmptyUnorderedMap()
110+
111+
expectNotNil(m[1])
112+
expectEqual(n.size(), 0)
113+
114+
m = m.filter { k, v in k != 1 }
115+
n = n.filter { k, v in false }
116+
117+
expectNil(m[1])
118+
expectEqual(m[2], 2)
119+
expectEqual(m[3], 3)
120+
expectTrue(n.empty())
121+
}
122+
91123
StdMapTestSuite.test("Map.erase") {
92124
var m = initMap()
93125
expectNotNil(m[1])

0 commit comments

Comments
 (0)