<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">Hi Kevin,</div><div class="gmail_quote"><br></div><div class="gmail_quote">Thank you for the proposal. This is in line with the current design of String. One of the Swift 3 goals is a redesign of String, to make the API easier to use. I don't think that should block this improvement, since whatever the new design is, it should provide the UnicodeScalar view functionality for String, and the same API should be exposed on StaticString.</div><div class="gmail_quote"><br></div><div class="gmail_quote">On Sun, Dec 6, 2015 at 1:21 AM, Kevin Ballard via swift-evolution <span dir="ltr"><<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><u></u>
<div><div>There's no way to create a substring of `StaticString` that's still typed as `StaticString`. This is occasionally desirable, for example if you want to extract the filename from `__FILE__` to pass to another API that requires a `StaticString`.<br></div>
<div> </div>
<div>I believe the best solution to this is to add a type `StaticString.UnicodeScalarView`, similar to `String.UnicodeScalarView`. `StaticString` would also be extended with a property `unicodeScalars` and two initializers to construct a `StaticString` from a `String.UnicodeScalarView`. The full proposed API looks like:<br></div>
<div> </div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif">extension StaticString {</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> /// The value of `self` as a collection of [Unicode scalar values](<a href="http://www.unicode.org/glossary/#unicode_scalar_value" target="_blank">http://www.unicode.org/glossary/#unicode_scalar_value</a>).</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> public var unicodeScalars: UnicodeScalarView</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div> </div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> /// Construct the `StaticString` corresponding to the given</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> /// `UnicodeScalarView`.</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> public init(_: UnicodeScalarView)</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div> </div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> /// Construct the `StaticString` corresponding to the given</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> /// `UnicodeScalarView` slice.</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> public init(_: Slice<UnicodeScalarView>)</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div> </div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> /// A collection of [Unicode scalar values](<a href="http://www.unicode.org/glossary/#unicode_scalar_value" target="_blank">http://www.unicode.org/glossary/#unicode_scalar_value</a>) that</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> /// encode a `StaticString`.</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> public struct UnicodeScalarView : CollectionType {</span></div></div></blockquote><div><br></div><div>UnicodeScalarView should be a slice type, that is, UnicodeScalarView.SubSequence == UnicodeScalarView.</div><div><br></div><div>Then, you will be able to remove the StaticString.init(Slice<UnicodeScalarView>) initializer.</div><div><br></div><div>It should also be CustomStringConvertible, CustomDebugStringConvertible, with the same behavior as String.</div><div><br></div><div>Please also add a CustomReflectable conformance, that extracts the string value and reflects that.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> init(_: StaticString)</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div> </div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> /// A position in a `StaticString.UnicodeScalarView`.</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> public struct Index : BidirectionalIndexType, Comparable {</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> /// Returns the next consecutive value after `self`.</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> ///</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> /// - Requires: The next value is representable.</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> @warn_unused_result</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> public func successor() -> Index</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div> </div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> /// Returns the previous consecutive value before `self`.</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> ///</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> /// - Requires: The previous value is representable.</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> @warn_unused_result</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> public func predecessor() -> Index</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> }</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div> </div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> /// The position of the first `UnicodeScalar` if the `StaticString` is</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> /// non-empty; identical to `endIndex` otherwise.</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> public var startIndex: Index</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div> </div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> /// The "past the end" position.</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> ///</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> /// `endIndex` is not a valid argument to `subscript`, and is always</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> /// reachable from `startIndex` by zero or more applications of</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> /// `successor()`.</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> public var endIndex: Index</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div> </div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> /// Returns `true` iff `self` is empty.</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> public var isEmpty: Bool</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div> </div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> public subscript(position: Index) -> UnicodeScalar</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"> }</span><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,'courier new',monospace,sans-serif">}</span></div></div></blockquote><div><br></div><div>You omitted == and < APIs for indices.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div>
<div>An alternative would be to make StaticString itself conform to CollectionType, but this is a bad idea for the same reasons that String doesn't conform to CollectionType.<br></div>
<div></div></div></blockquote></div><div class="gmail_extra"><br></div>Agreed.</div><div class="gmail_extra"><br></div><div class="gmail_extra">Dmitri<br clear="all"><div><br></div>-- <br><div>main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if<br>(j){printf("%d\n",i);}}} /*Dmitri Gribenko <<a href="mailto:gribozavr@gmail.com" target="_blank">gribozavr@gmail.com</a>>*/</div>
</div></div>