Skip to content
This repository has been archived by the owner on Dec 22, 2021. It is now read-only.

Commit

Permalink
Bring back WrappedString
Browse files Browse the repository at this point in the history
The motivation is the same as for Arrays which were originally
wrapped in ArrayView but we later changed it back to WrappedArray
(and ImmutableArray): It is very convenient to have an implicit
conversion of a String to a Seq[Char] but a View is no longer a Seq
in the new collection library.
  • Loading branch information
szeiger committed Jan 18, 2018
1 parent c17c6c8 commit b871ac2
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package strawman.collection
package immutable

import scala.{Char, Int}
import scala.Predef.String
import mutable.{Builder, StringBuilder}

/**
* This class serves as a wrapper augmenting `String`s with all the operations
* found in indexed sequences.
*
* The difference between this class and `StringOps` is that calling transformer
* methods such as `filter` and `map` will yield an object of type `WrappedString`
* rather than a `String`.
*
* @param self a string contained within this wrapped string
*
* @since 2.8
* @define Coll `WrappedString`
* @define coll wrapped string
*/
final class WrappedString(val self: String) extends AbstractSeq[Char] with IndexedSeq[Char] {

def apply(i: Int): Char = self.charAt(i)

protected[this] def fromSpecificIterable(coll: strawman.collection.Iterable[Char]): IndexedSeq[Char] =
WrappedString.fromSpecific(coll)
protected[this] def newSpecificBuilder(): Builder[Char, IndexedSeq[Char]] = WrappedString.newBuilder()
def iterableFactory: SeqFactory[IndexedSeq] = ImmutableArray

override def slice(from: Int, until: Int): WrappedString = {
val start = if (from < 0) 0 else from
if (until <= start || start >= self.length)
return new WrappedString("")

val end = if (until > length) length else until
new WrappedString(self.substring(start, end))
}
override def length = self.length
override def toString = self
override def view: StringView = new StringView(self)
}

/** A companion object for wrapped strings.
*
* @since 2.8
*/
object WrappedString extends SpecificIterableFactory[Char, WrappedString] {
def fromSpecific(it: IterableOnce[Char]): WrappedString = {
val b = newBuilder()
it match {
case it: Iterable[_] =>
val s = it.knownSize
if(s >= 0) b.sizeHint(s)
case _ =>
}
b ++= it
b.result()
}
val empty: WrappedString = new WrappedString("")
def newBuilder(): Builder[Char, WrappedString] =
new StringBuilder().mapResult(x => new WrappedString(x))
}
4 changes: 2 additions & 2 deletions collections/src/main/scala/strawman/collection/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,6 @@ class LowPriority {
/** Convert array to WrappedArray. Lower priority than ArrayOps */
implicit def arrayToWrappedArray[T](xs: Array[T]): mutable.IndexedSeq[T] = mutable.WrappedArray.make[T](xs)

/** Convert string to iterable via view. Lower priority than StringOps */
implicit def stringToView(s: String): immutable.StringView = new immutable.StringView(s)
/** Convert String to Seq. Lower priority than StringOps */
implicit def stringToSeq(s: String): immutable.WrappedString = new immutable.WrappedString(s)
}

0 comments on commit b871ac2

Please sign in to comment.