Converted automatically with Xcode tools; fixed bugs Xcode didn't cover; removed useless files to reduce work; updated CocoaPods to Swift 3.

This commit is contained in:
Vinicius Vendramini 2017-03-16 12:35:52 -03:00
parent feaaefcb71
commit 8431fe0580
40 changed files with 404 additions and 3026 deletions

View File

@ -24,38 +24,13 @@
24ED21CD1C6C2397009C40FC /* MetaballDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24ED21CC1C6C2397009C40FC /* MetaballDataSource.swift */; };
24FC38341C7F931E0085C04A /* Metaball.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FC38331C7F931E0085C04A /* Metaball.swift */; };
24FC38361C7F9ABE0085C04A /* Dispatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FC38351C7F9ABE0085C04A /* Dispatch.swift */; };
24FFA86B1C6BA038005ACD60 /* ApproximationOperator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA84C1C6BA038005ACD60 /* ApproximationOperator.swift */; };
24FFA86C1C6BA038005ACD60 /* Collections.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA84D1C6BA038005ACD60 /* Collections.swift */; };
24FFA86D1C6BA038005ACD60 /* ComparatorChains.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA84E1C6BA038005ACD60 /* ComparatorChains.swift */; };
24FFA86E1C6BA038005ACD60 /* Dictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA84F1C6BA038005ACD60 /* Dictionary.swift */; };
24FFA86F1C6BA038005ACD60 /* NSNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA8511C6BA038005ACD60 /* NSNumber.swift */; };
24FFA8701C6BA038005ACD60 /* Numeric.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA8521C6BA038005ACD60 /* Numeric.swift */; };
24FFA8711C6BA038005ACD60 /* PowerOperator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA8531C6BA038005ACD60 /* PowerOperator.swift */; };
24FFA8721C6BA038005ACD60 /* Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA8541C6BA038005ACD60 /* Sequence.swift */; };
24FFA8731C6BA038005ACD60 /* Memoize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA8561C6BA038005ACD60 /* Memoize.swift */; };
24FFA8741C6BA038005ACD60 /* SignOperator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA8571C6BA038005ACD60 /* SignOperator.swift */; };
24FFA8751C6BA038005ACD60 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA8581C6BA038005ACD60 /* String.swift */; };
24FFA8761C6BA038005ACD60 /* Categorise.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA85A1C6BA038005ACD60 /* Categorise.swift */; };
24FFA8771C6BA038005ACD60 /* ChunkWindowSplit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA85B1C6BA038005ACD60 /* ChunkWindowSplit.swift */; };
24FFA8781C6BA038005ACD60 /* Combinations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA85C1C6BA038005ACD60 /* Combinations.swift */; };
24FFA8791C6BA038005ACD60 /* Cycle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA85D1C6BA038005ACD60 /* Cycle.swift */; };
24FFA87A1C6BA038005ACD60 /* Enumerate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA85E1C6BA038005ACD60 /* Enumerate.swift */; };
24FFA87B1C6BA038005ACD60 /* Finding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA85F1C6BA038005ACD60 /* Finding.swift */; };
24FFA87C1C6BA038005ACD60 /* FlatMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA8601C6BA038005ACD60 /* FlatMap.swift */; };
24FFA87D1C6BA038005ACD60 /* Hopping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA8611C6BA038005ACD60 /* Hopping.swift */; };
24FFA87E1C6BA038005ACD60 /* Interpose.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA8621C6BA038005ACD60 /* Interpose.swift */; };
24FFA87F1C6BA038005ACD60 /* Iterate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA8631C6BA038005ACD60 /* Iterate.swift */; };
24FFA8801C6BA038005ACD60 /* NestedSequences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA8641C6BA038005ACD60 /* NestedSequences.swift */; };
24FFA8811C6BA038005ACD60 /* Permutations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA8651C6BA038005ACD60 /* Permutations.swift */; };
24FFA8821C6BA038005ACD60 /* ScanReduce.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA8661C6BA038005ACD60 /* ScanReduce.swift */; };
24FFA8831C6BA038005ACD60 /* Slicing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA8671C6BA038005ACD60 /* Slicing.swift */; };
24FFA8841C6BA038005ACD60 /* TakeDrop.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA8681C6BA038005ACD60 /* TakeDrop.swift */; };
24FFA8851C6BA038005ACD60 /* Zip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA8691C6BA038005ACD60 /* Zip.swift */; };
24FFA8861C6BA038005ACD60 /* TestCommons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24FFA86A1C6BA038005ACD60 /* TestCommons.swift */; };
2BF7957B6518CA68241BB2CE /* Pods_PixelImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C55F9558B3B267413C3A07A6 /* Pods_PixelImage.framework */; };
400CECBA73C835B415805169 /* Pods_PixelImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93D10DBF530542A19EEF699A /* Pods_PixelImage.framework */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
0C9CE70F7D2C2896912B7B14 /* Pods-PixelImage.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PixelImage.release.xcconfig"; path = "Pods/Target Support Files/Pods-PixelImage/Pods-PixelImage.release.xcconfig"; sourceTree = "<group>"; };
242686841C63B72A00D62456 /* PixelImage.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PixelImage.app; sourceTree = BUILT_PRODUCTS_DIR; };
242686871C63B72A00D62456 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
242686891C63B72A00D62456 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
@ -75,37 +50,10 @@
24ED21CC1C6C2397009C40FC /* MetaballDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MetaballDataSource.swift; sourceTree = "<group>"; };
24FC38331C7F931E0085C04A /* Metaball.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Metaball.swift; sourceTree = "<group>"; };
24FC38351C7F9ABE0085C04A /* Dispatch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Dispatch.swift; sourceTree = "<group>"; };
24FFA84C1C6BA038005ACD60 /* ApproximationOperator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApproximationOperator.swift; sourceTree = "<group>"; };
24FFA84D1C6BA038005ACD60 /* Collections.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Collections.swift; sourceTree = "<group>"; };
24FFA84E1C6BA038005ACD60 /* ComparatorChains.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ComparatorChains.swift; sourceTree = "<group>"; };
24FFA84F1C6BA038005ACD60 /* Dictionary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Dictionary.swift; sourceTree = "<group>"; };
24FFA8511C6BA038005ACD60 /* NSNumber.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSNumber.swift; sourceTree = "<group>"; };
24FFA8521C6BA038005ACD60 /* Numeric.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Numeric.swift; sourceTree = "<group>"; };
24FFA8531C6BA038005ACD60 /* PowerOperator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PowerOperator.swift; sourceTree = "<group>"; };
24FFA8541C6BA038005ACD60 /* Sequence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Sequence.swift; sourceTree = "<group>"; };
24FFA8561C6BA038005ACD60 /* Memoize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Memoize.swift; sourceTree = "<group>"; };
24FFA8571C6BA038005ACD60 /* SignOperator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignOperator.swift; sourceTree = "<group>"; };
24FFA8581C6BA038005ACD60 /* String.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = "<group>"; };
24FFA85A1C6BA038005ACD60 /* Categorise.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Categorise.swift; sourceTree = "<group>"; };
24FFA85B1C6BA038005ACD60 /* ChunkWindowSplit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChunkWindowSplit.swift; sourceTree = "<group>"; };
24FFA85C1C6BA038005ACD60 /* Combinations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Combinations.swift; sourceTree = "<group>"; };
24FFA85D1C6BA038005ACD60 /* Cycle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Cycle.swift; sourceTree = "<group>"; };
24FFA85E1C6BA038005ACD60 /* Enumerate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Enumerate.swift; sourceTree = "<group>"; };
24FFA85F1C6BA038005ACD60 /* Finding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Finding.swift; sourceTree = "<group>"; };
24FFA8601C6BA038005ACD60 /* FlatMap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlatMap.swift; sourceTree = "<group>"; };
24FFA8611C6BA038005ACD60 /* Hopping.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Hopping.swift; sourceTree = "<group>"; };
24FFA8621C6BA038005ACD60 /* Interpose.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Interpose.swift; sourceTree = "<group>"; };
24FFA8631C6BA038005ACD60 /* Iterate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Iterate.swift; sourceTree = "<group>"; };
24FFA8641C6BA038005ACD60 /* NestedSequences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NestedSequences.swift; sourceTree = "<group>"; };
24FFA8651C6BA038005ACD60 /* Permutations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Permutations.swift; sourceTree = "<group>"; };
24FFA8661C6BA038005ACD60 /* ScanReduce.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScanReduce.swift; sourceTree = "<group>"; };
24FFA8671C6BA038005ACD60 /* Slicing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Slicing.swift; sourceTree = "<group>"; };
24FFA8681C6BA038005ACD60 /* TakeDrop.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TakeDrop.swift; sourceTree = "<group>"; };
24FFA8691C6BA038005ACD60 /* Zip.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Zip.swift; sourceTree = "<group>"; };
24FFA86A1C6BA038005ACD60 /* TestCommons.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestCommons.swift; sourceTree = "<group>"; };
B1A755EFC03DA2A172C2B82F /* Pods-PixelImage.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PixelImage.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PixelImage/Pods-PixelImage.debug.xcconfig"; sourceTree = "<group>"; };
C419D37C90A6BE8B5139806A /* Pods-PixelImage.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PixelImage.release.xcconfig"; path = "Pods/Target Support Files/Pods-PixelImage/Pods-PixelImage.release.xcconfig"; sourceTree = "<group>"; };
C55F9558B3B267413C3A07A6 /* Pods_PixelImage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PixelImage.framework; sourceTree = BUILT_PRODUCTS_DIR; };
24FFA8521C6BA038005ACD60 /* Numeric.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Numeric.swift; path = SwiftSugar/Numeric.swift; sourceTree = "<group>"; };
24FFA8531C6BA038005ACD60 /* PowerOperator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PowerOperator.swift; path = SwiftSugar/PowerOperator.swift; sourceTree = "<group>"; };
6659D12A5984961F335BDF69 /* Pods-PixelImage.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PixelImage.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PixelImage/Pods-PixelImage.debug.xcconfig"; sourceTree = "<group>"; };
93D10DBF530542A19EEF699A /* Pods_PixelImage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PixelImage.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -115,13 +63,22 @@
files = (
24E1E7E41C67D39300ECF1C4 /* MetalKit.framework in Frameworks */,
24E1E7E21C67D37F00ECF1C4 /* Metal.framework in Frameworks */,
2BF7957B6518CA68241BB2CE /* Pods_PixelImage.framework in Frameworks */,
400CECBA73C835B415805169 /* Pods_PixelImage.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
0C205AE1A1A55E89EFAEE593 /* Pods */ = {
isa = PBXGroup;
children = (
6659D12A5984961F335BDF69 /* Pods-PixelImage.debug.xcconfig */,
0C9CE70F7D2C2896912B7B14 /* Pods-PixelImage.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
2426867B1C63B72A00D62456 = {
isa = PBXGroup;
children = (
@ -129,8 +86,8 @@
24E1E7E11C67D37F00ECF1C4 /* Metal.framework */,
242686861C63B72A00D62456 /* PixelImage */,
242686851C63B72A00D62456 /* Products */,
F1933B48ED44BA9FCD7A4A1F /* Pods */,
588576572D7A188031904848 /* Frameworks */,
0C205AE1A1A55E89EFAEE593 /* Pods */,
8C02F866C2C0C9A954BB9375 /* Frameworks */,
);
sourceTree = "<group>";
};
@ -145,7 +102,9 @@
242686861C63B72A00D62456 /* PixelImage */ = {
isa = PBXGroup;
children = (
24FFA84B1C6BA038005ACD60 /* SwiftSugar */,
2461651A1C6DA4F400A913C8 /* Interpolation.swift */,
24FFA8521C6BA038005ACD60 /* Numeric.swift */,
24FFA8531C6BA038005ACD60 /* PowerOperator.swift */,
242686871C63B72A00D62456 /* AppDelegate.swift */,
24FC38351C7F9ABE0085C04A /* Dispatch.swift */,
24E1E7D61C67C8B200ECF1C4 /* UIKit.swift */,
@ -165,83 +124,14 @@
path = PixelImage;
sourceTree = "<group>";
};
24FFA84B1C6BA038005ACD60 /* SwiftSugar */ = {
8C02F866C2C0C9A954BB9375 /* Frameworks */ = {
isa = PBXGroup;
children = (
24FFA84C1C6BA038005ACD60 /* ApproximationOperator.swift */,
2461651A1C6DA4F400A913C8 /* Interpolation.swift */,
24FFA84D1C6BA038005ACD60 /* Collections.swift */,
24FFA84E1C6BA038005ACD60 /* ComparatorChains.swift */,
24FFA84F1C6BA038005ACD60 /* Dictionary.swift */,
24FFA8501C6BA038005ACD60 /* Foundation */,
24FFA8521C6BA038005ACD60 /* Numeric.swift */,
24FFA8531C6BA038005ACD60 /* PowerOperator.swift */,
24FFA8541C6BA038005ACD60 /* Sequence.swift */,
24FFA8551C6BA038005ACD60 /* Sequences */,
24FFA8571C6BA038005ACD60 /* SignOperator.swift */,
24FFA8581C6BA038005ACD60 /* String.swift */,
24FFA8591C6BA038005ACD60 /* SwiftSequences */,
24FFA86A1C6BA038005ACD60 /* TestCommons.swift */,
);
path = SwiftSugar;
sourceTree = "<group>";
};
24FFA8501C6BA038005ACD60 /* Foundation */ = {
isa = PBXGroup;
children = (
24FFA8511C6BA038005ACD60 /* NSNumber.swift */,
);
path = Foundation;
sourceTree = "<group>";
};
24FFA8551C6BA038005ACD60 /* Sequences */ = {
isa = PBXGroup;
children = (
24FFA8561C6BA038005ACD60 /* Memoize.swift */,
);
path = Sequences;
sourceTree = "<group>";
};
24FFA8591C6BA038005ACD60 /* SwiftSequences */ = {
isa = PBXGroup;
children = (
24FFA85A1C6BA038005ACD60 /* Categorise.swift */,
24FFA85B1C6BA038005ACD60 /* ChunkWindowSplit.swift */,
24FFA85C1C6BA038005ACD60 /* Combinations.swift */,
24FFA85D1C6BA038005ACD60 /* Cycle.swift */,
24FFA85E1C6BA038005ACD60 /* Enumerate.swift */,
24FFA85F1C6BA038005ACD60 /* Finding.swift */,
24FFA8601C6BA038005ACD60 /* FlatMap.swift */,
24FFA8611C6BA038005ACD60 /* Hopping.swift */,
24FFA8621C6BA038005ACD60 /* Interpose.swift */,
24FFA8631C6BA038005ACD60 /* Iterate.swift */,
24FFA8641C6BA038005ACD60 /* NestedSequences.swift */,
24FFA8651C6BA038005ACD60 /* Permutations.swift */,
24FFA8661C6BA038005ACD60 /* ScanReduce.swift */,
24FFA8671C6BA038005ACD60 /* Slicing.swift */,
24FFA8681C6BA038005ACD60 /* TakeDrop.swift */,
24FFA8691C6BA038005ACD60 /* Zip.swift */,
);
path = SwiftSequences;
sourceTree = "<group>";
};
588576572D7A188031904848 /* Frameworks */ = {
isa = PBXGroup;
children = (
C55F9558B3B267413C3A07A6 /* Pods_PixelImage.framework */,
93D10DBF530542A19EEF699A /* Pods_PixelImage.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
F1933B48ED44BA9FCD7A4A1F /* Pods */ = {
isa = PBXGroup;
children = (
B1A755EFC03DA2A172C2B82F /* Pods-PixelImage.debug.xcconfig */,
C419D37C90A6BE8B5139806A /* Pods-PixelImage.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -249,13 +139,13 @@
isa = PBXNativeTarget;
buildConfigurationList = 242686961C63B72A00D62456 /* Build configuration list for PBXNativeTarget "PixelImage" */;
buildPhases = (
EF55C7246917A184756D93D8 /* Check Pods Manifest.lock */,
041D2472535A642E23154A31 /* [CP] Check Pods Manifest.lock */,
242686801C63B72A00D62456 /* Sources */,
242686811C63B72A00D62456 /* Frameworks */,
242686821C63B72A00D62456 /* Resources */,
C7A2DF67265A9D17DEFBD193 /* Embed Pods Frameworks */,
FADC01F75BFAC01F0260D1C9 /* Copy Pods Resources */,
DD0396CE594E3EAC8D18CC6C /* Tailor */,
3CA888DC160972BAEB74EC52 /* [CP] Embed Pods Frameworks */,
47F9F13E3CB75C7B4B0136A5 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@ -279,6 +169,7 @@
242686831C63B72A00D62456 = {
CreatedOnToolsVersion = 7.2;
DevelopmentTeam = HHT774898M;
LastSwiftMigration = 0830;
};
};
};
@ -314,14 +205,29 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
C7A2DF67265A9D17DEFBD193 /* Embed Pods Frameworks */ = {
041D2472535A642E23154A31 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Embed Pods Frameworks";
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
3CA888DC160972BAEB74EC52 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
@ -329,6 +235,21 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PixelImage/Pods-PixelImage-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
47F9F13E3CB75C7B4B0136A5 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PixelImage/Pods-PixelImage-resources.sh\"\n";
showEnvVarsInLog = 0;
};
DD0396CE594E3EAC8D18CC6C /* Tailor */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@ -343,36 +264,6 @@
shellPath = /bin/sh;
shellScript = "if hash tailor 2>/dev/null; then\n tailor --except=function-whitespace,leading-whitespace,constant-k-prefix --max-severity error\nelse\n echo \"warning: Please install Tailor from https://tailor.sh\"\nfi";
};
EF55C7246917A184756D93D8 /* Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
FADC01F75BFAC01F0260D1C9 /* Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PixelImage/Pods-PixelImage-resources.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@ -380,46 +271,20 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
24FFA87B1C6BA038005ACD60 /* Finding.swift in Sources */,
24FFA8751C6BA038005ACD60 /* String.swift in Sources */,
24FFA8781C6BA038005ACD60 /* Combinations.swift in Sources */,
24FFA87E1C6BA038005ACD60 /* Interpose.swift in Sources */,
2426868A1C63B72A00D62456 /* ViewController.swift in Sources */,
24FFA8841C6BA038005ACD60 /* TakeDrop.swift in Sources */,
24FFA8771C6BA038005ACD60 /* ChunkWindowSplit.swift in Sources */,
24FFA86F1C6BA038005ACD60 /* NSNumber.swift in Sources */,
2461651B1C6DA4F400A913C8 /* Interpolation.swift in Sources */,
24FC38341C7F931E0085C04A /* Metaball.swift in Sources */,
24FFA8861C6BA038005ACD60 /* TestCommons.swift in Sources */,
24FFA8741C6BA038005ACD60 /* SignOperator.swift in Sources */,
24FFA8821C6BA038005ACD60 /* ScanReduce.swift in Sources */,
24ED21CD1C6C2397009C40FC /* MetaballDataSource.swift in Sources */,
24FFA8831C6BA038005ACD60 /* Slicing.swift in Sources */,
24FFA8721C6BA038005ACD60 /* Sequence.swift in Sources */,
24FFA87F1C6BA038005ACD60 /* Iterate.swift in Sources */,
24FC38361C7F9ABE0085C04A /* Dispatch.swift in Sources */,
24FFA8761C6BA038005ACD60 /* Categorise.swift in Sources */,
24FFA86D1C6BA038005ACD60 /* ComparatorChains.swift in Sources */,
24FFA8711C6BA038005ACD60 /* PowerOperator.swift in Sources */,
24E1E7D71C67C8B200ECF1C4 /* UIKit.swift in Sources */,
24FFA8851C6BA038005ACD60 /* Zip.swift in Sources */,
249CF84C1C6D113C008B0C78 /* Matrix.swift in Sources */,
24FFA8791C6BA038005ACD60 /* Cycle.swift in Sources */,
24E1E7F11C67D74300ECF1C4 /* shaders.metal in Sources */,
24FFA86E1C6BA038005ACD60 /* Dictionary.swift in Sources */,
24FFA87D1C6BA038005ACD60 /* Hopping.swift in Sources */,
24E1E7EB1C67D70300ECF1C4 /* MetalMetaballRenderer.swift in Sources */,
246B0F831C70635D00A71D05 /* UIColor.swift in Sources */,
24FFA87A1C6BA038005ACD60 /* Enumerate.swift in Sources */,
242686881C63B72A00D62456 /* AppDelegate.swift in Sources */,
24E1E7F01C67D74300ECF1C4 /* Metal.swift in Sources */,
24FFA87C1C6BA038005ACD60 /* FlatMap.swift in Sources */,
24FFA8701C6BA038005ACD60 /* Numeric.swift in Sources */,
24FFA8811C6BA038005ACD60 /* Permutations.swift in Sources */,
24FFA86B1C6BA038005ACD60 /* ApproximationOperator.swift in Sources */,
24FFA8801C6BA038005ACD60 /* NestedSequences.swift in Sources */,
24FFA8731C6BA038005ACD60 /* Memoize.swift in Sources */,
24FFA86C1C6BA038005ACD60 /* Collections.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -530,25 +395,29 @@
};
242686971C63B72A00D62456 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = B1A755EFC03DA2A172C2B82F /* Pods-PixelImage.debug.xcconfig */;
baseConfigurationReference = 6659D12A5984961F335BDF69 /* Pods-PixelImage.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEVELOPMENT_TEAM = HHT774898M;
INFOPLIST_FILE = PixelImage/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = vinivendra.PixelImage;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
242686981C63B72A00D62456 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = C419D37C90A6BE8B5139806A /* Pods-PixelImage.release.xcconfig */;
baseConfigurationReference = 0C9CE70F7D2C2896912B7B14 /* Pods-PixelImage.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEVELOPMENT_TEAM = HHT774898M;
INFOPLIST_FILE = PixelImage/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = vinivendra.PixelImage;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Release;
};

View File

@ -13,30 +13,30 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(application: UIApplication) {
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
func applicationDidEnterBackground(application: UIApplication) {
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(application: UIApplication) {
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(application: UIApplication) {
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(application: UIApplication) {
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}

View File

@ -1,6 +1,10 @@
import Dispatch
func delay(duration: Float = 1, block: () -> ()) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(duration * Float(NSEC_PER_SEC))), dispatch_get_main_queue(), block)
func delay(_ duration: Float = 1, block: @escaping () -> ()) {
DispatchQueue.main.asyncAfter(
deadline: DispatchTime.now() +
Double(duration * Float(NSEC_PER_SEC)) /
Double(NSEC_PER_SEC),
execute: block)
}

View File

@ -1,23 +1,23 @@
import Darwin
func interpolateCubeEaseIn<T: Numeric>(linear: T) -> T {
func interpolateCubeEaseIn<T: Numeric>(_ linear: T) -> T {
return linear ^ 3
}
func interpolateSquareEaseIn<T: Numeric>(linear: T) -> T {
func interpolateSquareEaseIn<T: Numeric>(_ linear: T) -> T {
return linear ^ 2
}
func interpolateSquareEaseOut<T: Numeric>(linear: T) -> T {
func interpolateSquareEaseOut<T: Numeric>(_ linear: T) -> T {
return 1 - (1 - linear) * (1 - linear)
}
func interpolateSmooth<T: Numeric>(linear: T) -> T {
func interpolateSmooth<T: Numeric>(_ linear: T) -> T {
return ((linear) * (linear) * (linear) * ((linear) * ((linear) * 6 - 15) + 10))
}
func createStringKeyframes(bounces: Int = 2, elasticity: Double = 1.1, bounceSpeed: Double) -> [(time: Double, position: Double)] {
func createStringKeyframes(_ bounces: Int = 2, elasticity: Double = 1.1, bounceSpeed: Double) -> [(time: Double, position: Double)] {
// Setup keyframes
var keyFrames: [(time: Double, position: Double)] = [(1, 1)]
@ -35,7 +35,7 @@ func createStringKeyframes(bounces: Int = 2, elasticity: Double = 1.1, bounceSpe
keyFrames.append((1.0 - currentBounceTime, currentBouncePosition))
for i in (1..<bounces).reverse() {
for i in (1..<bounces).reversed() {
currentBounceTime += overreach / (bounceSpeed ^ Double(i + 1))
currentBounceTime += overreach / (bounceSpeed ^ Double(i))
bounceDirection = Double((i % 2) * 2 - 1)
@ -53,14 +53,14 @@ func createStringKeyframes(bounces: Int = 2, elasticity: Double = 1.1, bounceSpe
keyFrames.append((0, 0))
var reversed = [(time: Double, position: Double)]()
for keyFrame in keyFrames.reverse() {
for keyFrame in keyFrames.reversed() {
reversed.append(keyFrame)
}
return reversed
}
func interpolateSpring<T: Numeric>(linear: T, bounces: Int = 2, elasticity: Double = 1.1, bounceSpeed: Double = 1.0) -> T {
func interpolateSpring<T: Numeric>(_ linear: T, bounces: Int = 2, elasticity: Double = 1.1, bounceSpeed: Double = 1.0) -> T {
let keyFrames: [(time: Double, position: Double)]
keyFrames = createStringKeyframes(bounces, elasticity: elasticity, bounceSpeed: bounceSpeed)

View File

@ -17,12 +17,12 @@ class Graph<T> {
self.adjacencyMatrix = Matrix(size: size)
}
func addEdge(i: Int, _ j: Int) {
func addEdge(_ i: Int, _ j: Int) {
adjacencyMatrix.set(i, j)
adjacencyMatrix.set(j, i)
}
func removeEdge(i: Int, _ j: Int) {
func removeEdge(_ i: Int, _ j: Int) {
adjacencyMatrix.reset(i, j)
adjacencyMatrix.reset(j, i)
}
@ -35,30 +35,30 @@ struct Matrix: CustomStringConvertible {
let size: Int
init(size: Int) {
buffer = [Float](count: size * size, repeatedValue: 0.0)
buffer = [Float](repeating: 0.0, count: size * size)
self.size = size
}
func get(i: Int, j: Int) -> Float {
func get(_ i: Int, j: Int) -> Float {
return buffer[index(i, j)]
}
mutating func set(i: Int, _ j: Int, value: Float = 1.0) {
mutating func set(_ i: Int, _ j: Int, value: Float = 1.0) {
buffer[index(i, j)] = value
}
mutating func reset(i: Int, _ j: Int) {
mutating func reset(_ i: Int, _ j: Int) {
buffer[index(i, j)] = 0.0
}
private func index(i: Int, _ j: Int) -> Int {
fileprivate func index(_ i: Int, _ j: Int) -> Int {
return j * size + i
}
var description: String {
get {
var result = ""
for (index, value) in buffer.enumerate() {
for (index, value) in buffer.enumerated() {
result = result + "\(value)"
if index % size == size - 1 {
result = result + "\n"

View File

@ -5,7 +5,8 @@ class Metaball: UIView {
var color: UIColor
init(position: CGPoint, color: UIColor = UIColor(randomFlatColorOfShadeStyle: .Light)) {
init(position: CGPoint,
color: UIColor = UIColor(randomFlatColorOf: .light)) {
self.color = color
super.init(frame: CGRect.zero)
@ -14,23 +15,25 @@ class Metaball: UIView {
}
required init?(coder aDecoder: NSCoder) {
self.color = UIColor(randomFlatColorOfShadeStyle: .Light)
self.color = UIColor(randomFlatColorOf: .light)
super.init(coder: aDecoder)
}
}
class EdgeAnimationParameters {
let startDate: NSDate
let startDate: Date
let duration: Float
let fadeIn: Bool
let i: Int
let j: Int
func unpack() -> (startDate: NSDate, duration: Float, fadeIn: Bool, i: Int, j: Int) {
func unpack() -> (startDate: Date, duration: Float, fadeIn: Bool,
i: Int, j: Int)
{
return (startDate, duration, fadeIn, i, j)
}
init(startDate: NSDate, duration: Float, fadeIn: Bool, i: Int, j: Int) {
init(startDate: Date, duration: Float, fadeIn: Bool, i: Int, j: Int) {
self.startDate = startDate
self.duration = duration
self.fadeIn = fadeIn
@ -40,17 +43,21 @@ class EdgeAnimationParameters {
}
class VertexAnimationParameters {
let startDate: NSDate
let startDate: Date
let duration: Float
let origin: CGPoint
let destination: CGPoint
let metaball: Metaball
func unpack() -> (startDate: NSDate, duration: Float, origin: CGPoint, destination: CGPoint, metaball: Metaball) {
func unpack() -> (startDate: Date, duration: Float, origin: CGPoint,
destination: CGPoint, metaball: Metaball)
{
return (startDate, duration, origin, destination, metaball)
}
init(startDate: NSDate, duration: Float, origin: CGPoint, destination: CGPoint, metaball: Metaball) {
init(startDate: Date, duration: Float, origin: CGPoint,
destination: CGPoint, metaball: Metaball)
{
self.startDate = startDate
self.duration = duration
self.origin = origin

View File

@ -9,13 +9,13 @@ class MTLContext {
init(device: MTLDevice = MTLCreateSystemDefaultDevice()!) {
self.device = device
self.library = device.newDefaultLibrary()!
self.commandQueue = device.newCommandQueue()
self.commandQueue = device.makeCommandQueue()
}
}
class MTLComputeContext {
var texture: MTLTexture
var imageBuffer: UnsafeMutablePointer<Void>
var imageBuffer: UnsafeMutableRawPointer
init(size: CGSize, texture: MTLTexture) {
let width = Int(size.width)
@ -26,7 +26,7 @@ class MTLComputeContext {
self.texture = texture
}
func updateToSize(size: CGSize, texture: MTLTexture) {
func updateToSize(_ size: CGSize, texture: MTLTexture) {
free(imageBuffer)
let width = Int(size.width)

View File

@ -14,18 +14,18 @@ import ChameleonFramework
let dataSource: MetaballDataSource
let semaphore = dispatch_semaphore_create(2)
let semaphore = DispatchSemaphore(value: 2)
enum RendererState {
case Idle
case Running
case Ending
case idle
case running
case ending
}
var state: RendererState = .Idle {
var state: RendererState = .idle {
willSet {
if state == .Idle {
if newValue == .Running {
if state == .idle {
if newValue == .running {
updateTargetView()
}
}
@ -39,32 +39,40 @@ import ChameleonFramework
let width = Int(frame.width)
let height = Int(frame.height)
let textureDescriptor = MTLTextureDescriptor.texture2DDescriptorWithPixelFormat(.BGRA8Unorm, width: width, height: height, mipmapped: false)
let textureDescriptor =
MTLTextureDescriptor.texture2DDescriptor(
pixelFormat: .bgra8Unorm,
width: width,
height: height,
mipmapped: false)
let texture1 = context.device.newTextureWithDescriptor(textureDescriptor)
activeComputeContext = MTLComputeContext(size: targetView.size, texture: texture1)
let texture2 = context.device.newTextureWithDescriptor(textureDescriptor)
idleComputeContext = MTLComputeContext(size: targetView.size, texture: texture2)
let texture1 =
context.device.makeTexture(descriptor: textureDescriptor)
activeComputeContext = MTLComputeContext(size: targetView.size,
texture: texture1)
let texture2 =
context.device.makeTexture(descriptor: textureDescriptor)
idleComputeContext = MTLComputeContext(size: targetView.size,
texture: texture2)
}
internal func updateTargetView() {
let timeout = DispatchTime.now() + Double(1000000000) / Double(NSEC_PER_SEC)
semaphore.wait(timeout: timeout)
let timeout = dispatch_time(DISPATCH_TIME_NOW, 1000000000)
dispatch_semaphore_wait(semaphore, timeout)
state = .Ending
let userInteractiveQueue = dispatch_get_global_queue(Int(QOS_CLASS_USER_INTERACTIVE.rawValue), 0)
dispatch_async(userInteractiveQueue) { () -> Void in
state = .ending
let userInteractiveQueue =
DispatchQueue.global(qos: DispatchQoS.QoSClass.userInteractive)
userInteractiveQueue.async { () -> Void in
let computeContext = self.activeComputeContext
swap(&self.activeComputeContext, &self.idleComputeContext)
// Render graphics to metal texture
self.renderToContext(computeContext)
if self.state != .Running {
self.state = .Idle
if self.state != .running {
self.state = .idle
} else {
self.updateTargetView()
}
@ -72,16 +80,16 @@ import ChameleonFramework
// Transform metal texture into image
let uiimage = self.createImageFromContext(computeContext)
dispatch_semaphore_signal(self.semaphore)
self.semaphore.signal()
dispatch_async(dispatch_get_main_queue()) { () -> Void in
DispatchQueue.main.async { () -> Void in
// Send image to view
self.targetView.image = uiimage
}
}
}
internal func renderToContext(computeContext: MTLComputeContext) {
internal func renderToContext(_ computeContext: MTLComputeContext) {
let width = Int(targetView.width)
let height = Int(targetView.height)
@ -89,23 +97,27 @@ import ChameleonFramework
let pipeline: MTLComputePipelineState
do {
// Get long-lived objects
kernelFunction = context.library.newFunctionWithName("drawMetaballs")
pipeline = try context.device.newComputePipelineStateWithFunction(kernelFunction!)
kernelFunction =
context.library.makeFunction(name: "drawMetaballs")
pipeline = try context.device.makeComputePipelineState(
function: kernelFunction!)
// Configure info for computing
let threadGroupCounts = MTLSizeMake(8, 8, 1)
let threadGroups = MTLSizeMake(width / threadGroupCounts.width, height / threadGroupCounts.height, 1)
let threadGroups = MTLSizeMake(width / threadGroupCounts.width,
height / threadGroupCounts.height,
1)
// Send commands to metal and render
let commandBuffer = context.commandQueue.commandBuffer()
let commandBuffer = context.commandQueue.makeCommandBuffer()
let commandEncoder = commandBuffer.computeCommandEncoder()
let commandEncoder = commandBuffer.makeComputeCommandEncoder()
commandEncoder.setComputePipelineState(pipeline)
commandEncoder.setTexture(computeContext.texture, atIndex: 0)
commandEncoder.setTexture(computeContext.texture, at: 0)
let metaballInfoBuffer = metaballBuffer()
commandEncoder.setBuffer(metaballInfoBuffer, offset: 0, atIndex: 0)
commandEncoder.setBuffer(metaballInfoBuffer, offset: 0, at: 0)
let edgesBuffer = metaballEdgesBuffer()
commandEncoder.setBuffer(edgesBuffer, offset: 0, atIndex: 1)
commandEncoder.setBuffer(edgesBuffer, offset: 0, at: 1)
commandEncoder.dispatchThreadgroups(threadGroups,
threadsPerThreadgroup: threadGroupCounts)
commandEncoder.endEncoding()
@ -117,11 +129,14 @@ import ChameleonFramework
}
}
internal func createImageFromContext(computeContext: MTLComputeContext) -> UIImage {
internal func createImageFromContext(_ computeContext: MTLComputeContext)
-> UIImage
{
let texture = computeContext.texture
// Get image info
let imageSize = CGSizeMake(CGFloat(texture.width), CGFloat(texture.height))
let imageSize = CGSize(width: CGFloat(texture.width),
height: CGFloat(texture.height))
let width = Int(imageSize.width)
let height = Int(imageSize.height)
let imageByteCount = width * height * 4
@ -134,20 +149,35 @@ import ChameleonFramework
}
// Transfer texture info into image buffer
texture.getBytes(computeContext.imageBuffer, bytesPerRow: bytesPerRow, fromRegion: region, mipmapLevel: 0)
texture.getBytes(computeContext.imageBuffer,
bytesPerRow: bytesPerRow,
from: region,
mipmapLevel: 0)
// Get info for UIImage
let provider = CGDataProviderCreateWithData(nil, computeContext.imageBuffer, imageByteCount, nil)
let bitsPerComponent = 8
let provider = CGDataProvider(dataInfo: nil,
data: computeContext.imageBuffer,
size: imageByteCount) {
(_, _, _) in }
let bitsPerComponent = 8
let bitsperPixel = 32
let colorSpaceRef = CGColorSpaceCreateDeviceRGB()
let bitmapInfoRaw = CGImageAlphaInfo.PremultipliedLast.rawValue | CGBitmapInfo.ByteOrder32Big.rawValue
let bitmapInfoRaw = CGImageAlphaInfo.premultipliedLast.rawValue |
CGBitmapInfo.byteOrder32Big.rawValue
let bitmapInfo = CGBitmapInfo(rawValue: bitmapInfoRaw)
let renderingIntent = CGColorRenderingIntent.RenderingIntentDefault
let renderingIntent = CGColorRenderingIntent.defaultIntent
// Create UIImage from image buffer
let imageRef = CGImageCreate(width, height, bitsPerComponent, bitsperPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, nil, false, renderingIntent)
let image = UIImage(CGImage: imageRef!, scale: 0.0, orientation: .Up)
let imageRef = CGImage(width: width, height: height,
bitsPerComponent: bitsPerComponent,
bitsPerPixel: bitsperPixel,
bytesPerRow: bytesPerRow,
space: colorSpaceRef,
bitmapInfo: bitmapInfo,
provider: provider!,
decode: nil, shouldInterpolate: false,
intent: renderingIntent)
let image = UIImage(cgImage: imageRef!, scale: 0.0, orientation: .up)
return image
}
@ -155,9 +185,11 @@ import ChameleonFramework
internal func metaballEdgesBuffer() -> MTLBuffer {
let floats = dataSource.metaballGraph.adjacencyMatrix.buffer
let bufferLength = floats.count * sizeof(Float)
let bufferLength = floats.count * MemoryLayout<Float>.size
let device = context.device
let buffer = device.newBufferWithBytes(floats, length: bufferLength, options: .StorageModeShared)
let buffer = device.makeBuffer(bytes: floats,
length: bufferLength,
options: MTLResourceOptions())
return buffer
}
@ -166,16 +198,19 @@ import ChameleonFramework
// Create Float array for buffer
// Exclude metaballs far from the view's bounds
let border: CGFloat = 100
let metaballs = self.dataSource.metaballs
let metaballs = self.dataSource.metaballs!
var floats = [Float](count: 5, repeatedValue: 0)
var floats = [Float](repeating: 0, count: 5)
floats = metaballs.reduce(floats) {
(var array, metaball) -> [Float] in
(array, metaball) -> [Float] in
var array = array
let x = CGFloat(metaball.midX)
let y = CGFloat(metaball.midY)
if -border < x targetView.width + border &&
-border < y targetView.height + border {
if -border < x,
x < targetView.width + border,
-border < y,
y < targetView.height + border {
array.append(Float(x))
array.append(Float(y))
@ -192,9 +227,11 @@ import ChameleonFramework
floats[0] = Float(floats.count) / 5
// Create buffer
let bufferLength = floats.count * sizeof(Float)
let bufferLength = floats.count * MemoryLayout<Float>.size
let device = context.device
let buffer = device.newBufferWithBytes(floats, length: bufferLength, options: .StorageModeShared)
let buffer = device.makeBuffer(bytes: floats,
length: bufferLength,
options: MTLResourceOptions())
return buffer
}

View File

@ -1,12 +0,0 @@
import Darwin
infix operator ==~ { associativity right precedence 130 }
func ==~ (left: DoubleValuable, right: DoubleValuable) -> Bool {
let leftDouble = left.toDouble
let rightDouble = right.toDouble
let epsilon = abs(leftDouble/10000)
return (leftDouble <= rightDouble + epsilon) &&
(leftDouble >= rightDouble - epsilon)
}

View File

@ -1,6 +0,0 @@
func iterate<C, R>(collection: C, block: (String?, Any) -> R) {
let mirror = Mirror(reflecting: collection)
for child in mirror.children {
block(child.0, child.1)
}
}

View File

@ -1,57 +0,0 @@
let doubleMax: Double = 1E+37
let doubleMin: Double = -1E+37
let floatMax: Float = 1E+37
let floatMin: Float = -1E+37
let int32Max: Int = 0x7fffffff
let int32Min: Int = -0x7fffffff - 1
infix operator { associativity right precedence 131 }
func <T: Numeric>
(left: T, right: T) -> T {
if left < right {
return left
} else {
return -0x7fffffff
}
}
//
infix operator = { associativity right precedence 131 }
func = <T: Numeric>
(left: T, right: T) -> T {
if left <= right {
return left
} else {
return -0x7fffffff
}
}
//
infix operator { associativity right precedence 131 }
func <T: Numeric>
(left: T, right: T) -> T {
if left > right {
return left
} else {
return 0x7fffffff
}
}
//
infix operator = { associativity right precedence 131 }
func = <T: Numeric>
(left: T, right: T) -> T {
if left >= right {
return left
} else {
return 0x7fffffff
}
}

View File

@ -1,12 +0,0 @@
extension Dictionary {
subscript(keys: [Key]) -> [Value] {
get {
return keys.unwrappedMap { self[$0] }
}
set (values) {
for (key, value) in zip(keys, values) {
self[key] = value
}
}
}
}

View File

@ -1,14 +0,0 @@
import Foundation
extension NSNumber: DoubleValuable {
var toDouble: Double {
get {
return self.doubleValue
}
}
static func fromDouble(double: Double) -> Self {
return self.init(double: double)
}
}

View File

@ -1,23 +1,23 @@
protocol DoubleValuable {
var toDouble: Double { get }
static func fromDouble(double: Double) -> Self
static func fromDouble(_ double: Double) -> Self
}
postfix operator ++ { }
protocol Incrementable {
postfix func ++ (inout _: Self) -> Self
postfix func ++ (_: inout Self) -> Self
}
protocol Numeric: DoubleValuable, Incrementable, Comparable,
IntegerLiteralConvertible {
ExpressibleByIntegerLiteral {
@warn_unused_result func / (lhs: Self, rhs: Self) -> Self
@warn_unused_result func - (lhs: Self, rhs: Self) -> Self
@warn_unused_result func + (lhs: Self, rhs: Self) -> Self
@warn_unused_result func * (lhs: Self, rhs: Self) -> Self
postfix func ++ (inout _: Self) -> Self
postfix func ++ (_: inout Self) -> Self
}
protocol FastNumeric: Numeric {}
@ -29,7 +29,7 @@ extension Double: FastNumeric {
}
}
static func fromDouble(double: Double) -> Double {
static func fromDouble(_ double: Double) -> Double {
return double
}
@ -42,7 +42,7 @@ extension Float: FastNumeric {
}
}
static func fromDouble(double: Double) -> Float {
static func fromDouble(_ double: Double) -> Float {
return Float(double)
}
@ -55,19 +55,8 @@ extension Int: FastNumeric {
}
}
static func fromDouble(double: Double) -> Int {
static func fromDouble(_ double: Double) -> Int {
return Int(double)
}
}
//
extension Int {
func times(@noescape block: () throws -> ()) rethrows {
for _ in 1...self {
try block()
}
}
}

View File

@ -1,16 +0,0 @@
extension SequenceType {
func unwrappedMap<T>
(@noescape transform: (Self.Generator.Element) throws -> T?) rethrows
-> [T] {
return try self.reduce( [T]() ) {
(var accumulator: [T], element: Self.Generator.Element) -> [T] in
let transformed = try transform(element)
if let unwrapped = transformed {
accumulator.append(unwrapped)
}
return accumulator
}
}
}

View File

@ -1,167 +0,0 @@
protocol MemoizedSequence: LazySequenceType {
typealias IndexType: Hashable
typealias ReturnType
init(first: IndexType,
incrementer: ((inout IndexType) -> Void),
memoizedFunction: (IndexType -> ReturnType))
}
struct HashMemoizedSequence<IndexType: Hashable, ReturnType>:
MemoizedSequence {
let memoizedFunction: (IndexType -> ReturnType)
let increment: ((inout IndexType) -> Void)
let firstIndex: IndexType
var index: IndexType
init(first: IndexType,
incrementer: ((inout IndexType) -> Void),
memoizedFunction: (IndexType -> ReturnType)) {
self.firstIndex = first
self.index = first
self.increment = incrementer
self.memoizedFunction = memoizedFunction
}
init(first: IndexType,
incrementer: ((inout IndexType) -> Void),
closure: ((IndexType -> ReturnType, IndexType) -> ReturnType)) {
let memoizedFunction = memoize(closure)
self.init(first: first, incrementer: incrementer,
memoizedFunction: memoizedFunction)
}
init(first: IndexType,
incrementer: ((inout IndexType) -> Void),
function: (IndexType -> ReturnType)) {
let memoizedFunction = memoize(function)
self.init(first: first, incrementer: incrementer,
memoizedFunction: memoizedFunction)
}
}
extension HashMemoizedSequence: GeneratorType {
mutating func next() -> ReturnType? {
let result = memoizedFunction(index)
increment(&index)
return result
}
}
extension HashMemoizedSequence: LazySequenceType {
func generate() -> HashMemoizedSequence {
return self
}
}
extension HashMemoizedSequence where ReturnType: Comparable {
@warn_unused_result
func contains(element: ReturnType) -> Bool {
var index = firstIndex
while true {
let value = memoizedFunction(index)
if value == element {
return true
} else if value > element {
return false
}
increment(&index)
}
}
}
extension HashMemoizedSequence where IndexType: Incrementable {
init(first: IndexType,
closure: ((IndexType -> ReturnType, IndexType) -> ReturnType)) {
self.firstIndex = first
self.index = first
self.increment = { (inout index: IndexType) in
index++
}
self.memoizedFunction = memoize(closure)
}
init(first: IndexType,
function: (IndexType -> ReturnType)) {
self.firstIndex = first
self.index = first
self.increment = { (inout index: IndexType) in
index++
}
self.memoizedFunction = memoize(function)
}
}
extension HashMemoizedSequence where IndexType: Incrementable,
IndexType: IntegerLiteralConvertible {
init(_ closure: ((IndexType -> ReturnType, IndexType) -> ReturnType)) {
self.firstIndex = 1
self.index = 1
self.increment = { (inout index: IndexType) in
index++
}
self.memoizedFunction = memoize(closure)
}
init(_ function: (IndexType -> ReturnType)) {
self.firstIndex = 1
self.index = 1
self.increment = { (inout index: IndexType) in
index++
}
self.memoizedFunction = memoize(function)
}
}
func memoize<H: Hashable, R>(closure: ((H -> R, H) -> R)) -> (H -> R) {
var table = [H: R]()
var auxiliaryFunction: (H -> R)!
auxiliaryFunction = { index in
if let result = table[index] {
return result
}
let result = closure(auxiliaryFunction, index)
table[index] = result
return result
}
return auxiliaryFunction
}
func memoize<H: Hashable, R>(function: (H -> R)) -> (H -> R) {
var table = [H: R]()
let result: (H -> R) = { index in
if let result = table[index] {
return result
}
let result = function(index)
table[index] = result
return result
}
return result
}

View File

@ -1,12 +0,0 @@
prefix operator ± { }
prefix func ± <T: Numeric>(number: T) -> T {
if number > 0 {
return 1
} else if number == 0 {
return 0
} else {
return -1
}
}

View File

@ -1,12 +0,0 @@
extension String: DoubleValuable {
var toDouble: Double {
get {
return Double(self) ?? Double(0)
}
}
static func fromDouble(double: Double) -> String {
return "\(double)"
}
}

View File

@ -1,211 +0,0 @@
// MARK: - Eager
// MARK: Categorise
public extension SequenceType {
/**
Categorises elements of `self` into a dictionary, with the keys
given by `keyFunc`
```swift
struct Person : CustomStringConvertible {
let name: String
let age : Int
init(_ name: String, _ age: Int) {
self.name = name
self.age = age
}
var description: String { return name }
}
let people = [
Person("Jo", 20),
Person("An", 20),
Person("Cthulu", 4000)
]
people.categorise { p in p.age }
//[20: [Jo, An], 4000: [Cthulu]]
```
*/
@warn_unused_result
func categorise<U : Hashable>(@noescape keyFunc: Generator.Element throws -> U)
rethrows -> [U:[Generator.Element]] {
var dict: [U:[Generator.Element]] = [:]
for el in self {
let key = try keyFunc(el)
if case nil = dict[key]?.append(el) { dict[key] = [el] }
}
return dict
}
}
public extension SequenceType where Generator.Element : Hashable {
// MARK: Frequencies
/**
Returns a dictionary where the keys are the elements of self, and
the values are their respective frequencies
```swift
[0, 3, 0, 1, 1, 3, 2, 3, 1, 0].freqs()
// [2: 1, 0: 3, 3: 3, 1: 3]
```
*/
@warn_unused_result
func freqs() -> [Generator.Element:Int] {
var freqs: [Generator.Element:Int] = [:]
for el in self { freqs[el] = freqs[el]?.successor() ?? 1 }
return freqs
}
// MARK: Uniques
/**
Returns an array of the elements of `self`, in order, with
duplicates removed
```swift
[3, 1, 2, 3, 2, 1, 1, 2, 3, 3].uniques()
// [3, 1, 2]
```
*/
@warn_unused_result
public func uniques() -> [Generator.Element] {
var prevs: Set<Generator.Element> = []
var uniqs: [Generator.Element] = []
for el in self where !prevs.contains(el) {
prevs.insert(el)
uniqs.append(el)
}
return uniqs
}
/// Returns the element which occurs most frequently in `self`
@warn_unused_result
public func mostFrequent() -> Generator.Element? {
var g = generate()
guard let b = g.next() else { return nil }
var be = b
var bn = 1
var freqs: [Generator.Element:Int] = [:]
for e in self {
let n = (freqs[e] ?? 0) + 1
if n > bn { (be,bn) = (e,n) }
freqs[e] = n
}
return be
}
}
// MARK: - Lazy
// MARK: Uniques
/// :nodoc:
public struct UniquesGen<G : GeneratorType where G.Element : Hashable> : GeneratorType {
private var prevs: Set<G.Element>
private var g: G
/// :nodoc:
public mutating func next() -> G.Element? {
while let next = g.next() {
if !prevs.contains(next) {
prevs.insert(next)
return next
}
}
return nil
}
}
/// :nodoc:
public struct UniquesSeq<
S : SequenceType where
S.Generator.Element : Hashable
> : LazySequenceType {
private let seq: S
/// :nodoc:
public func generate() -> UniquesGen<S.Generator> {
return UniquesGen(prevs: [], g: seq.generate())
}
}
public extension LazySequenceType where Generator.Element : Hashable {
/// returns a `LazySequence` of the elements of `self`, in order, with
/// duplicates removed
@warn_unused_result
func uniques() -> UniquesSeq<Self> {
return UniquesSeq(seq: self)
}
}
// MARK: Grouping
/// :nodoc:
public struct GroupByGen<G : GeneratorType> : GeneratorType {
private var genr: G
private var last: G.Element?
private let isEq: (G.Element, G.Element) -> Bool
/// :nodoc:
mutating public func next() -> [G.Element]? {
guard let head = last else { return nil }
var group = [head]
last = nil
while let next = genr.next() {
guard isEq(group.last!, next) else {
last = next
return group
}
group.append(next)
}
return group
}
private init(g : G, isEquivalent: (G.Element, G.Element) -> Bool) {
genr = g
last = genr.next()
isEq = isEquivalent
}
}
/// :nodoc:
public struct GroupBySeq<S : SequenceType> : LazySequenceType {
private let seq: S
private let isEquivalent: (S.Generator.Element, S.Generator.Element) -> Bool
/// :nodoc:
public func generate() -> GroupByGen<S.Generator> {
return GroupByGen(g: seq.generate(), isEquivalent: isEquivalent)
}
}
public extension LazySequenceType where Generator.Element : Equatable {
/// Returns a lazy sequence of self, chunked into arrays of adjacent equal values
/// ```swift
/// [1, 2, 2, 3, 1, 1, 3, 4, 2].lazy.group()
///
/// [1], [2, 2], [3], [1, 1], [3], [4], [2]
/// ```
@warn_unused_result
func group() -> GroupBySeq<Self> {
return GroupBySeq(seq: self, isEquivalent: ==)
}
}
public extension LazySequenceType {
/// Returns a lazy sequence of self, chunked into arrays of adjacent equal values
/// - Parameter isEquivalent: a function that returns true if its two parameters are equal
/// ```swift
/// [1, 3, 5, 20, 22, 18, 6, 7].lazy.groupBy { (a,b) in abs(a - b) < 5 }
///
/// [1, 3, 5], [20, 22, 18], [6, 7]
/// ```
@warn_unused_result
func group(isEquivalent: (Generator.Element, Generator.Element) -> Bool)
-> GroupBySeq<Self> {
return GroupBySeq(seq: self, isEquivalent: isEquivalent)
}
}

View File

@ -1,146 +0,0 @@
// MARK: - Eager
// MARK: Chunk
public extension CollectionType {
/// Returns an array of arrays of n non-overlapping elements of self
/// - Parameter n: The size of the chunk
/// - Precondition: `n > 0`
/// - SeeAlso: `func window(n: Int) -> [[Self.Generator.Element]]`
/// ```swift
/// [1, 2, 3, 4, 5].chunk(2)
///
/// [[1, 2], [3, 4], [5]]
/// ```
@warn_unused_result
public func chunk(n: Index.Distance) -> [SubSequence] {
var res: [SubSequence] = []
var i = startIndex
var j: Index
while i != endIndex {
j = i.advancedBy(n, limit: endIndex)
res.append(self[i..<j])
i = j
}
return res
}
}
// MARK: Window
public extension CollectionType {
/// Returns an array of arrays of n overlapping elements of self
/// - Parameter n: The size of the window
/// - SeeAlso: `func chunk(n: Int) -> [[Self.Generator.Element]]`
/// ```swift
/// [1, 2, 3, 4].window(2)
///
/// [[1, 2], [2, 3], [3, 4]]
/// ```
@warn_unused_result
func window(n: Index.Distance) -> [SubSequence] {
var ret: [SubSequence] = []
ret.reserveCapacity(underestimateCount() - numericCast(n))
var i = startIndex
var j = i.advancedBy(n, limit: endIndex)
while true {
ret.append(self[i..<j])
i = i.successor()
if j == endIndex { return ret }
j = j.successor()
}
}
}
// MARK: - Lazy
// MARK: Chunk
/// :nodoc:
public struct ChunkGen<C: CollectionType> : GeneratorType {
private var c: C
private let n: C.Index.Distance
private var i: C.Index
public mutating func next() -> C.SubSequence? {
if i == c.endIndex { return nil }
let j = i.advancedBy(n, limit: c.endIndex)
defer { i = j }
return c[i..<j]
}
}
/// :nodoc:
public struct ChunkSeq<C: CollectionType> : LazySequenceType {
private let c: C
private let n: C.Index.Distance
/// :nodoc:
public func generate() -> ChunkGen<C> {
return ChunkGen(c: c, n: n, i: c.startIndex)
}
}
public extension LazyCollectionType {
/// Returns lazily-generated arrays of n non-overlapping elements of self
/// - Parameter n: The size of the chunk
/// - SeeAlso: `func window(n: Int) -> WindowSeq<Self>`
/// ```swift
/// lazy([1, 2, 3, 4, 5]).chunk(2)
///
/// [1, 2], [3, 4], [5]
/// ```
@warn_unused_result
func chunk(n: Index.Distance) -> ChunkSeq<Self> {
return ChunkSeq(c: self, n: n)
}
}
// MARK: Window
/// :nodoc:
public struct WindowGen<C: CollectionType> : GeneratorType {
private let c: C
private var i, j: C.Index
private var s: Bool
/// :nodoc:
mutating public func next() -> C.SubSequence? {
if s { return nil }
if j == c.endIndex {
s = true
return c[i..<j]
}
defer { (i,j) = (i.successor(),j.successor()) }
return c[i..<j]
}
}
/// :nodoc:
public struct WindowSeq<C: CollectionType> : LazySequenceType {
private let c: C
private let n: C.Index.Distance
/// :nodoc:
public func generate() -> WindowGen<C> {
return WindowGen(c: c, i: c.startIndex, j: c.startIndex.advancedBy(n, limit: c.endIndex), s: false)
}
}
public extension LazyCollectionType {
/// Returns lazily-generated arrays of n overlapping elements of self
/// - Parameter n: The size of the window
/// - SeeAlso: `func chunk(n: Int) -> ChunkSeq<Self>`
/// ```swift
/// lazy([1, 2, 3, 4]).window(2)
///
/// [1, 2], [2, 3], [3, 4]
/// ```
@warn_unused_result
func window(n: Index.Distance) -> WindowSeq<Self> {
return WindowSeq(c: self, n: n)
}
}

View File

@ -1,114 +0,0 @@
/// :nodoc:
public struct ComboGen<SubElement> : GeneratorType {
private let coll: [SubElement]
private var curr: [SubElement]
private var inds: [Int]
/// :nodoc:
mutating public func next() -> [SubElement]? {
for (max, curInd) in zip(coll.indices.reverse(), inds.indices.reverse())
where max != inds[curInd] {
curr[curInd] = coll[++inds[curInd]]
for j in inds.indices.suffixFrom(curInd+1) {
inds[j] = inds[j-1].successor()
curr[j] = coll[inds[j]]
}
return curr
}
return nil
}
}
/// :nodoc:
public struct ComboSeq<Element> : LazySequenceType {
private let start: [Element]
private let col : [Element]
private let inds : [Int]
/// :nodoc:
public func generate() -> ComboGen<Element> {
return ComboGen<Element>(coll: col, curr: start, inds: inds)
}
internal init(n: Int, col: [Element]) {
self.col = col
start = Array(col.prefixUpTo(n))
var inds = Array(col.indices.prefixUpTo(n))
if !inds.isEmpty { --inds[n.predecessor()] }
self.inds = inds
}
}
/// :nodoc:
public struct ComboRepGen<Element> : GeneratorType {
private let coll: [Element]
private var curr: [Element]
private var inds: [Int]
private let max : Int
/// :nodoc:
mutating public func next() -> [Element]? {
for curInd in inds.indices.reverse() where max != inds[curInd] {
curr[curInd] = coll[++inds[curInd]]
for j in (curInd+1)..<inds.count {
inds[j] = inds[j-1]
curr[j] = coll[inds[j]]
}
return curr
}
return nil
}
}
/// :nodoc:
public struct ComboRepSeq<Element> : LazySequenceType {
private let start: [Element]
private let inds : [Int]
private let col : [Element]
private let max : Int
/// :nodoc:
public func generate() -> ComboRepGen<Element> {
return ComboRepGen(coll: col, curr: start, inds: inds, max: max)
}
internal init(n: Int, col: [Element]) {
self.col = col
start = col.first.map { x in Array(count: n, repeatedValue: x) } ?? []
var inds = Array(count: n, repeatedValue: col.startIndex)
if !inds.isEmpty { --inds[n-1] }
self.inds = inds
max = col.endIndex.predecessor()
}
}
extension SequenceType {
/**
Returns the combinations without repetition of length `n` of `self`
*/
@warn_unused_result
public func combos(n: Int = 2) -> [[Generator.Element]] {
return Array(ComboSeq(n: n, col: Array(self)))
}
/**
Returns the combinations with repetition of length `n` of `self`
*/
@warn_unused_result
public func combosWithRep(n: Int) -> [[Generator.Element]] {
return Array(ComboRepSeq(n: n, col: Array(self)))
}
/**
Returns the combinations without repetition of length `n` of `self`, generated lazily
and on-demand
*/
@warn_unused_result
public func lazyCombos(n: Int) -> ComboSeq<Generator.Element> {
return ComboSeq(n: n, col: Array(self))
}
/**
Returns the combinations with repetition of length `n` of `self`, generated lazily and
on-demand
*/
@warn_unused_result
public func lazyCombosWithRep(n: Int) -> ComboRepSeq<Generator.Element> {
return ComboRepSeq(n: n, col: Array(self))
}
}

View File

@ -1,86 +0,0 @@
// MARK: - Eager
// MARK: Cycle n
public extension CollectionType {
/// Returns an array of n cycles of self.
/// ```swift
/// [1, 2, 3].cycle(2)
///
/// [1, 2, 3, 1, 2, 3]
/// ```
@warn_unused_result
func cycle(n: Int) -> [Generator.Element] {
var cycled: [Generator.Element] = []
cycled.reserveCapacity(underestimateCount() * n)
for _ in 0..<n {
cycled.appendContentsOf(self)
}
return cycled
}
}
// MARK: - Lazy
// MARK: Cycle n
/// :nodoc:
public struct CycleNGen<C: CollectionType> : GeneratorType, LazySequenceType {
private let inner: C
private var innerGen: C.Generator
private var n: Int
/// :nodoc:
public mutating func next() -> C.Generator.Element? {
while true {
if let next = innerGen.next() { return next }
n -= 1
if n > 0 { innerGen = inner.generate() }
else { return nil }
}
}
}
public extension LazySequenceType where Self : CollectionType {
/// Returns a generator of n cycles of self.
/// ```swift
/// [1, 2, 3].lazy.cycle(2)
///
/// 1, 2, 3, 1, 2, 3
/// ```
@warn_unused_result
func cycle(n: Int) -> CycleNGen<Self> {
return CycleNGen(inner: self, innerGen: generate(), n: n)
}
}
// MARK: Cycle infinite
/// :nodoc:
public struct CycleGen<C: CollectionType> : GeneratorType, LazySequenceType {
private let inner: C
private var innerGen: C.Generator
/// :nodoc:
public mutating func next() -> C.Generator.Element? {
for ;;innerGen = inner.generate() {
if let next = innerGen.next() {
return next
}
}
}
}
public extension CollectionType {
/// Returns an infinite generator of cycles of self.
/// ```swift
/// [1, 2, 3].cycle()
///
/// 1, 2, 3, 1, 2, 3, 1...
/// ```
@warn_unused_result
func cycle() -> CycleGen<Self> {
return CycleGen(inner: self, innerGen: generate())
}
}

View File

@ -1,33 +0,0 @@
/// :nodoc:
public struct SpecEnumerateGen<Base : CollectionType> : GeneratorType {
private let base: Base
private var i: Base.Index
/// :nodoc:
public mutating func next() -> (Base.Index, Base.Generator.Element)? {
return i == base.endIndex ? nil : (i, base[i++])
}
}
/// :nodoc:
public struct SpecEnumerateSeq<Base : CollectionType> : SequenceType {
private let col: Base
/// :nodoc:
public func generate() -> SpecEnumerateGen<Base> {
return SpecEnumerateGen(base: col, i: col.startIndex)
}
}
public extension CollectionType {
/// Returns a lazy generator of tuples `(i, e)` where `i` is successive indices of self,
/// and `e` is the respective elements. Effectively the same as `.enumerate()`, but the
/// indices returned are `Self.Index`s, rather than `Int`s
/// - SeeAlso: `enumerate()`
@warn_unused_result
func specEnumerate() -> SpecEnumerateSeq<Self> {
return SpecEnumerateSeq(col: self)
}
}

View File

@ -1,80 +0,0 @@
prefix operator ! {}
public prefix func !<A>(f: A -> Bool) -> A -> Bool {
return { x in !f(x) }
}
public extension SequenceType {
/// Returns the first element in self that satisfies a predicate, or nil if it doesn't
/// exist
@warn_unused_result
func first(@noescape thatSatisfies: Generator.Element throws -> Bool) rethrows -> Generator.Element? {
for el in self where try thatSatisfies(el) { return el }
return nil
}
/// Returns the number of elements in `self` that satisfy `predicate`
@warn_unused_result
func count(@noescape predicate: Generator.Element throws -> Bool) rethrows -> Int {
var i = 0
for el in self where try predicate(el) { i += 1 }
return i
}
/// Returns true iff every element in `self` satisfies `predicate`
@warn_unused_result
func all(@noescape predicate: Generator.Element throws -> Bool) rethrows -> Bool {
for x in self { guard try predicate(x) else { return false } }
return true
}
}
public extension CollectionType where Index : BidirectionalIndexType {
/// Returns the last element in self that satisfies a predicate, or nil if it doesn't
/// exist
@warn_unused_result
func last(@noescape predicate: Generator.Element throws -> Bool) rethrows -> Generator.Element? {
for el in reverse() {
if try predicate(el) {
return el
}
}
return nil
}
/**
Returns the index of the final element in `self` which satisfies
`isElement`, or `nil` if it doesn't exist.
*/
@warn_unused_result
func lastIndexOf(@noescape isElement: Generator.Element throws -> Bool) rethrows -> Index? {
for i in indices.reverse() where try isElement(self[i]) {
return i
}
return nil
}
}
extension CollectionType {
/**
Returns the indices of elements of `self` that satisfy the predicate `isElement`
*/
@warn_unused_result
func indicesOf(@noescape isElement: Generator.Element throws -> Bool) rethrows -> [Index] {
return try indices.filter { i in try isElement(self[i]) }
}
}
public extension SequenceType {
@warn_unused_result
func partition(@noescape predicate: Generator.Element throws -> Bool) rethrows -> ([Generator.Element], [Generator.Element]) {
var t,f: [Generator.Element]
(t,f) = ([],[])
for e in self {
if try predicate(e) { t.append(e) } else { f.append(e) }
}
return (t,f)
}
}

View File

@ -1,23 +0,0 @@
extension LazySequenceType {
@warn_unused_result
public func flatMap<T>(transform: Elements.Generator.Element -> T?)
-> LazyMapSequence<LazyFilterSequence<LazyMapSequence<Elements, T?>>, T> {
return self
.map(transform)
.filter { opt in opt != nil }
.map { notNil in notNil! }
}
}
extension LazyCollectionType {
@warn_unused_result
public func flatMap<T>(transform: Elements.Generator.Element -> T?)
-> LazyMapCollection<LazyFilterCollection<LazyMapCollection<Elements, T?>>, T> {
return self
.map(transform)
.filter { opt in opt != nil }
.map { notNil in notNil! }
}
}

View File

@ -1,78 +0,0 @@
public struct RandomAccessHopCollection<
Base: CollectionType where
Base.Index : RandomAccessIndexType,
Base.Index.Distance : ForwardIndexType
>: CollectionType {
private let base: Base
private let by : Base.Index.Stride
private let fac : Base.Index.Distance
public let startIndex: Base.Index.Distance
public let endIndex: Base.Index.Distance
public typealias SubSequence = RandomAccessHopCollection<Base>
public subscript(i: Base.Index.Distance) -> Base.Generator.Element {
return base[base.startIndex.advancedBy(fac * i)]
}
public func generate() -> IndexingGenerator<RandomAccessHopCollection<Base>> {
return IndexingGenerator(self)
}
private init(_ b: Base, _ by: Base.Index.Stride) {
base = b
self.by = by
fac = base.startIndex.distanceTo(base.startIndex.advancedBy(by))
if base.isEmpty { endIndex = 0 }
else { endIndex = (base.startIndex.distanceTo(base.endIndex.predecessor()) / fac).successor() }
startIndex = 0
}
private init(_ b: Base, _ by: Base.Index.Stride, from: Base.Index.Distance, to: Base.Index.Distance) {
base = b
self.by = by
fac = base.startIndex.distanceTo(base.startIndex.advancedBy(by))
startIndex = from
endIndex = to
}
public subscript(r: Range<Base.Index.Distance>) -> RandomAccessHopCollection<Base> {
return RandomAccessHopCollection(base, by, from: r.startIndex, to: r.endIndex)
}
}
extension CollectionType where Index: RandomAccessIndexType, Index.Distance: ForwardIndexType {
public subscript(by by: Index.Stride) -> RandomAccessHopCollection<Self> {
return RandomAccessHopCollection(self, by)
}
}
extension RandomAccessHopCollection: CustomStringConvertible, CustomDebugStringConvertible {
public var debugDescription: String {
return Array(self).debugDescription
}
public var description: String {
return String(Array(self))
}
}
public extension CollectionType where
SubSequence: CollectionType,
Index == SubSequence.Index,
SubSequence.Index: RandomAccessIndexType,
SubSequence.Index.Distance: ForwardIndexType {
subscript(r: Range<Index>, by by: Index.Stride) -> RandomAccessHopCollection<SubSequence> {
return self[r][by: by]
}
subscript(r: OpenEndedRange<Index>, by by: Index.Stride) -> RandomAccessHopCollection<SubSequence> {
return suffixFrom(r.val)[by: by]
}
subscript(r: OpenStartedRangeTo<Index>, by by: Index.Stride) -> RandomAccessHopCollection<SubSequence> {
return prefixUpTo(r.val)[by: by]
}
subscript(r: OpenStartedRangeThrough<Index>, by by: Index.Stride) -> RandomAccessHopCollection<SubSequence> {
return prefixThrough(r.val)[by: by]
}
}

View File

@ -1,366 +0,0 @@
// MARK: - Eager
// MARK: Interpose with single element
public extension SequenceType {
/// Returns an array that alternates between successive elements of self and element
/// ```swift
/// [1, 2, 3].interpose(10)
///
/// [1, 10, 2, 10, 3]
/// ```
@warn_unused_result
func interpose(element: Generator.Element) -> [Generator.Element] {
var g = generate()
return g.next().map {
var ret = [$0]
while let next = g.next() {
ret.append(element)
ret.append(next)
}
return ret
} ?? []
}
/// Returns an array that alternates between n successive elements of self and element
/// ```swift
/// [1, 2, 3, 4, 5].interpose(10, n: 2)
///
/// [1, 2, 10, 3, 4, 10, 5]
/// ```
@warn_unused_result
func interpose(element: Generator.Element, n: Int) -> [Generator.Element] {
var ret: [Generator.Element] = []
var g = generate()
var i = n + 1
while let next = g.next() {
if --i == 0 {
ret.append(element)
i = n
}
ret.append(next)
}
return ret
}
}
// MARK: Interpose with collection
public extension SequenceType {
/// Returns an array that alternates between successive elements of self and elements of
/// a colletion
/// ```swift
/// [1, 2, 3].interpose([10, 20])
///
/// [1, 10, 20, 2, 10, 20, 3]
/// ```
@warn_unused_result
func interpose<C : CollectionType where C.Generator.Element == Generator.Element>
(col: C) -> [Generator.Element] {
var g = generate()
return g.next().map {
var ret = [$0]
while let next = g.next() {
ret.appendContentsOf(col)
ret.append(next)
}
return ret
} ?? []
}
/// Returns an array that alternates between n successive elements of self and elements
/// of a colletion
/// ```swift
/// [1, 2, 3, 4, 5].interpose([10, 20], n: 2)
///
/// [1, 2, 10, 20, 3, 4, 10, 20, 5]
/// ```
func interpose<C : CollectionType where C.Generator.Element == Generator.Element>
(col: C, n: Int) -> [Generator.Element] {
var g = generate()
return g.next().map {
var i = n
var ret = [$0]
while let next = g.next() {
if --i == 0 {
ret.appendContentsOf(col)
i = n
}
ret.append(next)
}
return ret
} ?? []
}
}
// MARK: Interdigitate
/// Returns an array of two sequences interdigitated
/// ```swift
/// interdig([1, 2, 3], [10, 20, 30])
///
/// [1, 10, 2, 20, 3, 30]
/// ```
@warn_unused_result
public func interdig<
S0 : SequenceType, S1 : SequenceType where
S0.Generator.Element == S1.Generator.Element
>(s0: S0, _ s1: S1) -> [S0.Generator.Element] {
var ret: [S0.Generator.Element] = []
var (g0, g1) = (s0.generate(), s1.generate())
while let e0 = g0.next(), e1 = g1.next() {
ret.append(e0)
ret.append(e1)
}
return ret
}
/// Returns an array of two sequences interdigitated, with the respective length of each
/// interdigitation specified
/// - Parameter s0Len: The length of the first sequence's interdigitations
/// - Parameter s1Len: The length of the second sequence's interdigitations
/// ```swift
/// interdig([1, 2, 3, 4, 5], [10, 20, 30, 40, 50, 60], s0Len: 2, s1Len: 3)
///
/// [1, 2, 10, 20, 30, 3, 4, 40, 50, 60, 5]
/// ```
@warn_unused_result
public func interdig<
S0 : SequenceType, S1 : SequenceType where
S0.Generator.Element == S1.Generator.Element
>(s0: S0, _ s1: S1, s0Len: Int, s1Len: Int) -> [S0.Generator.Element] {
var ret: [S0.Generator.Element] = []
var (g0, g1) = (s0.generate(), s1.generate())
for ;; {
for _ in 0..<s0Len {
if let next = g0.next() {
ret.append(next)
} else {
return ret
}
}
for _ in 0..<s1Len {
if let next = g1.next() {
ret.append(next)
} else {
return ret
}
}
}
}
// MARK: - Lazy
// MARK: Interpose with single element
/// :nodoc:
public struct InterposeElGen<G : GeneratorType> : GeneratorType {
private let n: Int
private var count: Int
private var g: G
private let element: G.Element
/// :nodoc:
public mutating func next() -> G.Element? {
return --count < 0 ? {count = n; return element}() : g.next()
}
}
/// :nodoc:
public struct InterposeElSeq<S : SequenceType> : LazySequenceType {
private let element: InterposeElGen<S.Generator>.Element
private let n: Int
private let seq: S
/// :nodoc:
public func generate() -> InterposeElGen<S.Generator> {
return InterposeElGen(n: n, count: n, g: seq.generate(), element: element)
}
}
public extension LazySequenceType {
/// Returns a lazy sequence that alternates between successive elements of self and an
/// element
/// ```swift
/// [1, 2, 3].lazy.interpose(10)
///
/// 1, 10, 2, 10, 3, 10
/// ```
@warn_unused_result
func interpose(element: Generator.Element) -> InterposeElSeq<Self> {
return InterposeElSeq(element: element, n: 1, seq: self)
}
/// Returns a lazy sequence that alternates between n successive elements of self and an
/// element
/// ```swift
/// [1, 2, 3, 4, 5].lazy.interpose(10, n: 2)
///
/// 1, 2, 10, 3, 4, 10, 5
/// ```
@warn_unused_result
func interpose(element: Generator.Element, n: Int) -> InterposeElSeq<Self> {
return InterposeElSeq(element: element, n: n, seq: self)
}
}
// MARK: Interpose with collection
/// :nodoc:
public struct InterposeColGen<
G : GeneratorType,
C: CollectionType where
G.Element == C.Generator.Element
> : GeneratorType {
private let col: C
private var g: G
private let n: Int
private var count: Int
private var colG: C.Generator
/// :nodoc:
public mutating func next() -> G.Element? {
return --count <= 0 ? {
colG.next() ?? {
count = n
colG = col.generate()
return g.next()
}()}() : g.next()
}
}
/// :nodoc:
public struct InterposeColSeq<
S : SequenceType,
C: CollectionType where
S.Generator.Element == C.Generator.Element
> : LazySequenceType {
private let col: C
private let n: Int
private let seq: S
/// :nodoc:
public func generate() -> InterposeColGen<S.Generator, C> {
return InterposeColGen(col: col, g: seq.generate(), n: n, count: n + 1, colG: col.generate())
}
}
public extension LazySequenceType {
/// Returns a lazy sequence that alternates between successive elements of self and
/// elements of a colletion
/// ```swift
/// [1, 2, 3].lazy.interpose([10, 20])
///
/// 1, 10, 20, 2, 10, 20, 3, 10, 20
/// ```
@warn_unused_result
func interpose<
C: CollectionType where
C.Generator.Element == Generator.Element
>(elements: C) -> InterposeColSeq<Self, C> {
return InterposeColSeq(col: elements, n: 1, seq: self)
}
/// Returns a lazy sequence that alternates between n successive elements of self and
/// elements of a colletion
/// ```swift
/// [1, 2, 3, 4, 5].lazy.interpose([10, 20], n: 2)
///
/// 1, 2, 10, 20, 3, 4, 10, 20, 5
/// ```
@warn_unused_result
func interpose<
C: CollectionType where
C.Generator.Element == Generator.Element
>(elements: C, n: Int) -> InterposeColSeq<Self, C> {
return InterposeColSeq(col: elements, n: n, seq: self)
}
}
// MARK: Interdigitate
/// :nodoc:
public struct InterDigGen<
G0 : GeneratorType,
G1 : GeneratorType where
G0.Element == G1.Element
> : GeneratorType {
private var g0: G0
private var g1: G1
private let aN: Int
private let bN: Int
private var count: Int
/// :nodoc:
public mutating func next() -> G0.Element? {
for (--count;;count = aN) {
if count >= bN { return count < 0 ? g1.next() : g0.next() }
}
}
}
/// :nodoc:
public struct InterDigSeq<
S0 : LazySequenceType,
S1 : LazySequenceType where
S0.Generator.Element == S1.Generator.Element
> : LazySequenceType {
private let s0: S0
private let s1: S1
private let aN: Int
private let bN: Int
/// :nodoc:
public func generate() -> InterDigGen<S0.Generator, S1.Generator> {
return InterDigGen(
g0: s0.generate(),
g1: s1.generate(),
aN: aN - 1,
bN: -bN,
count: aN
)
}
}
/// Returns a lazy sequence of two sequences interdigitated
/// ```swift
/// interdig([1, 2, 3].lazy, [10, 20, 30].lazy)
///
/// 1, 10, 2, 20, 3, 30
/// ```
@warn_unused_result
public func interdig<
S0 : LazySequenceType, S1 : LazySequenceType where
S0.Generator.Element == S1.Generator.Element
>(s0: S0, _ s1: S1) -> InterDigSeq<S0, S1> {
return InterDigSeq(s0: s0, s1: s1, aN: 1, bN: 1)
}
/// Returns a lazy sequence of two sequences interdigitated, with the respective length of
/// each interdigitation specified
/// - Parameter s0Len: The length of the first sequence's interdigitations
/// - Parameter s1Len: The length of the second sequence's interdigitations
/// ```swift
/// interdig([1, 2, 3, 4, 5].lazy, [10, 20, 30, 40, 50, 60].lazy, s0Len: 2, s1Len: 3)
///
/// 1, 2, 10, 20, 30, 3, 4, 40, 50, 60, 5
/// ```
@warn_unused_result
public func interdig<
S0 : SequenceType, S1 : SequenceType where
S0.Generator.Element == S1.Generator.Element
>(s0: S0, _ s1: S1, s0Len: Int, s1Len: Int = 1) -> InterDigSeq<S0, S1> {
return InterDigSeq(s0: s0, s1: s1, aN: s0Len, bN: s1Len)
}

View File

@ -1,34 +0,0 @@
public struct IterateGenerator<Element>: GeneratorType {
private var x: Element
private let f: Element -> Element
public mutating func next() -> Element? {
defer { x = f(x) }
return x
}
}
public struct IterateSequence<Element>: SequenceType {
private let x: Element
private let f: Element -> Element
public func generate() -> IterateGenerator<Element> {
return IterateGenerator(x: x, f: f)
}
}
public struct IterateEndGenerator<Element>: GeneratorType {
private var x: Element?
private var f: Element -> Element?
public mutating func next() -> Element? {
guard let y = x else { return nil }
defer { x = f(y) }
return y
}
}
public struct IterateEndSequence<Element>: SequenceType {
private let x: Element
private let f: Element -> Element?
public func generate() -> IterateEndGenerator<Element> {
return IterateEndGenerator(x: x, f: f)
}
}

View File

@ -1,229 +0,0 @@
// MARK: - Eager
// MARK: Cartesian Product
private extension GeneratorType where Element : CollectionType {
mutating private func product() -> [[Element.Generator.Element]] {
guard let x = next() else { return [[]] }
let xs = product()
return x.flatMap { h in xs.map { [h] + $0 } }
}
}
public extension SequenceType where Generator.Element : SequenceType, Generator.Element : CollectionType {
/// Returns a cartesian product of self
/// ```swift
/// [[1, 2], [3, 4]].product()
/// [[1, 3], [1, 4], [2, 3], [2, 4]]
/// ```
@warn_unused_result
public func product() -> [[Generator.Element.Generator.Element]] {
var g = generate()
return g.product()
}
}
public extension SequenceType where Generator.Element : SequenceType {
/// Returns a cartesian product of self
/// ```swift
/// [[1, 2], [3, 4]].product()
/// [[1, 3], [1, 4], [2, 3], [2, 4]]
/// ```
@warn_unused_result
public func product() -> [[Generator.Element.Generator.Element]] {
return map(Array.init).product()
}
}
/// Cartesian product
/// ```swift
/// product([1, 2], [3, 4])
/// [[1, 3], [1, 4], [2, 3], [2, 4]]
/// ```
@warn_unused_result
public func product<C : CollectionType>(cols: C...) -> [[C.Generator.Element]] {
return cols.product()
}
/// Cartesian product
/// ```swift
/// product([1, 2], [3, 4])
/// [[1, 3], [1, 4], [2, 3], [2, 4]]
/// ```
public func product<S : SequenceType>(cols: S...) -> [[S.Generator.Element]] {
return cols.product()
}
// MARK: Transposition
private extension SequenceType {
private func mapM<U>(@noescape transform: Generator.Element -> U?) -> [U]? {
var result: [U] = []
result.reserveCapacity(underestimateCount())
for e in self {
if let r = transform(e) { result.append(r) } else { return nil }
}
return result
}
}
public extension SequenceType where Generator.Element : SequenceType {
/// Returns a transposed self
/// ```swift
/// [[1, 2, 3], [1, 2, 3], [1, 2, 3]].transpose()
///
/// [[1, 1, 1], [2, 2, 2], [3, 3, 3]]
/// ```
@warn_unused_result
func transpose() -> [[Generator.Element.Generator.Element]] {
return Array(TransposeSeq(seq: self))
}
}
// MARK: - Lazy
// MARK: Cartesian Product
/// :nodoc:
public struct ProdGen<C : CollectionType> : GeneratorType {
private let cols: [C] // Must be collections, not sequences, in order to be multi-pass
private var gens: [C.Generator]
private var curr: [C.Generator.Element]
/// :nodoc:
public mutating func next() -> [C.Generator.Element]? {
for i in gens.indices.reverse() { // Loop through generators in reverse order, rolling over
if let n = gens[i].next() { // if generator isn't finished, just increment that column, return
curr[i] = n
return curr
} else { // generator is finished
gens[i] = cols[i].generate() // reset the generator
curr[i] = gens[i].next()! // set the current column to the first element of the generator
}
}
return nil
}
private init(cols: [C]) {
var gens = cols.map{$0.generate()}
self.cols = cols
curr = gens.dropLast().indices.map{gens[$0].next()!} + [self.cols.last!.first!]
/**
set curr to the first value of each of the generators, except the last: don't
increment this generator, so that the first value returned contains it.
*/
self.gens = gens
}
}
/// :nodoc:
public struct ProdSeq<C : CollectionType> : LazySequenceType {
private let cols: [C]
/// :nodoc:
public func generate() -> ProdGen<C> {
return ProdGen( cols: cols )
}
/// :nodoc:
public func underestimateCount() -> Int {
return cols.reduce(1) { (n,c) in n * c.underestimateCount() }
}
}
/// Lazy Cartesian Product
/// ```swift
/// lazyProduct([1, 2], [3, 4])
///
/// [1, 3], [1, 4], [2, 3], [2, 4]
/// ```
@warn_unused_result
public func lazyProduct<C : CollectionType>
(cols: C...) -> ProdSeq<C> {
return ProdSeq(cols: cols)
}
/// Lazy Cartesian Product
/// ```swift
/// lazyProduct([1, 2], [3, 4])
///
/// [1, 3], [1, 4], [2, 3], [2, 4]
/// ```
@warn_unused_result
public func lazyProduct<S : SequenceType>
(cols: S...) -> ProdSeq<[S.Generator.Element]> {
return ProdSeq(cols: cols.map(Array.init))
}
public extension SequenceType where Generator.Element : SequenceType {
/// Lazy Cartesian Product
/// ```swift
/// [[1, 2], [3, 4]].lazyProduct()
///
/// [1, 3], [1, 4], [2, 3], [2, 4]
/// ```
@warn_unused_result
func lazyProduct() -> ProdSeq<[Generator.Element.Generator.Element]> {
return ProdSeq(cols: map(Array.init))
}
}
public extension SequenceType where Generator.Element : CollectionType {
/// Lazy Cartesian Product
/// ```swift
/// [[1, 2], [3, 4]].lazyProduct()
///
/// [1, 3], [1, 4], [2, 3], [2, 4]
/// ```
@warn_unused_result
func lazyProduct() -> ProdSeq<Generator.Element> {
return ProdSeq(cols: Array(self))
}
}
// MARK: Transposition
/// :nodoc:
public struct TransposeGen<T, G : GeneratorType where G.Element == T> : GeneratorType {
private var gens: [G]
/// :nodoc:
mutating public func next() -> [T]? {
return gens.indices.mapM { i in gens[i].next() }
}
}
/// :nodoc:
public struct TransposeSeq<
S : SequenceType where
S.Generator.Element : SequenceType
> : LazySequenceType {
private let seq: S
/// :nodoc:
public func generate()
-> TransposeGen<S.Generator.Element.Generator.Element, S.Generator.Element.Generator>{
return TransposeGen(gens: seq.map { g in g.generate() })
}
}
public extension TransposeSeq where S: CollectionType {
@warn_unused_result
public func underestimateCount() -> Int {
return seq.first?.underestimateCount() ?? 0
}
}
public extension LazySequenceType where Generator.Element: SequenceType {
/// Returns a lazily transposed self
/// ```swift
/// lazy([[1, 2, 3], [1, 2, 3], [1, 2, 3]]).transpose()
///
/// [1, 1, 1], [2, 2, 2], [3, 3, 3]
/// ```
@warn_unused_result
func transpose() -> TransposeSeq<Self> {
return TransposeSeq(seq: self)
}
}

View File

@ -1,187 +0,0 @@
// MARK: - Common
public extension MutableCollectionType {
/// [Algorithm](https://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order)
public mutating func nextLexPerm
(isOrderedBefore: (Generator.Element, Generator.Element) -> Bool) -> Self? {
for k in indices.reverse().dropFirst()
where isOrderedBefore(self[k], self[k.successor()]) {
for l in indices.reverse() where isOrderedBefore(self[k], self[l]) {
swap(&self[k], &self[l])
let r = (k.successor()..<endIndex)
for (x, y) in zip(r, r.reverse()) {
if x == y || x == y.successor() { return self }
swap(&self[x], &self[y])
}
}
}
return nil
}
}
public extension MutableCollectionType where Generator.Element : Comparable {
/// [Algorithm](https://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order)
public mutating func nextLexPerm() -> Self? {
return nextLexPerm(<)
}
}
/// :nodoc:
public struct LexPermGen<C : MutableCollectionType> : GeneratorType {
private var col: C?
private let order: (C.Generator.Element, C.Generator.Element) -> Bool
/// :nodoc:
mutating public func next() -> C? {
defer { col = col?.nextLexPerm(order) }
return col
}
}
/// :nodoc:
public struct LexPermSeq<C : MutableCollectionType> : LazySequenceType {
private let col: C
private let order: (C.Generator.Element, C.Generator.Element) -> Bool
/// :nodoc:
public func generate() -> LexPermGen<C> {
return LexPermGen(col: col, order: order)
}
}
// MARK: - Eager
public extension SequenceType {
/// Returns an array of the permutations of self, ordered lexicographically, according
/// to the closure `isOrderedBefore`.
/// - Note: The permutations returned follow self, so if self is not the first
/// lexicographically ordered permutation, not all permutations will be returned.
/// ```swift
/// [1, 2, 3].lexPermutations(<)
///
/// [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
/// ```
/// ```swift
/// [1, 2, 3].lexPermutations(>)
///
/// [[1, 2, 3]]
/// ```
@warn_unused_result
public func lexPermutations
(isOrderedBefore: (Generator.Element, Generator.Element) -> Bool) -> [[Generator.Element]] {
return Array(LexPermSeq(col: Array(self), order: isOrderedBefore))
}
}
public extension MutableCollectionType where Generator.Element : Comparable {
/// Returns an array of the permutations of self, ordered lexicographically.
/// - Note: The permutations returned follow self, so if self is not the first
/// lexicographically ordered permutation, not all permutations will be returned.
/// ```swift
/// [1, 2, 3].lexPermutations()
///
/// [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
/// ```
/// ```swift
/// [3, 2, 1].lexPermutations()
///
/// [[3, 2, 1]]
/// ```
@warn_unused_result
public func lexPermutations() -> [[Generator.Element]] {
return Array(LexPermSeq(col: Array(self), order: <))
}
}
public extension SequenceType {
/// Returns an array of the permutations of self.
/// ```swift
/// [1, 2, 3].permutations()
///
/// [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
/// ```
@warn_unused_result
public func permutations() -> [[Generator.Element]] {
var col = Array(self)
return Array(LexPermSeq(col: Array(col.indices), order: <).map { inds in inds.map{col[$0]} })
}
/// Returns an array of the permutations of length `n` of self.
/// ```swift
/// [1, 2, 3].permutations()
///
/// [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
/// ```
public func permutations(n: Int) -> [[Generator.Element]] {
return Array(lazyCombos(n).flatMap { a in a.permutations() })
}
}
// MARK: - Lazy
public extension SequenceType {
/// Returns a lazy sequence of the permutations of self, ordered lexicographically,
/// according to the closure `isOrderedBefore`.
/// - Note: The permutations returned follow self, so if self is not the first
/// lexicographically ordered permutation, not all permutations will be returned.
/// ```swift
/// lazy([1, 2, 3]).lazyLexPermutations(<)
///
/// [1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]
/// ```
/// ```swift
/// lazy([1, 2, 3]).lazyLexPermutations(>)
///
/// [1, 2, 3]
/// ```
@warn_unused_result
public func lazyLexPermutations(isOrderedBefore: (Generator.Element, Generator.Element) -> Bool)
-> LexPermSeq<[Generator.Element]> {
return LexPermSeq(col: Array(self), order: isOrderedBefore)
}
}
public extension SequenceType where Generator.Element : Comparable {
/// Returns a lazy sequence of the permutations of self, ordered lexicographically.
/// - Note: The permutations returned follow self, so if self is not the first
/// lexicographically ordered permutation, not all permutations will be returned.
/// ```swift
/// lazy([1, 2, 3]).lazyLexPermutations()
///
/// [1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]
/// ```
/// ```swift
/// lazy([3, 2, 1]).lazyLexPermutations()
///
/// [3, 2, 1]
/// ```
@warn_unused_result
public func lazyLexPermutations() -> LexPermSeq<[Generator.Element]> {
return LexPermSeq(col: Array(self), order: <)
}
}
public extension SequenceType {
/// Returns a lazy sequence of the permutations of self.
/// - Note: The permutations are lexicographically ordered, based on the indices of self
/// ```swift
/// lazy([1, 2, 3]).lazyPermutations()
///
/// [1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]
/// ```
/// ```swift
/// lazy([3, 2, 1]).lazyPermutations()
///
/// [3, 2, 1], [3, 1, 2], [2, 3, 1], [2, 1, 3], [1, 3, 2], [1, 2, 3]
/// ```
@warn_unused_result
public func lazyPermutations() -> LazyMapSequence<LexPermSeq<[Int]>, [Self.Generator.Element]> {
let col = Array(self)
return col.indices.lazyLexPermutations().map { $0.map { col[$0] } }
}
}

View File

@ -1,152 +0,0 @@
// MARK: - Eager
public extension SequenceType {
// MARK: Reduce1
/// Return the result of repeatedly calling combine with an accumulated value
/// initialized to the first element of self and each element of self, in turn, i.e.
/// return combine(combine(...combine(combine(self[0], self[1]),
/// self[2]),...self[count-2]), self[count-1]).
/// ```swift
/// [1, 2, 3].reduce(+) // 6
/// ```
@warn_unused_result
func reduce
(@noescape combine: (accumulator: Generator.Element, element: Generator.Element) throws -> Generator.Element)
rethrows -> Generator.Element? {
var g = generate()
guard let a = g.next() else { return nil }
var accu = a
while let next = g.next() {
accu = try combine(accumulator: accu, element: next)
}
return accu
}
// MARK: Scan
/// Return an array where every value is equal to combine called on the previous
/// element, and the current element. The first element is taken to be initial.
/// ```swift
/// [1, 2, 3].scan(0, combine: +)
///
/// [1, 3, 6]
/// ```
@warn_unused_result
func scan<T>(initial: T, @noescape combine: (accumulator: T, element: Generator.Element) throws -> T) rethrows -> [T] {
var accu = initial
return try map { e in
accu = try combine(accumulator: accu, element: e)
return accu
}
}
// MARK: Scan1
/// Return an array where every value is equal to combine called on the previous
/// element, and the current element.
/// ```swift
/// [1, 2, 3].scan(+)
///
/// [3, 6]
/// ```
@warn_unused_result
func scan(@noescape combine: (accumulator: Generator.Element, element: Generator.Element) throws -> Generator.Element) rethrows -> [Generator.Element] {
var g = generate()
guard let i = g.next() else { return [] }
return try GeneratorSequence(g).scan(i, combine: combine)
}
}
// MARK: - Lazy
// MARK: Scan
/// :nodoc:
public struct ScanGen<G : GeneratorType, T> : GeneratorType {
private let combine: (T, G.Element) -> T
private var initial: T
private var g: G
/// :nodoc:
public mutating func next() -> T? {
guard let e = g.next() else { return nil }
initial = combine(initial, e)
return initial
}
}
/// :nodoc:
public struct LazyScanSeq<S : SequenceType, T> : LazySequenceType {
private let seq : S
private let combine: (T, S.Generator.Element) -> T
private let initial: T
/// :nodoc:
public func generate() -> ScanGen<S.Generator, T> {
return ScanGen(combine: combine, initial: initial, g: seq.generate())
}
}
public extension LazySequenceType {
/// Return a lazy sequence where every value is equal to combine called on the previous
/// element, and the current element. The first element is taken to be initial.
/// ```swift
/// lazy([1, 2, 3]).scan(0, combine: +)
///
/// 1, 3, 6
/// ```
@warn_unused_result
func scan<T>(initial: T, combine: (accumulator: T, element: Generator.Element) -> T) -> LazyScanSeq<Self, T> {
return LazyScanSeq(seq: self, combine: combine, initial: initial)
}
}
// MARK: Scan1
/// :nodoc:
public struct Scan1Gen<G : GeneratorType> : GeneratorType {
private let combine: (G.Element, G.Element) -> G.Element
private var accu: G.Element?
private var g: G
public mutating func next() -> G.Element? {
guard let a = accu, e = g.next() else { return nil }
accu = combine(a, e)
return accu!
}
private init(combine: (G.Element, G.Element) -> G.Element, generator: G) {
g = generator
self.combine = combine
accu = g.next()
}
}
/// :nodoc:
public struct LazyScan1Seq<S : SequenceType> : LazySequenceType {
private let seq: S
private let combine: (S.Generator.Element, S.Generator.Element) -> S.Generator.Element
/// :nodoc:
public func generate() -> Scan1Gen<S.Generator> {
return Scan1Gen(combine: combine, generator: seq.generate())
}
}
public extension LazySequenceType {
/// Return a lazy sequence where every value is equal to combine called on the previous
/// element, and the current element.
/// ```swift
/// lazy([1, 2, 3]).scan(+)
///
/// 3, 6
/// ```
@warn_unused_result
func scan(combine: (accumulator: Generator.Element, element: Generator.Element) -> Generator.Element)
-> LazyScan1Seq<Self> {
return LazyScan1Seq(seq: self, combine: combine)
}
}

View File

@ -1,138 +0,0 @@
// IntervalTypes
public protocol OpenIntervalType {
typealias Value
func contains(v: Value) -> Bool
}
public protocol OpenEndedIntervalType: OpenIntervalType {
typealias Value: Comparable
var val: Value { get }
}
public protocol OpenStartedIntervalTypeTo: OpenIntervalType {
typealias Value: Comparable
var val: Value { get }
}
public protocol OpenStartedIntervalTypeThrough: OpenIntervalType {
typealias Value: Comparable
var val: Value { get }
}
// Interval Structs
public struct OpenEndedInterval<C: Comparable>: OpenEndedIntervalType {
public let val: C
}
public struct OpenStartedIntervalTo<C: Comparable>: OpenStartedIntervalTypeTo {
public let val: C
}
public struct OpenStartedIntervalThrough<C: Comparable>: OpenStartedIntervalTypeThrough {
public let val: C
}
// Range structs
public struct OpenEndedRange<I: ForwardIndexType where I: Comparable>: OpenEndedIntervalType {
public var val: I
}
public struct OpenStartedRangeTo<I: BidirectionalIndexType where I: Comparable>: OpenStartedIntervalTypeTo {
public var val: I
}
public struct OpenStartedRangeThrough<I: BidirectionalIndexType where I: Comparable>: OpenStartedIntervalTypeThrough {
public var val: I
}
// Generators
public struct EndlessIncrement<I: ForwardIndexType>: GeneratorType {
private var i: I
public mutating func next() -> I? {
defer { i = i.successor() }
return i
}
}
// SequenceType
extension OpenEndedRange: SequenceType {
public func generate() -> EndlessIncrement<I> {
return EndlessIncrement(i: val)
}
}
// Operators
postfix operator ... {}
prefix operator ... {}
prefix operator ..< {}
public postfix func ...<C: Comparable>(c: C) -> OpenEndedInterval<C> {
return OpenEndedInterval(val: c)
}
public postfix func ...<I: ForwardIndexType>(c: I) -> OpenEndedRange<I> {
return OpenEndedRange(val: c)
}
public prefix func ..<<C: Comparable>(c: C) -> OpenStartedIntervalTo<C> {
return OpenStartedIntervalTo(val: c)
}
public prefix func ..<<C: BidirectionalIndexType>(c: C) -> OpenStartedRangeTo<C> {
return OpenStartedRangeTo(val: c)
}
public prefix func ... <C: Comparable>(c: C) -> OpenStartedIntervalThrough<C> {
return OpenStartedIntervalThrough(val: c)
}
public prefix func ... <C: BidirectionalIndexType>(c: C) -> OpenStartedRangeThrough<C> {
return OpenStartedRangeThrough(val: c)
}
// Contains
extension OpenEndedIntervalType {
public func contains(v: Value) -> Bool { return val <= v }
}
extension OpenStartedIntervalTypeTo {
public func contains(v: Value) -> Bool { return val > v }
}
extension OpenStartedIntervalTypeThrough {
public func contains(v: Value) -> Bool { return val >= v }
}
// Pattern Matching
public func ~=<I: OpenIntervalType>(lhs: I, rhs: I.Value) -> Bool {
return lhs.contains(rhs)
}
// Indexing
public extension CollectionType where Index: Comparable {
subscript(r: OpenEndedRange<Index>) -> SubSequence {
return suffixFrom(r.val)
}
}
public extension CollectionType where Index: Comparable, Index: BidirectionalIndexType {
subscript(r: OpenStartedRangeTo<Index>) -> SubSequence {
return prefixUpTo(r.val)
}
subscript(r: OpenStartedRangeThrough<Index>) -> SubSequence {
return prefixThrough(r.val)
}
}
public extension MutableCollectionType where Index: Comparable {
subscript(r: OpenEndedRange<Index>) -> SubSequence {
get { return suffixFrom(r.val) }
set { self[r.val..<endIndex] = newValue }
}
}
public extension MutableCollectionType where Index: Comparable, Index: BidirectionalIndexType {
subscript(r: OpenStartedRangeTo<Index>) -> SubSequence {
get { return prefixUpTo(r.val) }
set { self[startIndex..<r.val] = newValue }
}
subscript(r: OpenStartedRangeThrough<Index>) -> SubSequence {
get { return prefixThrough(r.val) }
set { self[startIndex...r.val] = newValue }
}
}

View File

@ -1,208 +0,0 @@
// MARK: - Eager
// MARK: prefixWhile
public extension SequenceType {
/// Returns an array of self up until the first element that returns false for condition
/// ```swift
/// [1, 2, 3, 4, 5, 2].prefixWhile { $0 < 4 }
///
/// [1, 2, 3]
/// ```
@warn_unused_result
func prefixWhile(@noescape condition: Generator.Element throws -> Bool) rethrows -> [Generator.Element] {
var ret : [Generator.Element] = []
var g = generate()
while let next = g.next() where try condition(next) { ret.append(next) }
return ret
}
}
// MARK: DropWhile
public extension SequenceType {
/// Returns an array of self with the first elements that return true for condition
/// dropped
/// ```swift
/// [1, 2, 3, 4, 5, 2].dropWhile { $0 < 4 }
///
/// [4, 5, 2]
/// ```
@warn_unused_result
func dropWhile(@noescape condition: Generator.Element throws -> Bool) rethrows -> [Generator.Element] {
var g = generate()
while let next = g.next() {
if try !condition(next) {
return [next] + GeneratorSequence(g)
}
}
return []
}
}
public extension SequenceType {
/**
Returns a tuple of the prefix and suffix of `self`, the first element
being the prefix up to `n`.
*/
public func breakAt(n: Int) -> ([Generator.Element],[Generator.Element]) {
let r = max(0, underestimateCount() - n)
var f,b : [Generator.Element]
(f,b) = ([],[])
f.reserveCapacity(n)
b.reserveCapacity(r)
var g = generate()
for _ in 0..<n {
if let e = g.next() { f.append(e) } else { return (f,b) }
}
while let e = g.next() { b.append(e) }
return (f,b)
}
}
public extension CollectionType {
/**
Returns a tuple of the prefix and suffix of `self`, the first element
being the prefix up to `n`.
*/
public func breakAt(n: Index) -> (SubSequence, SubSequence) {
return (prefixUpTo(n),suffixFrom(n))
}
}
public extension CollectionType where Index == Int {
/**
Returns a tuple of the prefix and suffix of `self`, the first element
being the prefix up to `n`.
*/
public func breakAt(n: Int) -> (SubSequence, SubSequence) {
return (prefixUpTo(n),suffixFrom(n))
}
}
public extension SequenceType {
/**
Returns a tuple of the prefix and suffix of `self`, the first element
being the prefix up to the first elements of `self` which returns
`true` for `isBreak`.
*/
public func breakAt(@noescape isBreak: Generator.Element throws -> Bool)
rethrows -> ([Generator.Element],[Generator.Element]) {
var f,b : [Generator.Element]
(f,b) = ([],[])
var g = generate()
while let e = g.next() {
if try isBreak(e) {
b.append(e)
while let be = g.next() { b.append(be) }
return (f,b)
} else {
f.append(e)
}
}
return (f,b)
}
}
public extension CollectionType {
/**
Returns a tuple of the prefix and suffix of `self`, the first element
being the prefix up to the first elements of `self` which returns
`true` for `isBreak`.
*/
public func breakAt(@noescape isBreak: Generator.Element throws -> Bool) rethrows -> (SubSequence, SubSequence) {
return try indexOf(isBreak).map(breakAt) ?? (suffixFrom(startIndex),prefixUpTo(startIndex))
}
}
// MARK: - Lazy
// MARK: TakeWhile
/// :nodoc:
public struct WhileGen<G : GeneratorType> : GeneratorType {
private var g: G
private let condition : G.Element -> Bool
/// :nodoc:
mutating public func next() -> G.Element? {
if let next = g.next() where condition(next) {
return next
}
return nil
}
}
/// :nodoc:
public struct WhileSeq<S : SequenceType> : LazySequenceType {
private let seq: S
private let condition: S.Generator.Element -> Bool
/// :nodoc:
public func generate() -> WhileGen<S.Generator> {
return WhileGen(g: seq.generate(), condition: condition)
}
}
public extension LazySequenceType {
/// Returns a lazy sequence of self up until the first element that returns false for
/// condition
/// ```swift
/// [1, 2, 3, 4, 5, 2].lazy.takeWhile { $0 < 4 }
///
/// 1, 2, 3
/// ```
@warn_unused_result
func prefixWhile(condition: Generator.Element -> Bool) -> WhileSeq<Self> {
return WhileSeq(seq: self, condition: condition)
}
}
// MARK: DropWhile
/// :nodoc:
public struct DropWhileGen<G : GeneratorType> : GeneratorType {
private let predicate: G.Element -> Bool
private var nG: G?
private var oG: G
private init(g: G, predicate: G.Element -> Bool) {
nG = nil
oG = g
self.predicate = predicate
}
/// :nodoc:
public mutating func next() -> G.Element? {
guard nG == nil else { return nG!.next() }
while let next = oG.next() {
if !predicate(next) {
nG = oG
return next
}
}
return nil
}
}
/// :nodoc:
public struct DropWhileSeq<S : SequenceType> : LazySequenceType {
private let predicate: S.Generator.Element -> Bool
private let seq: S
/// :nodoc:
public func generate() -> DropWhileGen<S.Generator> {
return DropWhileGen(g: seq.generate(), predicate: predicate)
}
}
public extension LazySequenceType {
/// Returns a lazy sequence of self with the first elements that return true for
/// condition dropped
/// ```swift
/// [1, 2, 3, 4, 5, 2].lazy.dropWhile { $0 < 4 }
///
/// 4, 5, 2
/// ```
@warn_unused_result
func dropWhile(predicate: Generator.Element -> Bool) -> DropWhileSeq<Self> {
return DropWhileSeq(predicate: predicate, seq: self)
}
}

View File

@ -1,90 +0,0 @@
/// :nodoc:
public struct NilPaddedZipGenerator<G0: GeneratorType, G1: GeneratorType> : GeneratorType {
private var (g0, g1): (G0?, G1?)
public mutating func next() -> (G0.Element?, G1.Element?)? {
let (e0,e1) = (g0?.next(),g1?.next())
switch (e0,e1) {
case (nil,nil): return nil
case ( _,nil): g1 = nil
case (nil, _): g0 = nil
default: break
}
return (e0,e1)
}
}
/// :nodoc:
public struct NilPaddedZip<S0: SequenceType, S1: SequenceType> : LazySequenceType {
private let (s0, s1): (S0, S1)
/// :nodoc:
public func generate() -> NilPaddedZipGenerator<S0.Generator, S1.Generator> {
return NilPaddedZipGenerator(g0: s0.generate(), g1: s1.generate())
}
}
/// A sequence of pairs built out of two underlying sequences, where the elements of the
/// ith pair are optional ith elements of each underlying sequence. If one sequence is
/// shorter than the other, pairs will continue to be returned after it is exhausted, but
/// with its elements replaced by nil.
/// ```swift
/// zipWithPadding([1, 2, 3], [1, 2])
///
/// (1?, 1?), (2?, 2?), (3?, nil)
/// ```
@warn_unused_result
public func zipWithPadding<S0: SequenceType, S1: SequenceType>(s0: S0, _ s1: S1)
-> NilPaddedZip<S0, S1> {
return NilPaddedZip(s0: s0, s1: s1)
}
/// :nodoc:
public struct PaddedZipGenerator<G0: GeneratorType, G1: GeneratorType> : GeneratorType {
typealias E0 = G0.Element
typealias E1 = G1.Element
private var g: NilPaddedZipGenerator<G0, G1>
private let (p0, p1): (E0, E1)
public mutating func next() -> (E0, E1)? {
guard let (e0,e1) = g.next() else { return nil }
return (e0 ?? p0, e1 ?? p1)
}
}
/// :nodoc:
public struct PaddedZip<S0: SequenceType, S1: SequenceType> : LazySequenceType {
private let (s0, s1): (S0, S1)
private let (p0, p1): (S0.Generator.Element, S1.Generator.Element)
/// :nodoc:
public func generate() -> PaddedZipGenerator<S0.Generator, S1.Generator> {
return PaddedZipGenerator(
g: NilPaddedZipGenerator(
g0: s0.generate(),
g1: s1.generate()
),
p0: p0,
p1: p1
)
}
}
/// A sequence of pairs built out of two underlying sequences, where the elements of the
/// ith pair are the ith elements of each underlying sequence. If one sequence is
/// shorter than the other, pairs will continue to be returned after it is exhausted, but
/// with its elements replaced by its respective pad.
/// - Parameter pad0: the element to pad `s0` with after it is exhausted
/// - Parameter pad1: the element to pad `s1` with after it is exhausted
/// ```swift
/// zipWithPadding([1, 2, 3], [1, 2], pad0: 100, pad1: 900)
///
/// (1, 1), (2, 2), (3, 900)
/// ```
@warn_unused_result
public func zipWithPadding<
S0: SequenceType, S1: SequenceType
>(s0: S0, _ s1: S1, pad0: S0.Generator.Element, pad1: S1.Generator.Element)
-> PaddedZip<S0, S1> {
return PaddedZip(s0: s0, s1: s1, p0: pad0, p1: pad1)
}

View File

@ -1,96 +0,0 @@
// TODO: Preconditions
// TODO: Test memoization
// TODO: Reorganize Swift Sugar folders
// TODO: Sugar documentation
// TODO: Add Swift Sugar to git
// TODO: Add LINT to EngineKit
// TODO: Add @warnunusedresult where appropriate
import Darwin
class Random<T: Numeric> {
let max: Double = Double(INT32_MAX)
let exponent: Double = 7
init(example: T) {
setupRandomSeed()
}
private func expRandom() -> Double {
let rawRandom = Double(rand()) / max
let exponentiated = (3 * rawRandom) ^ exponent
return exponentiated
}
private func uniRandom() -> Double {
return Double(rand()) / max
}
private func setupRandomSeed() {
var now = time(nil)
var date = tm()
localtime_r(&now, &date)
let day = date.tm_yday
let year = date.tm_year
srand(UInt32(365 * year + day))
}
func nonnegativeRandomNumber() -> T {
let random = expRandom()
return T.fromDouble(random)
}
func positiveRandomNumber() -> T {
let random = expRandom()
let result = T.fromDouble(random)
guard result != 0 else {
return positiveRandomNumber()
}
return result
}
func randomNumber() -> T {
let random = expRandom()
let signed = random * ±(Double(rand()) - max)
return T.fromDouble(signed)
}
func uniformRandomNumber(from tStart: T, to tEnd: T) -> T {
let start = tStart.toDouble
let end = tEnd.toDouble
let rawRandom = uniRandom()
let interval = end - start
let result = start + (rawRandom * interval)
return T.fromDouble(result)
}
func uniformRandomNumber(start tStart: T, interval tInterval: T)
-> T {
let start = tStart.toDouble
let interval = tInterval.toDouble
let rawRandom = uniRandom()
let result = start + (rawRandom * interval)
return T.fromDouble(result)
}
func uniformRandomNumber(center tCenter: T,
maxDeviation tInterval: T) -> T {
let center = tCenter.toDouble
let interval = tInterval.toDouble
let start = T.fromDouble(center - interval / 2)
return uniformRandomNumber(start: start, interval: tInterval)
}
func randomSign() -> T {
let rawRandom = rand() % 2
let result = Double((2 * rawRandom) - 1)
return T.fromDouble(result)
}
}

View File

@ -42,7 +42,7 @@ extension CGFloat: DoubleValuable {
}
}
static func fromDouble(double: Double) -> CGFloat {
static func fromDouble(_ double: Double) -> CGFloat {
return CGFloat(double)
}
@ -206,7 +206,7 @@ extension CALayer {
}
}
let screenRect = UIScreen.mainScreen().bounds
let screenRect = UIScreen.main.bounds
let screenWidth = screenRect.size.width
let screenHeight = screenRect.size.height

View File

@ -2,186 +2,225 @@ import UIKit
class ViewController: UIViewController, MetaballDataSource {
var metaballView: UIImageView!
var renderer: MetalMetaballRenderer!
var metaballView: UIImageView!
var renderer: MetalMetaballRenderer!
let width = 350
let height = 600
let width = 350
let height = 600
var metaballGraph: Graph<Metaball>!
var previousLocation: CGPoint!
var metaballGraph: Graph<Metaball>!
var previousLocation: CGPoint!
var selectedMetaball: Metaball?
var selectedMetaball: Metaball?
let edgeAnimationDuration: Float = 1
let edgeAnimationDuration: Float = 1
override func viewDidLoad() {
super.viewDidLoad()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.whiteColor()
view.backgroundColor = UIColor.white
let recognizer = UIPanGestureRecognizer(target: self, action: "handlePan:")
view.addGestureRecognizer(recognizer)
let recognizer = UIPanGestureRecognizer(target: self,
action: "handlePan:")
view.addGestureRecognizer(recognizer)
var positions = [CGPoint]()
positions.append(CGPoint(x: Double(screenWidth) / 2, y: Double(screenHeight) / 2))
for i in 1...5 {
let sine = sin(Double(i) * 2 * M_PI / 5)
let cosine = cos(Double(i) * 2 * M_PI / 5)
let radius: Double = 150
let x = Double(screenWidth) / 2 + sine * radius
let y = Double(screenHeight) / 2 + cosine * radius
positions.append(CGPoint(x: x, y: y))
}
var positions = [CGPoint]()
positions.append(CGPoint(
x: Double(screenWidth) / 2,
y: Double(screenHeight) / 2))
for i in 1...5 {
let sine = sin(Double(i) * 2 * M_PI / 5)
let cosine = cos(Double(i) * 2 * M_PI / 5)
let radius: Double = 150
let x = Double(screenWidth) / 2 + sine * radius
let y = Double(screenHeight) / 2 + cosine * radius
positions.append(CGPoint(x: x, y: y))
}
let colors =
[UIColor(red255: 110, green: 220, blue: 220, alpha: 1.0),
UIColor(red255: 250, green: 235, blue: 50, alpha: 1.0),
UIColor(red255: 110, green: 220, blue: 220, alpha: 1.0),
UIColor(red255: 90, green: 170, blue: 170, alpha: 1.0),
UIColor(red255: 90, green: 170, blue: 170, alpha: 1.0),
UIColor(red255: 110, green: 220, blue: 220, alpha: 1.0)]
let metaballs = zip(positions, colors).map { Metaball(position: $0.0, color: $0.1) }
let colors =
[UIColor(red255: 110, green: 220, blue: 220, alpha: 1.0),
UIColor(red255: 250, green: 235, blue: 50, alpha: 1.0),
UIColor(red255: 110, green: 220, blue: 220, alpha: 1.0),
UIColor(red255: 90, green: 170, blue: 170, alpha: 1.0),
UIColor(red255: 90, green: 170, blue: 170, alpha: 1.0),
UIColor(red255: 110, green: 220, blue: 220, alpha: 1.0)]
let metaballs = zip(positions, colors).map {
Metaball(position: $0.0, color: $0.1)
}
metaballGraph = Graph(vertices: metaballs)
metaballGraph = Graph(vertices: metaballs)
let metaballViewFrame = screenRect
renderer = MetalMetaballRenderer(dataSource: self, frame: metaballViewFrame)
metaballView = renderer.targetView
view.addSubview(metaballView)
let metaballViewFrame = screenRect
renderer = MetalMetaballRenderer(dataSource: self,
frame: metaballViewFrame)
metaballView = renderer.targetView
view.addSubview(metaballView)
for metaball in metaballs {
metaballView.addSubview(metaball)
}
for metaball in metaballs {
metaballView.addSubview(metaball)
}
delay(1.0) {
self.addEdge(0, 1)
self.addEdge(0, 2)
self.addEdge(0, 3)
self.addEdge(0, 4)
self.addEdge(0, 5)
}
delay(1.0) {
self.addEdge(0, 1)
self.addEdge(0, 2)
self.addEdge(0, 3)
self.addEdge(0, 4)
self.addEdge(0, 5)
}
delay(2.3) {
self.removeEdge(0, 1)
self.removeEdge(0, 2)
self.removeEdge(0, 3)
self.removeEdge(0, 4)
self.removeEdge(0, 5)
}
delay(2.3) {
self.removeEdge(0, 1)
self.removeEdge(0, 2)
self.removeEdge(0, 3)
self.removeEdge(0, 4)
self.removeEdge(0, 5)
}
delay(4) {
for i in 1...5 {
UIView.animateWithDuration(1.0, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in
let sine = sin(Double(i) * 2 * M_PI / 5)
let cosine = cos(Double(i) * 2 * M_PI / 5)
let radius: Double = 85
let x = Double(screenWidth) / 2 + sine * radius
let y = Double(screenHeight) / 2 + cosine * radius
let metaball = metaballs[i]
self.animateMetaball(metaball, toPoint: CGPoint(x: x, y: y))
}, completion: nil)
}
}
delay(4) {
for i in 1...5 {
UIView.animate(withDuration: 1.0, delay: 0,
options: UIViewAnimationOptions(),
animations: { () -> Void in
let sine = sin(Double(i) * 2 * M_PI / 5)
let cosine = cos(Double(i) * 2 * M_PI / 5)
let radius: Double = 85
let x = Double(screenWidth) / 2 + sine * radius
let y = Double(screenHeight) / 2 + cosine * radius
let metaball = metaballs[i]
self.animateMetaball(metaball, toPoint: CGPoint(x: x, y: y))
}, completion: nil)
}
}
delay(6) { () -> () in
for i in 1...5 {
UIView.animateWithDuration(1.0, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in
let sine = sin(Double(i) * 2 * M_PI / 5)
let cosine = cos(Double(i) * 2 * M_PI / 5)
let radius: Double = 150
let x = Double(screenWidth) / 2 + sine * radius
let y = Double(screenHeight) / 2 + cosine * radius
let metaball = metaballs[i]
self.animateMetaball(metaball, toPoint: CGPoint(x: x, y: y))
}, completion: nil)
}
}
delay(6) { () -> () in
for i in 1...5 {
UIView.animate(withDuration: 1.0, delay: 0,
usingSpringWithDamping: 0.5,
initialSpringVelocity: 0,
options: UIViewAnimationOptions(),
animations: { () -> Void in
let sine = sin(Double(i) * 2 * M_PI / 5)
let cosine = cos(Double(i) * 2 * M_PI / 5)
let radius: Double = 150
let x = Double(screenWidth) / 2 + sine * radius
let y = Double(screenHeight) / 2 + cosine * radius
let metaball = metaballs[i]
self.animateMetaball(metaball, toPoint: CGPoint(x: x, y: y))
}, completion: nil)
}
}
renderer.state = .Running
}
renderer.state = .running
}
func addEdge(i: Int, _ j: Int) {
animateEdge(i, j, fadeIn: true)
}
func addEdge(_ i: Int, _ j: Int) {
animateEdge(i, j, fadeIn: true)
}
func removeEdge(i: Int, _ j: Int) {
animateEdge(i, j, fadeIn: false)
}
func removeEdge(_ i: Int, _ j: Int) {
animateEdge(i, j, fadeIn: false)
}
func animateMetaball(metaball: Metaball, toPoint destination: CGPoint) {
let parameters = VertexAnimationParameters(startDate: NSDate(), duration: 1.0, origin: metaball.center, destination: destination, metaball: metaball)
NSTimer.scheduledTimerWithTimeInterval(1.0 / 60.0, target: self, selector: "animateMetaballWithTimer:", userInfo: parameters, repeats: true)
}
func animateMetaball(_ metaball: Metaball, toPoint destination: CGPoint) {
let parameters = VertexAnimationParameters(startDate: Date(),
duration: 1.0,
origin: metaball.center,
destination: destination,
metaball: metaball)
Timer.scheduledTimer(
timeInterval: 1.0 / 60.0,
target: self,
selector: "animateMetaballWithTimer:",
userInfo: parameters,
repeats: true)
}
func animateMetaball(withTimer timer: NSTimer) {
guard let userInfo = timer.userInfo as? VertexAnimationParameters else { preconditionFailure() }
let (animationStart, duration, origin, destination, metaball) = (userInfo).unpack()
func animateMetaball(withTimer timer: Timer) {
guard let userInfo = timer.userInfo as? VertexAnimationParameters else {
preconditionFailure()
}
let (animationStart, duration, origin, destination, metaball) =
(userInfo).unpack()
let now = NSDate()
var timeElapsed = Float(now.timeIntervalSinceDate(animationStart))
let now = Date()
var timeElapsed = Float(now.timeIntervalSince(animationStart))
if timeElapsed > duration {
timer.invalidate()
timeElapsed = duration
}
if timeElapsed > duration {
timer.invalidate()
timeElapsed = duration
}
let linearValue = timeElapsed / duration
let interpolatedValue = interpolateSmooth(linearValue)
print(interpolatedValue)
let linearValue = timeElapsed / duration
let interpolatedValue = interpolateSmooth(linearValue)
print(interpolatedValue)
let position = origin + ((destination - origin) * interpolatedValue)
metaball.center = position
let position = origin + ((destination - origin) * interpolatedValue)
metaball.center = position
renderer.state = .Running
}
renderer.state = .running
}
func animateEdge(i: Int, _ j: Int, fadeIn: Bool) {
let parameters = EdgeAnimationParameters(startDate: NSDate(), duration: edgeAnimationDuration, fadeIn: fadeIn, i: i, j: j)
NSTimer.scheduledTimerWithTimeInterval(1.0 / 60.0, target: self, selector: "animateEdgeWithTimer:", userInfo: parameters, repeats: true)
}
func animateEdge(_ i: Int, _ j: Int, fadeIn: Bool) {
let parameters = EdgeAnimationParameters(startDate: Date(),
duration: edgeAnimationDuration,
fadeIn: fadeIn,
i: i,
j: j)
Timer.scheduledTimer(
timeInterval: 1.0 / 60.0,
target: self,
selector: "animateEdgeWithTimer:",
userInfo: parameters,
repeats: true)
}
func animateEdge(withTimer timer: NSTimer) {
guard let userInfo = timer.userInfo as? EdgeAnimationParameters else { preconditionFailure() }
let (animationStart, duration, fadeIn, i, j) = (userInfo).unpack()
func animateEdge(withTimer timer: Timer) {
guard let userInfo = timer.userInfo as? EdgeAnimationParameters else {
preconditionFailure()
}
let (animationStart, duration, fadeIn, i, j) = (userInfo).unpack()
let now = NSDate()
var timeElapsed = Float(now.timeIntervalSinceDate(animationStart))
let now = Date()
var timeElapsed = Float(now.timeIntervalSince(animationStart))
if timeElapsed > duration {
timer.invalidate()
timeElapsed = duration
}
if timeElapsed > duration {
timer.invalidate()
timeElapsed = duration
}
let linearValue = timeElapsed / duration
let interpolatedValue = fadeIn ? interpolateSquareEaseOut(linearValue) : (1 - interpolateSquareEaseIn(linearValue))
let linearValue = timeElapsed / duration
let interpolatedValue = fadeIn ?
interpolateSquareEaseOut(linearValue) :
(1 - interpolateSquareEaseIn(linearValue))
metaballGraph.adjacencyMatrix.set(i, j, value: interpolatedValue)
metaballGraph.adjacencyMatrix.set(j, i, value: interpolatedValue)
metaballGraph.adjacencyMatrix.set(i, j, value: interpolatedValue)
metaballGraph.adjacencyMatrix.set(j, i, value: interpolatedValue)
renderer.state = .Running
}
renderer.state = .running
}
func handlePan(recognizer: UIPanGestureRecognizer) {
let location = recognizer.locationInView(metaballView)
func handlePan(_ recognizer: UIPanGestureRecognizer) {
let location = recognizer.location(in: metaballView)
if selectedMetaball == nil {
for metaball in metaballs where
abs(metaball.midX - location.x) < 50 && abs(metaball.midY - location.y) < 50 {
selectedMetaball = metaball
break
}
}
if selectedMetaball == nil {
for metaball in metaballs where
abs(metaball.midX - location.x) < 50 &&
abs(metaball.midY - location.y) < 50
{
selectedMetaball = metaball
break
}
}
guard selectedMetaball != nil else { return }
guard selectedMetaball != nil else { return }
selectedMetaball?.middle = location
selectedMetaball?.middle = location
renderer.state = .Running
renderer.state = .running
if recognizer.state == .Ended {
selectedMetaball = nil
}
}
if recognizer.state == .ended {
selectedMetaball = nil
}
}
}

View File

@ -33,7 +33,8 @@ kernel void
for (x = 1; x <= numberOfMetaballs; x += 1) {
metaballData metaball = metaballBuffer[x];
float2 metaballPosition = float2(metaball.x, metaball.y);
float2 vector = float2(metaballPosition.x - gid.x, metaballPosition.y - gid.y);
float2 vector = float2(metaballPosition.x - gid.x,
metaballPosition.y - gid.y);
float dotProduct = dot(vector, vector);
float squaredDistance = dotProduct > 0 ? dotProduct : 1;
float realDistance = sqrt(squaredDistance);

View File

@ -2,5 +2,5 @@ platform :ios, '9.2'
use_frameworks!
target 'PixelImage' do
pod 'ChameleonFramework/Swift'
pod 'ChameleonFramework/Swift', :git => 'https://github.com/ViccAlexander/Chameleon.git'
end

View File

@ -4,9 +4,20 @@ PODS:
- ChameleonFramework/Default
DEPENDENCIES:
- ChameleonFramework/Swift
- ChameleonFramework/Swift (from `https://github.com/ViccAlexander/Chameleon.git`)
EXTERNAL SOURCES:
ChameleonFramework:
:git: https://github.com/ViccAlexander/Chameleon.git
CHECKOUT OPTIONS:
ChameleonFramework:
:commit: acc480fbe023c6e5fe40f68593f4a70a8c4c7ad5
:git: https://github.com/ViccAlexander/Chameleon.git
SPEC CHECKSUMS:
ChameleonFramework: d21a3cc247abfe5e37609a283a8238b03575cf64
COCOAPODS: 0.39.0
PODFILE CHECKSUM: 01ad8f20bdbed983c319dde08426f855f26bc5a0
COCOAPODS: 1.2.0