Skip to content

Commit c4fc783

Browse files
committed
Support Scala 2.10
... by adding the specialized variants of `andThen`, `compose`, `curried`, and `tupled`. In Scala 2.11, these variants no longer exists, as the `@unspecialized` facility has been fixed and now suppresses specialization for those methods. But having these in the functional interface cross-compatible with 2.10 and 2.11.
1 parent a678b91 commit c4fc783

File tree

2 files changed

+50
-11
lines changed

2 files changed

+50
-11
lines changed

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
scalaVersion := "2.11.0-RC1"
1+
scalaVersion := "2.10.3"
22

33
sourceGenerators in Compile <+= sourceManaged in Compile map { dir =>
44
def write(name: String, content: String) = {

project/CodeGen.scala

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ object CodeGen {
141141

142142
private val initName = "$init$"
143143
private val function1ImplClass = "scala.Function1$class"
144+
private val function2ImplClass = "scala.Function2$class"
144145
private val copyright =
145146
"""
146147
|/*
@@ -164,6 +165,9 @@ object CodeGen {
164165
methods.map(indent).mkString("\n\n")
165166
}
166167

168+
val function1SpecTs = List(Type.Int, Type.Long, Type.Float, Type.Double)
169+
val function1SpecRs = List(Type.Void, Type.Boolean, Type.Int, Type.Float, Type.Long, Type.Double)
170+
167171
private def apply1MethodSpec(t1: Type, r: Type): String = {
168172
val name = "apply$mc" + s"${r.code}${t1.code}" + "$sp"
169173
val applyCall = s"apply((T1) ((${t1.ref}) v1));"
@@ -177,12 +181,31 @@ object CodeGen {
177181
}
178182

179183
private def apply1SpecMethods = {
180-
val ts = List(Type.Int, Type.Long, Type.Float, Type.Double)
181-
val rs = List(Type.Void, Type.Boolean, Type.Int, Type.Float, Type.Long, Type.Double)
182-
val methods = for (t1 <- ts; r <- rs) yield apply1MethodSpec(t1, r)
184+
val methods = for (t1 <- function1SpecTs; r <- function1SpecRs) yield apply1MethodSpec(t1, r)
185+
methods.map(indent).mkString("\n\n")
186+
}
187+
188+
private def andThenComposeMethodSpec(t1: Type, r: Type): String = {
189+
val suffix = "$mc" + s"${r.code}${t1.code}" + "$sp"
190+
s"""
191+
|default scala.Function1 compose$suffix(scala.Function1 g) {
192+
| return compose(g);
193+
|}
194+
|default scala.Function1 andThen$suffix(scala.Function1 g) {
195+
| return andThen(g);
196+
|}
197+
|""".stripMargin.trim
198+
}
199+
200+
// No longer needed under 2.11 (@unspecialized has been fixed), but harmless to keep around to avoid cross-publishing this artifact.
201+
private def andThenComposeSpecMethods = {
202+
val methods = for (t1 <- function1SpecTs; r <- function1SpecRs) yield andThenComposeMethodSpec(t1, r)
183203
methods.map(indent).mkString("\n\n")
184204
}
185205

206+
val function2SpecTs = List(Type.Int, Type.Long, Type.Double)
207+
val function2SpecRs = function1SpecRs
208+
186209
private def apply2MethodSpec(t1: Type, t2: Type, r: Type): String = {
187210
val name = "apply$mc" + s"${r.code}${t1.code}${t2.code}" + "$sp"
188211
val applyCall = s"apply((T1) ((${t1.ref}) v1), (T2) ((${t2.ref}) v2));"
@@ -196,22 +219,38 @@ object CodeGen {
196219
}
197220

198221
private def apply2SpecMethods = {
199-
val ts = List(Type.Int, Type.Long, Type.Double)
200-
val rs = List(Type.Void, Type.Boolean, Type.Int, Type.Float, Type.Long, Type.Double)
201-
val methods = for (t1 <- ts; t2 <- ts; r <- rs) yield apply2MethodSpec(t1, t2, r)
222+
val methods = for (t1 <- function2SpecTs; t2 <- function2SpecTs; r <- function2SpecRs) yield apply2MethodSpec(t1, t2, r)
223+
methods.map(indent).mkString("\n\n")
224+
}
225+
226+
private def curriedTupled2MethodSpec(t1: Type, t2: Type, r: Type): String = {
227+
val suffix = "$mc" + s"${r.code}${t1.code}${t2.code}" + "$sp"
228+
s"""
229+
|default scala.Function1 curried$suffix() {
230+
| return curried();
231+
|}
232+
|default scala.Function1 tupled$suffix() {
233+
| return tupled();
234+
|}
235+
|""".stripMargin.trim
236+
}
237+
238+
// No longer needed under 2.11 (@unspecialized has been fixed), but harmless to keep around to avoid cross-publishing this artifact.
239+
private def curriedTupled2SpecMethods = {
240+
val methods = for (t1 <- function2SpecTs; t2 <- function2SpecTs; r <- function2SpecRs) yield curriedTupled2MethodSpec(t1, t2, r)
202241
methods.map(indent).mkString("\n\n")
203242
}
204243

205244
def fN(n: Int) = {
206245
val header = arity(n).fHeader
207-
val applyMethods = n match {
246+
val specializedVariants = n match {
208247
case 0 => apply0SpecMethods
209-
case 1 => apply1SpecMethods
210-
case 2 => apply2SpecMethods
248+
case 1 => apply1SpecMethods + "\n\n" + andThenComposeSpecMethods
249+
case 2 => apply2SpecMethods + "\n\n" + curriedTupled2SpecMethods
211250
case x => ""
212251
}
213252
val trailer = "}\n"
214-
List(header, applyMethods, trailer).mkString
253+
List(header, specializedVariants, trailer).mkString
215254
}
216255

217256
def pN(n: Int) = arity(n).pN

0 commit comments

Comments
 (0)