Skip to content

Commit ae551f1

Browse files
committed
Add collections of functional Op interfaces
These can be used to easily determine the arity of a known functional interface and allow to match interfaces of different types via these arities (e.g., Function3 <--> 3 <--> Computer3). This will be used in the next commit to merge Op transformers that only operate on interfaces of specific arities into more general transformers.
1 parent b7fdd06 commit ae551f1

3 files changed

Lines changed: 159 additions & 10 deletions

File tree

src/main/java/org/scijava/ops/util/Computers.java

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,59 @@
11
package org.scijava.ops.util;
22

3+
import com.google.common.collect.BiMap;
4+
import com.google.common.collect.ImmutableBiMap;
5+
36
import java.lang.reflect.Type;
7+
import java.util.Collections;
8+
import java.util.HashMap;
9+
import java.util.Map;
410

511
import org.scijava.ops.OpService;
6-
import org.scijava.ops.core.Op;
712
import org.scijava.ops.core.computer.BiComputer;
813
import org.scijava.ops.core.computer.Computer;
914
import org.scijava.ops.core.computer.Computer3;
1015
import org.scijava.ops.core.computer.Computer4;
1116
import org.scijava.ops.core.computer.Computer5;
17+
import org.scijava.ops.core.computer.Computer6;
1218
import org.scijava.ops.core.computer.NullaryComputer;
1319
import org.scijava.ops.types.Nil;
1420
import org.scijava.util.Types;
1521

16-
/**
17-
* Utility providing adaptation between {@link Op} types.
18-
*/
1922
public class Computers {
2023

24+
/**
25+
* All known computer types and their arities. The entries are sorted by
26+
* arity, i.e., the {@code i}-th entry has an arity of {@code i}.
27+
*/
28+
public static final BiMap<Class<?>, Integer> ALL_COMPUTERS;
29+
30+
static {
31+
final Map<Class<?>, Integer> computers = new HashMap<>(7);
32+
computers.put(NullaryComputer.class, 0);
33+
computers.put(Computer.class, 1);
34+
computers.put(BiComputer.class, 2);
35+
computers.put(Computer3.class, 3);
36+
computers.put(Computer4.class, 4);
37+
computers.put(Computer5.class, 5);
38+
computers.put(Computer6.class, 6);
39+
ALL_COMPUTERS = ImmutableBiMap.copyOf(computers);
40+
}
41+
2142
private Computers() {
2243
// NB: Prevent instantiation of utility class.
2344
}
2445

46+
/**
47+
* @return {@code true} if the given type is a {@link #ALL_COMPUTERS known}
48+
* computer type, {@code false} otherwise. <br>
49+
* Note that only the type itself and not its type hierarchy is
50+
* considered.
51+
* @throws NullPointerException If {@code type} is {@code null}.
52+
*/
53+
public static boolean isComputer(Type type) {
54+
return ALL_COMPUTERS.containsKey(Types.raw(type));
55+
}
56+
2557
public static <O> NullaryComputer<O> nullary(final OpService ops, final String opName, final Nil<O> outputType,
2658
final Object... secondaryArgs) {
2759
Nil<NullaryComputer<O>> computerNil = new Nil<NullaryComputer<O>>() {

src/main/java/org/scijava/ops/util/Functions.java

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,66 @@
11
package org.scijava.ops.util;
22

3+
import com.google.common.collect.BiMap;
4+
import com.google.common.collect.ImmutableBiMap;
5+
36
import java.lang.reflect.Type;
7+
import java.util.Collections;
8+
import java.util.HashMap;
9+
import java.util.Map;
410
import java.util.function.BiFunction;
511
import java.util.function.Function;
12+
import java.util.function.Supplier;
613

714
import org.scijava.ops.OpService;
815
import org.scijava.ops.core.Op;
916
import org.scijava.ops.core.function.Function3;
1017
import org.scijava.ops.core.function.Function4;
1118
import org.scijava.ops.core.function.Function5;
19+
import org.scijava.ops.core.function.Function6;
20+
import org.scijava.ops.core.function.Function7;
21+
import org.scijava.ops.core.function.Function8;
22+
import org.scijava.ops.core.function.Function9;
1223
import org.scijava.ops.types.Nil;
1324
import org.scijava.util.Types;
1425

15-
/**
16-
* Utility providing adaptation between {@link Op} types.
17-
*/
1826
public class Functions {
1927

28+
/**
29+
* All known function types and their arities. The entries are sorted by
30+
* arity, i.e., the {@code i}-th entry has an arity of {@code i}.
31+
*/
32+
public static final BiMap<Class<?>, Integer> ALL_FUNCTIONS;
33+
34+
static {
35+
final Map<Class<?>, Integer> functions = new HashMap<>(10);
36+
functions.put(Supplier.class, 0);
37+
functions.put(Function.class, 1);
38+
functions.put(BiFunction.class, 2);
39+
functions.put(Function3.class, 3);
40+
functions.put(Function4.class, 4);
41+
functions.put(Function5.class, 5);
42+
functions.put(Function6.class, 6);
43+
functions.put(Function7.class, 7);
44+
functions.put(Function8.class, 8);
45+
functions.put(Function9.class, 9);
46+
ALL_FUNCTIONS = ImmutableBiMap.copyOf(functions);
47+
}
48+
2049
private Functions() {
2150
// NB: Prevent instantiation of utility class.
2251
}
2352

53+
/**
54+
* @return {@code true} if the given type is a {@link #ALL_FUNCTIONS known}
55+
* function type, {@code false} otherwise.<br>
56+
* Note that only the type itself and not its type hierarchy is
57+
* considered.
58+
* @throws NullPointerException If {@code type} is {@code null}.
59+
*/
60+
public static boolean isFunction(Type type) {
61+
return ALL_FUNCTIONS.containsKey(Types.raw(type));
62+
}
63+
2464
public static <I, O> Function<I, O> unary(final OpService ops, final String opName,
2565
final Nil<I> inputType, final Nil<O> outputType, final Object... secondaryArgs) {
2666

src/main/java/org/scijava/ops/util/Inplaces.java

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
package org.scijava.ops.util;
22

33
import java.lang.reflect.Type;
4+
import java.util.ArrayList;
5+
import java.util.Collections;
6+
import java.util.HashMap;
7+
import java.util.LinkedHashMap;
8+
import java.util.List;
9+
import java.util.Map;
10+
import java.util.Map.Entry;
11+
import java.util.stream.Collectors;
412

513
import org.scijava.ops.OpService;
614
import org.scijava.ops.core.Op;
@@ -25,18 +33,68 @@
2533
import org.scijava.ops.core.inplace.Inplace6Second;
2634
import org.scijava.ops.core.inplace.Inplace6Sixth;
2735
import org.scijava.ops.core.inplace.Inplace6Third;
36+
import org.scijava.ops.core.inplace.Inplace7Second;
2837
import org.scijava.ops.types.Nil;
38+
import org.scijava.ops.util.Inplaces.InplaceInfo;
2939
import org.scijava.util.Types;
3040

31-
/**
32-
* Utility providing adaptation between {@link Op} types.
33-
*/
3441
public class Inplaces {
3542

43+
/**
44+
* All known inplace types and their arities and mutable positions. The
45+
* entries are sorted by arity and mutable position.
46+
*/
47+
public static final Map<Class<?>, InplaceInfo> ALL_INPLACES;
48+
49+
static {
50+
final Map<Class<?>, InplaceInfo> inplaces = new LinkedHashMap<>(22);
51+
inplaces.put(Inplace.class, new InplaceInfo(1, 0));
52+
inplaces.put(BiInplaceFirst.class, new InplaceInfo(2, 0));
53+
inplaces.put(BiInplaceSecond.class, new InplaceInfo(2, 1));
54+
inplaces.put(Inplace3First.class, new InplaceInfo(3, 0));
55+
inplaces.put(Inplace3Second.class, new InplaceInfo(3, 1));
56+
inplaces.put(Inplace3Third.class, new InplaceInfo(3, 2));
57+
inplaces.put(Inplace4First.class, new InplaceInfo(4, 0));
58+
inplaces.put(Inplace4Second.class, new InplaceInfo(4, 1));
59+
inplaces.put(Inplace4Third.class, new InplaceInfo(4, 2));
60+
inplaces.put(Inplace4Fourth.class, new InplaceInfo(4, 3));
61+
inplaces.put(Inplace5First.class, new InplaceInfo(5, 0));
62+
inplaces.put(Inplace5Second.class, new InplaceInfo(5, 1));
63+
inplaces.put(Inplace5Third.class, new InplaceInfo(5, 2));
64+
inplaces.put(Inplace5Fourth.class, new InplaceInfo(5, 3));
65+
inplaces.put(Inplace5Fifth.class, new InplaceInfo(5, 4));
66+
inplaces.put(Inplace6First.class, new InplaceInfo(6, 0));
67+
inplaces.put(Inplace6Second.class, new InplaceInfo(6, 1));
68+
inplaces.put(Inplace6Third.class, new InplaceInfo(6, 2));
69+
inplaces.put(Inplace6Fourth.class, new InplaceInfo(6, 3));
70+
inplaces.put(Inplace6Fifth.class, new InplaceInfo(6, 4));
71+
inplaces.put(Inplace6Sixth.class, new InplaceInfo(6, 5));
72+
inplaces.put(Inplace7Second.class, new InplaceInfo(7, 1));
73+
ALL_INPLACES = Collections.unmodifiableMap(inplaces);
74+
}
75+
3676
private Inplaces() {
3777
// NB: Prevent instantiation of utility class.
3878
}
3979

80+
/**
81+
* @return {@code true} if the given type is a {@link #ALL_INPLACES known}
82+
* inplace type, {@code false} otherwise. <br>
83+
* Note that only the type itself and not its type hierarchy is
84+
* considered.
85+
* @throws NullPointerException If {@code type} is {@code null}.
86+
*/
87+
public static boolean isInplace(Type type) {
88+
return ALL_INPLACES.containsKey(Types.raw(type));
89+
}
90+
91+
public static List<Class<?>> getInplacesOfArity(final int arity) {
92+
return Inplaces.ALL_INPLACES.entrySet().stream() //
93+
.filter(e -> e.getValue().arity() == arity) //
94+
.map(Entry<Class<?>, InplaceInfo>::getKey) //
95+
.collect(Collectors.toList());
96+
}
97+
4098
public static <IO> Inplace<IO> unary(final OpService ops, final String opName, final Nil<IO> inputOutputType,
4199
final Object... secondaryArgs) {
42100

@@ -458,4 +516,23 @@ public Type getType() {
458516
inputOutputType, //
459517
secondaryArgs);
460518
}
519+
520+
public static class InplaceInfo {
521+
522+
private final int arity;
523+
private final int mutablePosition;
524+
525+
public InplaceInfo(final int arity, final int mutablePosition) {
526+
this.arity = arity;
527+
this.mutablePosition = mutablePosition;
528+
}
529+
530+
public int arity() {
531+
return arity;
532+
}
533+
534+
public int mutablePosition() {
535+
return mutablePosition;
536+
}
537+
}
461538
}

0 commit comments

Comments
 (0)