aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/util/SimpleMap.scala
blob: 218af2fc5011d3001121c11145975dab5e19070e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package dotty.tools.dotc.util

abstract class SimpleMap[-K, +V >: Null] {
  def apply(k: K): V
  def remove(k: K): SimpleMap[K, V]
  def updated[V1 >: V](k: K, v: V1): SimpleMap[K, V1]
  def contains(k: K): Boolean = apply(k) != null
  def mapValues[V1 >: V](f: V1 => V1): SimpleMap[K, V1]
}

object SimpleMap {

  object Empty extends SimpleMap[Any, Null] {
    def apply(k: Any) = null
    def remove(k: Any) = this
    def updated[V1 >: Null](k: Any, v: V1) = new Map1(k, v)
    def mapValues[V1 >: Null](f: V1 => V1) = this
  }

  class Map1[-K, +V >: Null] (k1: K, v1: V) extends SimpleMap[K, V] {
    def apply(k: K) =
      if (k == k1) v1
      else null
    def remove(k: K) =
      if (k == k1) Empty
      else this
    def updated[V1 >: V](k: K, v: V1) =
      if (k == k1) new Map1(k, v)
      else new Map2(k1, v1, k, v)
    def mapValues[V1 >: V](f: V1 => V1) =
      new Map1(k1, f(v1))
  }

  class Map2[-K, +V >: Null] (k1: K, v1: V, k2: K, v2: V) extends SimpleMap[K, V] {
    def apply(k: K) =
      if (k == k1) v1
      else if (k == k2) v2
      else null
    def remove(k: K) =
      if (k == k1) new Map1(k2, v2)
      else if (k == k2) new Map1(k1, v1)
      else this
    def updated[V1 >: V](k: K, v: V1) =
      if (k == k1) new Map2(k, v, k2, v2)
      else if (k == k2) new Map2(k1, v1, k, v)
      else new Map3(k1, v1, k2, v2, k, v)
    def mapValues[V1 >: V](f: V1 => V1) =
      new Map2(k1, f(v1), k2, f(v2))
  }

  class Map3[-K, +V >: Null] (k1: K, v1: V, k2: K, v2: V, k3: K, v3: V) extends SimpleMap[K, V] {
    def apply(k: K) =
      if (k == k1) v1
      else if (k == k2) v2
      else if (k == k3) v3
      else null
    def remove(k: K) =
      if (k == k1) new Map2(k2, v2, k3, v3)
      else if (k == k2) new Map2(k1, v1, k3, v3)
      else if (k == k3) new Map2(k1, v1, k2, v2)
      else this
    def updated[V1 >: V](k: K, v: V1) =
      if (k == k1) new Map3(k, v, k2, v2, k3, v3)
      else if (k == k2) new Map3(k1, v1, k, v, k3, v3)
      else if (k == k3) new Map3(k1, v1, k2, v2, k, v)
      else new Map4(k1, v1, k2, v2, k3, v3, k, v)
    def mapValues[V1 >: V](f: V1 => V1) =
      new Map3(k1, f(v1), k2, f(v2), k3, f(v3))
  }

  class Map4[-K, +V >: Null] (k1: K, v1: V, k2: K, v2: V, k3: K, v3: V, k4: K, v4: V) extends SimpleMap[K, V] {
    def apply(k: K) =
      if (k == k1) v1
      else if (k == k2) v2
      else if (k == k3) v3
      else if (k == k4) v4
      else null
    def remove(k: K) =
      if (k == k1) new Map3(k2, v2, k3, v3, k4, v4)
      else if (k == k2) new Map3(k1, v1, k3, v3, k4, v4)
      else if (k == k3) new Map3(k1, v1, k2, v2, k4, v4)
      else if (k == k4) new Map3(k1, v1, k2, v2, k3, v3)
      else this
    def updated[V1 >: V](k: K, v: V1) =
      if (k == k1) new Map4(k, v, k2, v2, k3, v3, k4, v4)
      else if (k == k2) new Map4(k1, v1, k, v, k3, v3, k4, v4)
      else if (k == k3) new Map4(k1, v1, k2, v2, k, v, k4, v4)
      else if (k == k4) new Map4(k1, v1, k2, v2, k3, v3, k, v)
      else new Map5(k1, v1, k2, v2, k3, v3, k4, v4, k, v)
    def mapValues[V1 >: V](f: V1 => V1) =
      new Map4(k1, f(v1), k2, f(v2), k3, f(v3), k4, f(v4))
  }

  class Map5[-K, +V >: Null] (k1: K, v1: V, k2: K, v2: V, k3: K, v3: V, k4: K, v4: V, k5: K, v5: V) extends SimpleMap[K, V] {
    def apply(k: K) =
      if (k == k1) v1
      else if (k == k2) v2
      else if (k == k3) v3
      else if (k == k4) v4
      else if (k == k5) v5
      else null
    def remove(k: K) =
      if (k == k1) new Map4(k2, v2, k3, v3, k4, v4, k5, v5)
      else if (k == k2) new Map4(k1, v1, k3, v3, k4, v4, k5, v5)
      else if (k == k3) new Map4(k1, v1, k2, v2, k4, v4, k5, v5)
      else if (k == k4) new Map4(k1, v1, k2, v2, k3, v3, k5, v5)
      else if (k == k5) new Map4(k1, v1, k2, v2, k3, v3, k4, v4)
      else this
    def updated[V1 >: V](k: K, v: V1) =
      if (k == k1) new Map5(k, v, k2, v2, k3, v3, k4, v4, k5, v5)
      else if (k == k2) new Map5(k1, v1, k, v, k3, v3, k4, v4, k5, v5)
      else if (k == k3) new Map5(k1, v1, k2, v2, k, v, k4, v4, k5, v5)
      else if (k == k4) new Map5(k1, v1, k2, v2, k3, v3, k, v, k5, v5)
      else if (k == k5) new Map5(k1, v1, k2, v2, k3, v3, k4, v4, k, v)
      else new MapMore(Map(k1 -> v1, k2 -> v2, k3 -> v3, k4 -> v4, k5 -> v5, k -> v))
    def mapValues[V1 >: V](f: V1 => V1) =
      new Map5(k1, f(v1), k2, f(v2), k3, f(v3), k4, f(v4), k5, f(v5))
  }

  class MapMore[-K, +V >: Null] (m: Map[K, V]) extends SimpleMap[K, V] {
    def apply(k: K) = m get k match {
      case Some(v) => v
      case None => null
    }
    def remove(k: K) = {
      val m1 = m - k
      if (m1.size > 5) new MapMore(m1)
      else {
        val List((k1, v1), (k2, v2), (k3, v3), (k4, v4), (k5, v5)) = m1.toList
        new Map5(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5)
      }
    }
    def updated[V1 >: V](k: K, v: V1) =
      new MapMore(m.updated(k, v))
    override def contains(k: K) = m contains k
    def mapValues[V1 >: V](f: V1 => V1) =
      new MapMore(m mapValues f)
  }
}