package breeze.linalg.support

import breeze.math.Complex



/**
 * Marker for being able to transform the keys and values in a value collection
 * to new values.
 *
 * @author dramage
 * @author dlwh
 */
trait CanTransformValues[From, @specialized(Double, Int, Float) A] {
  /**Transforms all key-value pairs from the given collection. */
  def transform(from: From, fn: (A => A))

  /**Transforms all active key-value pairs from the given collection. */
  def transformActive(from: From, fn: (A => A))
}



object CanTransformValues {
  type Op[From, A] = CanTransformValues[From, A]

  //
  // Arrays
  //

  class OpArray[@specialized(Double, Int, Float, Long) A]
    extends Op[Array[A], A] {

    /**Transforms all values from the given collection. */
    def transform(from: Array[A], fn: (A) => A) {
      import spire.syntax.cfor._
      cforRange(0 until from.length) { i =>
        from(i) = fn(from(i))
      }
    }

    /**Transforms all active key-value pairs from the given collection. */
    def transformActive(from: Array[A], fn: (A) => A) { transform(from, fn)}
  }


  implicit def opArray[@specialized A] =
    new OpArray[A]

  implicit object OpArrayII extends OpArray[Int]

  implicit object OpArraySS extends OpArray[Short]

  implicit object OpArrayLL extends OpArray[Long]

  implicit object OpArrayFF extends OpArray[Float]

  implicit object OpArrayDD extends OpArray[Double]

  implicit object OpArrayCC extends OpArray[Complex]
}