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

scala.scalanative.util.ScopedVar.scala Maven / Gradle / Ivy

There is a newer version: 0.5.5
Show newest version
package scala.scalanative
package util

import language.implicitConversions
import scala.annotation.nowarn

class ScopedVar[A] {
  import ScopedVar.Assignment

  private var init = false
  @nowarn("msg=`= _` has been deprecated")
  private var value: A = _

  def get: A = if (!init) throw ScopedVar.Unitialized() else value
  def :=(newValue: A): Assignment[A] = new Assignment(this, newValue)
  def isInitialized: Boolean = init
}

object ScopedVar {
  case class Unitialized() extends Exception

  class Assignment[T](scVar: ScopedVar[T], value: T) {
    private[ScopedVar] def push(): AssignmentStackElement[T] = {
      val stack = new AssignmentStackElement(scVar, scVar.init, scVar.value)
      scVar.init = true
      scVar.value = value
      stack
    }
  }

  private class AssignmentStackElement[T](
      scVar: ScopedVar[T],
      oldInit: Boolean,
      oldValue: T
  ) {
    private[ScopedVar] def pop(): Unit = {
      scVar.init = oldInit
      scVar.value = oldValue
    }
  }

  implicit def toValue[T](scVar: ScopedVar[T]): T = scVar.get

  @nowarn("msg=`_` is deprecated for wildcard arguments of types")
  def scoped[T](ass: Assignment[_]*)(body: => T): T = {
    val stack = ass.map(_.push())
    try body
    finally stack.reverse.foreach(_.pop())
  }
  // @nowarn("msg=The syntax `x: _\\*` is no longer supported for vararg splices")
  // @nowarn("msg=`_` is deprecated for wildcard arguments of types")
  @nowarn() // Cannot define multiple @nowarn annottations in Scala 2.12
  def scopedPushIf[T](
      shouldPushAssignments: Boolean
  )(lazyAssignments: => Seq[Assignment[_]])(body: => T): T = {
    if (shouldPushAssignments) scoped(lazyAssignments: _*)(body)
    else body
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy