Skip to content

Commit 48c673b

Browse files
committed
Version 1.8.0.
- Random-based functions take `RandomGenerator` arguments instead of `Random`. - Add a `isPowerOf2` extension.
1 parent 1c13057 commit 48c673b

File tree

89 files changed

+560
-132
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+560
-132
lines changed

.scalafmt.conf

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
version = 3.8.3
2-
runner.dialect = scala3
1+
version = 3.9.10
2+
runner.dialect = scala36
33

44
fileOverride {
55
"glob:**/*.sbt" {
@@ -24,6 +24,7 @@ newlines {
2424
usingParamListModifierPrefer = before
2525
avoidForSimpleOverflow = [tooLong,punct,slc]
2626
avoidInResultType = true
27+
forceBeforeMultilineAssign = def
2728
}
2829

2930
spaces {
@@ -33,10 +34,6 @@ spaces {
3334
}
3435

3536
literals {
36-
long = Upper
37-
float = Lower
38-
double = Lower
39-
hexPrefix = Lower
4037
hexDigits = Upper
4138
scientific = Upper
4239
}

J/src/main/java/tinyscalautils/java/Collection.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package tinyscalautils.java;
22

33
import java.util.*;
4+
import java.util.random.RandomGenerator;
45

56
public class Collection {
67
private Collection() {
@@ -13,15 +14,15 @@ public static <A> Iterator<A> circular(Iterable<A> iterable) {
1314
return collection.circular(iterable);
1415
}
1516

16-
public static <A> Iterator<A> randomly(Iterable<A> iterable, Random rand) {
17+
public static <A> Iterator<A> randomly(Iterable<A> iterable, RandomGenerator rand) {
1718
return collection.randomly(iterable, rand);
1819
}
1920

20-
public static <A> A pickOne(Iterable<A> iterable, Random rand) {
21+
public static <A> A pickOne(Iterable<A> iterable, RandomGenerator rand) {
2122
return collection.pickOne(iterable, rand);
2223
}
2324

24-
public static <A> Optional<A> pickOneOption(Iterable<A> iterable, Random rand) {
25+
public static <A> Optional<A> pickOneOption(Iterable<A> iterable, RandomGenerator rand) {
2526
return collection.pickOneOption(iterable, rand);
2627
}
2728

J/src/main/java/tinyscalautils/java/Text.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ public static void print(Object ignoredArg) {
2424
public static void println(Object ignoredArg) {
2525
}
2626

27+
// added so SILENT_MODE.println() can easily replace STANDARD_MODE.println()
28+
public static void println() {
29+
}
30+
2731
public static void printf(String ignoredFormat, Object... ignoredArgs) {
2832
}
2933
}
@@ -41,6 +45,11 @@ public static void println(Object arg) {
4145
textScala.standardMode().print(arg, true);
4246
}
4347

48+
// added so STANDARD_MODE.println() can easily replace System.out.println()
49+
public static void println() {
50+
println("");
51+
}
52+
4453
public static void printf(String format, Object... arg) {
4554
textScala.standardMode().print(String.format(format, arg), false);
4655
}
@@ -157,6 +166,10 @@ public static void info() {
157166
textScala.info();
158167
}
159168

169+
public static void info(int newlines) {
170+
textScala.info(newlines);
171+
}
172+
160173
public static String plural(Number x, String singularForm, String pluralForm) {
161174
return textScala.plural(x, singularForm, pluralForm);
162175
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package tinyscalautils.java;
2+
3+
public class Util {
4+
private Util() {
5+
throw new AssertionError("this class cannot be instantiated");
6+
}
7+
8+
private static final UtilScala util = new UtilScala();
9+
10+
public static boolean isEven(int n) {
11+
return (n & 1) == 0;
12+
}
13+
14+
public static boolean isEven(long n) {
15+
return (n & 1L) == 0L;
16+
}
17+
18+
public static boolean isOdd(int n) {
19+
return (n & 1) != 0;
20+
}
21+
22+
public static boolean isOdd(long n) {
23+
return (n & 1L) != 0L;
24+
}
25+
26+
public static int pow(int n, int m) {
27+
return util.pow(n, m);
28+
}
29+
30+
public static long pow(long n, int m) {
31+
return util.pow(n, m);
32+
}
33+
34+
public static boolean isPowerOf2(int n) {
35+
return util.isPowerOf2(n);
36+
}
37+
38+
public static boolean isPowerOf2(long n) {
39+
return util.isPowerOf2(n);
40+
}
41+
}
Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,30 @@
11
package tinyscalautils.java
22

3-
import tinyscalautils.collection.{ circular, pickOne, randomly, pickOneOption }
3+
import tinyscalautils.collection.{ circular, pickOne, pickOneOption, randomly }
4+
import tinyscalautils.util.RandomAdapter
45

6+
import java.{ lang as jl, util as ju }
7+
import java.util.random.RandomGenerator
58
import scala.jdk.CollectionConverters.{ IterableHasAsScala, IteratorHasAsJava }
6-
import scala.util.Random
79
import scala.jdk.OptionConverters.RichOption
10+
import scala.util.Random
811

912
private final class CollectionScala:
10-
def circular[A](iterable: java.lang.Iterable[A]): java.util.Iterator[A] =
11-
iterable.asScala.circular.asJava
13+
def circular[A](iterable: jl.Iterable[A]): ju.Iterator[A] = iterable.asScala.circular.asJava
14+
15+
def randomly[A](iterable: jl.Iterable[A], rand: RandomGenerator): ju.Iterator[A] =
16+
iterable.asScala.randomly(using Random(adapt(rand))).asJava
17+
18+
def pickOne[A](iterable: java.lang.Iterable[A], rand: RandomGenerator): A =
19+
iterable.asScala.pickOne(using Random(adapt(rand)))
1220

13-
def randomly[A](iterable: java.lang.Iterable[A], rand: java.util.Random): java.util.Iterator[A] =
14-
iterable.asScala.randomly(using Random(rand)).asJava
21+
def pickOneOption[A](iterable: jl.Iterable[A], rand: RandomGenerator): ju.Optional[A] =
22+
iterable.asScala.pickOneOption(using Random(adapt(rand))).toJava
1523

16-
def pickOne[A](iterable: java.lang.Iterable[A], rand: java.util.Random): A =
17-
iterable.asScala.pickOne(using Random(rand))
24+
private def adapt(randGen: RandomGenerator): ju.Random =
25+
randGen match
26+
case rand: ju.Random => rand
27+
case _ => RandomGeneratorAdapter(randGen)
1828

19-
def pickOneOption[A](
20-
iterable: java.lang.Iterable[A],
21-
rand: java.util.Random
22-
): java.util.Optional[A] =
23-
iterable.asScala.pickOneOption(using Random(rand)).toJava
29+
private final class RandomGeneratorAdapter(randGen: RandomGenerator) extends RandomAdapter:
30+
protected def rand = randGen

J/src/main/scala/tinyscalautils/java/TextScala.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ private final class TextScala:
99
)
1010

1111
def info(): Unit = tinyscalautils.text.info()
12+
13+
def info(newlines: Int): Unit = tinyscalautils.text.info(newlines)
1214

1315
def plural(x: Number, singularForm: String, pluralForm: String): String =
1416
tinyscalautils.text.plural(x.doubleValue(), singularForm, pluralForm)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package tinyscalautils.java
2+
3+
import tinyscalautils.util.pow
4+
import tinyscalautils.util.isPowerOf2
5+
6+
private final class UtilScala:
7+
def pow(n: Int, m: Int): Int = n.pow(m)
8+
def pow(n: Long, m: Int): Long = n.pow(m)
9+
10+
def isPowerOf2(n: Int) = n.isPowerOf2
11+
def isPowerOf2(n: Long) = n.isPowerOf2

J/src/test/java/PrintoutSuite.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@ public class PrintoutSuite {
99
@Test
1010
void testPrintout() {
1111
assertEquals("X\n", printout(() -> println("X")));
12+
assertEquals("\n", printout(() -> println()));
1213
assertEquals("X", printout(() -> printf("%s","X")));
1314
}
1415

1516
@Test
1617
void testPrintoutStandard() {
1718
assertEquals("X\n", printout(() -> System.out.println("X")));
19+
assertEquals("\n", printout(() -> System.out.println()));
1820
assertEquals("X", printout(() -> System.out.printf("%s","X")));
1921
}
2022
}

J/src/test/java/TextSuite.java

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import org.junit.jupiter.api.Test;
22
import tinyscalautils.java.Text;
33

4-
import java.util.stream.Collectors;
5-
64
import static org.junit.jupiter.api.Assertions.assertEquals;
75
import static org.junit.jupiter.api.Assertions.assertTrue;
86
import static tinyscalautils.java.Text.*;
@@ -12,13 +10,15 @@ public class TextSuite {
1210
void testSilent() {
1311
assertTrue(printout(() -> SILENT_MODE.print("X")).isEmpty());
1412
assertTrue(printout(() -> SILENT_MODE.println("X")).isEmpty());
13+
assertTrue(printout(() -> SILENT_MODE.println()).isEmpty());
1514
assertTrue(printout(() -> SILENT_MODE.printf("%s", "X")).isEmpty());
1615
}
1716

1817
@Test
1918
void testStandard() {
2019
assertEquals("X", printout(() -> STANDARD_MODE.print("X")));
2120
assertEquals("X\n", printout(() -> STANDARD_MODE.println("X")));
21+
assertEquals("\n", printout(() -> STANDARD_MODE.println()));
2222
assertEquals("X", printout(() -> STANDARD_MODE.printf("%s", "X")));
2323
}
2424

@@ -80,11 +80,22 @@ void testPlural() {
8080

8181
@Test
8282
void testInfo() {
83-
var lines = printout(Text::info).lines().collect(Collectors.toList());
84-
assertEquals(3, lines.size());
85-
assertTrue(lines.get(0).startsWith("Java"));
86-
assertTrue(lines.get(1).endsWith("processors") || lines.get(1).endsWith("processor"));
87-
assertTrue(lines.get(2).endsWith("maximum memory"));
83+
var lines = printout(Text::info).lines().toList();
84+
assertEquals(4, lines.size());
85+
assertTrue(lines.get(0).contains("Java"));
86+
assertTrue(lines.get(2).endsWith("processors") || lines.get(2).endsWith("processor"));
87+
assertTrue(lines.get(3).endsWith("maximum memory"));
88+
}
89+
90+
@Test
91+
void testInfoNewlines() {
92+
var lines = printout(() -> Text.info(2)).lines().toList();
93+
assertEquals(6, lines.size());
94+
assertTrue(lines.get(0).contains("Java"));
95+
assertTrue(lines.get(2).endsWith("processors") || lines.get(2).endsWith("processor"));
96+
assertTrue(lines.get(3).endsWith("maximum memory"));
97+
assertTrue(lines.get(4).isEmpty());
98+
assertTrue(lines.get(5).isEmpty());
8899
}
89100

90101
@Test

J/src/test/java/UtilSuite.java

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import org.junit.jupiter.api.Test;
2+
3+
import static org.junit.jupiter.api.Assertions.*;
4+
import static tinyscalautils.java.Util.*;
5+
6+
public class UtilSuite {
7+
@Test
8+
void testPow() {
9+
assertThrows(IllegalArgumentException.class, () -> pow(2, -1));
10+
assertEquals(1, pow(0, 0));
11+
assertEquals(0, pow(0, 1));
12+
assertEquals(1, pow(1, 0));
13+
assertEquals(1, pow(1, 100_000));
14+
assertEquals(1, pow(2, 0));
15+
assertEquals(1024, pow(2, 10));
16+
assertEquals(2048, pow(2, 11));
17+
assertEquals(1L, pow(2L, 0));
18+
assertEquals(1073741824L, pow(2L, 30));
19+
assertEquals(536870912L, pow(2L, 29));
20+
assertEquals(576460752303423488L, pow(2L, 59));
21+
assertEquals(59049, pow(3, 10));
22+
assertEquals(205891132094649L, pow(3L, 30));
23+
}
24+
25+
@Test
26+
void testEvenOddInt() {
27+
assertTrue(isEven(42));
28+
assertTrue(isEven(-42));
29+
assertFalse(isEven(41));
30+
assertFalse(isEven(-41));
31+
assertFalse(isOdd(42));
32+
assertFalse(isOdd(-42));
33+
assertTrue(isOdd(41));
34+
assertTrue(isOdd(-41));
35+
}
36+
37+
@Test
38+
void testEvenOddLong() {
39+
assertTrue(isEven(42L));
40+
assertTrue(isEven(-42L));
41+
assertFalse(isEven(41L));
42+
assertFalse(isEven(-41L));
43+
assertFalse(isOdd(42L));
44+
assertFalse(isOdd(-42L));
45+
assertTrue(isOdd(41L));
46+
assertTrue(isOdd(-41L));
47+
}
48+
49+
@Test
50+
void testIsPowerOf2Int() {
51+
assertThrows(IllegalArgumentException.class, () -> isPowerOf2(-1));
52+
assertFalse(isPowerOf2(3));
53+
assertFalse(isPowerOf2(5));
54+
assertFalse(isPowerOf2(6));
55+
assertFalse(isPowerOf2(7));
56+
for (int n = 1073741825; n < 2147483647; n++)
57+
assertFalse(isPowerOf2(n));
58+
for (int n = 1, c = 0; c < 31; c++, n <<= 1)
59+
assertTrue(isPowerOf2(n));
60+
}
61+
62+
@Test
63+
void testIsPowerOf2Long() {
64+
assertThrows(IllegalArgumentException.class, () -> isPowerOf2(-1L));
65+
assertFalse(isPowerOf2(3L));
66+
assertFalse(isPowerOf2(5L));
67+
assertFalse(isPowerOf2(6L));
68+
assertFalse(isPowerOf2(7L));
69+
for (long n = 2147483649L; n <= 4294967295L; n++)
70+
assertFalse(isPowerOf2(n));
71+
for (long n = 1L, c = 0; c < 63; c++, n <<= 1)
72+
assertTrue(isPowerOf2(n));
73+
}
74+
}

0 commit comments

Comments
 (0)