Skip to content

Instantly share code, notes, and snippets.

@jandk
Created December 20, 2018 15:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jandk/a387f2e26974edd974adab3feefb6ee5 to your computer and use it in GitHub Desktop.
Save jandk/a387f2e26974edd974adab3feefb6ee5 to your computer and use it in GitHub Desktop.
import com.squareup.javapoet.*
import java.util.*
import javax.lang.model.element.Modifier
private fun generateIndexOfTriple(typeName: TypeName): List<MethodSpec> {
val arrayTypeName = ArrayTypeName.of(typeName)
val indexOf4 = indexOf4(arrayTypeName, false)
val indexOf2 = indexOf2(arrayTypeName, indexOf4, false)
val lastIndexOf4 = indexOf4(arrayTypeName, true)
val lastIndexOf2 = indexOf2(arrayTypeName, lastIndexOf4, true)
val contains = contains(arrayTypeName, indexOf2)
return listOf(contains, indexOf2, indexOf4, lastIndexOf2, lastIndexOf4)
}
private fun contains(typeName: ArrayTypeName, indexOf2: MethodSpec): MethodSpec {
return MethodSpec.methodBuilder("contains")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.returns(Boolean::class.javaPrimitiveType!!)
.addParameter(typeName, "array")
.addParameter(typeName.componentType, "value")
.addStatement("return \$N(array, value) >= 0", indexOf2)
.build()
}
private fun indexOf2(typeName: ArrayTypeName, indexOf4: MethodSpec, reverse: Boolean): MethodSpec {
return MethodSpec.methodBuilder(if (reverse) "lastIndexOf" else "indexOf")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.returns(Int::class.javaPrimitiveType!!)
.addParameter(typeName, "array")
.addParameter(typeName.componentType, "value")
.addStatement("return \$N(array, value, 0, array.length)", indexOf4)
.build()
}
private fun indexOf4(typeName: ArrayTypeName, reverse: Boolean): MethodSpec {
val forLoop =
if (reverse) "for (int i = end - 1; i >= start; i--)"
else "for (int i = start; i < end; i++)"
return MethodSpec.methodBuilder(if (reverse) "lastIndexOf" else "indexOf")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.returns(Int::class.javaPrimitiveType!!)
.addParameter(typeName, "array")
.addParameter(typeName.componentType, "value")
.addParameter(Int::class.javaPrimitiveType, "start")
.addParameter(Int::class.javaPrimitiveType, "end")
.addStatement("checkArguments(array.length, start, end)")
.beginControlFlow(forLoop)
.beginControlFlow("if (" + equalsTest("array[i]", "value", typeName.componentType) + ")")
.addStatement("return i")
.endControlFlow()
.endControlFlow()
.addStatement("return -1")
.build()
}
private fun equalsTest(left: String, right: String, typeName: TypeName): String {
if (typeName.isPrimitive) {
if (typeName === TypeName.FLOAT) {
return String.format("Float.compare(%s, %s) == 0", left, right)
}
if (typeName === TypeName.DOUBLE) {
return String.format("Double.compare(%s, %s) == 0", left, right)
}
return String.format("%s == %s", left, right)
}
return String.format("Objects.equals(%s, %s)", left, right)
}
fun main(args: Array<String>) {
val typeNames = Arrays.asList(
TypeName.BYTE,
TypeName.SHORT,
TypeName.INT,
TypeName.LONG,
TypeName.FLOAT,
TypeName.DOUBLE,
TypeName.CHAR,
TypeName.BOOLEAN
)
val constructor = MethodSpec.constructorBuilder()
.addModifiers(Modifier.PRIVATE)
.build()
val builder = TypeSpec.classBuilder("MoreArrays")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addMethod(constructor)
val methods = typeNames
.flatMap { generateIndexOfTriple(it) }
.sortedWith(compareBy({ it.name }/* , { it.parameters.size } */))
builder.addMethods(methods)
val moreArrays = builder.build()
JavaFile.builder("be.tjoener.common", moreArrays)
.skipJavaLangImports(true)
.indent(" ")
.build()
.writeTo(System.out)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment