From 5a5e277b486bb95066cc3d6b38f6009a864df400 Mon Sep 17 00:00:00 2001
From: Ryo Aoyama
Date: Tue, 2 Oct 2018 13:49:03 +0900
Subject: [PATCH 01/11] Add utility computed property for Changeset
---
Sources/Changeset.swift | 55 +++++++++++++++++++++++++++------------
Tests/ChangesetTest.swift | 22 ++++++++++++++++
2 files changed, 60 insertions(+), 17 deletions(-)
diff --git a/Sources/Changeset.swift b/Sources/Changeset.swift
index 1563ca0..0388fa0 100644
--- a/Sources/Changeset.swift
+++ b/Sources/Changeset.swift
@@ -26,23 +26,6 @@ public struct Changeset {
/// The pairs of source and target path of moved elements.
public var elementMoved: [(source: ElementPath, target: ElementPath)]
- /// The number of all changes.
- public var changeCount: Int {
- return sectionDeleted.count
- + sectionInserted.count
- + sectionUpdated.count
- + sectionMoved.count
- + elementDeleted.count
- + elementInserted.count
- + elementUpdated.count
- + elementMoved.count
- }
-
- /// A Boolean value indicating whether has changes.
- public var hasChanges: Bool {
- return changeCount > 0
- }
-
/// Creates a new `Changeset`.
///
/// - Parameters:
@@ -78,6 +61,44 @@ public struct Changeset {
}
}
+public extension Changeset {
+ /// The number of section changes.
+ public var sectionChangeCount: Int {
+ return sectionDeleted.count
+ + sectionInserted.count
+ + sectionUpdated.count
+ + sectionMoved.count
+ }
+
+ /// The number of element changes.
+ public var elementChangeCount: Int {
+ return elementDeleted.count
+ + elementInserted.count
+ + elementUpdated.count
+ + elementMoved.count
+ }
+
+ /// The number of all changes.
+ public var changeCount: Int {
+ return sectionChangeCount + elementChangeCount
+ }
+
+ /// A Boolean value indicating whether has section changes.
+ public var hasSectionChanges: Bool {
+ return sectionChangeCount > 0
+ }
+
+ /// A Boolean value indicating whether has element changes.
+ public var hasElementChanges: Bool {
+ return elementChangeCount > 0
+ }
+
+ /// A Boolean value indicating whether has changes.
+ public var hasChanges: Bool {
+ return changeCount > 0
+ }
+}
+
extension Changeset: Equatable where Collection: Equatable {
public static func == (lhs: Changeset, rhs: Changeset) -> Bool {
return lhs.data == rhs.data
diff --git a/Tests/ChangesetTest.swift b/Tests/ChangesetTest.swift
index b8632ad..15c20f4 100644
--- a/Tests/ChangesetTest.swift
+++ b/Tests/ChangesetTest.swift
@@ -4,39 +4,55 @@ import DifferenceKit
final class ChangesetTestCase: XCTestCase {
func testchangeCount() {
let c1 = Changeset(data: [()], sectionDeleted: [0, 1])
+ XCTAssertEqual(c1.sectionChangeCount, 2)
+ XCTAssertEqual(c1.elementChangeCount, 0)
XCTAssertEqual(c1.changeCount, 2)
let c2 = Changeset(data: [()], sectionInserted: [0, 1, 2])
+ XCTAssertEqual(c2.sectionChangeCount, 3)
+ XCTAssertEqual(c2.elementChangeCount, 0)
XCTAssertEqual(c2.changeCount, 3)
let c3 = Changeset(data: [()], sectionUpdated: [0, 1, 2, 3])
+ XCTAssertEqual(c3.sectionChangeCount, 4)
+ XCTAssertEqual(c3.elementChangeCount, 0)
XCTAssertEqual(c3.changeCount, 4)
let c4 = Changeset(data: [()], sectionMoved: [(source: 0, target: 1)])
+ XCTAssertEqual(c4.sectionChangeCount, 1)
+ XCTAssertEqual(c4.elementChangeCount, 0)
XCTAssertEqual(c4.changeCount, 1)
let c5 = Changeset(
data: [()],
elementDeleted: [ElementPath(element: 0, section: 0), ElementPath(element: 1, section: 1)]
)
+ XCTAssertEqual(c5.sectionChangeCount, 0)
+ XCTAssertEqual(c5.elementChangeCount, 2)
XCTAssertEqual(c5.changeCount, 2)
let c6 = Changeset(
data: [()],
elementInserted: [ElementPath(element: 0, section: 0), ElementPath(element: 1, section: 1)]
)
+ XCTAssertEqual(c6.sectionChangeCount, 0)
+ XCTAssertEqual(c6.elementChangeCount, 2)
XCTAssertEqual(c6.changeCount, 2)
let c7 = Changeset(
data: [()],
elementUpdated: [ElementPath(element: 0, section: 0), ElementPath(element: 1, section: 1)]
)
+ XCTAssertEqual(c7.sectionChangeCount, 0)
+ XCTAssertEqual(c7.elementChangeCount, 2)
XCTAssertEqual(c7.changeCount, 2)
let c8 = Changeset(
data: [()],
elementMoved: [(source: ElementPath(element: 0, section: 0), target: ElementPath(element: 1, section: 1))]
)
+ XCTAssertEqual(c8.sectionChangeCount, 0)
+ XCTAssertEqual(c8.elementChangeCount, 1)
XCTAssertEqual(c8.changeCount, 1)
let c9 = Changeset(
@@ -50,14 +66,20 @@ final class ChangesetTestCase: XCTestCase {
elementUpdated: [ElementPath(element: 9, section: 10)],
elementMoved: [(source: ElementPath(element: 11, section: 12), target: ElementPath(element: 13, section: 14))]
)
+ XCTAssertEqual(c9.sectionChangeCount, 4)
+ XCTAssertEqual(c9.elementChangeCount, 4)
XCTAssertEqual(c9.changeCount, 8)
}
func testHasChanges() {
let c1 = Changeset(data: [()])
+ XCTAssertFalse(c1.hasSectionChanges)
+ XCTAssertFalse(c1.hasElementChanges)
XCTAssertFalse(c1.hasChanges)
let c2 = Changeset(data: [()], sectionDeleted: [0])
+ XCTAssertTrue(c2.hasSectionChanges)
+ XCTAssertFalse(c2.hasElementChanges)
XCTAssertTrue(c2.hasChanges)
}
From 0b5aaf1356e7db0b0e94c079865a118536f08360 Mon Sep 17 00:00:00 2001
From: Ryo Aoyama
Date: Tue, 2 Oct 2018 13:58:16 +0900
Subject: [PATCH 02/11] Add ContentEquatable
---
DifferenceKit.xcodeproj/project.pbxproj | 4 ++++
Sources/ContentEquatable.swift | 26 +++++++++++++++++++++++
Sources/Differentiable.swift | 28 ++-----------------------
3 files changed, 32 insertions(+), 26 deletions(-)
create mode 100644 Sources/ContentEquatable.swift
diff --git a/DifferenceKit.xcodeproj/project.pbxproj b/DifferenceKit.xcodeproj/project.pbxproj
index 4384718..f7b8448 100644
--- a/DifferenceKit.xcodeproj/project.pbxproj
+++ b/DifferenceKit.xcodeproj/project.pbxproj
@@ -8,6 +8,7 @@
/* Begin PBXBuildFile section */
6B2DF878210E2C12004D2D40 /* DifferenceKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B2DF86E210E2C12004D2D40 /* DifferenceKit.framework */; };
+ 6B444B392163312700AEE32B /* ContentEquatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B444B382163312700AEE32B /* ContentEquatable.swift */; };
6B5B409C211066BF00A931DB /* AlgorithmTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B5B4093211066BF00A931DB /* AlgorithmTest.swift */; };
6B5B409D211066BF00A931DB /* ArraySectionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B5B4094211066BF00A931DB /* ArraySectionTest.swift */; };
6B5B409E211066BF00A931DB /* StagedChangesetTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B5B4095211066BF00A931DB /* StagedChangesetTest.swift */; };
@@ -42,6 +43,7 @@
6B2DF86E210E2C12004D2D40 /* DifferenceKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DifferenceKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
6B2DF877210E2C12004D2D40 /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
6B2DF88A210E39A8004D2D40 /* DifferenceKit.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DifferenceKit.xcconfig; sourceTree = ""; };
+ 6B444B382163312700AEE32B /* ContentEquatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentEquatable.swift; sourceTree = ""; };
6B5B4086211066B300A931DB /* Algorithm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Algorithm.swift; sourceTree = ""; };
6B5B4088211066B300A931DB /* UIKitExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIKitExtension.swift; sourceTree = ""; };
6B5B408A211066B300A931DB /* ArraySection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArraySection.swift; sourceTree = ""; };
@@ -117,6 +119,7 @@
6B5B4086211066B300A931DB /* Algorithm.swift */,
6B5B408F211066B300A931DB /* Changeset.swift */,
6B5B408C211066B300A931DB /* StagedChangeset.swift */,
+ 6B444B382163312700AEE32B /* ContentEquatable.swift */,
6B5B4091211066B300A931DB /* Differentiable.swift */,
6B5B408E211066B300A931DB /* DifferentiableSection.swift */,
6B5B408B211066B300A931DB /* AnyDifferentiable.swift */,
@@ -261,6 +264,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 6B444B392163312700AEE32B /* ContentEquatable.swift in Sources */,
6B5B40A8211066EA00A931DB /* Changeset.swift in Sources */,
6B5B40AB211066EA00A931DB /* AnyDifferentiable.swift in Sources */,
755D649621514ECB0049A3C5 /* AppKitExtension.swift in Sources */,
diff --git a/Sources/ContentEquatable.swift b/Sources/ContentEquatable.swift
new file mode 100644
index 0000000..b38fddc
--- /dev/null
+++ b/Sources/ContentEquatable.swift
@@ -0,0 +1,26 @@
+/// Represents a value that can compare whether the content are equal.
+public protocol ContentEquatable {
+ /// Indicate whether the content of `self` is equals to the content of
+ /// the given source value.
+ ///
+ /// - Parameters:
+ /// - source: A source value to be compared.
+ ///
+ /// - Returns: A Boolean value indicating whether the content of `self` is equals
+ /// to the content of the given source value.
+ func isContentEqual(to source: Self) -> Bool
+}
+
+public extension ContentEquatable where Self: Equatable {
+ /// Indicate whether the content of `self` is equals to the content of the given source value.
+ /// Updates are compared using `==` operator of `Equatable'.
+ ///
+ /// - Parameters:
+ /// - source: A source value to be compared.
+ ///
+ /// - Returns: A Boolean value indicating whether the content of `self` is equals
+ /// to the content of the given source value.
+ func isContentEqual(to source: Self) -> Bool {
+ return self == source
+ }
+}
diff --git a/Sources/Differentiable.swift b/Sources/Differentiable.swift
index 1079666..e52bf68 100644
--- a/Sources/Differentiable.swift
+++ b/Sources/Differentiable.swift
@@ -1,34 +1,10 @@
-/// Represents the value that identified and can be compared to whether has updated.
-public protocol Differentiable {
+/// Represents the value that identified for differentiate.
+public protocol Differentiable: ContentEquatable {
/// A type representing the identifier.
associatedtype DifferenceIdentifier: Hashable
/// An identifier value for difference calculation.
var differenceIdentifier: DifferenceIdentifier { get }
-
- /// Indicate whether the content of `self` is equals to the content of
- /// the given source value.
- ///
- /// - Parameters:
- /// - source: A source value to be compared.
- ///
- /// - Returns: A Boolean value indicating whether the content of `self` is equals
- /// to the content of the given source value.
- func isContentEqual(to source: Self) -> Bool
-}
-
-public extension Differentiable where Self: Equatable {
- /// Indicate whether the content of `self` is equals to the content of the given source value.
- /// Updates are compared using `==` operator of `Equatable'.
- ///
- /// - Parameters:
- /// - source: A source value to be compared.
- ///
- /// - Returns: A Boolean value indicating whether the content of `self` is equals
- /// to the content of the given source value.
- func isContentEqual(to source: Self) -> Bool {
- return self == source
- }
}
public extension Differentiable where Self: Hashable {
From c5bd0f72c317fc8acb2c6e4f50ed0ee54f522efe Mon Sep 17 00:00:00 2001
From: Ryo Aoyama
Date: Tue, 2 Oct 2018 15:59:14 +0900
Subject: [PATCH 03/11] Inlining
---
Sources/Algorithm.swift | 93 ++++++++++++++++++++++-----------
Sources/AnyDifferentiable.swift | 63 ++++++++++++++++++----
Sources/ArraySection.swift | 9 ++--
Sources/Changeset.swift | 7 +++
Sources/ContentEquatable.swift | 1 +
Sources/Differentiable.swift | 1 +
Sources/ElementPath.swift | 2 +-
Sources/StagedChangeset.swift | 12 ++++-
8 files changed, 140 insertions(+), 48 deletions(-)
diff --git a/Sources/Algorithm.swift b/Sources/Algorithm.swift
index 905d7b0..624b6cc 100644
--- a/Sources/Algorithm.swift
+++ b/Sources/Algorithm.swift
@@ -18,6 +18,7 @@ public extension StagedChangeset where Collection: RangeReplaceableCollection, C
/// - target: A target collection to calculate differences.
///
/// - Complexity: O(n)
+ @inlinable
public init(source: Collection, target: Collection) {
self.init(source: source, target: target, section: 0)
}
@@ -42,6 +43,7 @@ public extension StagedChangeset where Collection: RangeReplaceableCollection, C
/// - section: An Int value to use as section index (or offset) of element.
///
/// - Complexity: O(n)
+ @inlinable
public init(source: Collection, target: Collection, section: Int) {
let sourceElements = ContiguousArray(source)
let targetElements = ContiguousArray(target)
@@ -134,6 +136,7 @@ public extension StagedChangeset where Collection: RangeReplaceableCollection, C
/// - target: A target sectioned collection to calculate differences.
///
/// - Complexity: O(n)
+ @inlinable
public init(source: Collection, target: Collection) {
typealias Section = Collection.Element
typealias SectionIdentifier = Collection.Element.DifferenceIdentifier
@@ -405,8 +408,9 @@ public extension StagedChangeset where Collection: RangeReplaceableCollection, C
}
/// The shared algorithm to calculate differences between two linear collections.
+@inlinable
@discardableResult
-private func differentiate(
+internal func differentiate(
source: ContiguousArray,
target: ContiguousArray,
trackTargetIndexAsUpdated: Bool,
@@ -528,16 +532,23 @@ private func differentiate(
}
/// A set of changes and metadata as a result of calculating differences in linear collection.
-private struct DifferentiateResult {
- typealias Metadata = (sourceTraces: ContiguousArray>, targetReferences: ContiguousArray)
-
- let deleted: [Index]
- let inserted: [Index]
- let updated: [Index]
- let moved: [(source: Index, target: Index)]
- let metadata: Metadata
-
- init(
+@usableFromInline
+internal struct DifferentiateResult {
+ @usableFromInline
+ internal typealias Metadata = (sourceTraces: ContiguousArray>, targetReferences: ContiguousArray)
+ @usableFromInline
+ internal let deleted: [Index]
+ @usableFromInline
+ internal let inserted: [Index]
+ @usableFromInline
+ internal let updated: [Index]
+ @usableFromInline
+ internal let moved: [(source: Index, target: Index)]
+ @usableFromInline
+ internal let metadata: Metadata
+
+ @inlinable
+ internal init(
deleted: [Index] = [],
inserted: [Index] = [],
updated: [Index] = [],
@@ -553,32 +564,46 @@ private struct DifferentiateResult {
}
/// A set of informations in middle of difference calculation.
-private struct Trace {
- var reference: Index?
- var deleteOffset = 0
- var isTracked = false
+@usableFromInline
+internal struct Trace {
+ @usableFromInline
+ internal var reference: Index?
+ @usableFromInline
+ internal var deleteOffset = 0
+ @usableFromInline
+ internal var isTracked = false
+
+ @inlinable
+ init() {}
}
/// The occurrences of element.
-private enum Occurrence {
+@usableFromInline
+internal enum Occurrence {
case unique(index: Int)
case duplicate(reference: IndicesReference)
}
/// A mutable reference to indices of elements.
-private final class IndicesReference {
- private var indices: ContiguousArray
- private var position = 0
-
- init(_ indices: ContiguousArray) {
+@usableFromInline
+internal final class IndicesReference {
+ @usableFromInline
+ internal var indices: ContiguousArray
+ @usableFromInline
+ internal var position = 0
+
+ @inlinable
+ internal init(_ indices: ContiguousArray) {
self.indices = indices
}
- func push(_ index: Int) {
+ @inlinable
+ internal func push(_ index: Int) {
indices.append(index)
}
- func next() -> Int? {
+ @inlinable
+ internal func next() -> Int? {
guard position < indices.endIndex else {
return nil
}
@@ -588,23 +613,29 @@ private final class IndicesReference {
}
/// Dictionary key using UnsafePointer for performance optimization.
-private struct TableKey: Hashable {
- let hashValue: Int
- private let pointer: UnsafePointer
-
- init(pointer: UnsafePointer) {
+@usableFromInline
+internal struct TableKey: Hashable {
+ @usableFromInline
+ internal let hashValue: Int
+ @usableFromInline
+ internal let pointer: UnsafePointer
+
+ @inlinable
+ internal init(pointer: UnsafePointer) {
self.hashValue = pointer.pointee.hashValue
self.pointer = pointer
}
- static func == (lhs: TableKey, rhs: TableKey) -> Bool {
+ @inlinable
+ internal static func == (lhs: TableKey, rhs: TableKey) -> Bool {
return lhs.hashValue == rhs.hashValue
&& (lhs.pointer.distance(to: rhs.pointer) == 0 || lhs.pointer.pointee == rhs.pointer.pointee)
}
}
-private extension MutableCollection where Element: MutableCollection, Index == Int, Element.Index == Int {
- subscript(path: ElementPath) -> Element.Element {
+internal extension MutableCollection where Element: MutableCollection, Index == Int, Element.Index == Int {
+ @inlinable
+ internal subscript(path: ElementPath) -> Element.Element {
get { return self[path.section][path.element] }
set { self[path.section][path.element] = newValue }
}
diff --git a/Sources/AnyDifferentiable.swift b/Sources/AnyDifferentiable.swift
index 343c560..75b4492 100644
--- a/Sources/AnyDifferentiable.swift
+++ b/Sources/AnyDifferentiable.swift
@@ -24,24 +24,27 @@
/// print(changeset.isEmpty) // prints "false"
public struct AnyDifferentiable: Differentiable {
/// The value wrapped by this instance.
- public let base: Any
+ @inlinable
+ public var base: Any {
+ return box.base
+ }
+
/// A type-erased identifier value for difference calculation.
- public let differenceIdentifier: AnyHashable
+ @inlinable
+ public var differenceIdentifier: AnyHashable {
+ return box.differenceIdentifier
+ }
- private let isContentEqualTo: (AnyDifferentiable) -> Bool
+ @usableFromInline
+ internal let box: AnyDifferentiableBox
/// Creates a type-erased differentiable value that wraps the given instance.
///
/// - Parameters:
/// - base: A differentiable value to wrap.
+ @inlinable
public init(_ base: D) {
- self.base = base
- self.differenceIdentifier = AnyHashable(base.differenceIdentifier)
-
- self.isContentEqualTo = { source in
- guard let sourceBase = source.base as? D else { return false }
- return base.isContentEqual(to: sourceBase)
- }
+ box = ConcretDifferentiableBox(base)
}
/// Indicate whether the content of `base` is equals to the content of the given source value.
@@ -51,8 +54,9 @@ public struct AnyDifferentiable: Differentiable {
///
/// - Returns: A Boolean value indicating whether the content of `base` is equals
/// to the content of `base` of the given source value.
+ @inlinable
public func isContentEqual(to source: AnyDifferentiable) -> Bool {
- return isContentEqualTo(source)
+ return box.isContentEqual(to: source.box)
}
}
@@ -61,3 +65,40 @@ extension AnyDifferentiable: CustomDebugStringConvertible {
return "AnyDifferentiable(\(String(reflecting: base))"
}
}
+
+@usableFromInline
+internal protocol AnyDifferentiableBox {
+ var base: Any { get }
+ var differenceIdentifier: AnyHashable { get }
+
+ func isContentEqual(to source: AnyDifferentiableBox) -> Bool
+}
+
+@usableFromInline
+internal struct ConcretDifferentiableBox: AnyDifferentiableBox {
+ @usableFromInline
+ internal let baseComponent: Base
+
+ @inlinable
+ internal var base: Any {
+ return baseComponent
+ }
+
+ @inlinable
+ internal var differenceIdentifier: AnyHashable {
+ return AnyHashable(baseComponent.differenceIdentifier)
+ }
+
+ @inlinable
+ internal init(_ base: Base) {
+ baseComponent = base
+ }
+
+ @inlinable
+ internal func isContentEqual(to source: AnyDifferentiableBox) -> Bool {
+ guard let sourceBase = source.base as? Base else {
+ return false
+ }
+ return baseComponent.isContentEqual(to: sourceBase)
+ }
+}
diff --git a/Sources/ArraySection.swift b/Sources/ArraySection.swift
index c82931a..9716706 100644
--- a/Sources/ArraySection.swift
+++ b/Sources/ArraySection.swift
@@ -9,8 +9,9 @@ public struct ArraySection: Diff
public var elements: [Element]
/// An identifier value that of model for difference calculation.
+ @inlinable
public var differenceIdentifier: Model.DifferenceIdentifier {
- @inline(__always) get { return model.differenceIdentifier }
+ return model.differenceIdentifier
}
/// Creates a section with the model and the elements.
@@ -18,7 +19,7 @@ public struct ArraySection: Diff
/// - Parameters:
/// - model: A differentiable model of section.
/// - elements: The collection of element in the section.
- @inline(__always)
+ @inlinable
public init(model: Model, elements: C) where C.Element == Element {
self.model = model
self.elements = Array(elements)
@@ -29,7 +30,7 @@ public struct ArraySection: Diff
/// - Parameters:
/// - source: A source section to reproduce.
/// - elements: The collection of elements for the new section.
- @inline(__always)
+ @inlinable
public init(source: ArraySection, elements: C) where C.Element == Element {
self.init(model: source.model, elements: elements)
}
@@ -44,7 +45,7 @@ public struct ArraySection: Diff
///
/// - Returns: A Boolean value indicating whether the content of `self` is equals
/// to the content of the given source section.
- @inline(__always)
+ @inlinable
public func isContentEqual(to source: ArraySection) -> Bool {
return model.isContentEqual(to: source.model)
}
diff --git a/Sources/Changeset.swift b/Sources/Changeset.swift
index 0388fa0..6c3d74e 100644
--- a/Sources/Changeset.swift
+++ b/Sources/Changeset.swift
@@ -38,6 +38,7 @@ public struct Changeset {
/// - elementInserted: The paths of inserted elements.
/// - elementUpdated: The paths of updated elements.
/// - elementMoved: The pairs of source and target path of moved elements.
+ @inlinable
public init(
data: Collection,
sectionDeleted: [Int] = [],
@@ -63,6 +64,7 @@ public struct Changeset {
public extension Changeset {
/// The number of section changes.
+ @inlinable
public var sectionChangeCount: Int {
return sectionDeleted.count
+ sectionInserted.count
@@ -71,6 +73,7 @@ public extension Changeset {
}
/// The number of element changes.
+ @inlinable
public var elementChangeCount: Int {
return elementDeleted.count
+ elementInserted.count
@@ -79,21 +82,25 @@ public extension Changeset {
}
/// The number of all changes.
+ @inlinable
public var changeCount: Int {
return sectionChangeCount + elementChangeCount
}
/// A Boolean value indicating whether has section changes.
+ @inlinable
public var hasSectionChanges: Bool {
return sectionChangeCount > 0
}
/// A Boolean value indicating whether has element changes.
+ @inlinable
public var hasElementChanges: Bool {
return elementChangeCount > 0
}
/// A Boolean value indicating whether has changes.
+ @inlinable
public var hasChanges: Bool {
return changeCount > 0
}
diff --git a/Sources/ContentEquatable.swift b/Sources/ContentEquatable.swift
index b38fddc..9032212 100644
--- a/Sources/ContentEquatable.swift
+++ b/Sources/ContentEquatable.swift
@@ -20,6 +20,7 @@ public extension ContentEquatable where Self: Equatable {
///
/// - Returns: A Boolean value indicating whether the content of `self` is equals
/// to the content of the given source value.
+ @inlinable
func isContentEqual(to source: Self) -> Bool {
return self == source
}
diff --git a/Sources/Differentiable.swift b/Sources/Differentiable.swift
index e52bf68..0610b24 100644
--- a/Sources/Differentiable.swift
+++ b/Sources/Differentiable.swift
@@ -9,6 +9,7 @@ public protocol Differentiable: ContentEquatable {
public extension Differentiable where Self: Hashable {
/// The `self` value as an identifier for difference calculation.
+ @inlinable
var differenceIdentifier: Self {
return self
}
diff --git a/Sources/ElementPath.swift b/Sources/ElementPath.swift
index bd86b90..bbcaffa 100644
--- a/Sources/ElementPath.swift
+++ b/Sources/ElementPath.swift
@@ -12,7 +12,7 @@ public struct ElementPath: Hashable {
/// - Parameters:
/// - element: The element index (or offset).
/// - section: The section index (or offset).
- @inline(__always)
+ @inlinable
public init(element: Int, section: Int) {
self.element = element
self.section = section
diff --git a/Sources/StagedChangeset.swift b/Sources/StagedChangeset.swift
index 9160930..a917203 100644
--- a/Sources/StagedChangeset.swift
+++ b/Sources/StagedChangeset.swift
@@ -30,51 +30,61 @@
/// let changeset = StagedChangeset(source: sectionedSource, target: sectionedTarget)
/// print(changeset.isEmpty) // prints "false"
public struct StagedChangeset {
- private var changesets: ContiguousArray>
+ @usableFromInline
+ internal var changesets: ContiguousArray>
/// Creates a new `StagedChangeset`.
///
/// - Parameters:
/// - changesets: The collection of `Changeset`.
+ @inlinable
public init(_ changesets: C) where C.Element == Changeset {
self.changesets = ContiguousArray(changesets)
}
}
extension StagedChangeset: RandomAccessCollection, RangeReplaceableCollection, MutableCollection {
+ @inlinable
public init() {
self.init([])
}
+ @inlinable
public var startIndex: Int {
return changesets.startIndex
}
+ @inlinable
public var endIndex: Int {
return changesets.endIndex
}
+ @inlinable
public func index(after i: Int) -> Int {
return changesets.index(after: i)
}
+ @inlinable
public subscript(position: Int) -> Changeset {
get { return changesets[position] }
set { changesets[position] = newValue }
}
+ @inlinable
public mutating func replaceSubrange(_ subrange: R, with newElements: C) where C.Element == Changeset, R.Bound == Int {
changesets.replaceSubrange(subrange, with: newElements)
}
}
extension StagedChangeset: Equatable where Collection: Equatable {
+ @inlinable
public static func == (lhs: StagedChangeset, rhs: StagedChangeset) -> Bool {
return lhs.changesets == rhs.changesets
}
}
extension StagedChangeset: ExpressibleByArrayLiteral {
+ @inlinable
public init(arrayLiteral elements: Changeset...) {
self.init(elements)
}
From f4e05557069c290bc8a9251d129a05f463443cab Mon Sep 17 00:00:00 2001
From: Ryo Aoyama
Date: Tue, 2 Oct 2018 16:02:12 +0900
Subject: [PATCH 04/11] Swift4.2
---
.swift-version | 2 +-
.travis.yml | 6 ------
DifferenceKit.xcodeproj/project.pbxproj | 4 ++--
README.md | 4 ++--
4 files changed, 5 insertions(+), 11 deletions(-)
diff --git a/.swift-version b/.swift-version
index 7d5c902..bf77d54 100644
--- a/.swift-version
+++ b/.swift-version
@@ -1 +1 @@
-4.1
+4.2
diff --git a/.travis.yml b/.travis.yml
index f477c9b..a00abf8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -12,11 +12,5 @@ matrix:
- xcodebuild build-for-testing test-without-building -scheme DifferenceKit -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 8' ENABLE_TESTABILITY=YES | xcpretty - c
- xcodebuild build-for-testing test-without-building -scheme DifferenceKit -configuration Release -sdk appletvsimulator -destination 'platform=tvOS Simulator,name=Apple TV' ENABLE_TESTABILITY=YES | xcpretty -c
- xcodebuild build -scheme DifferenceKit -configuration Release -sdk watchsimulator -destination 'platform=watchOS Simulator,name=Apple Watch - 38mm' ENABLE_TESTABILITY=YES | xcpretty -c
- - os: osx
- language: objective-c
- osx_image: xcode9.4
- script:
- - xcodebuild build -scheme DifferenceKit -configuration Release ENABLE_TESTABILITY=YES | xcpretty -c
- - xcodebuild build -scheme DifferenceKit -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 8' | xcpretty -c
notifications:
email: false
diff --git a/DifferenceKit.xcodeproj/project.pbxproj b/DifferenceKit.xcodeproj/project.pbxproj
index f7b8448..4cdfafd 100644
--- a/DifferenceKit.xcodeproj/project.pbxproj
+++ b/DifferenceKit.xcodeproj/project.pbxproj
@@ -362,7 +362,7 @@
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- SWIFT_VERSION = 4.0;
+ SWIFT_VERSION = 4.2;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
@@ -419,7 +419,7 @@
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
- SWIFT_VERSION = 4.0;
+ SWIFT_VERSION = 4.2;
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
diff --git a/README.md b/README.md
index f36ff8d..57fd28d 100644
--- a/README.md
+++ b/README.md
@@ -170,7 +170,7 @@ collectionView.reload(using: changeset, interrupt: { $0.changeCount > 100 }) { d
## Comparison with Other Frameworks
Made a fair comparison as much as possible in features and performance with other **popular** and **awesome** frameworks.
-⚠️ This does `NOT` determine superiority or inferiority of the frameworks. I know that each framework has different benefits.
+This does **NOT** determine superiority or inferiority of the frameworks. I know that each framework has different benefits.
The frameworks and its version that compared is below.
- [DifferenceKit](https://github.com/ra1028/DifferenceKit) - master
@@ -268,7 +268,7 @@ Use `Foundation.UUID` as an element.
---
## Requirements
-- Swift4.1+
+- Swift4.2+
- iOS 9.0+
- tvOS 9.0+
- OS X 10.9+
From 30189ea8e2e2961f29a8abdd09f5eaab63c5ed2c Mon Sep 17 00:00:00 2001
From: Ryo Aoyama
Date: Tue, 2 Oct 2018 16:47:24 +0900
Subject: [PATCH 05/11] Update README
---
README.md | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/README.md b/README.md
index 57fd28d..1e97285 100644
--- a/README.md
+++ b/README.md
@@ -87,16 +87,14 @@ In the case of definition above, `id` uniquely identifies the element and get to
There are default implementations of `Differentiable` for the types that conformed to `Equatable` or `Hashable`:
```swift
-public extension Differentiable where Self: Equatable {
- func isContentEqual(to source: Self) -> Bool {
- return self == source
- }
+// If `Self` conform to `Hashable`.
+var differenceIdentifier: Self {
+ return self
}
-public extension Differentiable where Self: Hashable {
- var differenceIdentifier: Self {
- return self
- }
+// If `Self` conform to `Equatable`.
+func isContentEqual(to source: Self) -> Bool {
+ return self == source
}
```
So, you can simply:
From 6c5dcb8756dd2dc6ef2fbfb4062f56ca51e7ae3a Mon Sep 17 00:00:00 2001
From: Ryo Aoyama
Date: Tue, 2 Oct 2018 17:37:52 +0900
Subject: [PATCH 06/11] Update README
---
README.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 1e97285..69b4090 100644
--- a/README.md
+++ b/README.md
@@ -230,7 +230,7 @@ Use `Foundation.UUID` as an element.
#### - From 5,000 elements to 500 deleted and 500 inserted
| |Time(second)|
|:------------|:-----------|
-|DifferenceKit|0.0032 |
+|DifferenceKit|0.0022 |
|RxDataSources|0.0078 |
|FlexibleDiff |0.0168 |
|IGListKit |0.0412 |
@@ -242,7 +242,7 @@ Use `Foundation.UUID` as an element.
#### - From 10,000 elements to 1,000 deleted and 1,000 inserted
| |Time(second)|
|:------------|:-----------|
-|DifferenceKit|0.0076 |
+|DifferenceKit|0.0049 |
|RxDataSources|0.0143 |
|FlexibleDiff |0.0305 |
|IGListKit |0.0891 |
@@ -254,7 +254,7 @@ Use `Foundation.UUID` as an element.
#### - From 100,000 elements to 10,000 deleted and 10,000 inserted
| |Time(second)|
|:------------|:-----------|
-|DifferenceKit|0.087 |
+|DifferenceKit|0.057 |
|RxDataSources|0.179 |
|FlexibleDiff |0.356 |
|IGListKit |1.329 |
From 62bd6402e6e846c1478b49b14a1afd9d5e424852 Mon Sep 17 00:00:00 2001
From: Ryo Aoyama
Date: Tue, 2 Oct 2018 17:41:10 +0900
Subject: [PATCH 07/11] Build with Swift4.1 on CI
---
.travis.yml | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/.travis.yml b/.travis.yml
index a00abf8..a6c46ec 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -12,5 +12,11 @@ matrix:
- xcodebuild build-for-testing test-without-building -scheme DifferenceKit -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 8' ENABLE_TESTABILITY=YES | xcpretty - c
- xcodebuild build-for-testing test-without-building -scheme DifferenceKit -configuration Release -sdk appletvsimulator -destination 'platform=tvOS Simulator,name=Apple TV' ENABLE_TESTABILITY=YES | xcpretty -c
- xcodebuild build -scheme DifferenceKit -configuration Release -sdk watchsimulator -destination 'platform=watchOS Simulator,name=Apple Watch - 38mm' ENABLE_TESTABILITY=YES | xcpretty -c
+ - os: osx
+ language: objective-c
+ osx_image: xcode9.4
+ script:
+ - xcodebuild build -scheme DifferenceKit -configuration Release ENABLE_TESTABILITY=YES | xcpretty -c
+ - xcodebuild build -scheme DifferenceKit -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 8' | xcpretty -c
notifications:
- email: false
+email: false
\ No newline at end of file
From 7d5a9cf85b1da6c566d177125cd605ba465d2e65 Mon Sep 17 00:00:00 2001
From: Ryo Aoyama
Date: Tue, 2 Oct 2018 17:54:27 +0900
Subject: [PATCH 08/11] End support for Swift 4.1 or lower
---
.travis.yml | 6 ------
Sources/Extensions/UIKitExtension.swift | 5 -----
2 files changed, 11 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index a6c46ec..30d0800 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -12,11 +12,5 @@ matrix:
- xcodebuild build-for-testing test-without-building -scheme DifferenceKit -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 8' ENABLE_TESTABILITY=YES | xcpretty - c
- xcodebuild build-for-testing test-without-building -scheme DifferenceKit -configuration Release -sdk appletvsimulator -destination 'platform=tvOS Simulator,name=Apple TV' ENABLE_TESTABILITY=YES | xcpretty -c
- xcodebuild build -scheme DifferenceKit -configuration Release -sdk watchsimulator -destination 'platform=watchOS Simulator,name=Apple Watch - 38mm' ENABLE_TESTABILITY=YES | xcpretty -c
- - os: osx
- language: objective-c
- osx_image: xcode9.4
- script:
- - xcodebuild build -scheme DifferenceKit -configuration Release ENABLE_TESTABILITY=YES | xcpretty -c
- - xcodebuild build -scheme DifferenceKit -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 8' | xcpretty -c
notifications:
email: false
\ No newline at end of file
diff --git a/Sources/Extensions/UIKitExtension.swift b/Sources/Extensions/UIKitExtension.swift
index f9bc60f..e40f75d 100644
--- a/Sources/Extensions/UIKitExtension.swift
+++ b/Sources/Extensions/UIKitExtension.swift
@@ -2,11 +2,6 @@
import UIKit
public extension UITableView {
- #if swift(>=4.2)
- #else
- typealias RowAnimation = UITableViewRowAnimation
- #endif
-
/// Applies multiple animated updates in stages using `StagedChangeset`.
///
/// - Note: There are combination of changes that crash when applied simultaneously in `performBatchUpdates`.
From 7886f39b4f790990207f97ecd44bd66fc1ab7a90 Mon Sep 17 00:00:00 2001
From: Ryo Aoyama
Date: Tue, 2 Oct 2018 17:56:35 +0900
Subject: [PATCH 09/11] Update docs
---
docs/Extensions.html | 5 +-
docs/Extensions/UICollectionView.html | 5 +-
docs/Extensions/UITableView.html | 5 +-
docs/Protocols.html | 41 +++-
docs/Protocols/ContentEquatable.html | 167 +++++++++++++++
docs/Protocols/Differentiable.html | 72 +------
docs/Protocols/DifferentiableSection.html | 7 +-
docs/Structs.html | 33 +--
docs/Structs/AnyDifferentiable.html | 35 ++--
docs/Structs/ArraySection.html | 16 +-
docs/Structs/Changeset.html | 236 ++++++++++++++++------
docs/Structs/ElementPath.html | 9 +-
docs/Structs/StagedChangeset.html | 55 +++--
docs/index.html | 67 +++---
docs/search.json | 2 +-
15 files changed, 533 insertions(+), 222 deletions(-)
create mode 100644 docs/Protocols/ContentEquatable.html
diff --git a/docs/Extensions.html b/docs/Extensions.html
index c92e607..5299973 100644
--- a/docs/Extensions.html
+++ b/docs/Extensions.html
@@ -42,6 +42,9 @@
Protocols
+ -
+ ContentEquatable
+
-
Differentiable
@@ -141,7 +144,7 @@ Declaration
diff --git a/docs/Extensions/UICollectionView.html b/docs/Extensions/UICollectionView.html
index 9fc44da..96dac2e 100644
--- a/docs/Extensions/UICollectionView.html
+++ b/docs/Extensions/UICollectionView.html
@@ -42,6 +42,9 @@
-
Protocols
+ -
+ ContentEquatable
+
-
Differentiable
@@ -175,7 +178,7 @@ Parameters
diff --git a/docs/Extensions/UITableView.html b/docs/Extensions/UITableView.html
index c25fbc1..d9e60a9 100644
--- a/docs/Extensions/UITableView.html
+++ b/docs/Extensions/UITableView.html
@@ -42,6 +42,9 @@
-
Protocols
+ -
+ ContentEquatable
+
-
Differentiable
@@ -349,7 +352,7 @@ Parameters
diff --git a/docs/Protocols.html b/docs/Protocols.html
index 03403d8..d899c63 100644
--- a/docs/Protocols.html
+++ b/docs/Protocols.html
@@ -42,6 +42,9 @@
-
Protocols
diff --git a/docs/Protocols/DifferentiableSection.html b/docs/Protocols/DifferentiableSection.html
index 6a7c985..9efc09c 100644
--- a/docs/Protocols/DifferentiableSection.html
+++ b/docs/Protocols/DifferentiableSection.html
@@ -42,6 +42,9 @@
-
Protocols
Example for calculating differences between the two linear collections.
-extension String: Differentiable {}
+extension String: Differentiable {}
let source = ["A", "B", "C"]
let target = ["B", "C", "D"]
-let changeset = StagedChangeset(source: source, target: target)
+let changeset = StagedChangeset(source: source, target: target)
print(changeset.isEmpty) // prints "false"
Example for calculating differences between the two sectioned collections.
let source = [
- Section(model: "A", elements: ["😉"]),
+ Section(model: "A", elements: ["😉"]),
]
let target = [
- Section(model: "A", elements: ["😉, 😺"]),
- Section(model: "B", elements: ["😪"])
+ Section(model: "A", elements: ["😉, 😺"]),
+ Section(model: "B", elements: ["😪"])
]
-let changeset = StagedChangeset(source: sectionedSource, target: sectionedTarget)
+let changeset = StagedChangeset(source: sectionedSource, target: sectionedTarget)
print(changeset.isEmpty) // prints "false"
@@ -165,20 +168,20 @@ Declaration
You can store mixed-type elements in collection that require Differentiable
conformance by
wrapping mixed-type elements in AnyDifferentiable
:
-extension String: Differentiable {}
-extension Int: Differentiable {}
+extension String: Differentiable {}
+extension Int: Differentiable {}
let source = [
- AnyDifferentiable("ABC"),
- AnyDifferentiable(100)
+ AnyDifferentiable("ABC"),
+ AnyDifferentiable(100)
]
let target = [
- AnyDifferentiable("ABC"),
- AnyDifferentiable(100),
- AnyDifferentiable(200)
+ AnyDifferentiable("ABC"),
+ AnyDifferentiable(100),
+ AnyDifferentiable(200)
]
-let changeset = StagedChangeset(source: source, target: target)
+let changeset = StagedChangeset(source: source, target: target)
print(changeset.isEmpty) // prints "false"
@@ -309,7 +312,7 @@ Declaration
diff --git a/docs/Structs/AnyDifferentiable.html b/docs/Structs/AnyDifferentiable.html
index 6d6f24d..d2ff66e 100644
--- a/docs/Structs/AnyDifferentiable.html
+++ b/docs/Structs/AnyDifferentiable.html
@@ -42,6 +42,9 @@
Protocols
extension String: Differentiable {}
-extension Int: Differentiable {}
+extension String: Differentiable {}
+extension Int: Differentiable {}
let source = [
- AnyDifferentiable("ABC"),
- AnyDifferentiable(100)
+ AnyDifferentiable("ABC"),
+ AnyDifferentiable(100)
]
let target = [
- AnyDifferentiable("ABC"),
- AnyDifferentiable(100),
- AnyDifferentiable(200)
+ AnyDifferentiable("ABC"),
+ AnyDifferentiable(100),
+ AnyDifferentiable(200)
]
-let changeset = StagedChangeset(source: source, target: target)
+let changeset = StagedChangeset(source: source, target: target)
print(changeset.isEmpty) // prints "false"
@@ -131,7 +134,8 @@ AnyDifferentiable
Declaration
Swift
-
public let base: Any
+
@inlinable
+public var base: Any { get }
@@ -158,7 +162,8 @@ Declaration
Declaration
Swift
-
public let differenceIdentifier: AnyHashable
+
@inlinable
+public var differenceIdentifier: AnyHashable { get }
@@ -185,7 +190,8 @@ Declaration
Declaration
@@ -231,7 +237,8 @@ Parameters
Declaration
Swift
-
public func isContentEqual(to source: AnyDifferentiable) -> Bool
+
@inlinable
+public func isContentEqual(to source: AnyDifferentiable) -> Bool
@@ -285,7 +292,7 @@ Return Value
Declaration
Swift
-
public var debugDescription: String { get }
+
public var debugDescription: String { get }
@@ -297,7 +304,7 @@ Declaration
diff --git a/docs/Structs/ArraySection.html b/docs/Structs/ArraySection.html
index 4115b35..3db5bcb 100644
--- a/docs/Structs/ArraySection.html
+++ b/docs/Structs/ArraySection.html
@@ -42,6 +42,9 @@
Protocols
+ -
+ ContentEquatable
+
-
Differentiable
@@ -165,7 +168,8 @@ Declaration
Declaration
Swift
-
public var differenceIdentifier: Model.DifferenceIdentifier { get }
+
@inlinable
+public var differenceIdentifier: Model.DifferenceIdentifier { get }
@@ -192,7 +196,7 @@ Declaration
Declaration
Swift
-
@inline(__always)
+ @inlinable
public init<C>(model: Model, elements: C) where Element == C.Element, C : Collection
@@ -251,7 +255,7 @@ Parameters
Declaration
Swift
-
@inline(__always)
+ @inlinable
public init<C>(source: ArraySection, elements: C) where Element == C.Element, C : Collection
@@ -316,7 +320,7 @@ Parameters
Declaration
Swift
-
@inline(__always)
+ @inlinable
public func isContentEqual(to source: ArraySection) -> Bool
@@ -401,7 +405,7 @@ Declaration
Declaration
Swift
-
public var debugDescription: String { get }
+
public var debugDescription: String { get }
@@ -413,7 +417,7 @@ Declaration
diff --git a/docs/Structs/Changeset.html b/docs/Structs/Changeset.html
index fdd0909..c4957e2 100644
--- a/docs/Structs/Changeset.html
+++ b/docs/Structs/Changeset.html
@@ -42,6 +42,9 @@
-
Protocols
- -
-
-
-
-
-
-
-
The number of all changes.
-
-
-
-
Declaration
-
-
Swift
-
public var changeCount: Int { get }
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
A Boolean value indicating whether has changes.
-
-
-
-
Declaration
-
-
Swift
-
public var hasChanges: Bool { get }
-
-
-
-
-
-
-
@@ -410,7 +359,8 @@ Declaration
Declaration
Swift
-
public init(
+ @inlinable
+public init(
data: Collection,
sectionDeleted: [Int] = [],
sectionInserted: [Int] = [],
@@ -544,6 +494,178 @@ Parameters
+
+
+ -
+
+
+
+
+
+
+
The number of section changes.
+
+
+
+
Declaration
+
+
Swift
+
@inlinable
+public var sectionChangeCount: Int { get }
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
The number of element changes.
+
+
+
+
Declaration
+
+
Swift
+
@inlinable
+public var elementChangeCount: Int { get }
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
The number of all changes.
+
+
+
+
Declaration
+
+
Swift
+
@inlinable
+public var changeCount: Int { get }
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
A Boolean value indicating whether has section changes.
+
+
+
+
Declaration
+
+
Swift
+
@inlinable
+public var hasSectionChanges: Bool { get }
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
A Boolean value indicating whether has element changes.
+
+
+
+
Declaration
+
+
Swift
+
@inlinable
+public var hasElementChanges: Bool { get }
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
A Boolean value indicating whether has changes.
+
+
+
+
Declaration
+
+
Swift
+
@inlinable
+public var hasChanges: Bool { get }
+
+
+
+
+
+
+
+
-
@@ -595,7 +717,7 @@
Declaration
Declaration
Swift
-
public var debugDescription: String { get }
+
public var debugDescription: String { get }
@@ -607,7 +729,7 @@ Declaration
diff --git a/docs/Structs/ElementPath.html b/docs/Structs/ElementPath.html
index 8dc6287..17b744f 100644
--- a/docs/Structs/ElementPath.html
+++ b/docs/Structs/ElementPath.html
@@ -42,6 +42,9 @@
-
Protocols
+ -
+ ContentEquatable
+
-
Differentiable
@@ -167,7 +170,7 @@ Declaration
Declaration
Swift
-
@inline(__always)
+ @inlinable
public init(element: Int, section: Int)
@@ -229,7 +232,7 @@ Parameters
Declaration
Swift
-
public var debugDescription: String { get }
+
public var debugDescription: String { get }
@@ -241,7 +244,7 @@ Declaration
diff --git a/docs/Structs/StagedChangeset.html b/docs/Structs/StagedChangeset.html
index a485b12..87e328e 100644
--- a/docs/Structs/StagedChangeset.html
+++ b/docs/Structs/StagedChangeset.html
@@ -42,6 +42,9 @@
-
Protocols
extension String: Differentiable {}
+extension String: Differentiable {}
let source = ["A", "B", "C"]
let target = ["B", "C", "D"]
-let changeset = StagedChangeset(source: source, target: target)
+let changeset = StagedChangeset(source: source, target: target)
print(changeset.isEmpty) // prints "false"
Example for calculating differences between the two sectioned collections.
let source = [
- Section(model: "A", elements: ["😉"]),
+ Section(model: "A", elements: ["😉"]),
]
let target = [
- Section(model: "A", elements: ["😉, 😺"]),
- Section(model: "B", elements: ["😪"])
+ Section(model: "A", elements: ["😉, 😺"]),
+ Section(model: "B", elements: ["😪"])
]
-let changeset = StagedChangeset(source: sectionedSource, target: sectionedTarget)
+let changeset = StagedChangeset(source: sectionedSource, target: sectionedTarget)
print(changeset.isEmpty) // prints "false"
@@ -138,7 +141,8 @@ StagedChangeset
Declaration
Swift
-
public init<C>(_ changesets: C) where C : Collection, C.Element == Changeset<Collection>
+
@inlinable
+public init<C>(_ changesets: C) where C : Collection, C.Element == Changeset<Collection>
@@ -214,7 +218,8 @@ Parameters
Declaration
Swift
-
public init(source: Collection, target: Collection)
+
@inlinable
+public init(source: Collection, target: Collection)
@@ -298,7 +303,8 @@ Parameters
Declaration
Swift
-
public init(source: Collection, target: Collection, section: Int)
+
@inlinable
+public init(source: Collection, target: Collection, section: Int)
@@ -398,7 +404,8 @@ Parameters
Declaration
Swift
-
public init(source: Collection, target: Collection)
+
@inlinable
+public init(source: Collection, target: Collection)
@@ -459,7 +466,8 @@ Parameters
Declaration
Swift
-
public init()
+
@inlinable
+public init()
@@ -485,7 +493,8 @@ Declaration
Declaration
Swift
-
public var startIndex: Int { get }
+
@inlinable
+public var startIndex: Int { get }
@@ -511,7 +520,8 @@ Declaration
Declaration
Swift
-
public var endIndex: Int { get }
+
@inlinable
+public var endIndex: Int { get }
@@ -537,7 +547,8 @@ Declaration
Declaration
Swift
-
public func index(after i: Int) -> Int
+
@inlinable
+public func index(after i: Int) -> Int
@@ -563,7 +574,8 @@ Declaration
Declaration
Swift
-
public subscript(position: Int) -> Changeset<Collection> { get set }
+
@inlinable
+public subscript(position: Int) -> Changeset<Collection> { get set }
@@ -589,7 +601,8 @@ Declaration
Declaration
Swift
-
public mutating func replaceSubrange<C, R>(_ subrange: R, with newElements: C) where C : Collection, R : RangeExpression, C.Element == Changeset<Collection>, R.Bound == Int
+
@inlinable
+public mutating func replaceSubrange<C, R>(_ subrange: R, with newElements: C) where C : Collection, R : RangeExpression, C.Element == Changeset<Collection>, R.Bound == Int
@@ -619,7 +632,8 @@ Declaration
Declaration
Swift
-
public static func == (lhs: StagedChangeset, rhs: StagedChangeset) -> Bool
+
@inlinable
+public static func == (lhs: StagedChangeset, rhs: StagedChangeset) -> Bool
@@ -649,7 +663,8 @@ Declaration
Declaration
Swift
-
public init(arrayLiteral elements: Changeset<Collection>...)
+
@inlinable
+public init(arrayLiteral elements: Changeset<Collection>...)
@@ -679,7 +694,7 @@ Declaration
Declaration
Swift
-
public var debugDescription: String { get }
+
public var debugDescription: String { get }
@@ -691,7 +706,7 @@ Declaration
diff --git a/docs/index.html b/docs/index.html
index 88f3433..85b5185 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -41,6 +41,9 @@
-
Protocols
+ -
+ ContentEquatable
+
-
Differentiable
@@ -149,15 +152,15 @@ Example codes
The type of the element that to take the differences must be conform to the Differentiable
protocol.
The differenceIdentifier
‘s type is determined generic by the associated type:
-
struct User: Differentiable {
+struct User: Differentiable {
let id: Int
let name: String
- var differenceIdentifier: Int {
+ var differenceIdentifier: Int {
return id
}
- func isContentEqual(to source: User) -> Bool {
+ func isContentEqual(to source: User) -> Bool {
return name == source.name
}
}
@@ -166,62 +169,60 @@ Example codes
In the case of definition above, id
uniquely identifies the element and get to know the user updated by comparing equality of name
of the elements in source and target.
There are default implementations of Differentiable
for the types that conformed to Equatable
or Hashable
:
-public extension Differentiable where Self: Equatable {
- func isContentEqual(to source: Self) -> Bool {
- return self == source
- }
+// If `Self` conform to `Hashable`.
+var differenceIdentifier: Self {
+ return self
}
-public extension Differentiable where Self: Hashable {
- var differenceIdentifier: Self {
- return self
- }
+// If `Self` conform to `Equatable`.
+func isContentEqual(to source: Self) -> Bool {
+ return self == source
}
So, you can simply:
-extension String: Differentiable {}
+extension String: Differentiable {}
Calculates the differences by creating StagedChangeset
from two collections of elements conforming to Differentiable
:
let source = [
- User(id: 0, name: "Vincent"),
- User(id: 1, name: "Jules")
+ User(id: 0, name: "Vincent"),
+ User(id: 1, name: "Jules")
]
let target = [
- User(id: 1, name: "Jules"),
- User(id: 0, name: "Vincent"),
- User(id: 2, name: "Butch")
+ User(id: 1, name: "Jules"),
+ User(id: 0, name: "Vincent"),
+ User(id: 2, name: "Butch")
]
-let changeset = StagedChangeset(source: source, target: target)
+let changeset = StagedChangeset(source: source, target: target)
If you want to include multiple types conformed to Differentiable
in the collection, use AnyDifferentiable
:
let source = [
- AnyDifferentiable("A"),
- AnyDifferentiable(User(id: 0, name: "Vincent"))
+ AnyDifferentiable("A"),
+ AnyDifferentiable(User(id: 0, name: "Vincent"))
]
In the case of sectioned collection, the section itself must have a unique identifier and be able to compare whether there is an update.
So each section must conform to DifferentiableSection
protocol, but in most cases you can use ArraySection
that general type conformed to it.
ArraySection
requires a model conforming to Differentiable
for differentiate from other sections:
-enum Model: Differentiable {
+enum Model: Differentiable {
case a, b, c
}
let source: [ArraySection<Model, String>] = [
- ArraySection(model: .a, elements: ["A", "B"]),
- ArraySection(model: .b, elements: ["C"])
+ ArraySection(model: .a, elements: ["A", "B"]),
+ ArraySection(model: .b, elements: ["C"])
]
let target: [ArraySection<Model, String>] = [
- ArraySection(model: .c, elements: ["D", "E"]),
- ArraySection(model: .a, elements: ["A"]),
- ArraySection(model: .b, elements: ["B", "C"])
+ ArraySection(model: .c, elements: ["D", "E"]),
+ ArraySection(model: .a, elements: ["A"]),
+ ArraySection(model: .b, elements: ["B", "C"])
]
-let changeset = StagedChangeset(source: source, target: target)
+let changeset = StagedChangeset(source: source, target: target)
You can perform incremental updates on UITableView
and UICollectionView
using the created StagedChangeset
.
@@ -243,7 +244,7 @@ Example codes
Comparison with Other Frameworks
Made a fair comparison as much as possible in features and performance with other popular and awesome frameworks.
-⚠️ This does NOT
determine superiority or inferiority of the frameworks. I know that each framework has different benefits.
+This does NOT determine superiority or inferiority of the frameworks. I know that each framework has different benefits.
The frameworks and its version that compared is below.
@@ -481,7 +482,7 @@ - F
DifferenceKit |
-0.0032 |
+0.0022 |
RxDataSources |
@@ -522,7 +523,7 @@ Requirements
-- Swift4.1+
+- Swift4.2+
- iOS 9.0+
- tvOS 9.0+
- OS X 10.9+
@@ -666,7 +667,7 @@ License
diff --git a/docs/search.json b/docs/search.json
index e0365f9..2a0c3c7 100644
--- a/docs/search.json
+++ b/docs/search.json
@@ -1 +1 @@
-{"Structs/ElementPath.html#/s:13DifferenceKit11ElementPathV7elementSivp":{"name":"element","abstract":"The element index (or offset) of this path.
","parent_name":"ElementPath"},"Structs/ElementPath.html#/s:13DifferenceKit11ElementPathV7sectionSivp":{"name":"section","abstract":"The section index (or offset) of this path.
","parent_name":"ElementPath"},"Structs/ElementPath.html#/s:13DifferenceKit11ElementPathV7element7sectionACSi_Sitcfc":{"name":"init(element:section:)","abstract":"Creates a new ElementPath
.
","parent_name":"ElementPath"},"Structs/ElementPath.html#/s:s28CustomDebugStringConvertibleP16debugDescriptionSSvp":{"name":"debugDescription","parent_name":"ElementPath"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV4dataxvp":{"name":"data","abstract":"The collection after changed.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV14sectionDeletedSaySiGvp":{"name":"sectionDeleted","abstract":"The offsets of deleted sections.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV15sectionInsertedSaySiGvp":{"name":"sectionInserted","abstract":"The offsets of inserted sections.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV14sectionUpdatedSaySiGvp":{"name":"sectionUpdated","abstract":"The offsets of updated sections.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV12sectionMovedSaySi6source_Si6targettGvp":{"name":"sectionMoved","abstract":"The pairs of source and target offset of moved sections.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV14elementDeletedSayAA11ElementPathVGvp":{"name":"elementDeleted","abstract":"The paths of deleted elements.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV15elementInsertedSayAA11ElementPathVGvp":{"name":"elementInserted","abstract":"The paths of inserted elements.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV14elementUpdatedSayAA11ElementPathVGvp":{"name":"elementUpdated","abstract":"The paths of updated elements.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV12elementMovedSayAA11ElementPathV6source_AF6targettGvp":{"name":"elementMoved","abstract":"The pairs of source and target path of moved elements.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV11changeCountSivp":{"name":"changeCount","abstract":"The number of all changes.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV10hasChangesSbvp":{"name":"hasChanges","abstract":"A Boolean value indicating whether has changes.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV4data14sectionDeleted0E8Inserted0E7Updated0E5Moved07elementF00jG00jH00jI0ACyxGx_SaySiGA2NSaySi6source_Si6targettGSayAA11ElementPathVGA2TSayAsO_AsPtGtcfc":{"name":"init(data:sectionDeleted:sectionInserted:sectionUpdated:sectionMoved:elementDeleted:elementInserted:elementUpdated:elementMoved:)","abstract":"Creates a new Changeset
.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:SQ2eeoiySbx_xtFZ":{"name":"==(_:_:)","parent_name":"Changeset"},"Structs/Changeset.html#/s:s28CustomDebugStringConvertibleP16debugDescriptionSSvp":{"name":"debugDescription","parent_name":"Changeset"},"Structs/ArraySection.html#/s:13DifferenceKit12ArraySectionV5modelxvp":{"name":"model","abstract":"The model of section for differentiated with other section.
","parent_name":"ArraySection"},"Structs/ArraySection.html#/s:13DifferenceKit12ArraySectionV8elementsSayq_Gvp":{"name":"elements","abstract":"The array of element in the section.
","parent_name":"ArraySection"},"Structs/ArraySection.html#/s:13DifferenceKit12ArraySectionV20differenceIdentifier0aF0Qzvp":{"name":"differenceIdentifier","abstract":"An identifier value that of model for difference calculation.
","parent_name":"ArraySection"},"Structs/ArraySection.html#/s:13DifferenceKit12ArraySectionV5model8elementsACyxq_Gx_qd__tc7ElementQyd__Rs_SlRd__lufc":{"name":"init(model:elements:)","abstract":"Creates a section with the model and the elements.
","parent_name":"ArraySection"},"Structs/ArraySection.html#/s:13DifferenceKit12ArraySectionV6source8elementsACyxq_GAF_qd__tc7ElementQyd__Rs_SlRd__lufc":{"name":"init(source:elements:)","abstract":"Creates a new section reproducing the given source section with replacing the elements.
","parent_name":"ArraySection"},"Structs/ArraySection.html#/s:13DifferenceKit12ArraySectionV14isContentEqual2toSbACyxq_G_tF":{"name":"isContentEqual(to:)","abstract":"Indicate whether the content of self
is equals to the content of","parent_name":"ArraySection"},"Structs/ArraySection.html#/s:SQ2eeoiySbx_xtFZ":{"name":"==(_:_:)","parent_name":"ArraySection"},"Structs/ArraySection.html#/s:s28CustomDebugStringConvertibleP16debugDescriptionSSvp":{"name":"debugDescription","parent_name":"ArraySection"},"Structs/AnyDifferentiable.html#/s:13DifferenceKit17AnyDifferentiableV4baseypvp":{"name":"base","abstract":"
The value wrapped by this instance.
","parent_name":"AnyDifferentiable"},"Structs/AnyDifferentiable.html#/s:13DifferenceKit17AnyDifferentiableV20differenceIdentifiers0C8HashableVvp":{"name":"differenceIdentifier","abstract":"A type-erased identifier value for difference calculation.
","parent_name":"AnyDifferentiable"},"Structs/AnyDifferentiable.html#/s:13DifferenceKit17AnyDifferentiableVyACxcAA0D0Rzlufc":{"name":"init(_:)","abstract":"Creates a type-erased differentiable value that wraps the given instance.
","parent_name":"AnyDifferentiable"},"Structs/AnyDifferentiable.html#/s:13DifferenceKit17AnyDifferentiableV14isContentEqual2toSbAC_tF":{"name":"isContentEqual(to:)","abstract":"Indicate whether the content of base
is equals to the content of the given source value.
","parent_name":"AnyDifferentiable"},"Structs/AnyDifferentiable.html#/s:s28CustomDebugStringConvertibleP16debugDescriptionSSvp":{"name":"debugDescription","parent_name":"AnyDifferentiable"},"Structs/StagedChangeset.html#/s:13DifferenceKit15StagedChangesetVyACyxGqd__cSlRd__AA0D0VyxG7ElementRtd__lufc":{"name":"init(_:)","abstract":"Creates a new StagedChangeset
.
","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html#/s:13DifferenceKit15StagedChangesetVAASmRzAA14Differentiable7ElementRpzrlE6source6targetACyxGx_xtcfc":{"name":"init(source:target:)","abstract":"Creates a new StagedChangeset
from the two collections.
","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html#/s:13DifferenceKit15StagedChangesetVAASmRzAA14Differentiable7ElementRpzrlE6source6target7sectionACyxGx_xSitcfc":{"name":"init(source:target:section:)","abstract":"Creates a new StagedChangeset
from the two collections.
","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html#/s:13DifferenceKit15StagedChangesetVAASmRzAA21DifferentiableSection7ElementRpzrlE6source6targetACyxGx_xtcfc":{"name":"init(source:target:)","abstract":"Creates a new StagedChangeset
from the two sectioned collections.
","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html#/s:Smxycfc":{"name":"init()","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html#/s:Sl10startIndex0B0Qzvp":{"name":"startIndex","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html#/s:Sl8endIndex0B0Qzvp":{"name":"endIndex","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html#/s:Sk5index5after5IndexQzAD_tF":{"name":"index(after:)","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html#/s:SMy7ElementQz5IndexQzcip":{"name":"subscript(_:)","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html#/s:Sm15replaceSubrange_4withySny5IndexQzG_qd__tSlRd__7ElementQyd__AFRtzlF":{"name":"replaceSubrange(_:with:)","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html#/s:SQ2eeoiySbx_xtFZ":{"name":"==(_:_:)","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html#/s:s25ExpressibleByArrayLiteralP05arrayD0x0cD7ElementQzd_tcfc":{"name":"init(arrayLiteral:)","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html#/s:s28CustomDebugStringConvertibleP16debugDescriptionSSvp":{"name":"debugDescription","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html":{"name":"StagedChangeset","abstract":"An ordered collection of Changeset
as staged set of changes in the sectioned collection.
"},"Structs/AnyDifferentiable.html":{"name":"AnyDifferentiable","abstract":"A type-erased differentiable value.
"},"Structs/ArraySection.html":{"name":"ArraySection","abstract":"A differentiable section with model and array of elements.
"},"Structs/Changeset.html":{"name":"Changeset","abstract":"A set of changes in the sectioned collection.
"},"Structs/ElementPath.html":{"name":"ElementPath","abstract":"Represents the path to a specific element in a tree of nested collections.
"},"Protocols/DifferentiableSection.html#/s:13DifferenceKit21DifferentiableSectionP10CollectionQa":{"name":"Collection","abstract":"A type representing the elements in section.
","parent_name":"DifferentiableSection"},"Protocols/DifferentiableSection.html#/s:13DifferenceKit21DifferentiableSectionP8elements10CollectionQzvp":{"name":"elements","abstract":"The collection of element in the section.
","parent_name":"DifferentiableSection"},"Protocols/DifferentiableSection.html#/s:13DifferenceKit21DifferentiableSectionP6source8elementsxx_qd__tcSlRd__10Collection_7ElementQZAGRtd__lufc":{"name":"init(source:elements:)","abstract":"Creates a new section reproducing the given source section with replacing the elements.
","parent_name":"DifferentiableSection"},"Protocols/Differentiable.html#/s:13DifferenceKit14DifferentiableP0A10IdentifierQa":{"name":"DifferenceIdentifier","abstract":"A type representing the identifier.
","parent_name":"Differentiable"},"Protocols/Differentiable.html#/s:13DifferenceKit14DifferentiableP20differenceIdentifier0aE0Qzvp":{"name":"differenceIdentifier","abstract":"An identifier value for difference calculation.
","parent_name":"Differentiable"},"Protocols/Differentiable.html#/s:13DifferenceKit14DifferentiableP14isContentEqual2toSbx_tF":{"name":"isContentEqual(to:)","abstract":"Indicate whether the content of self
is equals to the content of","parent_name":"Differentiable"},"Protocols/Differentiable.html":{"name":"Differentiable","abstract":"
Represents the value that identified and can be compared to whether has updated.
"},"Protocols/DifferentiableSection.html":{"name":"DifferentiableSection","abstract":"Represents the section of collection that can be identified and compared to whether has updated.
"},"Extensions/UICollectionView.html#/s:So16UICollectionViewC13DifferenceKitE6reload5using9interrupt7setDatayAC15StagedChangesetVyxG_SbAC0K0VyxGcSgyxXEtSlRzlF":{"name":"reload(using:interrupt:setData:)","abstract":"Applies multiple animated updates in stages using StagedChangeset
.
","parent_name":"UICollectionView"},"Extensions/UITableView.html#/s:So11UITableViewC13DifferenceKitE6reload5using4with9interrupt7setDatayAC15StagedChangesetVyxG_So0aB12RowAnimationVyXKSbAC0L0VyxGcSgyxXEtSlRzlF":{"name":"reload(using:with:interrupt:setData:)","abstract":"Applies multiple animated updates in stages using StagedChangeset
.
","parent_name":"UITableView"},"Extensions/UITableView.html#/s:So11UITableViewC13DifferenceKitE6reload5using23deleteSectionsAnimation06inserthI00ehI00g4RowsI00jkI00ekI09interrupt7setDatayAC15StagedChangesetVyxG_So0ab3RowI0VyXKARyXKARyXKARyXKARyXKARyXKSbAC0P0VyxGcSgyxXEtSlRzlF":{"name":"reload(using:deleteSectionsAnimation:insertSectionsAnimation:reloadSectionsAnimation:deleteRowsAnimation:insertRowsAnimation:reloadRowsAnimation:interrupt:setData:)","abstract":"Applies multiple animated updates in stages using StagedChangeset
.
","parent_name":"UITableView"},"Extensions/UITableView.html":{"name":"UITableView"},"Extensions/UICollectionView.html":{"name":"UICollectionView"},"Extensions.html":{"name":"Extensions","abstract":"The following extensions are available globally.
"},"Protocols.html":{"name":"Protocols","abstract":"The following protocols are available globally.
"},"Structs.html":{"name":"Structures","abstract":"The following structures are available globally.
"}}
\ No newline at end of file
+{"Structs/ElementPath.html#/s:13DifferenceKit11ElementPathV7elementSivp":{"name":"element","abstract":"The element index (or offset) of this path.
","parent_name":"ElementPath"},"Structs/ElementPath.html#/s:13DifferenceKit11ElementPathV7sectionSivp":{"name":"section","abstract":"The section index (or offset) of this path.
","parent_name":"ElementPath"},"Structs/ElementPath.html#/s:13DifferenceKit11ElementPathV7element7sectionACSi_Sitcfc":{"name":"init(element:section:)","abstract":"Creates a new ElementPath
.
","parent_name":"ElementPath"},"Structs/ElementPath.html#/s:s28CustomDebugStringConvertibleP16debugDescriptionSSvp":{"name":"debugDescription","parent_name":"ElementPath"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV4dataxvp":{"name":"data","abstract":"The collection after changed.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV14sectionDeletedSaySiGvp":{"name":"sectionDeleted","abstract":"The offsets of deleted sections.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV15sectionInsertedSaySiGvp":{"name":"sectionInserted","abstract":"The offsets of inserted sections.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV14sectionUpdatedSaySiGvp":{"name":"sectionUpdated","abstract":"The offsets of updated sections.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV12sectionMovedSaySi6source_Si6targettGvp":{"name":"sectionMoved","abstract":"The pairs of source and target offset of moved sections.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV14elementDeletedSayAA11ElementPathVGvp":{"name":"elementDeleted","abstract":"The paths of deleted elements.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV15elementInsertedSayAA11ElementPathVGvp":{"name":"elementInserted","abstract":"The paths of inserted elements.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV14elementUpdatedSayAA11ElementPathVGvp":{"name":"elementUpdated","abstract":"The paths of updated elements.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV12elementMovedSayAA11ElementPathV6source_AF6targettGvp":{"name":"elementMoved","abstract":"The pairs of source and target path of moved elements.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV4data14sectionDeleted0E8Inserted0E7Updated0E5Moved07elementF00jG00jH00jI0ACyxGx_SaySiGA2NSaySi6source_Si6targettGSayAA11ElementPathVGA2TSayAsO_AsPtGtcfc":{"name":"init(data:sectionDeleted:sectionInserted:sectionUpdated:sectionMoved:elementDeleted:elementInserted:elementUpdated:elementMoved:)","abstract":"Creates a new Changeset
.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV18sectionChangeCountSivp":{"name":"sectionChangeCount","abstract":"The number of section changes.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV18elementChangeCountSivp":{"name":"elementChangeCount","abstract":"The number of element changes.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV11changeCountSivp":{"name":"changeCount","abstract":"The number of all changes.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV17hasSectionChangesSbvp":{"name":"hasSectionChanges","abstract":"A Boolean value indicating whether has section changes.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV17hasElementChangesSbvp":{"name":"hasElementChanges","abstract":"A Boolean value indicating whether has element changes.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:13DifferenceKit9ChangesetV10hasChangesSbvp":{"name":"hasChanges","abstract":"A Boolean value indicating whether has changes.
","parent_name":"Changeset"},"Structs/Changeset.html#/s:SQ2eeoiySbx_xtFZ":{"name":"==(_:_:)","parent_name":"Changeset"},"Structs/Changeset.html#/s:s28CustomDebugStringConvertibleP16debugDescriptionSSvp":{"name":"debugDescription","parent_name":"Changeset"},"Structs/ArraySection.html#/s:13DifferenceKit12ArraySectionV5modelxvp":{"name":"model","abstract":"The model of section for differentiated with other section.
","parent_name":"ArraySection"},"Structs/ArraySection.html#/s:13DifferenceKit12ArraySectionV8elementsSayq_Gvp":{"name":"elements","abstract":"The array of element in the section.
","parent_name":"ArraySection"},"Structs/ArraySection.html#/s:13DifferenceKit12ArraySectionV20differenceIdentifier0aF0Qzvp":{"name":"differenceIdentifier","abstract":"An identifier value that of model for difference calculation.
","parent_name":"ArraySection"},"Structs/ArraySection.html#/s:13DifferenceKit12ArraySectionV5model8elementsACyxq_Gx_qd__tc7ElementQyd__Rs_SlRd__lufc":{"name":"init(model:elements:)","abstract":"Creates a section with the model and the elements.
","parent_name":"ArraySection"},"Structs/ArraySection.html#/s:13DifferenceKit12ArraySectionV6source8elementsACyxq_GAF_qd__tc7ElementQyd__Rs_SlRd__lufc":{"name":"init(source:elements:)","abstract":"Creates a new section reproducing the given source section with replacing the elements.
","parent_name":"ArraySection"},"Structs/ArraySection.html#/s:13DifferenceKit12ArraySectionV14isContentEqual2toSbACyxq_G_tF":{"name":"isContentEqual(to:)","abstract":"Indicate whether the content of self
is equals to the content of","parent_name":"ArraySection"},"Structs/ArraySection.html#/s:SQ2eeoiySbx_xtFZ":{"name":"==(_:_:)","parent_name":"ArraySection"},"Structs/ArraySection.html#/s:s28CustomDebugStringConvertibleP16debugDescriptionSSvp":{"name":"debugDescription","parent_name":"ArraySection"},"Structs/AnyDifferentiable.html#/s:13DifferenceKit17AnyDifferentiableV4baseypvp":{"name":"base","abstract":"
The value wrapped by this instance.
","parent_name":"AnyDifferentiable"},"Structs/AnyDifferentiable.html#/s:13DifferenceKit17AnyDifferentiableV20differenceIdentifiers0C8HashableVvp":{"name":"differenceIdentifier","abstract":"A type-erased identifier value for difference calculation.
","parent_name":"AnyDifferentiable"},"Structs/AnyDifferentiable.html#/s:13DifferenceKit17AnyDifferentiableVyACxcAA0D0Rzlufc":{"name":"init(_:)","abstract":"Creates a type-erased differentiable value that wraps the given instance.
","parent_name":"AnyDifferentiable"},"Structs/AnyDifferentiable.html#/s:13DifferenceKit17AnyDifferentiableV14isContentEqual2toSbAC_tF":{"name":"isContentEqual(to:)","abstract":"Indicate whether the content of base
is equals to the content of the given source value.
","parent_name":"AnyDifferentiable"},"Structs/AnyDifferentiable.html#/s:s28CustomDebugStringConvertibleP16debugDescriptionSSvp":{"name":"debugDescription","parent_name":"AnyDifferentiable"},"Structs/StagedChangeset.html#/s:13DifferenceKit15StagedChangesetVyACyxGqd__cSlRd__AA0D0VyxG7ElementRtd__lufc":{"name":"init(_:)","abstract":"Creates a new StagedChangeset
.
","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html#/s:13DifferenceKit15StagedChangesetVAASmRzAA14Differentiable7ElementRpzrlE6source6targetACyxGx_xtcfc":{"name":"init(source:target:)","abstract":"Creates a new StagedChangeset
from the two collections.
","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html#/s:13DifferenceKit15StagedChangesetVAASmRzAA14Differentiable7ElementRpzrlE6source6target7sectionACyxGx_xSitcfc":{"name":"init(source:target:section:)","abstract":"Creates a new StagedChangeset
from the two collections.
","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html#/s:13DifferenceKit15StagedChangesetVAASmRzAA21DifferentiableSection7ElementRpzrlE6source6targetACyxGx_xtcfc":{"name":"init(source:target:)","abstract":"Creates a new StagedChangeset
from the two sectioned collections.
","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html#/s:Smxycfc":{"name":"init()","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html#/s:Sl10startIndex0B0Qzvp":{"name":"startIndex","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html#/s:Sl8endIndex0B0Qzvp":{"name":"endIndex","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html#/s:Sk5index5after5IndexQzAD_tF":{"name":"index(after:)","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html#/s:SMy7ElementQz5IndexQzcip":{"name":"subscript(_:)","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html#/s:Sm15replaceSubrange_4withySny5IndexQzG_qd__tSlRd__7ElementQyd__AFRtzlF":{"name":"replaceSubrange(_:with:)","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html#/s:SQ2eeoiySbx_xtFZ":{"name":"==(_:_:)","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html#/s:s25ExpressibleByArrayLiteralP05arrayD0x0cD7ElementQzd_tcfc":{"name":"init(arrayLiteral:)","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html#/s:s28CustomDebugStringConvertibleP16debugDescriptionSSvp":{"name":"debugDescription","parent_name":"StagedChangeset"},"Structs/StagedChangeset.html":{"name":"StagedChangeset","abstract":"An ordered collection of Changeset
as staged set of changes in the sectioned collection.
"},"Structs/AnyDifferentiable.html":{"name":"AnyDifferentiable","abstract":"A type-erased differentiable value.
"},"Structs/ArraySection.html":{"name":"ArraySection","abstract":"A differentiable section with model and array of elements.
"},"Structs/Changeset.html":{"name":"Changeset","abstract":"A set of changes in the sectioned collection.
"},"Structs/ElementPath.html":{"name":"ElementPath","abstract":"Represents the path to a specific element in a tree of nested collections.
"},"Protocols/DifferentiableSection.html#/s:13DifferenceKit21DifferentiableSectionP10CollectionQa":{"name":"Collection","abstract":"A type representing the elements in section.
","parent_name":"DifferentiableSection"},"Protocols/DifferentiableSection.html#/s:13DifferenceKit21DifferentiableSectionP8elements10CollectionQzvp":{"name":"elements","abstract":"The collection of element in the section.
","parent_name":"DifferentiableSection"},"Protocols/DifferentiableSection.html#/s:13DifferenceKit21DifferentiableSectionP6source8elementsxx_qd__tcSlRd__10Collection_7ElementQZAGRtd__lufc":{"name":"init(source:elements:)","abstract":"Creates a new section reproducing the given source section with replacing the elements.
","parent_name":"DifferentiableSection"},"Protocols/Differentiable.html#/s:13DifferenceKit14DifferentiableP0A10IdentifierQa":{"name":"DifferenceIdentifier","abstract":"A type representing the identifier.
","parent_name":"Differentiable"},"Protocols/Differentiable.html#/s:13DifferenceKit14DifferentiableP20differenceIdentifier0aE0Qzvp":{"name":"differenceIdentifier","abstract":"An identifier value for difference calculation.
","parent_name":"Differentiable"},"Protocols/ContentEquatable.html#/s:13DifferenceKit16ContentEquatableP02isC5Equal2toSbx_tF":{"name":"isContentEqual(to:)","abstract":"Indicate whether the content of self
is equals to the content of","parent_name":"ContentEquatable"},"Protocols/ContentEquatable.html":{"name":"ContentEquatable","abstract":"
Represents a value that can compare whether the content are equal.
"},"Protocols/Differentiable.html":{"name":"Differentiable","abstract":"Represents the value that identified for differentiate.
"},"Protocols/DifferentiableSection.html":{"name":"DifferentiableSection","abstract":"Represents the section of collection that can be identified and compared to whether has updated.
"},"Extensions/UICollectionView.html#/s:So16UICollectionViewC13DifferenceKitE6reload5using9interrupt7setDatayAC15StagedChangesetVyxG_SbAC0K0VyxGcSgyxXEtSlRzlF":{"name":"reload(using:interrupt:setData:)","abstract":"Applies multiple animated updates in stages using StagedChangeset
.
","parent_name":"UICollectionView"},"Extensions/UITableView.html#/s:So11UITableViewC13DifferenceKitE6reload5using4with9interrupt7setDatayAC15StagedChangesetVyxG_So0aB12RowAnimationVyXKSbAC0L0VyxGcSgyxXEtSlRzlF":{"name":"reload(using:with:interrupt:setData:)","abstract":"Applies multiple animated updates in stages using StagedChangeset
.
","parent_name":"UITableView"},"Extensions/UITableView.html#/s:So11UITableViewC13DifferenceKitE6reload5using23deleteSectionsAnimation06inserthI00ehI00g4RowsI00jkI00ekI09interrupt7setDatayAC15StagedChangesetVyxG_So0ab3RowI0VyXKARyXKARyXKARyXKARyXKARyXKSbAC0P0VyxGcSgyxXEtSlRzlF":{"name":"reload(using:deleteSectionsAnimation:insertSectionsAnimation:reloadSectionsAnimation:deleteRowsAnimation:insertRowsAnimation:reloadRowsAnimation:interrupt:setData:)","abstract":"Applies multiple animated updates in stages using StagedChangeset
.
","parent_name":"UITableView"},"Extensions/UITableView.html":{"name":"UITableView"},"Extensions/UICollectionView.html":{"name":"UICollectionView"},"Extensions.html":{"name":"Extensions","abstract":"The following extensions are available globally.
"},"Protocols.html":{"name":"Protocols","abstract":"The following protocols are available globally.
"},"Structs.html":{"name":"Structures","abstract":"The following structures are available globally.
"}}
\ No newline at end of file
From eea050c77c41a9ede6f71edaa2cf39c5711e023f Mon Sep 17 00:00:00 2001
From: Ryo Aoyama
Date: Tue, 2 Oct 2018 17:57:10 +0900
Subject: [PATCH 10/11] Update podspec
---
DifferenceKit.podspec | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/DifferenceKit.podspec b/DifferenceKit.podspec
index 1a05f32..88a8334 100644
--- a/DifferenceKit.podspec
+++ b/DifferenceKit.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |spec|
spec.name = 'DifferenceKit'
- spec.version = '0.6.0'
+ spec.version = '0.7.0'
spec.author = { 'ra1028' => 'r.fe51028.r@gmail.com' }
spec.homepage = 'https://github.com/ra1028/DifferenceKit'
spec.documentation_url = 'https://ra1028.github.io/DifferenceKit'
From ff1cd540acd8e39cb11ab753992554f7f5839074 Mon Sep 17 00:00:00 2001
From: Ryo Aoyama
Date: Tue, 2 Oct 2018 18:03:56 +0900
Subject: [PATCH 11/11] Refactor
---
Sources/AnyDifferentiable.swift | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Sources/AnyDifferentiable.swift b/Sources/AnyDifferentiable.swift
index 75b4492..ed3032f 100644
--- a/Sources/AnyDifferentiable.swift
+++ b/Sources/AnyDifferentiable.swift
@@ -44,7 +44,7 @@ public struct AnyDifferentiable: Differentiable {
/// - base: A differentiable value to wrap.
@inlinable
public init(_ base: D) {
- box = ConcretDifferentiableBox(base)
+ box = DifferentiableBox(base)
}
/// Indicate whether the content of `base` is equals to the content of the given source value.
@@ -75,7 +75,7 @@ internal protocol AnyDifferentiableBox {
}
@usableFromInline
-internal struct ConcretDifferentiableBox: AnyDifferentiableBox {
+internal struct DifferentiableBox: AnyDifferentiableBox {
@usableFromInline
internal let baseComponent: Base