pyrtsa/poly 46
Solving the Expression Problem in C++11
The spiritual successor to Less Framework
System duplicate formulae for the Homebrew package manager
The Numerical Template Toolbox - C++ Scientific Computing Made Easy
Algebraic graphs
A Idris Mode for Atom.io
Nix syntax highlighting for Atom
An Objective-C library dependency manager.
Crypto related functions and helpers for Swift implemented in Swift programming language
Tiny ISO-compliant C++ EXIF parsing library, third-party dependency free.
created tagapple/swift-llbuild
A low-level build system, used by Xcode and the Swift Package Manager
created time in 17 hours
Pull request review commentapple/swift-algorithms
+//===----------------------------------------------------------------------===//+//+// This source file is part of the Swift Algorithms open source project+//+// Copyright (c) 2021 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+//+//===----------------------------------------------------------------------===//++//===----------------------------------------------------------------------===//+// Suffix(while:)+//===----------------------------------------------------------------------===//++extension BidirectionalCollection {+ /// Returns a subsequence containing the elements from the end until `predicate`+ /// returns `false` and skipping the remaining elements.+ ///+ /// - Parameter predicate: A closure that takes an element of the+ /// sequence as its argument and returns `true` if the element should+ /// be included or `false` if it should be excluded. Once the predicate+ /// returns `false` it will not be called again.+ ///+ /// - Complexity: O(*n*), where *n* is the length of the collection.+ public func suffix(+ while predicate: (Element) throws -> Bool+ ) rethrows -> SubSequence {+ let start = startIndex+ var result = endIndex+ while result != start {+ let previous = index(before: result)+ guard try predicate(self[previous]) else { break }+
comment created time in a day
Pull request review commentapple/swift-algorithms
//===----------------------------------------------------------------------===// extension BidirectionalCollection {+ /// Returns a subsequence containing the elements from the end until `predicate`+ /// returns `false` and skipping the remaining elements.
/// Returns a subsequence containing the elements from the end until
/// `predicate` returns `false` and skipping the remaining elements.
comment created time in a day
pull request commentapple/swift-algorithms
A lot of similar algorithms in the standard library use != instead of > or < for comparing indexes. I’ll have to do more research as to why that is. My initial guess is perhaps because implementations of custom indexes have slightly faster implementations of != than <. But either way, it would be good to have consistency here.
I agree that we should use !=
to be consistent with the stdlib.
One of the reasons stdlib uses !=
is historical. Originally Collection.Index
in the stdlib was only Equatable
, not Comparable
. From SE-0065 which added the Comparable
requirement:
It's worth noting that this requirement isn't strictly necessary. Without it, though, indices would have no requirements beyond
Equatable
, and creation of aRange<T>
would have to be allowed for anyT
conforming toEquatable
. As a consequence, most interesting range operations, such as containment checks, would be unavailable unlessT
were alsoComparable
, and we'd be unable to provide bounds-checking in the general case.That said, the requirement has real benefits. For example, it allows us to support distance measurement between arbitrary indices, even in collections without random access traversal. In the old model,
x.distance(to: y)
for these collections had the undetectable precondition thatx
precedey
, with unpredictable consequences for violation in the general case.
comment created time in a day
Pull request review commentapple/swift-algorithms
//===----------------------------------------------------------------------===// extension BidirectionalCollection {- @inlinable- public __consuming func Suffix(while predicate: (Element) throws -> Bool- ) rethrows -> [Element] {- var result = ContiguousArray<Element>()- self.reverse()- for element in self {- guard try predicate(element) else {- break- }- result.append(element)+ public func suffix(+ while predicate: (Element) throws -> Bool+ ) rethrows -> SubSequence {+ let start = startIndex+ var result = endIndex+ while result != start {+ let previous = index(before: result)+ guard try predicate(self[previous]) else { break }++ result = previous }- result.reverse()- return Array(result)+ return self[result...] }-}+}
}
comment created time in 2 days
pull request commentapple/swift-algorithms
Add `contains(countIn:where:)` to `Sequence`
I thought that the Sequence
level is the wrong approach. Maybe we could start from the IteratorProtcol
level. I wrote a core routine as an extension
to iterators. However, we generally don't put new API onto IteratorProtcol
; we usually take an iterator as an inout
argument or as a return value. So I moved the iterator approach as a return value:
extension Sequence {
/// Returns an iterator into the sequence that is just past the given number
/// of elements that match the given predicate.
///
/// The following example prints the value after the fifth even element of the range.
///
/// let range = -3..<20
/// if var iterator = range.skippingOver(count: 5, where: { $0.isMultiple(of: 2) }) {
/// if let nextValue = iterator.next() {
/// print(nextValue)
/// } else {
/// print("The range ended at its fifth even number.")
/// }
/// } else {
/// print("The range had less than five even numbers.")
/// }
///
/// // Prints: "7"
///
/// - Precondition:
/// - `count >= 0`.
/// - Either the sequence is finite or at least `count` elements in the
/// sequence match `predicate`.
///
/// - Parameters:
/// - count: The number of occurrences of matching elements to find before
/// stopping.
/// - predicate: A closure that takes an element of the sequence as its
/// argument and returns a Boolean value indicating whether the element
/// is a match.
/// - Returns: If the sequence has fewer than `count` elements that match
/// `predicate`, then `nil`. Otherwise, an iterator that starts with the
/// element after the last match. If that last match was also the last
/// element, then the iterator's virtual sequence will be empty.
///
/// - Complexity: O(*n*), where *n* is the length of the sequence.
public func skippingOver(
count: Int,
where predicate: (Element) throws -> Bool
) rethrows -> Iterator? {
var result = makeIterator()
counter: for _ in 0..<count {
while let element = result.next() {
if try predicate(element) {
continue counter
}
}
return nil
}
return result
}
}
extension Sequence where Element: Equatable {
/// Returns an iterator into the sequence that is just past the given number
/// of elements that equal the given element.
///
/// The following example prints the character after the third "a".
///
/// let sample = "Mary had a little lamb"
/// if var iterator = sample.skippingOver(count: 3, of: "a") {
/// if let nextCharacter = iterator.next() {
/// print("The next character is '\(nextCharacter)'.")
/// } else {
/// print("The third occurence of 'a' is at the last position.")
/// }
/// } else {
/// print("The occurrence count of 'a' is less than 3.")
/// }
///
/// // Prints: "The next character is ' '."
///
/// - Precondition:
/// - `count >= 0`.
/// - Either the sequence is finite or at least `count` elements in the
/// sequence equal `element`.
///
/// - Parameters:
/// - count: The number of occurrences of matching elements to find before
/// stopping.
/// - element: An element to search for in the sequence.
/// - Returns: If the sequence has fewer than `count` elements that equal
/// `element`, then `nil`. Otherwise, an iterator that starts with the
/// element after the last match. If that last match was also the last
/// element, then the iterator's virtual sequence will be empty.
///
/// - Complexity: O(*n*), where *n* is the length of the sequence.
@inlinable
public func skippingOver(count: Int, of element: Element) -> Iterator? {
return skippingOver(count: count, where: { $0 == element })
}
}
Maybe this could form a building block to a better API.
comment created time in 3 days
issue commentapple/swift-algorithms
Partition: Make mutating functions return `@discardableResult`
It's a good question.
I can't recall, but I imagine we just followed the precedent set by partition(by:)
from the standard library which does not mark its result as a @discardableResult
.
While it could be argued that
bringForward(elementsSatisfying:)
should return anIndex
as well, even that return value isn’t always needed to be used and should be marked as@discardableResult
.
I do think bringForward(elementsSatisfying:)
should probably return an Index
(one of Alexander Stepanov's API design principles is "don't throw away useful information"), but I agree that should arguably be marked as @discardableResult
.
comment created time in 3 days
PR opened apple/swift-algorithms
<!-- Thanks for contributing to Swift Algorithms!
If this pull request adds new API, please add '?template=new.md'
to the URL to switch to the appropriate template.
Before you submit your request, please replace the paragraph
below with the relevant details, and complete the steps in the
checklist by placing an 'x' in each box:
- [x] I've completed this task
- [ ] This task isn't completed
-->
This PR adds a firstUpperBound
stored property to the LazyChunked
type to avoid computing the first chunk twice during iteration, similar to what the ChunkedByCount
and SlidingWindows
types do.
Checklist
- [x] I've added at least one test that validates that my change is working, if appropriate
- [x] I've followed the code style of the rest of the project
- [x] I've read the Contribution Guidelines
- [x] I've updated the documentation if necessary
pr created time in 3 days
issue openedapple/swift-algorithms
Partition: Make mutating functions return `@discardableResult`
Using the mutating partitioning functions are useful even when the returned index isn’t used.
The Embracing Algorithms (WWDC 2018) session implements a bringForward(elementsSatisfying:)
function on MutableCollection
.<sup>1</sup> It uses stablePartition(by:)
in its implementation, but doesn’t need its return value, resulting in a warning.
Actual behavior
extension MutableCollection {
mutating func bringForward(elementsSatisfying predicate: (Element) -> Bool) {
if let predecessor = indexBeforeFirst(where: predicate) {
self[predecessor...].stablePartition(by: { !predicate($0) }) // ⚠️ Result of call to 'stablePartition(by:)' is unused
}
}
}
Expected behavior
extension MutableCollection {
mutating func bringForward(elementsSatisfying predicate: (Element) -> Bool) {
if let predecessor = indexBeforeFirst(where: predicate) {
self[predecessor...].stablePartition(by: { !predicate($0) })
}
}
}
While it could be argued that bringForward(elementsSatisfying:)
should return an Index
as well, even that return value isn’t always needed to be used and should be marked as @discardableResult
.
Checklist
- [x] If possible, I've reproduced the issue using the
main
branch of this package - [x] I've searched for existing GitHub issues
- This implementation function can be seen on page 218 of the presentation slides PDF.
created time in 3 days
pull request commentapple/swift-algorithms
@CTMacUser I think that’s pretty much exactly what I imagined the implementation would look like.
Although, I think we might want to change
while result > start {
to
while result != start {
A lot of similar algorithms in the standard library use !=
instead of >
or <
for comparing indexes. I’ll have to do more research as to why that is. My initial guess is perhaps because implementations of custom indexes have slightly faster implementations of !=
than <
. But either way, it would be good to have consistency here.
comment created time in 4 days
pull request commentapple/swift-algorithms
What about something like (neither compiled nor tested):
extension BidirectionalCollection {
public func suffix(
while predicate: (Element) throws -> Bool
) rethrows -> SubSequence {
let start = startIndex
var result = endIndex
while result > start {
let previous = index(before: result)
guard try predicate(self[previous]) else { break }
result = previous
}
return self[result...]
}
}
?
comment created time in 4 days
pull request commentapple/swift-algorithms
@mdznr Oh I see this is still a draft, let us know when you're ready for us to review it!
comment created time in 4 days
startedCreativeCodeBerlin/creative-coding-minilist
started time in 4 days
PR opened apple/swift-algorithms
This PR adds implementations of index(_:offsetBy:)
and index(_:offsetBy:limitedBy:)
to the Product2
collection. There are ways to further reduce the amount of indices traversed, but this should perform well enough.
LIke Chain2
, Product2
's index offsetting behavior will now unfortunately perform slightly worse for non-random-access collections in specific scenarios, but there's not much we can do about that.
Checklist
- [x] I've added at least one test that validates that my change is working, if appropriate
- [x] I've followed the code style of the rest of the project
- [x] I've read the Contribution Guidelines
- [x] I've updated the documentation if necessary
pr created time in 4 days
Pull request review commentapple/swift-algorithms
+//===----------------------------------------------------------------------===//+//+// This source file is part of the Swift Algorithms open source project+//+// Copyright (c) 2020 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+//+//===----------------------------------------------------------------------===//++//===----------------------------------------------------------------------===//+// Suffix(while:)+//===----------------------------------------------------------------------===//++extension BidirectionalCollection {+ @inlinable+ public __consuming func Suffix(while predicate: (Element) throws -> Bool+ ) rethrows -> [Element] {+ var result = ContiguousArray<Element>()+ self.reverse()
I don’t believe reverse()
can be used here (won’t compile), because it is a mutating
function that reverses the elements of the collection in-place. This function, suffix(while:)
, isn’t mutating (and should remain that way), so it can’t use self.reverse()
in its implementation.
It seems that you might have meant to use the non-mutating version of that function, reversed()
, which returns a reversed collection:
for element in self.reversed() {
However, this comment likely won’t be applicable when changing the function to return SubSequence
instead.
comment created time in 4 days
Pull request review commentapple/swift-algorithms
+//===----------------------------------------------------------------------===//+//+// This source file is part of the Swift Algorithms open source project+//+// Copyright (c) 2020 Apple Inc. and the Swift project authors
// Copyright (c) 2021 Apple Inc. and the Swift project authors
comment created time in 4 days
Pull request review commentapple/swift-algorithms
+//===----------------------------------------------------------------------===//+//+// This source file is part of the Swift Algorithms open source project+//+// Copyright (c) 2020 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+//+//===----------------------------------------------------------------------===//++//===----------------------------------------------------------------------===//+// Suffix(while:)+//===----------------------------------------------------------------------===//++extension BidirectionalCollection {+ @inlinable+ public __consuming func Suffix(while predicate: (Element) throws -> Bool+ ) rethrows -> [Element] {+ var result = ContiguousArray<Element>()+ self.reverse()
Consistent indentation
var result = ContiguousArray<Element>()
self.reverse()
comment created time in 4 days
Pull request review commentapple/swift-algorithms
+//===----------------------------------------------------------------------===//+//+// This source file is part of the Swift Algorithms open source project+//+// Copyright (c) 2020 Apple Inc. and the Swift project authors
// Copyright (c) 2021 Apple Inc. and the Swift project authors
comment created time in 4 days
Pull request review commentapple/swift-algorithms
+//===----------------------------------------------------------------------===//+//+// This source file is part of the Swift Algorithms open source project+//+// Copyright (c) 2020 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+//+//===----------------------------------------------------------------------===//++//===----------------------------------------------------------------------===//+// Suffix(while:)+//===----------------------------------------------------------------------===//++extension BidirectionalCollection {+ @inlinable+ public __consuming func Suffix(while predicate: (Element) throws -> Bool+ ) rethrows -> [Element] {+ var result = ContiguousArray<Element>()+ self.reverse()+ for element in self {+ guard try predicate(element) else {+ break+ }+ result.append(element)+ }+ result.reverse()+ return Array(result)
This double-reverse operation and converting to Array
shouldn’t be necessary. The last index of the collection can be retrieved with endIndex
, then walked backwards using index(before:)
.
This would be similar to the implementation of prefix(while:)
<sup>1</sup>, but a little bit trickier. Since endIndex
is beyond the subscript-able range of a collection, the index has to be moved backwards before using it to subscript the collection, and ensuring it doesn’t go before the first element (start index). In SuffixTests.swift, I made some comments about test cases that will be important for ensuring that these cases are accounted for.
- https://github.com/apple/swift/blob/main/stdlib/public/core/Collection.swift#L1330
comment created time in 4 days
Pull request review commentapple/swift-algorithms
+//===----------------------------------------------------------------------===//+//+// This source file is part of the Swift Algorithms open source project+//+// Copyright (c) 2020 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+//+//===----------------------------------------------------------------------===//++import XCTest+import Algorithms++final class SuffixTests: XCTestCase {+ + func testSuffix() {+ let a = 0...10+ XCTAssertEqualSequences(a.suffix(while: { $0 > 5 }), (6...10))+}
}
}
comment created time in 4 days
Pull request review commentapple/swift-algorithms
+//===----------------------------------------------------------------------===//+//+// This source file is part of the Swift Algorithms open source project+//+// Copyright (c) 2020 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+//+//===----------------------------------------------------------------------===//++import XCTest+import Algorithms++final class SuffixTests: XCTestCase {+
comment created time in 4 days
Pull request review commentapple/swift-algorithms
+//===----------------------------------------------------------------------===//+//+// This source file is part of the Swift Algorithms open source project+//+// Copyright (c) 2020 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+//+//===----------------------------------------------------------------------===//++import XCTest+import Algorithms++final class SuffixTests: XCTestCase {
Tests should be added to handle:
- Empty input
- Empty output (predicate doesn’t match the first element)
- Predicate matches just the first element
- Predicate matches all elements
comment created time in 4 days
Pull request review commentapple/swift-algorithms
+//===----------------------------------------------------------------------===//+//+// This source file is part of the Swift Algorithms open source project+//+// Copyright (c) 2020 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+//+//===----------------------------------------------------------------------===//++//===----------------------------------------------------------------------===//+// Suffix(while:)
// suffix(while:)
comment created time in 4 days
Pull request review commentapple/swift-algorithms
+//===----------------------------------------------------------------------===//+//+// This source file is part of the Swift Algorithms open source project+//+// Copyright (c) 2020 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+//+//===----------------------------------------------------------------------===//++//===----------------------------------------------------------------------===//+// Suffix(while:)+//===----------------------------------------------------------------------===//++extension BidirectionalCollection {+ @inlinable
Documentation should be added. Mirroring the documentation for prefix(while:)
would be a good start.
comment created time in 4 days
Pull request review commentapple/swift-algorithms
+//===----------------------------------------------------------------------===//+//+// This source file is part of the Swift Algorithms open source project+//+// Copyright (c) 2020 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+//+//===----------------------------------------------------------------------===//++//===----------------------------------------------------------------------===//+// Suffix(while:)+//===----------------------------------------------------------------------===//++extension BidirectionalCollection {+ @inlinable+ public __consuming func Suffix(while predicate: (Element) throws -> Bool+ ) rethrows -> [Element] {
Can this return SubSequence
instead?
prefix(while:)
on Collection
returns a SubSequence
.<sup>1</sup>
- https://github.com/apple/swift/blob/main/stdlib/public/core/Collection.swift#L1328
comment created time in 4 days
Pull request review commentapple/swift-algorithms
+//===----------------------------------------------------------------------===//+//+// This source file is part of the Swift Algorithms open source project+//+// Copyright (c) 2020 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+//+//===----------------------------------------------------------------------===//++//===----------------------------------------------------------------------===//+// Suffix(while:)+//===----------------------------------------------------------------------===//++extension BidirectionalCollection {+ @inlinable+ public __consuming func Suffix(while predicate: (Element) throws -> Bool
public __consuming func suffix(
while predicate: (Element) throws -> Bool
comment created time in 4 days
Pull request review commentapple/swift-algorithms
+//===----------------------------------------------------------------------===//+//+// This source file is part of the Swift Algorithms open source project+//+// Copyright (c) 2020 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+//+//===----------------------------------------------------------------------===//++//===----------------------------------------------------------------------===//+// Suffix(while:)+//===----------------------------------------------------------------------===//++extension BidirectionalCollection {+ @inlinable+ public __consuming func Suffix(while predicate: (Element) throws -> Bool
public __consuming func suffix(while predicate: (Element) throws -> Bool
comment created time in 4 days
PR opened apple/swift-algorithms
<!-- Thanks for contributing to Swift Algorithms!
- [x] I've completed this task
- [ ] This task isn't completed
#62
Checklist
- [ ] I've added at least one test that validates that my change is working, if appropriate
- [ ] I've followed the code style of the rest of the project
- [ ] I've read the Contribution Guidelines
- [ ] I've updated the documentation if necessary
pr created time in 5 days
issue closedapple/swift-algorithms
The function that was used is unknown on my side ? I use Swift 5.3 and Xcode 12.3, macOS 11.1
closed time in 5 days
nilsnilsnils