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

commonMain.io.github.alexandrepiveteau.graphs.Edge.kt Maven / Gradle / Ivy

package io.github.alexandrepiveteau.graphs

import io.github.alexandrepiveteau.graphs.util.packInts
import io.github.alexandrepiveteau.graphs.util.unpackInt1
import io.github.alexandrepiveteau.graphs.util.unpackInt2
import kotlin.jvm.JvmInline
import kotlin.math.max
import kotlin.math.min

/** An undirected edge in a [UndirectedGraph] between two [Vertex]. */
@JvmInline
public value class Edge private constructor(private val encoded: Long) {

  /** Constructs a new [Edge] from the given [u] and [v] vertices. */
  // We use a long to encode the two vertices, and use the lower 32 bits for the first vertex, and
  // the upper 32 bits for the second vertex. The reason for storing the minimum vertex first is
  // that it allows us to use the standard [equals] and [hashCode] methods, which are based on the
  // underlying long value, and we're using this trick until typed equality for inline classes is
  // supported in Kotlin.
  public constructor(
      u: Vertex,
      v: Vertex
  ) : this(packInts(min(u.index, v.index), max(u.index, v.index)))

  /* Returns the vertex with the lowest id of this edge. Different from [v]. */
  private inline val u: Vertex
    get() = Vertex(unpackInt1(encoded))

  /* Returns the vertex with the highest id of this edge. Different from [u]. */
  private inline val v: Vertex
    get() = Vertex(unpackInt2(encoded))

  /** Returns an arbitrary vertex from this edge. */
  public fun any(): Vertex = u

  /**
   * Returns the vertex that is at the other end of this edge, compared to the given [vertex]. The
   * given [vertex] must be part of this edge; otherwise, an [IllegalArgumentException] is thrown.
   */
  public fun other(vertex: Vertex): Vertex =
      when (vertex) {
        u -> v
        v -> u
        else -> throw IllegalArgumentException("Vertex $vertex is not part of this edge.")
      }

  /** Returns a vertex of this edge, which is not the same as the one returned by [component2]. */
  public operator fun component1(): Vertex = u

  /** Returns a vertex of this edge, which is not the same as the one returned by [component1]. */
  public operator fun component2(): Vertex = v

  /** Returns `true` if the given [vertex] is part of this edge, and `false` otherwise. */
  public operator fun contains(vertex: Vertex): Boolean = vertex == u || vertex == v
}

/** Returns an [Edge] that contains both this and the [other] [Vertex]. */
public infix fun Vertex.edgeTo(other: Vertex): Edge = Edge(this, other)




© 2015 - 2025 Weber Informatics LLC | Privacy Policy