All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.scalactic.anyvals.NonEmptyString.scala Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2001-2013 Artima, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.scalactic.anyvals

import scala.annotation.unchecked.{ uncheckedVariance => uV }
import scala.collection.GenIterable
import scala.collection.GenSeq
import scala.collection.GenTraversableOnce
import scala.collection.generic.CanBuildFrom
import scala.collection.mutable.Buffer
import scala.reflect.ClassTag
import scala.collection.immutable
import scala.collection.mutable.ArrayBuffer
import org.scalactic.Every
import org.scalactic.Resources


// Can't be a LinearSeq[T] because Builder would be able to create an empty one.
/**
  * A non-empty list: an ordered, immutable, non-empty collection of elements with LinearSeq performance characteristics.
  *
  * 

* The purpose of NonEmptyString is to allow you to express in a type that a String is non-empty, thereby eliminating the * need for (and potential exception from) a run-time check for non-emptiness. For a non-empty sequence with IndexedSeq * performance, see Every. *

* *

Constructing NonEmptyStrings

* *

* You can construct a NonEmptyString by passing one or more elements to the NonEmptyString.apply factory method: *

* *
  * scala> NonEmptyString(1, 2, 3)
  * res0: org.scalactic.anyvals.NonEmptyString[Int] = NonEmptyString(1, 2, 3)
  * 
* *

* Alternatively you can cons elements onto the End singleton object, similar to making a String starting with Nil: *

* *
  * scala> 1 :: 2 :: 3 :: Nil
  * res0: String[Int] = String(1, 2, 3)
  *
  * scala> 1 :: 2 :: 3 :: End
  * res1: org.scalactic.NonEmptyString[Int] = NonEmptyString(1, 2, 3)
  * 
* *

* Note that although Nil is a String[Nothing], End is * not a NonEmptyString[Nothing], because no empty NonEmptyString exists. (A non-empty list is a series * of connected links; if you have no links, you have no non-empty list.) *

* *
  * scala> val nil: String[Nothing] = Nil
  * nil: String[Nothing] = String()
  *
  * scala> val nada: NonEmptyString[Nothing] = End
  * <console>:16: error: type mismatch;
  * found   : org.scalactic.anyvals.End.type
  * required: org.scalactic.anyvals.NonEmptyString[Nothing]
  *        val nada: NonEmptyString[Nothing] = End
  *                                          ^
  * 
* *

Working with NonEmptyStrings

* *

* NonEmptyString does not extend Scala's Seq or Traversable traits because these require that * implementations may be empty. For example, if you invoke tail on a Seq that contains just one element, * you'll get an empty Seq: *

* *
  * scala> String(1).tail
  * res6: String[Int] = String()
  * 
* *

* On the other hand, many useful methods exist on Seq that when invoked on a non-empty Seq are guaranteed * to not result in an empty Seq. For convenience, NonEmptyString defines a method corresponding to every such Seq * method. Here are some examples: *

* *
  * NonEmptyString(1, 2, 3).map(_ + 1)                        // Result: NonEmptyString(2, 3, 4)
  * NonEmptyString(1).map(_ + 1)                              // Result: NonEmptyString(2)
  * NonEmptyString(1, 2, 3).containsSlice(NonEmptyString(2, 3)) // Result: true
  * NonEmptyString(1, 2, 3).containsSlice(NonEmptyString(3, 4)) // Result: false
  * NonEmptyString(-1, -2, 3, 4, 5).minBy(_.abs)              // Result: -1
  * 
* *

* NonEmptyString does not currently define any methods corresponding to Seq methods that could result in * an empty Seq. However, an implicit converison from NonEmptyString to String * is defined in the NonEmptyString companion object that will be applied if you attempt to call one of the missing methods. As a * result, you can invoke filter on an NonEmptyString, even though filter could result * in an empty sequence—but the result type will be String instead of NonEmptyString: *

* *
  * NonEmptyString(1, 2, 3).filter(_ < 10) // Result: String(1, 2, 3)
  * NonEmptyString(1, 2, 3).filter(_ > 10) // Result: String()
  * 
* * *

* You can use NonEmptyStrings in for expressions. The result will be an NonEmptyString unless * you use a filter (an if clause). Because filters are desugared to invocations of filter, the * result type will switch to a String at that point. Here are some examples: *

* *
  * scala> import org.scalactic.anyvals._
  * import org.scalactic.anyvals._
  *
  * scala> for (i <- NonEmptyString(1, 2, 3)) yield i + 1
  * res0: org.scalactic.anyvals.NonEmptyString[Int] = NonEmptyString(2, 3, 4)
  *
  * scala> for (i <- NonEmptyString(1, 2, 3) if i < 10) yield i + 1
  * res1: String[Int] = String(2, 3, 4)
  *
  * scala> for {
  *      |   i <- NonEmptyString(1, 2, 3)
  *      |   j <- NonEmptyString('a', 'b', 'c')
  *      | } yield (i, j)
  * res3: org.scalactic.anyvals.NonEmptyString[(Int, Char)] =
  *         NonEmptyString((1,a), (1,b), (1,c), (2,a), (2,b), (2,c), (3,a), (3,b), (3,c))
  *
  * scala> for {
  *      |   i <- NonEmptyString(1, 2, 3) if i < 10
  *      |   j <- NonEmptyString('a', 'b', 'c')
  *      | } yield (i, j)
  * res6: String[(Int, Char)] =
  *         String((1,a), (1,b), (1,c), (2,a), (2,b), (2,c), (3,a), (3,b), (3,c))
  * 
* */ final class NonEmptyString private (val theString: String) extends AnyVal { /** * Returns a new NonEmptyString containing this NonEmptyString followed by the passed NonEmptyString. * * @param other the NonEmptyString to append * @return a new NonEmptyString that contains this NonEmptyString followed by other. */ def ++(other: NonEmptyString): NonEmptyString = new NonEmptyString(theString ++ other.theString) /** * Returns a new NonEmptyString containing this NonEmptyString followed by the characters of the passed Every. * * @param other the Every of Char to append * @return a new NonEmptyString that contains this NonEmptyString followed by all characters of other. */ def ++(other: Every[Char]): NonEmptyString = new NonEmptyString(theString ++ other.mkString) // TODO: Have I added these extra ++, etc. methods to Every that take a NonEmptyString? /** * Returns a new NonEmptyString containing this NonEmptyString followed by the characters of the passed GenTraversableOnce. * * @param other the GenTraversableOnce of Char to append * @return a new NonEmptyString that contains this NonEmptyString followed by all characters of other. */ def ++(other: GenTraversableOnce[Char]): NonEmptyString = if (other.isEmpty) this else new NonEmptyString(theString ++ other.mkString) /** * Returns a new NonEmptyString with the given character prepended. * *

* Note that :-ending operators are right associative. A mnemonic for +: vs. :+ is: the COLon goes on the COLlection side. *

* * @param c the character to prepend to this NonEmptyString * @return a new NonEmptyString consisting of c followed by all characters of this NonEmptyString. */ final def +:(c: Char): NonEmptyString = new NonEmptyString(c +: theString) /** * Returns a new NonEmptyString with the given character appended. * *

* Note a mnemonic for +: vs. :+ is: the COLon goes on the COLlection side. *

* * @param c the character to append to this NonEmptyString * @return a new NonEmptyString consisting of all characters of this NonEmptyString followed by the given c. */ def :+(c: Char): NonEmptyString = new NonEmptyString(theString :+ c) /** * Appends all characters of this NonEmptyString to a string builder. The written text will consist of a concatenation of the result of invoking toString * on of every element of this NonEmptyString, without any separator string. * * @param sb the string builder to which characters will be appended * @return the string builder, sb, to which elements were appended. */ final def addString(sb: StringBuilder): StringBuilder = theString.addString(sb) /** * Appends all characters of this NonEmptyString to a string builder using a separator string. The written text will consist of a concatenation of the * result of invoking toString * on of every character of this NonEmptyString, separated by the string sep. * * @param sb the string builder to which characters will be appended * @param sep the separator string * @return the string builder, sb, to which characters were appended. */ final def addString(sb: StringBuilder, sep: String): StringBuilder = theString.addString(sb, sep) /** * Appends all characters of this NonEmptyString to a string builder using start, end, and separator strings. The written text will consist of a concatenation of * the string start; the result of invoking toString on all characters of this NonEmptyString, * separated by the string sep; and the string end * * @param sb the string builder to which characters will be appended * @param start the starting string * @param sep the separator string * @param end the ending string * @return the string builder, sb, to which characters were appended. */ final def addString(sb: StringBuilder, start: String, sep: String, end: String): StringBuilder = theString.addString(sb, start, sep, end) /** * Selects a character by its index in the NonEmptyString. * * @return the character of this NonEmptyString at index idx, where 0 indicates the first element. */ final def apply(idx: Int): Char = theString(idx) /** * Gets a character by its index in the NonEmptyString. * * @return the character of this NonEmptyString at index idx, where 0 indicates the first element. */ final def charAt(idx: Int): Char = theString.charAt(idx) /** * Finds the first character of this NonEmptyString for which the given partial function is defined, if any, and applies the partial function to it. * * @param pf the partial function * @return an Option containing pf applied to the first character for which it is defined, or None if * the partial function was not defined for any character. */ final def collectFirst[U](pf: PartialFunction[Char, U]): Option[U] = theString.collectFirst(pf) /** * Indicates whether this NonEmptyString contains a given value as an character. * * @param c the element to look for * @return true if this NonEmptyString has an character that is equal (as determined by ==) to c, false otherwise. */ final def contains(c: Char): Boolean = theString.contains(c) /** * Indicates whether this NonEmptyString contains a given GenSeq of characters as a slice. * * @param that the GenSeq character slice to look for * @return true if this NonEmptyString contains a slice with the same characters as that, otherwise false. */ final def containsSlice(that: GenSeq[Char]): Boolean = theString.containsSlice(that) /** * Indicates whether this NonEmptyString contains a given Every of character as a slice. * * @param that the Every character slice to look for * @return true if this NonEmptyString contains a character slice with the same characters as that, otherwise false. */ final def containsSlice(that: Every[Char]): Boolean = theString.containsSlice(that.toVector) /** * Indicates whether this NonEmptyString contains a given NonEmptyString as a slice. * * @param that the NonEmptyString slice to look for * @return true if this NonEmptyString contains a slice with the same characters as that, otherwise false. */ final def containsSlice(that: NonEmptyString): Boolean = theString.containsSlice(that.theString) /** * Copies characters of this NonEmptyString to an array. Fills the given array arr with characters of this NonEmptyString. Copying * will stop once either the end of the current NonEmptyString is reached, or the end of the array is reached. * * @param arr the array to fill */ final def copyToArray(arr: Array[Char]): Unit = theString.copyToArray(arr, 0) /** * Copies characters of this NonEmptyString to an array. Fills the given array arr with characters of this NonEmptyString, beginning at * index start. Copying will stop once either the end of the current NonEmptyString is reached, or the end of the array is reached. * * @param arr the array to fill * @param start the starting index */ final def copyToArray(arr: Array[Char], start: Int): Unit = theString.copyToArray(arr, start) /** * Copies characters of this NonEmptyString to an array. Fills the given array arr with at most len characters of this NonEmptyString, beginning at * index start. Copying will stop once either the end of the current NonEmptyString is reached, the end of the array is reached, or * len elements have been copied. * * @param arr the array to fill * @param start the starting index * @param len the maximum number of elements to copy */ final def copyToArray(arr: Array[Char], start: Int, len: Int): Unit = theString.copyToArray(arr, start, len) /** * Copies all characters of this NonEmptyString to a buffer. * * @param buf the buffer to which characters are copied */ final def copyToBuffer(buf: Buffer[Char]): Unit = theString.copyToBuffer(buf) /** * Indicates whether every character of this NonEmptyString relates to the corresponding element of a given GenSeq by satisfying a given predicate. * * @tparam B the type of the elements of that * @param that the GenSeq to compare for correspondence * @param p the predicate, which relates elements from this NonEmptyString and the passed GenSeq * @return true if this NonEmptyString and the passed GenSeq have the same length and p(x, y) is true * for all corresponding elements x of this NonEmptyString and y of that, otherwise false. */ final def corresponds[B](that: GenSeq[B])(p: (Char, B) => Boolean): Boolean = theString.corresponds(that)(p) /** * Indicates whether every character of this NonEmptyString relates to the corresponding element of a given Every by satisfying a given predicate. * * @tparam B the type of the elements of that * @param that the Every to compare for correspondence * @param p the predicate, which relates elements from this NonEmptyString and the passed Every * @return true if this NonEmptyString and the passed Every have the same length and p(x, y) is true * for all corresponding elements x of this NonEmptyString and y of that, otherwise false. */ final def corresponds[B](that: Every[B])(p: (Char, B) => Boolean): Boolean = theString.corresponds(that.toVector)(p) /** * Indicates whether every character of this NonEmptyString relates to the corresponding character of a given NonEmptyString by satisfying a given predicate. * * @param that the NonEmptyString to compare for correspondence * @param p the predicate, which relates elements from this and the passed NonEmptyString * @return true if this and the passed NonEmptyString have the same length and p(x, y) is true * for all corresponding characters x of this NonEmptyString and y of that, otherwise false. */ final def corresponds(that: NonEmptyString)(p: (Char, Char) => Boolean): Boolean = theString.corresponds(that.theString)(p) /** * Counts the number of characters in this NonEmptyString that satisfy a predicate. * * @param p the predicate used to test characters. * @return the number of characters satisfying the predicate p. */ final def count(p: Char => Boolean): Int = theString.count(p) /** * Builds a new NonEmptyString from this NonEmptyString without any duplicate characters. * * @return A new NonEmptyString that contains the first occurrence of every character of this NonEmptyString. */ final def distinct: NonEmptyString = new NonEmptyString(theString.distinct) /** * Indicates whether this NonEmptyString ends with the given GenSeq of Char. * * @param that the sequence to test * @return true if this NonEmptyString has that as a suffix, false otherwise. */ final def endsWith[B](that: GenSeq[B]): Boolean = theString.endsWith(that) /** * Indicates whether this NonEmptyString ends with the given Every. * * @param that the Every to test * @return true if this NonEmptyString has that as a suffix, false otherwise. */ final def endsWith[B](that: Every[B]): Boolean = theString.endsWith(that.toVector) // TODO: Search for that: Every in here and add a that: NonEmptyString in Every. /** * Indicates whether this NonEmptyString ends with the given NonEmptyString. * * @param that the NonEmptyString to test * @return true if this NonEmptyString has that as a suffix, false otherwise. */ final def endsWith(that: NonEmptyString): Boolean = theString.endsWith(that.theString) /* override def equals(o: Any): Boolean = o match { case nonEmptyString: NonEmptyString[_] => toString == nonEmptyString.toString case _ => false } */ /** * Indicates whether a predicate holds for at least one of the characters of this NonEmptyString. * * @param p the predicate used to test characters. * @return true if the given predicate p holds for some of the elements of this NonEmptyString, otherwise false. */ final def exists(p: Char => Boolean): Boolean = theString.exists(p) /** * Finds the first character of this NonEmptyString that satisfies the given predicate, if any. * * @param p the predicate used to test characters * @return an Some containing the first character in this NonEmptyString that satisfies p, or None if none exists. */ final def find(p: Char => Boolean): Option[Char] = theString.find(p) /** * Builds a new NonEmptyString by applying a function to all characters of this NonEmptyString and using the characters of the resulting NonEmptyStrings. * * @param f the function to apply to each character. * @return a new NonEmptyString containing characters obtained by applying the given function f to each character of this NonEmptyString and concatenating * the characters of resulting NonEmptyStrings. */ final def flatMap(f: Char => NonEmptyString): NonEmptyString = { val buf = new ArrayBuffer[Char] for (c <- theString) buf ++= f(c).theString new NonEmptyString(buf.mkString) } /** * Folds the characters of this NonEmptyString using the specified associative binary operator. * *

* The order in which operations are performed on characters is unspecified and may be nondeterministic. *

* * @param z a neutral character for the fold operation; may be added to the result an arbitrary number of * times, and must not change the result (e.g., Nil for list concatenation, * 0 for addition, or 1 for multiplication.) * @param op a binary operator that must be associative * @return the result of applying fold operator op between all the elements and z */ final def fold(z: Char)(op: (Char, Char) => Char): Char = theString.fold(z)(op) /** * Applies a binary operator to a start value and all characters of this NonEmptyString, going left to right. * * @tparam B the result type of the binary operator. * @param z the start value. * @param op the binary operator. * @return the result of inserting op between consecutive characters of this NonEmptyString, going left to right, with the start value, * z, on the left: * *
    * op(...op(op(z, x_1), x_2), ..., x_n)
    * 
* *

* where x1, ..., xn are the elements of this NonEmptyString. *

*/ final def foldLeft[B](z: B)(op: (B, Char) => B): B = theString.foldLeft(z)(op) /** * Applies a binary operator to all characters of this NonEmptyString and a start value, going right to left. * * @tparam B the result of the binary operator * @param z the start value * @param op the binary operator * @return the result of inserting op between consecutive characters of this NonEmptyString, going right to left, with the start value, * z, on the right: * *
    * op(x_1, op(x_2, ... op(x_n, z)...))
    * 
* *

* where x1, ..., xn are the elements of this NonEmptyString. *

*/ final def foldRight[B](z: B)(op: (Char, B) => B): B = theString.foldRight(z)(op) /** * Indicates whether a predicate holds for all characters of this NonEmptyString. * * @param p the predicate used to test characters. * @return true if the given predicate p holds for all characters of this NonEmptyString, otherwise false. */ final def forall(p: Char => Boolean): Boolean = theString.forall(p) /** * Applies a function f to all characters of this NonEmptyString. * * @param f the function that is applied for its side-effect to every character. The result of function f is discarded. */ final def foreach(f: Char => Unit): Unit = theString.foreach(f) /** * Partitions this NonEmptyString into a map of NonEmptyStrings according to some discriminator function. * * @tparam K the type of keys returned by the discriminator function. * @param f the discriminator function. * @return A map from keys to NonEmptyStrings such that the following invariant holds: * *
    * (nonEmptyString.toString partition f)(k) = xs filter (x => f(x) == k)
    * 
* *

* That is, every key k is bound to a NonEmptyString of those elements x for which f(x) equals k. *

*/ final def groupBy[K](f: Char => K): Map[K, NonEmptyString] = { val mapKToString = theString.groupBy(f) mapKToString.mapValues { list => new NonEmptyString(list) }.toMap } /** * Partitions characters into fixed size NonEmptyStrings. * * @param size the number of characters per group * @return An iterator producing NonEmptyStrings of size size, except the last will be truncated if the characters don't divide evenly. */ final def grouped(size: Int): Iterator[NonEmptyString] = { if (size > 0) { val itOfString = theString.grouped(size) itOfString.map { list => new NonEmptyString(list) } } else throw new IllegalArgumentException(Resources.invalidSize(size)) } /** * Returns true to indicate this NonEmptyString has a definite size, since all NonEmptyStrings are strict collections. */ final def hasDefiniteSize: Boolean = true // override def hashCode: Int = toString.hashCode /** * Selects the first character of this NonEmptyString. * * @return the first character of this NonEmptyString. */ final def head: Char = theString.head // Methods like headOption I can't get rid of because of the implicit conversion to GenTraversable. // Users can call any of the methods I've left out on a NonEmptyString, and get whatever String would return // for that method call. Eventually I'll probably implement them all to save the implicit conversion. /** * Selects the first character of this NonEmptyString and returns it wrapped in a Some. * * @return the first character of this NonEmptyString, wrapped in a Some. */ final def headOption: Option[Char] = theString.headOption /** * Finds index of first occurrence of some value in this NonEmptyString. * * @param c the character value to search for. * @return the index of the first character of this NonEmptyString that is equal (as determined by ==) to c, * or -1, if none exists. */ final def indexOf(c: Char): Int = theString.indexOf(c, 0) /** * Finds index of first occurrence of some value in this NonEmptyString after or at some start index. * * @param c the character value to search for. * @param from the start index * @return the index >= from of the first element of this NonEmptyString that is equal (as determined by ==) to elem, * or -1, if none exists. */ final def indexOf(c: Char, from: Int): Int = theString.indexOf(c, from) /** * Finds first index where this NonEmptyString contains a given GenSeq[Char] as a slice. * * @param that the GenSeq[Char] defining the slice to look for * @return the first index at which the elements of this NonEmptyString starting at that index match the characters of * GenSeq that, or -1 of no such subsequence exists. */ final def indexOfSlice(that: GenSeq[Char]): Int = theString.indexOfSlice(that) /** * Finds first index after or at a start index where this NonEmptyString contains a given GenSeq[Char] as a slice. * * @param that the GenSeq[Char] defining the slice to look for * @param from the start index * @return the first index >= from at which the characters of this NonEmptyString starting at that index match the characters of * GenSeq[Char] that, or -1 of no such subsequence exists. */ final def indexOfSlice(that: GenSeq[Char], from: Int): Int = theString.indexOfSlice(that, from) /** * Finds first index where this NonEmptyString contains a given Every as a slice. * * @param that the Every defining the slice to look for * @return the first index such that the characters of this NonEmptyString starting at this index match the characters of * Every that, or -1 of no such subsequence exists. */ final def indexOfSlice(that: Every[Char]): Int = theString.indexOfSlice(that.toVector) /** * Finds first index where this NonEmptyString contains a given NonEmptyString as a slice. * * @param that the NonEmptyString defining the slice to look for * @return the first index such that the characters of this NonEmptyString starting at this index match the characters of * NonEmptyString that, or -1 of no such subsequence exists. */ final def indexOfSlice(that: NonEmptyString): Int = theString.indexOfSlice(that.theString) /** * Finds first index after or at a start index where this NonEmptyString contains a given Every as a slice. * * @param that the Every defining the slice to look for * @param from the start index * @return the first index >= from such that the characters of this NonEmptyString starting at this index match the characters of * Every that, or -1 of no such subsequence exists. */ final def indexOfSlice(that: Every[Char], from: Int): Int = theString.indexOfSlice(that.toVector, from) /** * Finds first index after or at a start index where this NonEmptyString contains a given NonEmptyString as a slice. * * @param that the NonEmptyString defining the slice to look for * @param from the start index * @return the first index >= from such that the characters of this NonEmptyString starting at this index match the characters of * NonEmptyString that, or -1 of no such subsequence exists. */ final def indexOfSlice(that: NonEmptyString, from: Int): Int = theString.indexOfSlice(that.theString, from) /** * Finds index of the first character satisfying some predicate. * * @param p the predicate used to test characters. * @return the index of the first character of this NonEmptyString that satisfies the predicate p, * or -1, if none exists. */ final def indexWhere(p: Char => Boolean): Int = theString.indexWhere(p) /** * Finds index of the first character satisfying some predicate after or at some start index. * * @param p the predicate used to test characters. * @param from the start index * @return the index >= from of the first character of this NonEmptyString that satisfies the predicate p, * or -1, if none exists. */ final def indexWhere(p: Char => Boolean, from: Int): Int = theString.indexWhere(p, from) /** * Produces the range of all indices of this NonEmptyString. * * @return a Range value from 0 to one less than the length of this NonEmptyString. */ final def indices: Range = theString.indices /** * Tests whether this NonEmptyString contains given index. * * @param idx the index to test * @return true if this NonEmptyString contains an character at position idx, false otherwise. */ final def isDefinedAt(idx: Int): Boolean = theString.isDefinedAt(idx) /** * Returns false to indicate this NonEmptyString, like all NonEmptyStrings, is non-empty. * * @return false */ final def isEmpty: Boolean = false /** * Returns true to indicate this NonEmptyString, like all NonEmptyStrings, can be traversed repeatedly. * * @return true */ final def isTraversableAgain: Boolean = true /** * Creates and returns a new iterator over all characters contained in this NonEmptyString. * * @return the new iterator */ final def iterator: Iterator[Char] = theString.iterator /** * Selects the last character of this NonEmptyString. * * @return the last character of this NonEmptyString. */ final def last: Char = theString.last /** * Finds the index of the last occurrence of some value in this NonEmptyString. * * @param c the character value to search for. * @return the index of the last character of this NonEmptyString that is equal (as determined by ==) to c, * or -1, if none exists. */ final def lastIndexOf(c: Char): Int = theString.lastIndexOf(c) /** * Finds the index of the last occurrence of some value in this NonEmptyString before or at a given end index. * * @param c the character value to search for. * @param end the end index. * @return the index >= end of the last character of this NonEmptyString that is equal (as determined by ==) * to elem, or -1, if none exists. */ final def lastIndexOf(c: Char, end: Int): Int = theString.lastIndexOf(c, end) /** * Finds the last index where this NonEmptyString contains a given GenSeq as a slice. * * @param that the GenSeq defining the slice to look for * @return the last index at which the elements of this NonEmptyString starting at that index match the characters of * GenSeq that, or -1 of no such subsequence exists. */ final def lastIndexOfSlice(that: GenSeq[Char]): Int = theString.lastIndexOfSlice(that) /** * Finds the last index before or at a given end index where this NonEmptyString contains a given GenSeq as a slice. * * @param that the GenSeq defining the slice to look for * @param end the end index * @return the last index >= end at which the elements of this NonEmptyString starting at that index match the characters of * GenSeq that, or -1 of no such subsequence exists. */ final def lastIndexOfSlice(that: GenSeq[Char], end: Int): Int = theString.lastIndexOfSlice(that, end) /** * Finds the last index where this NonEmptyString contains a given Every as a slice. * * @param that the Every defining the slice to look for * @return the last index at which the elements of this NonEmptyString starting at that index match the characters of * Every that, or -1 of no such subsequence exists. */ final def lastIndexOfSlice(that: Every[Char]): Int = theString.lastIndexOfSlice(that.toVector) /** * Finds the last index where this NonEmptyString contains a given NonEmptyString as a slice. * * @param that the NonEmptyString defining the slice to look for * @return the last index at which the elements of this NonEmptyString starting at that index match the characters of * NonEmptyString that, or -1 of no such subsequence exists. */ final def lastIndexOfSlice(that: NonEmptyString): Int = theString.lastIndexOfSlice(that.theString) /** * Finds the last index before or at a given end index where this NonEmptyString contains a given Every as a slice. * * @param that the Every defining the slice to look for * @param end the end index * @return the last index >= end at which the elements of this NonEmptyString starting at that index match the characters of * Every that, or -1 of no such subsequence exists. */ final def lastIndexOfSlice(that: Every[Char], end: Int): Int = theString.lastIndexOfSlice(that.toVector, end) /** * Finds the last index before or at a given end index where this NonEmptyString contains a given NonEmptyString as a slice. * * @param that the NonEmptyString defining the slice to look for * @param end the end index * @return the last index >= end at which the characters of this NonEmptyString starting at that index match the characters of * NonEmptyString that, or -1 of no such subsequence exists. */ final def lastIndexOfSlice(that: NonEmptyString, end: Int): Int = theString.lastIndexOfSlice(that.theString, end) /** * Finds index of last character satisfying some predicate. * * @param p the predicate used to test characters. * @return the index of the last character of this NonEmptyString that satisfies the predicate p, or -1, if none exists. */ final def lastIndexWhere(p: Char => Boolean): Int = theString.lastIndexWhere(p) /** * Finds index of last character satisfying some predicate before or at given end index. * * @param p the predicate used to test characters. * @param end the end index * @return the index >= end of the last character of this NonEmptyString that satisfies the predicate p, * or -1, if none exists. */ final def lastIndexWhere(p: Char => Boolean, end: Int): Int = theString.lastIndexWhere(p, end) /** * Returns the last element of this NonEmptyString, wrapped in a Some. * * @return the last element, wrapped in a Some. */ final def lastOption: Option[Char] = theString.lastOption // Will always return a Some /** * The length of this NonEmptyString. * *

* Note: length and size yield the same result, which will be >= 1. *

* * @return the number of characters in this NonEmptyString. */ final def length: Int = theString.length /** * Compares the length of this NonEmptyString to a test value. * * @param len the test value that gets compared with the length. * @return a value x where * *
    * x < 0 if this.length < len
    * x == 0 if this.length == len
    * x > 0 if this.length > len
    * 
*/ final def lengthCompare(len: Int): Int = theString.lengthCompare(len) /** * Builds a new NonEmptyString by applying a function to all characters of this NonEmptyString. * * @tparam U the character type of the returned NonEmptyString. * @param f the function to apply to each character. * @return a new NonEmptyString resulting from applying the given function f to each character of this NonEmptyString and collecting the results. */ final def map[U](f: Char => U): NonEmptyString = { //NonEmptyString("test") new NonEmptyString( theString.map { c => f(c).toString }.mkString ) } /** * Finds the largest character. * * @return the largest element of this NonEmptyString. */ final def max(implicit cmp: Ordering[Char]): Char = theString.max(cmp) /** * Finds the largest result after applying the given function to every character. * * @return the largest result of applying the given function to every character of this NonEmptyString. */ final def maxBy[U](f: Char => U)(implicit cmp: Ordering[U]): Char = theString.maxBy(f)(cmp) /** * Finds the smallest character. * * @return the smallest character of this NonEmptyString. */ final def min(implicit cmp: Ordering[Char]): Char = theString.min(cmp) /** * Finds the smallest result after applying the given function to every character. * * @return the smallest result of applying the given function to every character of this NonEmptyString. */ final def minBy[U](f: Char => U)(implicit cmp: Ordering[U]): Char = theString.minBy(f)(cmp) /** * Displays all characters of this NonEmptyString in a string. * * @return a string representation of this NonEmptyString. In the resulting string, the result of invoking toString on all characters of this * NonEmptyString follow each other without any separator string. */ final def mkString: String = theString.mkString /** * Displays all elements of this NonEmptyString in a string using a separator string. * * @param sep the separator string * @return a string representation of this NonEmptyString. In the resulting string, the result of invoking toString on all elements of this * NonEmptyString are separated by the string sep. */ final def mkString(sep: String): String = theString.mkString(sep) /** * Displays all characters of this NonEmptyString in a string using start, end, and separator strings. * * @param start the starting string. * @param sep the separator string. * @param end the ending string. * @return a string representation of this NonEmptyString. The resulting string begins with the string start and ends with the string * end. Inside, In the resulting string, the result of invoking toString on all characters of this NonEmptyString are * separated by the string sep. */ final def mkString(start: String, sep: String, end: String): String = theString.mkString(start, sep, end) /** * Returns true to indicate this NonEmptyString, like all NonEmptyStrings, is non-empty. * * @return true */ final def nonEmpty: Boolean = true /** * A copy of this NonEmptyString with an element value appended until a given target length is reached. * * @param len the target length * @param c the padding character * @return a new NonEmptyString consisting of all characters of this NonEmptyString followed by the minimal number of occurrences * of elem so that the resulting NonEmptyString has a length of at least len. */ final def padTo(len: Int, c: Char): NonEmptyString = new NonEmptyString(theString.padTo(len, c)) /** * Produces a new NonEmptyString where a slice of characters in this NonEmptyString is replaced by another NonEmptyString * * @param from the index of the first replaced character * @param that the NonEmptyString whose characters should replace a slice in this NonEmptyString * @param replaced the number of characters to drop in the original NonEmptyString */ final def patch(from: Int, that: NonEmptyString, replaced: Int): NonEmptyString = new NonEmptyString(theString.patch(from, that.theString, replaced)) /** * Iterates over distinct permutations. * *

* Here's an example: *

* *
    * NonEmptyString("abb").permutations.toList == list(NonEmptyString("abb"), NonEmptyString("bab"), NonEmptyString("bba"))
    * 
* * @return an iterator that traverses the distinct permutations of this NonEmptyString. */ final def permutations: Iterator[NonEmptyString] = { val it = theString.permutations it map { list => new NonEmptyString(list) } } /** * Returns the length of the longest prefix whose characters all satisfy some predicate. * * @param p the predicate used to test characters. * @return the length of the longest prefix of this NonEmptyString such that every characters * of the segment satisfies the predicate p. */ final def prefixLength(p: Char => Boolean): Int = theString.prefixLength(p) /** * The result of multiplying all the characters of this NonEmptyString. * *

* This method can be invoked for any NonEmptyString for which an implicit Numeric[T] exists. *

* * @return the product of all elements */ final def product(implicit num: Numeric[Char]): Char = theString.product(num) /** * Reduces the elements of this NonEmptyString using the specified associative binary operator. * *

* The order in which operations are performed on characters is unspecified and may be nondeterministic. *

* * @param op a binary operator that must be associative. * @return the result of applying reduce operator op between all the characters of this NonEmptyString. */ final def reduce(op: (Char, Char) => Char): Char = theString.reduce(op) /** * Applies a binary operator to all characters of this NonEmptyString, going left to right. * * @param op the binary operator. * @return the result of inserting op between consecutive characters of this NonEmptyString, going left to right: * *
    * op(...op(op(x_1, x_2), x_3), ..., x_n)
    * 
* *

* where x1, ..., xn are the characters of this NonEmptyString. *

*/ final def reduceLeft(op: (Char, Char) => Char): Char = theString.reduceLeft(op) /** * Applies a binary operator to all characters of this NonEmptyString, going left to right, returning the result in a Some. * * @param op the binary operator. * @return a Some containing the result of reduceLeft(op) *

*/ final def reduceLeftOption(op: (Char, Char) => Char): Option[Char] = theString.reduceLeftOption(op) final def reduceOption(op: (Char, Char) => Char): Option[Char] = theString.reduceOption(op) /** * Applies a binary operator to all characters of this NonEmptyString, going right to left. * * @param op the binary operator * @return the result of inserting op between consecutive characters of this NonEmptyString, going right to left: * *
    * op(x_1, op(x_2, ... op(x_{n-1}, x_n)...))
    * 
* *

* where x1, ..., xn are the elements of this NonEmptyString. *

*/ final def reduceRight(op: (Char, Char) => Char): Char = theString.reduceRight(op) /** * Applies a binary operator to all elements of this NonEmptyString, going right to left, returning the result in a Some. * * @param op the binary operator * @return a Some containing the result of reduceRight(op) */ final def reduceRightOption(op: (Char, Char) => Char): Option[Char] = theString.reduceRightOption(op) /** * Returns new NonEmptyString with characters in reverse order. * * @return a new NonEmptyString with all characters of this NonEmptyString in reversed order. */ final def reverse: NonEmptyString = new NonEmptyString(theString.reverse) /** * An iterator yielding characters in reverse order. * *

* Note: nonEmptyString.reverseIterator is the same as nonEmptyString.reverse.iterator, but might be more efficient. *

* * @return an iterator yielding the characters of this NonEmptyString in reversed order */ final def reverseIterator: Iterator[Char] = theString.reverseIterator /** * Builds a new GenIterable by applying a function to all characters of this NonEmptyString and collecting the results in reverse order. * *

* Note: nonEmptyString.reverseMap(f) is the same as nonEmptyString.reverse.map(f), but might be more efficient. *

* * @tparam U the element type of the returned GenIterable. * @param f the function to apply to each character. * @return a new GenIterable resulting from applying the given function f to each character of this NonEmptyString * and collecting the results in reverse order. */ final def reverseMap[U](f: Char => U): GenIterable[U] = theString.reverseMap(f) /** * Checks if the given GenIterable contains the same characters in the same order as this NonEmptyString. * * @param that the GenIterable with which to compare * @return true, if both this NonEmptyString and the given GenIterable contain the same characters * in the same order, false otherwise. */ final def sameElements(that: GenIterable[Char]): Boolean = theString.sameElements(that) /** * Checks if the given Every contains the same characters in the same order as this NonEmptyString. * * @param that the Every with which to compare * @return true, if both this and the given Every contain the same characters * in the same order, false otherwise. */ final def sameElements(that: Every[Char]): Boolean = theString.sameElements(that.toVector) /** * Checks if the given NonEmptyString contains the same characters in the same order as this NonEmptyString. * * @param that the NonEmptyString with which to compare * @return true, if both this and the given NonEmptyString contain the same characters * in the same order, false otherwise. */ final def sameElements(that: NonEmptyString): Boolean = theString.sameElements(that.theString) /** * Computes a prefix scan of the characters of this NonEmptyString. * *

* Note: The neutral character z may be applied more than once. *

* *

* Here are some examples: *

* *
    * NonEmptyString("123").scan(0)(_ + _) == NonEmptyString(0, 1, 3, 6)
    * NonEmptyString("123").scan("z")(_ + _.toString) == NonEmptyString("z", "z1", "z12", "z123")
    * 
* * @param z a neutral element for the scan operation; may be added to the result an arbitrary number of * times, and must not change the result (e.g., Nil for list concatenation, * 0 for addition, or 1 for multiplication.) * @param op a binary operator that must be associative * @return a new NonEmptyString containing the prefix scan of the elements in this NonEmptyString */ final def scan(z: Char)(op: (Char, Char) => Char): NonEmptyString = new NonEmptyString(theString.scan(z)(op).mkString) /** * Produces a NonEmptyString containing cumulative results of applying the operator going left to right. * *

* Here are some examples: *

* *
    * NonEmptyString("123").scanLeft(0)(_ + _.toString.toInt) == Vector(0, 1, 3, 6)
    * NonEmptyString("123").scanLeft("z")(_ + _) == Vector("z", "z1", "z12", "z123")
    * 
* * @tparam B the result type of the binary operator and type of the resulting NonEmptyString * @param z the start value. * @param op the binary operator. * @return a new NonEmptyString containing the intermediate results of inserting op between consecutive characters of this NonEmptyString, * going left to right, with the start value, z, on the left. */ final def scanLeft[B](z: B)(op: (B, Char) => B): GenIterable[B] = theString.scanLeft(z)(op) /** * Produces a NonEmptyString containing cumulative results of applying the operator going right to left. * *

* Here are some examples: *

* *
    * NonEmptyString("123").scanRight(0)(_.toString.toInt + _) == NonEmptyString(6, 5, 3, 0)
    * NonEmptyString("123").scanRight("z")(_ + _) == NonEmptyString("123z", "23z", "3z", "z")
    * 
* * @tparam B the result of the binary operator and type of the resulting NonEmptyString * @param z the start value * @param op the binary operator * @return a new NonEmptyString containing the intermediate results of inserting op between consecutive characters of this NonEmptyString, * going right to left, with the start value, z, on the right. */ final def scanRight[B](z: B)(op: (Char, B) => B): GenIterable[B] = theString.scanRight(z)(op) /** * Computes length of longest segment whose characters all satisfy some predicate. * * @param p the predicate used to test elements. * @param from the index where the search starts. * @return the length of the longest segment of this NonEmptyString starting from index from such that every character of the * segment satisfies the predicate p. */ final def segmentLength(p: Char => Boolean, from: Int): Int = theString.segmentLength(p, from) /** * Groups characters in fixed size blocks by passing a “sliding window” over them (as opposed to partitioning them, as is done in grouped.) * * @param size the number of characters per group * @return an iterator producing NonEmptyStrings of size size, except the last and the only element will be truncated * if there are fewer characters than size. */ final def sliding(size: Int): Iterator[NonEmptyString] = theString.sliding(size).map(new NonEmptyString(_)) /** * Groups characters in fixed size blocks by passing a “sliding window” over them (as opposed to partitioning them, as is done in grouped.), * moving the sliding window by a given step each time. * * @param size the number of characters per group * @param step the distance between the first characters of successive groups * @return an iterator producing NonEmptyStrings of size size, except the last and the only character will be truncated * if there are fewer characters than size. */ final def sliding(size: Int, step: Int): Iterator[NonEmptyString] = theString.sliding(size, step).map(new NonEmptyString(_)) /** * The size of this NonEmptyString. * *

* Note: length and size yield the same result, which will be >= 1. *

* * @return the number of characters in this NonEmptyString. */ final def size: Int = theString.size /** * Sorts this NonEmptyString according to the Ordering of the result of applying the given function to every character. * * @tparam U the target type of the transformation f, and the type where the Ordering ord is defined. * @param f the transformation function mapping elements to some other domain U. * @param ord the ordering assumed on domain U. * @return a NonEmptyString consisting of the elements of this NonEmptyString sorted according to the Ordering where * x < y if ord.lt(f(x), f(y)). */ final def sortBy[U](f: Char => U)(implicit ord: Ordering[U]): NonEmptyString = new NonEmptyString(theString.sortBy(f)) /** * Sorts this NonEmptyString according to a comparison function. * *

* The sort is stable. That is, characters that are equal (as determined by lt) appear in the same order in the * sorted NonEmptyString as in the original. *

* * @param lt the comparison function that tests whether its first argument precedes its second argument in the desired ordering. * @return a NonEmptyString consisting of the elements of this NonEmptyString sorted according to the comparison function lt. */ final def sortWith(lt: (Char, Char) => Boolean): NonEmptyString = new NonEmptyString(theString.sortWith(lt)) /** * Sorts this NonEmptyString according to an Ordering. * *

* The sort is stable. That is, elements that are equal (as determined by lt) appear in the same order in the * sorted NonEmptyString as in the original. *

* * @param ord the Ordering to be used to compare elements. * @return a NonEmptyString consisting of the characters of this NonEmptyString sorted according to the ordering defined by ord. */ final def sorted(implicit ord: Ordering[Char]): NonEmptyString = new NonEmptyString(theString.sorted(ord)) /** * Indicates whether this NonEmptyString starts with the given GenSeq. * * @param that the GenSeq slice to look for in this NonEmptyString * @return true if this NonEmptyString has that as a prefix, false otherwise. */ final def startsWith(that: GenSeq[Char]): Boolean = theString.startsWith(that.mkString) /** * Indicates whether this NonEmptyString starts with the given GenSeq at the given index. * * @param that the GenSeq slice to look for in this NonEmptyString * @param offset the index at which this NonEmptyString is searched. * @return true if this NonEmptyString has that as a slice at the index offset, false otherwise. */ final def startsWith(that: GenSeq[Char], offset: Int): Boolean = theString.startsWith(that, offset) /** * Indicates whether this NonEmptyString starts with the given Every. * * @param that the Every to test * @return true if this collection has that as a prefix, false otherwise. */ final def startsWith(that: Every[Char]): Boolean = theString.startsWith(that.mkString) /** * Indicates whether this NonEmptyString starts with the given NonEmptyString. * * @param that the NonEmptyString to test * @return true if this collection has that as a prefix, false otherwise. */ final def startsWith(that: NonEmptyString): Boolean = theString.startsWith(that.theString) /** * Indicates whether this NonEmptyString starts with the given Every at the given index. * * @param that the Every slice to look for in this NonEmptyString * @param offset the index at which this NonEmptyString is searched. * @return true if this NonEmptyString has that as a slice at the index offset, false otherwise. */ final def startsWith(that: Every[Char], offset: Int): Boolean = theString.startsWith(that.toVector, offset) /** * Indicates whether this NonEmptyString starts with the given NonEmptyString at the given index. * * @param that the NonEmptyString slice to look for in this NonEmptyString * @param offset the index at which this NonEmptyString is searched. * @return true if this NonEmptyString has that as a slice at the index offset, false otherwise. */ final def startsWith(that: NonEmptyString, offset: Int): Boolean = theString.startsWith(that.theString, offset) /** * Returns "NonEmptyString", the prefix of this object's toString representation. * * @return the string "NonEmptyString" */ def stringPrefix: String = "NonEmptyString" /** * The result of summing all the characters of this NonEmptyString. * *

* This method can be invoked for any NonEmptyString for which an implicit Numeric[Char] exists. *

* * @return the sum of all elements */ final def sum(implicit num: Numeric[Char]): Long = theString.sum(num) import scala.language.higherKinds /** * Converts this NonEmptyString into a collection of type Col by copying all elements. * * @tparam Col the collection type to build. * @return a new collection containing all elements of this NonEmptyString. */ final def to[Col[_]](factory: org.scalactic.ColCompatHelper.Factory[Char, Col[Char @ uV]]): Col[Char @ uV] = theString.to(factory) /** * Converts this NonEmptyString to an array. * * @return an array containing all characters of this NonEmptyString. A ClassTag must be available for the element type of this NonEmptyString. */ final def toArray(implicit classTag: ClassTag[Char]): Array[Char] = theString.toArray /** * Converts this NonEmptyString to a Vector. * * @return a Vector containing all characters of this NonEmptyString. */ final def toVector: Vector[Char] = theString.toVector /** * Converts this NonEmptyString to a mutable buffer. * * @return a buffer containing all characters of this NonEmptyString. */ final def toBuffer: Buffer[Char] = theString.toBuffer /** * Converts this NonEmptyString to an immutable IndexedSeq. * * @return an immutable IndexedSeq containing all characters of this NonEmptyString. */ final def toIndexedSeq: collection.immutable.IndexedSeq[Char] = theString.toVector /** * Converts this NonEmptyString to an iterable collection. * * @return an Iterable containing all characters of this NonEmptyString. */ final def toIterable: Iterable[Char] = theString.toIterable /** * Returns an Iterator over the elements in this NonEmptyString. * * @return an Iterator containing all characters of this NonEmptyString. */ final def toIterator: Iterator[Char] = theString.toIterator /** * Converts this NonEmptyString to a map. * *

* This method is unavailable unless the elements are members of Tuple2, each ((K, V)) becoming a key-value pair * in the map. Duplicate keys will be overwritten by later keys. *

* * @return a map of type immutable.Map[Int, Char] containing all index/character pairs of type (Int, Char) of this NonEmptyString. */ final def toMap: Map[Int, Char] = Map.empty[Int, Char] ++ theString.zipWithIndex.map(e => e._2 -> e._1) /** * Converts this NonEmptyString to an immutable IndexedSeq. * * @return an immutable IndexedSeq containing all characters of this NonEmptyString. */ final def toSeq: collection.immutable.Seq[Char] = theString /** * Converts this NonEmptyString to a set. * * @return a set containing all characters of this NonEmptyString. */ final def toSet: Set[Char] = theString.toSet /** * Converts this NonEmptyString to a stream. * * @return a stream containing all characters of this NonEmptyString. */ final def toStream: Stream[Char] = theString.toStream /** * Returns a string representation of this NonEmptyString. * * @return the string "NonEmptyString" followed by the result of invoking toString on * this NonEmptyString's elements, surrounded by parentheses. */ override def toString: String = stringPrefix + "(" + theString + ")" /** * Produces a new NonEmptyString that contains all characters of this NonEmptyString and also all characters of a given Every. * *

* nonEmptyStringX union everyY is equivalent to nonEmptyStringX ++ everyY. *

* *

* Another way to express this is that nonEmptyStringX union everyY computes the order-presevring multi-set union * of nonEmptyStringX and everyY. This union method is hence a counter-part of diff and intersect that * also work on multi-sets. *

* * @param that the Every to add. * @return a new NonEmptyString that contains all characters of this NonEmptyString followed by all characters of that Every. */ final def union(that: Every[Char]): NonEmptyString = new NonEmptyString((theString union that.toVector).mkString) /** * Produces a new NonEmptyString that contains all characters of this NonEmptyString and also all characters of a given NonEmptyString. * *

* nonEmptyStringX union nonEmptyStringY is equivalent to nonEmptyStringX ++ nonEmptyStringY. *

* *

* Another way to express this is that nonEmptyStringX union nonEmptyStringY computes the order-presevring multi-set union * of nonEmptyStringX and nonEmptyStringY. This union method is hence a counter-part of diff and intersect that * also work on multi-sets. *

* * @param that the NonEmptyString to add. * @return a new NonEmptyString that contains all elements of this NonEmptyString followed by all characters of that. */ final def union(that: NonEmptyString): NonEmptyString = new NonEmptyString((theString union that.theString).mkString) /** * Produces a new NonEmptyString that contains all characters of this NonEmptyString and also all characters of a given GenSeq. * *

* nonEmptyStringX union ys is equivalent to nonEmptyStringX ++ ys. *

* *

* Another way to express this is that nonEmptyStringX union ys computes the order-presevring multi-set union * of nonEmptyStringX and ys. This union method is hence a counter-part of diff and intersect that * also work on multi-sets. *

* * @param that the GenSeq to add. * @return a new NonEmptyString that contains all elements of this NonEmptyString followed by all elements of that GenSeq. */ final def union(that: GenSeq[Char]): NonEmptyString = new NonEmptyString((theString.union(that)).mkString) /** * Converts this NonEmptyString of pairs into two NonEmptyStrings of the first and second half of each pair. * * @tparam L the type of the first half of the character pairs * @tparam R the type of the second half of the character pairs * @param asPair an implicit conversion that asserts that the character type of this NonEmptyString is a pair. * @return a pair of NonEmptyStrings, containing the first and second half, respectively, of each character pair of this NonEmptyString. */ final def unzip[L, R](implicit asPair: Char => (L, R)): (GenIterable[L], GenIterable[R]) = { val unzipped = theString.unzip (unzipped._1, unzipped._2) } /** * Converts this NonEmptyString of triples into three NonEmptyStrings of the first, second, and and third character of each triple. * * @tparam L the type of the first member of the character triples * @tparam R the type of the second member of the character triples * @tparam R the type of the third member of the character triples * @param asTriple an implicit conversion that character that the character type of this NonEmptyString is a triple. * @return a triple of NonEmptyStrings, containing the first, second, and third member, respectively, of each character triple of this NonEmptyString. */ final def unzip3[L, M, R](implicit asTriple: Char => (L, M, R)): (GenIterable[L], GenIterable[M], GenIterable[R]) = { val unzipped = theString.unzip3 (unzipped._1, unzipped._2, unzipped._3) } /** * A copy of this NonEmptyString with one single replaced character. * * @param idx the position of the replacement * @param c the replacing character * @throws IndexOutOfBoundsException if the passed index is greater than or equal to the length of this NonEmptyString * @return a copy of this NonEmptyString with the character at position idx replaced by c. */ final def updated(idx: Int, c: Char): NonEmptyString = try new NonEmptyString(theString.updated(idx, c)) catch { case _: UnsupportedOperationException => throw new IndexOutOfBoundsException(idx.toString) } // This is needed for 2.10 support. Can drop after. // Because 2.11 throws IndexOutOfBoundsException. /** * Returns a NonEmptyString formed from this NonEmptyString and an iterable collection by combining corresponding * elements in pairs. If one of the two collections is shorter than the other, placeholder elements will be used to extend the * shorter collection to the length of the longer. * * @tparam O the element type of the other * @param other the Iterable providing the second half of each result pair * @param thisElem the element to be used to fill up the result if this NonEmptyString is shorter than that Iterable. * @param otherElem the element to be used to fill up the result if that Iterable is shorter than this NonEmptyString. * @return a new NonEmptyString containing pairs consisting of corresponding characters of this NonEmptyString and that. The * length of the returned collection is the maximum of the lengths of this NonEmptyString and that. If this NonEmptyString * is shorter than that, thisElem values are used to pad the result. If that is shorter than this * NonEmptyString, thatElem values are used to pad the result. */ final def zipAll[O](other: collection.Iterable[O], thisElem: Char, otherElem: O): GenIterable[(Char, O)] = theString.zipAll(other, thisElem, otherElem) /** * Returns a NonEmptyString formed from this NonEmptyString and another NonEmptyString combining corresponding * elements in pairs. If one of the two is shorter than the other, placeholder elements will be used to extend the * shorter collection to the length of the longer. * * @param other the NonEmptyString providing the second half of each result pair * @param thisElem the character to be used to fill up the result if this NonEmptyString is shorter than that NonEmptyString. * @param otherElem the character to be used to fill up the result if that Iterable is shorter than this NonEmptyString. * @return a new NonEmptyString containing pairs consisting of corresponding characters of this NonEmptyString and that. The * length of the returned collection is the maximum of the lengths of this NonEmptyString and that. If this NonEmptyString * is shorter than that, thisElem values are used to pad the result. If that is shorter than this * NonEmptyString, thatElem values are used to pad the result. */ final def zipAll(other: NonEmptyString, thisElem: Char, otherElem: Char): GenIterable[(Char, Char)] = theString.zipAll(other.theString, thisElem, otherElem) /** * Zips this NonEmptyString with its indices. * * @return A new NonEmptyString containing pairs consisting of all elements of this NonEmptyString paired with their index. Indices start at 0. */ final def zipWithIndex: Iterable[(Char, Int)] = theString.zipWithIndex } /** * Companion object for class NonEmptyString. */ object NonEmptyString { /** * Constructs a new NonEmptyString given at least one element. * * @param s the String represented by this NonEmptyString */ def apply(s: String): NonEmptyString = new NonEmptyString(s) /** * Constructs a new NonEmptyString given at least one character. * * @param firstChar the first character (with index 0) contained in this NonEmptyString * @param otherChars a varargs of zero or more other characters (with index 1, 2, 3, ...) contained in this NonEmptyString */ def apply(firstChar: Char, otherChars: Char*): NonEmptyString = new NonEmptyString(firstChar + otherChars.mkString) /** * Variable argument extractor for NonEmptyStrings. * * @param nonEmptyString: the NonEmptyString containing the elements to extract * @return an Seq containing this NonEmptyStrings elements, wrapped in a Some */ //def unapplySeq(nonEmptyString: NonEmptyString): Option[Seq[Char]] = Some(nonEmptyString.theString) def unapplySeq(nonEmptyString: NonEmptyString): Option[Seq[String]] = Some(Seq(nonEmptyString.theString)) /* // TODO: Figure out how to get case NonEmptyString() to not compile def unapplySeq[T](nonEmptyString: NonEmptyString[T]): Option[(T, Seq[T])] = Some(nonEmptyString.head, nonEmptyString.tail) */ /** * Optionally construct a NonEmptyString containing the characters, if any, of a given GenSeq. * * @param seq the GenSeq of Char with which to construct a NonEmptyString * @return a NonEmptyString containing the elements of the given GenSeq, if non-empty, wrapped in * a Some; else None if the GenSeq is empty */ def from[T](seq: GenSeq[Char]): Option[NonEmptyString] = seq.headOption match { case None => None case Some(first) => Some(new NonEmptyString(seq.mkString)) } import scala.language.implicitConversions /** * Implicit conversion from NonEmptyString to GenTraversableOnce[Char]. * *

* One use case for this implicit conversion is to enable GenSeq[NonEmptyString]s to be flattened. * Here's an example: *

* *
    * scala> Vector(NonEmptyString("123"), NonEmptyString("34"), NonEmptyString("5678")).flatten
    * res0: scala.collection.immutable.Vector[Char] = Vector('1', '2', '3', '3', '4', '5', '6', '7', '8')
    * 
* * @param nonEmptyString the NonEmptyString to convert to a GenTraversableOnce[Char] * @return a GenTraversableOnce[Char] containing the elements, in order, of this NonEmptyString */ implicit def nonEmptyStringToGenTraversableOnceOfChar(nonEmptyString: NonEmptyString): GenTraversableOnce[Char] = nonEmptyString.theString implicit def nonEmptyStringToPartialFunction(nonEmptyString: NonEmptyString): PartialFunction[Int, Char] = new PartialFunction[Int, Char] { def isDefinedAt(idx: Int): Boolean = nonEmptyString.theString.isDefinedAt(idx) def apply(idx: Int): Char = nonEmptyString.theString(idx) } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy