From 86393dd0f34749e35c871a2e286ce152257d666c Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Wed, 15 Apr 2020 14:38:44 +0300 Subject: [PATCH 01/27] Remove redundant `static`s from ClassUtil --- .../java/ru/progrm_jarvis/javacommons/util/ClassUtil.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/ClassUtil.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/ClassUtil.java index a4090744..bfb29aeb 100644 --- a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/ClassUtil.java +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/ClassUtil.java @@ -19,13 +19,13 @@ public class ClassUtil { /** * Comparator for sorting {@link Class classes} by their hash-code */ - private static final Comparator> CLASS_HASH_CODE_COMPARATOR = Comparator.comparing(Class::hashCode); + private final Comparator> CLASS_HASH_CODE_COMPARATOR = Comparator.comparing(Class::hashCode); /* *************************************** Sorted by PROgrammer_JARvis :) *************************************** */ /** * Array of primitive classes (those whose {@link Class#isPrimitive()} returns {@code true}) */ - private static final Class[] PRIMITIVE_CLASSES = new Class[]{ + private final Class[] PRIMITIVE_CLASSES = new Class[]{ boolean.class, byte.class, char.class, short.class, int.class, long.class, float.class, double.class }, From bda83a2887b2d9853ef0319592a9d80d781be27e Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Wed, 15 Apr 2020 14:40:21 +0300 Subject: [PATCH 02/27] Add `PrimitiveWrapper` --- .../primitive/wrapper/PrimitiveWrapper.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/PrimitiveWrapper.java diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/PrimitiveWrapper.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/PrimitiveWrapper.java new file mode 100644 index 00000000..af21f323 --- /dev/null +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/PrimitiveWrapper.java @@ -0,0 +1,21 @@ +package ru.progrm_jarvis.javacommons.primitive.wrapper; + +/** + * Mutable wrapper of a primitive type, this is mostly useful for passing these to lambdas. + */ +public interface PrimitiveWrapper { + + /** + * Returns the primitive class wrapped by this one. + * + * @return wrapped primitive class + */ + Class getPrimitiveClass(); + + /** + * Returns the {@link java.lang} primitive wrapper class corresponding to the one wrapped. + * + * @return related {@link java.lang} primitive wrapper + */ + Class getWrapperClass(); +} From af513942e668576759fa3f0e9ace4e60a1d025dd Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Wed, 15 Apr 2020 14:51:44 +0300 Subject: [PATCH 03/27] Add IntWrapper --- .../primitive/wrapper/IntWrapper.java | 363 ++++++++++++++++++ 1 file changed, 363 insertions(+) create mode 100644 java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java new file mode 100644 index 00000000..7f25d1a7 --- /dev/null +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java @@ -0,0 +1,363 @@ +package ru.progrm_jarvis.javacommons.primitive.wrapper; + +import lombok.*; +import lombok.experimental.FieldDefaults; + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.IntBinaryOperator; +import java.util.function.IntUnaryOperator; + +/** + * {@link PrimitiveWrapper Primitive wrapper} of {@code int}. + */ +public abstract class IntWrapper extends Number implements PrimitiveWrapper { + + @Override + public Class getPrimitiveClass() { + return int.class; + } + + @Override + public Class getWrapperClass() { + return Integer.class; + } + + /** + * Gets the value. + * + * @return value + */ + public abstract int get(); + + /** + * Sets the value. + * + * @param value value to be set + */ + public abstract void set(int value); + + /** + * Gets the value after what it gets incremented. + * + * @return value before increment + */ + public abstract int getAndIncrement(); + + /** + * Increments the value after what it is returned. + * + * @return value after increment + */ + public abstract int incrementAndGet(); + + /** + * Gets the value after what it gets decremented. + * + * @return value before decrement + */ + public abstract int getAndDecrement(); + + /** + * Decrements the value after what it is returned. + * + * @return value after decrement + */ + public abstract int decrementAndGet(); + + /** + * Gets the value after what delta is added to it. + * + * @param delta the value which should be added to the current value + * @return value before addition + */ + public abstract int getAndAdd(int delta); + + /** + * Adds the delta to the value after what it is returned. + * + * @param delta the value which should be added to the current value + * @return value after addition + */ + public abstract int addAndGet(int delta); + + /** + * Updates the current value using the specified function after what the new value is returned. + * + * @param updateFunction function to be used for updating the value + * @return value after update + */ + public abstract int getAndUpdate(@NonNull IntUnaryOperator updateFunction); + + /** + * Gets the value after what it gets updated using the specified function. + * + * @param updateFunction function to be used for updating the value + * @return value after update + */ + public abstract int updateAndGet(@NonNull IntUnaryOperator updateFunction); + + /** + * Updates the current value using specified function and update value after what the new value is returned. + * + * @param updateValue update value (will be passed as the second function parameter) + * @param accumulatorFunction function to be used for updating the value + * @return value after update + */ + public abstract int getAndAccumulate(int updateValue, @NonNull IntBinaryOperator accumulatorFunction); + + /** + * Gets the value after what it gets updated using the specified function and update value. + * + * @param updateValue update value (will be passed as the second function parameter) + * @param accumulatorFunction function to be used for updating the value + * @return value after update + */ + public abstract int accumulateAndGet(int updateValue, @NonNull IntBinaryOperator accumulatorFunction); + + /** + * Creates new simple int wrapper. + * + * @param value initial value of int wrapper + * @return created int wrapper + */ + public static IntWrapper create(final int value) { + return new IntIntWrapper(value); + } + + /** + * Creates new simple int wrapper with initial value set to {@code 0}. + * + * @return created int wrapper + */ + public static IntWrapper create() { + return new IntIntWrapper(0); + } + + /** + * Creates new atomic int wrapper. + * + * @param value initial value of int wrapper + * @return created int wrapper + */ + public static IntWrapper createAtomic(final int value) { + return new AtomicIntegerIntWrapper(value); + } + + /** + * Creates new atomic int wrapper with initial value set to {@code 0}. + * + * @return created int wrapper + */ + public static IntWrapper createAtomic() { + return new AtomicIntegerIntWrapper(); + } + + /** + * {@link IntWrapper} implementation based on {@code int}. + */ + @ToString + @NoArgsConstructor + @AllArgsConstructor + @EqualsAndHashCode(callSuper = false) + @FieldDefaults(level = AccessLevel.PRIVATE) + private static final class IntIntWrapper extends IntWrapper { + + int value; + + @Override + public int get() { + return value; + } + + @Override + public void set(final int value) { + this.value = value; + } + + @Override + public int getAndIncrement() { + return value++; + } + + @Override + public int incrementAndGet() { + return ++value; + } + + @Override + public int getAndDecrement() { + return value--; + } + + @Override + public int decrementAndGet() { + return --value; + } + + @Override + public int getAndAdd(final int delta) { + val oldValue = value; + value += delta; + + return oldValue; + } + + @Override + public int addAndGet(final int delta) { + return value += delta; + } + + @Override + public int getAndUpdate(@NonNull final IntUnaryOperator updateFunction) { + val oldValue = value; + value = updateFunction.applyAsInt(oldValue); + + return oldValue; + } + + @Override + public int updateAndGet(@NonNull final IntUnaryOperator updateFunction) { + return value = updateFunction.applyAsInt(value); + } + + @Override + public int getAndAccumulate(final int updateValue, @NonNull final IntBinaryOperator accumulatorFunction) { + val oldValue = value; + value = accumulatorFunction.applyAsInt(value, updateValue); + + return oldValue; + } + + @Override + public int accumulateAndGet(final int updateValue, @NonNull final IntBinaryOperator accumulatorFunction) { + return value = accumulatorFunction.applyAsInt(value, updateValue); + } + + @Override + public int intValue() { + return value; + } + + @Override + public long longValue() { + return value; + } + + @Override + public float floatValue() { + return value; + } + + @Override + public double doubleValue() { + return value; + } + } + + /** + * {@link IntWrapper} implementation based on {@link AtomicInteger}. + */ + @ToString + @EqualsAndHashCode(callSuper = false) + @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) + private static final class AtomicIntegerIntWrapper extends IntWrapper { + + @NonNull AtomicInteger value; + + /** + * Creates new atomic integer int wrapper. + * + * @param value initial value + */ + public AtomicIntegerIntWrapper(final int value) { + this.value = new AtomicInteger(value); + } + + /** + * Creates new atomic integer int wrapper with initial value set to {@code 0}. + */ + public AtomicIntegerIntWrapper() { + this.value = new AtomicInteger(); + } + + @Override + public int get() { + return value.get(); + } + + @Override + public void set(final int value) { + this.value.set(value); + } + + @Override + public int getAndIncrement() { + return value.getAndIncrement(); + } + + @Override + public int incrementAndGet() { + return value.incrementAndGet(); + } + + @Override + public int getAndDecrement() { + return value.getAndDecrement(); + } + + @Override + public int decrementAndGet() { + return value.decrementAndGet(); + } + + @Override + public int getAndAdd(final int delta) { + return value.getAndAdd(delta); + } + + @Override + public int addAndGet(final int delta) { + return value.addAndGet(delta); + } + + @Override + public int getAndUpdate(@NonNull final IntUnaryOperator updateFunction) { + return value.getAndUpdate(updateFunction); + } + + @Override + public int updateAndGet(@NonNull final IntUnaryOperator updateFunction) { + return value.updateAndGet(updateFunction); + } + + @Override + public int getAndAccumulate(final int updateValue, @NonNull final IntBinaryOperator accumulatorFunction) { + return value.getAndAccumulate(updateValue, accumulatorFunction); + } + + @Override + public int accumulateAndGet(final int updateValue, @NonNull final IntBinaryOperator accumulatorFunction) { + return value.accumulateAndGet(updateValue, accumulatorFunction); + } + + @Override + public int intValue() { + return value.intValue(); + } + + @Override + public long longValue() { + return value.longValue(); + } + + @Override + public float floatValue() { + return value.floatValue(); + } + + @Override + public double doubleValue() { + return value.doubleValue(); + } + } +} From 72dda2e703e2ab8e038f4fd3207d9d104e14f71f Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Wed, 15 Apr 2020 14:54:07 +0300 Subject: [PATCH 04/27] Add LongWrapper --- .../primitive/wrapper/LongWrapper.java | 363 ++++++++++++++++++ 1 file changed, 363 insertions(+) create mode 100644 java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/LongWrapper.java diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/LongWrapper.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/LongWrapper.java new file mode 100644 index 00000000..bdc1325e --- /dev/null +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/LongWrapper.java @@ -0,0 +1,363 @@ +package ru.progrm_jarvis.javacommons.primitive.wrapper; + +import lombok.*; +import lombok.experimental.FieldDefaults; + +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.LongBinaryOperator; +import java.util.function.LongUnaryOperator; + +/** + * {@link PrimitiveWrapper Primitive wrapper} of {@code long}. + */ +public abstract class LongWrapper extends Number implements PrimitiveWrapper { + + @Override + public Class getPrimitiveClass() { + return long.class; + } + + @Override + public Class getWrapperClass() { + return Long.class; + } + + /** + * Gets the value. + * + * @return value + */ + public abstract long get(); + + /** + * Sets the value. + * + * @param value value to be set + */ + public abstract void set(long value); + + /** + * Gets the value after what it gets incremented. + * + * @return value before increment + */ + public abstract long getAndIncrement(); + + /** + * Increments the value after what it is returned. + * + * @return value after increment + */ + public abstract long incrementAndGet(); + + /** + * Gets the value after what it gets decremented. + * + * @return value before decrement + */ + public abstract long getAndDecrement(); + + /** + * Decrements the value after what it is returned. + * + * @return value after decrement + */ + public abstract long decrementAndGet(); + + /** + * Gets the value after what delta is added to it. + * + * @param delta the value which should be added to the current value + * @return value before addition + */ + public abstract long getAndAdd(long delta); + + /** + * Adds the delta to the value after what it is returned. + * + * @param delta the value which should be added to the current value + * @return value after addition + */ + public abstract long addAndGet(long delta); + + /** + * Updates the current value using the specified function after what the new value is returned. + * + * @param updateFunction function to be used for updating the value + * @return value after update + */ + public abstract long getAndUpdate(@NonNull LongUnaryOperator updateFunction); + + /** + * Gets the value after what it gets updated using the specified function. + * + * @param updateFunction function to be used for updating the value + * @return value after update + */ + public abstract long updateAndGet(@NonNull LongUnaryOperator updateFunction); + + /** + * Updates the current value using specified function and update value after what the new value is returned. + * + * @param updateValue update value (will be passed as the second function parameter) + * @param accumulatorFunction function to be used for updating the value + * @return value after update + */ + public abstract long getAndAccumulate(long updateValue, @NonNull LongBinaryOperator accumulatorFunction); + + /** + * Gets the value after what it gets updated using the specified function and update value. + * + * @param updateValue update value (will be passed as the second function parameter) + * @param accumulatorFunction function to be used for updating the value + * @return value after update + */ + public abstract long accumulateAndGet(long updateValue, @NonNull LongBinaryOperator accumulatorFunction); + + /** + * Creates new simple long wrapper. + * + * @param value initial value of long wrapper + * @return created long wrapper + */ + public static LongWrapper create(final long value) { + return new LongLongWrapper(value); + } + + /** + * Creates new simple long wrapper with initial value set to {@code 0}. + * + * @return created long wrapper + */ + public static LongWrapper create() { + return new LongLongWrapper(0); + } + + /** + * Creates new atomic long wrapper. + * + * @param value initial value of long wrapper + * @return created long wrapper + */ + public static LongWrapper createAtomic(final long value) { + return new AtomicLongLongWrapper(value); + } + + /** + * Creates new atomic long wrapper with initial value set to {@code 0}. + * + * @return created long wrapper + */ + public static LongWrapper createAtomic() { + return new AtomicLongLongWrapper(); + } + + /** + * {@link LongWrapper} implementation based on {@code long}. + */ + @ToString + @NoArgsConstructor + @AllArgsConstructor + @EqualsAndHashCode(callSuper = false) + @FieldDefaults(level = AccessLevel.PRIVATE) + private static final class LongLongWrapper extends LongWrapper { + + long value; + + @Override + public long get() { + return value; + } + + @Override + public void set(final long value) { + this.value = value; + } + + @Override + public long getAndIncrement() { + return value++; + } + + @Override + public long incrementAndGet() { + return ++value; + } + + @Override + public long getAndDecrement() { + return value--; + } + + @Override + public long decrementAndGet() { + return --value; + } + + @Override + public long getAndAdd(final long delta) { + val oldValue = value; + value += delta; + + return oldValue; + } + + @Override + public long addAndGet(final long delta) { + return value += delta; + } + + @Override + public long getAndUpdate(@NonNull final LongUnaryOperator updateFunction) { + val oldValue = value; + value = updateFunction.applyAsLong(oldValue); + + return oldValue; + } + + @Override + public long updateAndGet(@NonNull final LongUnaryOperator updateFunction) { + return value = updateFunction.applyAsLong(value); + } + + @Override + public long getAndAccumulate(final long updateValue, @NonNull final LongBinaryOperator accumulatorFunction) { + val oldValue = value; + value = accumulatorFunction.applyAsLong(value, updateValue); + + return oldValue; + } + + @Override + public long accumulateAndGet(final long updateValue, @NonNull final LongBinaryOperator accumulatorFunction) { + return value = accumulatorFunction.applyAsLong(value, updateValue); + } + + @Override + public int intValue() { + return (int) value; + } + + @Override + public long longValue() { + return value; + } + + @Override + public float floatValue() { + return value; + } + + @Override + public double doubleValue() { + return value; + } + } + + /** + * {@link LongWrapper} implementation based on {@link AtomicLong}. + */ + @ToString + @EqualsAndHashCode(callSuper = false) + @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) + private static final class AtomicLongLongWrapper extends LongWrapper { + + @NonNull AtomicLong value; + + /** + * Creates new atomic long long wrapper. + * + * @param value initial value + */ + public AtomicLongLongWrapper(final long value) { + this.value = new AtomicLong(value); + } + + /** + * Creates new atomic long long wrapper with initial value set to {@code 0}. + */ + public AtomicLongLongWrapper() { + this.value = new AtomicLong(); + } + + @Override + public long get() { + return value.get(); + } + + @Override + public void set(final long value) { + this.value.set(value); + } + + @Override + public long getAndIncrement() { + return value.getAndIncrement(); + } + + @Override + public long incrementAndGet() { + return value.incrementAndGet(); + } + + @Override + public long getAndDecrement() { + return value.getAndDecrement(); + } + + @Override + public long decrementAndGet() { + return value.decrementAndGet(); + } + + @Override + public long getAndAdd(final long delta) { + return value.getAndAdd(delta); + } + + @Override + public long addAndGet(final long delta) { + return value.addAndGet(delta); + } + + @Override + public long getAndUpdate(@NonNull final LongUnaryOperator updateFunction) { + return value.getAndUpdate(updateFunction); + } + + @Override + public long updateAndGet(@NonNull final LongUnaryOperator updateFunction) { + return value.updateAndGet(updateFunction); + } + + @Override + public long getAndAccumulate(final long updateValue, @NonNull final LongBinaryOperator accumulatorFunction) { + return value.getAndAccumulate(updateValue, accumulatorFunction); + } + + @Override + public long accumulateAndGet(final long updateValue, @NonNull final LongBinaryOperator accumulatorFunction) { + return value.accumulateAndGet(updateValue, accumulatorFunction); + } + + @Override + public int intValue() { + return value.intValue(); + } + + @Override + public long longValue() { + return value.longValue(); + } + + @Override + public float floatValue() { + return value.floatValue(); + } + + @Override + public double doubleValue() { + return value.doubleValue(); + } + } +} From 5237761aea991c5f58ee5693530a38c4fa96e64c Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Wed, 15 Apr 2020 15:11:51 +0300 Subject: [PATCH 05/27] Add `BooleanUnaryOperator` --- .../util/function/BooleanUnaryOperator.java | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanUnaryOperator.java diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanUnaryOperator.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanUnaryOperator.java new file mode 100644 index 00000000..d9dee7cf --- /dev/null +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanUnaryOperator.java @@ -0,0 +1,69 @@ +package ru.progrm_jarvis.javacommons.util.function; + +import lombok.NonNull; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.util.function.UnaryOperator; + +/** + * Represents an operation on a single {@code boolean} operand that produces a {@code boolean}} result. + * This is the primitive type specialization of {@link UnaryOperator} for {@code boolean}. + * + * @see UnaryOperator non-primitive generic equivalent + */ +public interface BooleanUnaryOperator extends UnaryOperator { + + /** + * Applies this operator to the given operand. + * + * @param operand the operand to which to apply this operation + * @return result of applying this operation to the operand + */ + boolean applyAsBoolean(boolean operand); + + @Override + default Boolean apply(final Boolean operand /* no need for explicit null-check*/) { + return applyAsBoolean(operand); + } + + /** + * Returns a composed operator that first applies the {@code before} operator to its input + * and then applies this operator to the result. + * + * @param before the operator to provide the value to this operator + * @return a composed operator that first applies the provided operator and then this one + * @throws NullPointerException if before is null + * + * @see #andThen(BooleanUnaryOperator) behaving in opposite manner + */ + @Contract(value = "null -> fail; _ -> _", pure = true) + default @NotNull BooleanUnaryOperator compose(@NonNull final BooleanUnaryOperator before) { + return operand -> applyAsBoolean(before.applyAsBoolean(operand)); + } + + /** + * Returns a composed operator that first applies this operator to its input + * and then applies the {@code after} operator to the result. + * + * @param after the operator to operate on the value provided by this operator + * @return a composed operator that first applies this operator and then the provided one + * @throws NullPointerException if after is null + * + * @see #compose(BooleanUnaryOperator) behaving in opposite manner + */ + @Contract(value = "null -> fail; _ -> _", pure = true) + default @NotNull BooleanUnaryOperator andThen(@NonNull final BooleanUnaryOperator after) { + return operand -> after.applyAsBoolean(applyAsBoolean(operand)); + } + + /** + * Returns an unary operator that always returns its input argument. + * + * @return a unary operator that always returns its input argument + */ + @Contract(value = "-> _", pure = true) + static @NotNull BooleanUnaryOperator identity() { + return operand -> operand; + } +} From 480aeca44f3f85bccb9aa4040b2efd5a0c293720 Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Wed, 15 Apr 2020 15:19:23 +0300 Subject: [PATCH 06/27] Add `BooleanFunction` --- .../util/function/BooleanFunction.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanFunction.java diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanFunction.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanFunction.java new file mode 100644 index 00000000..ec1adbd9 --- /dev/null +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanFunction.java @@ -0,0 +1,29 @@ +package ru.progrm_jarvis.javacommons.util.function; + +import java.util.function.Function; +import java.util.function.UnaryOperator; + +/** + * Represents a function that accepts a {@code boolean} argument and produces result of specified type. + * This is the primitive type specialization of {@link UnaryOperator} for {@code boolean}. + * + * @param the type of the result of the function + * + * @see Function non-primitive generic equivalent + */ +@FunctionalInterface +public interface BooleanFunction extends Function { + + /** + * Applies this function to the given argument. + * + * @param argument the function argument + * @return the function result + */ + R apply(boolean argument); + + @Override + default R apply(final Boolean argument /* no need for explicit null-check */) { + return apply(argument.booleanValue()); + } +} From e4c061656b5be7375261681314546e1dd2c0d9da Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Wed, 15 Apr 2020 15:21:44 +0300 Subject: [PATCH 07/27] Make `BooleanUnaryOperator` a functional interface extending `BooleanFunction` --- .../util/function/BooleanUnaryOperator.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanUnaryOperator.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanUnaryOperator.java index d9dee7cf..a5a73874 100644 --- a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanUnaryOperator.java +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanUnaryOperator.java @@ -12,7 +12,8 @@ * * @see UnaryOperator non-primitive generic equivalent */ -public interface BooleanUnaryOperator extends UnaryOperator { +@FunctionalInterface +public interface BooleanUnaryOperator extends BooleanFunction, UnaryOperator { /** * Applies this operator to the given operand. @@ -23,7 +24,12 @@ public interface BooleanUnaryOperator extends UnaryOperator { boolean applyAsBoolean(boolean operand); @Override - default Boolean apply(final Boolean operand /* no need for explicit null-check*/) { + default Boolean apply(boolean argument) { + return applyAsBoolean(argument); + } + + @Override + default Boolean apply(final Boolean operand /* no need for explicit null-check */) { return applyAsBoolean(operand); } From 5f21a85ef904e959a29f3374c1512ec903c8d950 Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Wed, 15 Apr 2020 15:27:12 +0300 Subject: [PATCH 08/27] Add `BooleanBinaryOperator` --- .../util/function/BooleanBinaryOperator.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanBinaryOperator.java diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanBinaryOperator.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanBinaryOperator.java new file mode 100644 index 00000000..8f7fe999 --- /dev/null +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanBinaryOperator.java @@ -0,0 +1,29 @@ +package ru.progrm_jarvis.javacommons.util.function; + +import java.util.function.BinaryOperator; +import java.util.function.UnaryOperator; + +/** + * Represents an operation on a single {@code boolean} operand that produces a {@code boolean}} result. + * This is the primitive type specialization of {@link UnaryOperator} for {@code boolean}. + * + * @see UnaryOperator non-primitive generic equivalent + */ +@FunctionalInterface +public interface BooleanBinaryOperator extends BinaryOperator { + + /** + * Applies this operator to the given operands. + * + * @param left the first operand + * @param right the second operand + * @return result of applying this operation to the operands + */ + boolean applyAsBoolean(boolean left, boolean right); + + @Override + default Boolean apply(final Boolean left /* no need for explicit null-check */, + final Boolean right /* no need for explicit null-check */) { + return applyAsBoolean(left, right); + } +} From 1cf993c8bddeae781260e524f640df575239ab9a Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Wed, 15 Apr 2020 15:28:44 +0300 Subject: [PATCH 09/27] Rely on default value in `IntWrapper#create()` --- .../progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java index 7f25d1a7..5fbadf09 100644 --- a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java @@ -130,7 +130,7 @@ public static IntWrapper create(final int value) { * @return created int wrapper */ public static IntWrapper create() { - return new IntIntWrapper(0); + return new IntIntWrapper(); } /** From 5211976dd4f2f14ba3ab71a8887de802273a7d6a Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Wed, 15 Apr 2020 15:32:49 +0300 Subject: [PATCH 10/27] Add `tools` module --- pom.xml | 1 + tools/pom.xml | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 tools/pom.xml diff --git a/pom.xml b/pom.xml index c036fdfe..452927ca 100644 --- a/pom.xml +++ b/pom.xml @@ -10,6 +10,7 @@ java-commons reflector ultimate-messenger + tools pom diff --git a/tools/pom.xml b/tools/pom.xml new file mode 100644 index 00000000..aef2d873 --- /dev/null +++ b/tools/pom.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + + + padla + ru.progrm-jarvis + 1.0-SNAPSHOT + + + padla-tools + pom + + + \ No newline at end of file From 57d40a951a9c5cd0eeb2f3b3a56bec58450d6f74 Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Wed, 15 Apr 2020 20:07:37 +0300 Subject: [PATCH 11/27] Implement generator of class for accessing Unsafe methods This generator should yet be refactored --- tools/pom.xml | 18 ++- tools/unsafe-methods-access-generator/pom.xml | 32 ++++++ .../UnsafeMethodData.java | 104 +++++++++++++++++ .../UnsafeMethodsAccessGenerator.java | 108 ++++++++++++++++++ .../UnsafeMethodsAccess.java.velocity | 99 ++++++++++++++++ 5 files changed, 360 insertions(+), 1 deletion(-) create mode 100644 tools/unsafe-methods-access-generator/pom.xml create mode 100644 tools/unsafe-methods-access-generator/src/main/java/ru/progrm_jarvis/padla/tools/unsafemethodsaccessgenerator/UnsafeMethodData.java create mode 100644 tools/unsafe-methods-access-generator/src/main/java/ru/progrm_jarvis/padla/tools/unsafemethodsaccessgenerator/UnsafeMethodsAccessGenerator.java create mode 100644 tools/unsafe-methods-access-generator/src/main/resources/templates/UnsafeMethodsAccess.java.velocity diff --git a/tools/pom.xml b/tools/pom.xml index aef2d873..cccb988a 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -8,9 +8,25 @@ ru.progrm-jarvis 1.0-SNAPSHOT - padla-tools + + unsafe-methods-access-generator + pom + + + + commons-cli + commons-cli + 1.4 + + + org.apache.velocity + velocity + 1.7 + + + \ No newline at end of file diff --git a/tools/unsafe-methods-access-generator/pom.xml b/tools/unsafe-methods-access-generator/pom.xml new file mode 100644 index 00000000..d82a9f48 --- /dev/null +++ b/tools/unsafe-methods-access-generator/pom.xml @@ -0,0 +1,32 @@ + + + 4.0.0 + + + padla-tools + ru.progrm-jarvis + 1.0-SNAPSHOT + + unsafe-methods-access-generator + + + + commons-cli + commons-cli + + + org.apache.velocity + velocity + + + + org.projectlombok + lombok + + + org.jetbrains + annotations + + + \ No newline at end of file diff --git a/tools/unsafe-methods-access-generator/src/main/java/ru/progrm_jarvis/padla/tools/unsafemethodsaccessgenerator/UnsafeMethodData.java b/tools/unsafe-methods-access-generator/src/main/java/ru/progrm_jarvis/padla/tools/unsafemethodsaccessgenerator/UnsafeMethodData.java new file mode 100644 index 00000000..59686433 --- /dev/null +++ b/tools/unsafe-methods-access-generator/src/main/java/ru/progrm_jarvis/padla/tools/unsafemethodsaccessgenerator/UnsafeMethodData.java @@ -0,0 +1,104 @@ +package ru.progrm_jarvis.padla.tools.unsafemethodsaccessgenerator; + +import lombok.*; +import lombok.experimental.FieldDefaults; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.regex.Pattern; + +@Value +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@FieldDefaults(level = AccessLevel.PRIVATE) +public class UnsafeMethodData { + + private static final Pattern CAMEL_CASE_SPLIT_PATTERN = Pattern.compile("(?=\\p{Upper})"); + + @NonNull Method method; + @NonNull String upperCamelCaseName; + @NonNull String upperCamelCaseNameWithTypeInfo; + @NonNull String[] signature; + @NonNull String returnType; + boolean returnValue; + + public static UnsafeMethodData from(final @NonNull Method method) { + val upperCamelCaseName = camelCaseToUpperSnakeCase(method.getName()); + return new UnsafeMethodData( + method, upperCamelCaseName, + appendParameterNames(upperCamelCaseName, method), getSignature(method.getParameterTypes()), + getTypeName(method.getReturnType()), + method.getReturnType() != void.class + ); + } + + private static String camelCaseToUpperSnakeCase(@NotNull final String methodName) { + val words = CAMEL_CASE_SPLIT_PATTERN.split(methodName); + val length = words.length; + + assert length != 0; + if (length == 1) return words[0].toUpperCase(); + + val result = new StringBuilder(methodName.length() + length - 1) + .append(words[0]); + for (var i = 1; i < words.length; i++) result.append('_').append(words[i]); + + return result.toString().toUpperCase(); + } + + private static String getTypeName(@NotNull Class type) { + var depth = 0; + while (type.isArray()) { + type = type.getComponentType(); + depth++; + } + if (depth == 0) return type.getSimpleName(); + + val typeName = type.getSimpleName(); + val result = new StringBuilder(typeName.length() + depth * 2).append(typeName); + for (var i = 0; i < depth; i++) result.append('[').append(']'); + + return result.toString(); + } + + private static String[] getSignature(@SuppressWarnings("rawtypes") @NotNull final Class[] parameterTypes) { + if (true) return Arrays.stream(parameterTypes) + .map(UnsafeMethodData::getTypeName) + .toArray(String[]::new); + val signature = new String[parameterTypes.length]; + for (int i = 0; i < parameterTypes.length; i++) { + var parameterType = parameterTypes[i]; + + final StringBuilder postfix = new StringBuilder(); + while (parameterType.isArray()) { + postfix.append('[').append(']'); + parameterType = parameterType.getComponentType(); + } + signature[i] = parameterType.getSimpleName() + postfix.toString(); + } + + return signature; + } + + private static String appendParameterNames(@NotNull final String string, + @NotNull final Method method) { + final int parameterCount = method.getParameterCount(); + if (parameterCount == 0) return string; + + val result = new StringBuilder(string.length() + 1 + parameterCount * 2 /* minimal growth*/) + .append(string).append('_'); + for (var parameterType : method.getParameterTypes()) { + result.append('_'); + var depth = 0; + while (parameterType.isArray()) { + ++depth; + parameterType = parameterType.getComponentType(); + } + if (parameterType.isPrimitive()) result.append('$'); + result.append(parameterType.getSimpleName().toUpperCase()); + for (var i = 0; i < depth; i++) result.append('$'); + } + + return result.toString(); + } +} diff --git a/tools/unsafe-methods-access-generator/src/main/java/ru/progrm_jarvis/padla/tools/unsafemethodsaccessgenerator/UnsafeMethodsAccessGenerator.java b/tools/unsafe-methods-access-generator/src/main/java/ru/progrm_jarvis/padla/tools/unsafemethodsaccessgenerator/UnsafeMethodsAccessGenerator.java new file mode 100644 index 00000000..b99a2c74 --- /dev/null +++ b/tools/unsafe-methods-access-generator/src/main/java/ru/progrm_jarvis/padla/tools/unsafemethodsaccessgenerator/UnsafeMethodsAccessGenerator.java @@ -0,0 +1,108 @@ +package ru.progrm_jarvis.padla.tools.unsafemethodsaccessgenerator; + +import lombok.NonNull; +import lombok.val; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; +import org.apache.velocity.runtime.RuntimeConstants; +import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * CLI tool used for generating accessor class for {@code Unsafe}. + */ +public final class UnsafeMethodsAccessGenerator { + + private static final Options OPTIONS = new Options() + .addRequiredOption("c", "class-name", true, "Class name") + .addOption("p", "package-name", true, "Package name"); + + public static void main(@NotNull final String... args) throws ParseException, IOException { + @NotNull final String className; + @Nullable final String packageName; + { + val commandLine = new DefaultParser().parse(OPTIONS, args); + + className = commandLine.getOptionValue("class-name"); + packageName = commandLine.getOptionValue('p'); + } + + val engine = new VelocityEngine(); + engine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); + engine.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName()); + engine.init(); + + val template = engine.getTemplate("/templates/UnsafeMethodsAccess.java.velocity"); + val writer = new OutputStreamWriter(System.out); + writeUnsafeMethodsAccessClass( + className, packageName, template, writer + ); + writer.flush(); // close shouldn't be called on System.out + } + + protected static void addImport(final @NotNull Set importedClasses, + /* may be replaced with content */ @NotNull Class possiblyImportedClass) { + while (possiblyImportedClass.isArray()) possiblyImportedClass = possiblyImportedClass.getComponentType(); + if (possiblyImportedClass.isPrimitive()) return; + + val className = possiblyImportedClass.getName(); + if (className.startsWith("java.lang.") && className.indexOf('.', 10) == -1) return; + + importedClasses.add(className); + } + + private static void writeUnsafeMethodsAccessClass(final @NonNull String className, + final @Nullable String packageName, + final @NonNull Template template, + final @NonNull Writer output) { + final Class unsafeClass; + { + Class sunMiscUnsafeClass; + try { + sunMiscUnsafeClass = Class.forName("sun.misc.Unsafe"); + } catch (final ClassNotFoundException e) { + sunMiscUnsafeClass = null; + } + + if (sunMiscUnsafeClass == null) try { + unsafeClass = Class.forName("jdk.internal.misc.Unsafe"); + } catch (final ClassNotFoundException classNotFoundException) { + throw new RuntimeException("Could not find Unsafe class"); + } else unsafeClass = sunMiscUnsafeClass; + } + + val unsafeMethods = unsafeClass.getMethods(); // we only need public Unsafe methods + val importedClasses = new HashSet(); + for (val unsafeMethod : unsafeMethods) { + addImport(importedClasses, unsafeMethod.getReturnType()); + for (val parameter : unsafeMethod.getParameterTypes()) addImport(importedClasses, parameter); + } + + val context = new VelocityContext(); + context.put("className", className); + context.put("packageName", packageName); + context.put("importedClasses", importedClasses); + context.put( + "unsafeMethods", + Arrays.stream(unsafeMethods) + .filter(method -> !Modifier.isStatic(method.getModifiers())) + .map(UnsafeMethodData::from) + .toArray(UnsafeMethodData[]::new) + ); + + template.merge(context, output); + } +} diff --git a/tools/unsafe-methods-access-generator/src/main/resources/templates/UnsafeMethodsAccess.java.velocity b/tools/unsafe-methods-access-generator/src/main/resources/templates/UnsafeMethodsAccess.java.velocity new file mode 100644 index 00000000..c3d37d9d --- /dev/null +++ b/tools/unsafe-methods-access-generator/src/main/resources/templates/UnsafeMethodsAccess.java.velocity @@ -0,0 +1,99 @@ +## @vtlvariable name="packageName" type="java.lang.String" +## @vtlvariable name="className" type="java.lang.String" +## @vtlvariable name="unsafeClassName" type="java.lang.String" +## @vtlvariable name="importedClasses" type="java.lang.String[]" +## @vtlvariable name="unsafeMethods" type="ru.progrm_jarvis.padla.tools.unsafemethodsaccessgenerator.UnsafeMethodData[]" +#if (${packageName} && !${packageName.equals("")})package ${packageName}; + +#end## +import lombok.SneakyThrows; +import lombok.experimental.UtilityClass; +import lombok.val; +import ru.progrm_jarvis.javacommons.invoke.InvokeUtil; + +#foreach(${importedClass} in ${importedClasses}) +import ${importedClass}; +#end + +import java.lang.invoke.MethodHandle; + +import static java.lang.invoke.MethodType.methodType; + +@UtilityClass +public class ${className} { + + private final MethodHandle +#foreach(${method} in ${unsafeMethods}) + UNSAFE_${method.upperCamelCaseNameWithTypeInfo}_METHOD#if(${foreach.hasNext}),#else;#end + +#end + + private final boolean USE_SUN_MISC_UNSAFE; + + static { + final Class unsafeClass; + { + boolean useSunMiscUnsafe = false; + { + Class sunMiscUnsafeClass; + try { + sunMiscUnsafeClass = Class.forName("sun.misc.Unsafe"); + useSunMiscUnsafe = true; + } catch (final ClassNotFoundException e) { + sunMiscUnsafeClass = null; + } + + if (!useSunMiscUnsafe) try { + unsafeClass = Class.forName("jdk.internal.misc.Unsafe"); + useSunMiscUnsafe = false; + } catch (final ClassNotFoundException classNotFoundException) { + throw new RuntimeException("Could not find Unsafe class"); + } else unsafeClass = sunMiscUnsafeClass; + } + USE_SUN_MISC_UNSAFE = useSunMiscUnsafe; + } + val unsafeClassLookup = InvokeUtil.lookup(unsafeClass); + + try { +#foreach(${unsafeMethod} in ${unsafeMethods}) + UNSAFE_${unsafeMethod.upperCamelCaseNameWithTypeInfo}_METHOD = unsafeClassLookup.findVirtual( + unsafeClass, "${unsafeMethod.method.name}", methodType(unsafeClass#foreach(${parameterType} in ${unsafeMethod.signature}), ${parameterType}.class#end) + ); +#end## + } catch (final NoSuchMethodException | IllegalAccessException e) { + throw new IllegalStateException("Could not find Unsafe method", e); + } + } + +#foreach(${unsafeMethod} in ${unsafeMethods}) + + @SneakyThrows + public ${unsafeMethod.returnType} ${unsafeMethod.method.name}(sun.misc.Unsafe unsafe## +#foreach(${parameterType} in ${unsafeMethod.signature}), final ${parameterType} p${foreach.index}#end) { + if (USE_SUN_MISC_UNSAFE) #if(${unsafeMethod.returnValue})return #{end}SunMiscUnsafeWrapper.${unsafeMethod.method.name}(unsafe#foreach(${parameterType} in ${unsafeMethod.signature}), p${foreach.index}#end); + #if(${unsafeMethod.returnValue})return#{else}else#{end} JdkInternalMiscUnsafeWrapper.${unsafeMethod.method.name}(unsafe#foreach(${parameterType} in ${unsafeMethod.signature}), p${foreach.index}#end); + } +#end + + private static final class SunMiscUnsafeWrapper { +#foreach(${unsafeMethod} in ${unsafeMethods}) + + @SneakyThrows + public static ${unsafeMethod.returnType} ${unsafeMethod.method.name}(final Object unsafe## +#foreach(${parameterType} in ${unsafeMethod.signature}), final ${parameterType} p${foreach.index}#end) { + #if(${unsafeMethod.returnValue})return (${unsafeMethod.returnType}) #{end}UNSAFE_${unsafeMethod.upperCamelCaseNameWithTypeInfo}_METHOD.invokeExact((sun.misc.Unsafe) unsafe#foreach(${parameterType} in ${unsafeMethod.signature}), p${foreach.index}#end); + } +#end + } + + private static final class JdkInternalMiscUnsafeWrapper { +#foreach(${unsafeMethod} in ${unsafeMethods}) + + @SneakyThrows + public static ${unsafeMethod.returnType} ${unsafeMethod.method.name}(final Object unsafe## +#foreach(${parameterType} in ${unsafeMethod.signature}), final ${parameterType} p${foreach.index}#end) { + #if(${unsafeMethod.returnValue})return (${unsafeMethod.returnType}) #{end}UNSAFE_${unsafeMethod.upperCamelCaseNameWithTypeInfo}_METHOD.invokeExact((jdk.internal.misc.Unsafe) unsafe#foreach(${parameterType} in ${unsafeMethod.signature}), p${foreach.index}#end); + } +#end + } +} From a9bed32553dabc06f08fec78a17b0ed199b5bcf2 Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Wed, 15 Apr 2020 20:33:43 +0300 Subject: [PATCH 12/27] Cleanup velocity template --- .../UnsafeMethodsAccess.java.velocity | 69 +++++++++++++------ 1 file changed, 47 insertions(+), 22 deletions(-) diff --git a/tools/unsafe-methods-access-generator/src/main/resources/templates/UnsafeMethodsAccess.java.velocity b/tools/unsafe-methods-access-generator/src/main/resources/templates/UnsafeMethodsAccess.java.velocity index c3d37d9d..d4b48b87 100644 --- a/tools/unsafe-methods-access-generator/src/main/resources/templates/UnsafeMethodsAccess.java.velocity +++ b/tools/unsafe-methods-access-generator/src/main/resources/templates/UnsafeMethodsAccess.java.velocity @@ -3,7 +3,7 @@ ## @vtlvariable name="unsafeClassName" type="java.lang.String" ## @vtlvariable name="importedClasses" type="java.lang.String[]" ## @vtlvariable name="unsafeMethods" type="ru.progrm_jarvis.padla.tools.unsafemethodsaccessgenerator.UnsafeMethodData[]" -#if (${packageName} && !${packageName.equals("")})package ${packageName}; +#if ($packageName && !$packageName.equals(""))package $packageName; #end## import lombok.SneakyThrows; @@ -11,8 +11,8 @@ import lombok.experimental.UtilityClass; import lombok.val; import ru.progrm_jarvis.javacommons.invoke.InvokeUtil; -#foreach(${importedClass} in ${importedClasses}) -import ${importedClass}; +#foreach($importedClass in $importedClasses) +import $importedClass; #end import java.lang.invoke.MethodHandle; @@ -20,11 +20,11 @@ import java.lang.invoke.MethodHandle; import static java.lang.invoke.MethodType.methodType; @UtilityClass -public class ${className} { +public class $className} { private final MethodHandle -#foreach(${method} in ${unsafeMethods}) - UNSAFE_${method.upperCamelCaseNameWithTypeInfo}_METHOD#if(${foreach.hasNext}),#else;#end +#foreach($method in $unsafeMethods) + UNSAFE_$method.upperCamelCaseNameWithTypeInfo}_METHOD#if($foreach.hasNext),#else;#end #end @@ -55,9 +55,11 @@ public class ${className} { val unsafeClassLookup = InvokeUtil.lookup(unsafeClass); try { -#foreach(${unsafeMethod} in ${unsafeMethods}) +#foreach($unsafeMethod in $unsafeMethods) UNSAFE_${unsafeMethod.upperCamelCaseNameWithTypeInfo}_METHOD = unsafeClassLookup.findVirtual( - unsafeClass, "${unsafeMethod.method.name}", methodType(unsafeClass#foreach(${parameterType} in ${unsafeMethod.signature}), ${parameterType}.class#end) + unsafeClass, "$unsafeMethod.method.name", + methodType(unsafeClass## +#foreach($parameterType in $unsafeMethod.signature), $parameterType.class#end) ); #end## } catch (final NoSuchMethodException | IllegalAccessException e) { @@ -65,34 +67,57 @@ public class ${className} { } } -#foreach(${unsafeMethod} in ${unsafeMethods}) - +## Macro for generating `else` or `return` depending on the method +#macro(returnOrElse $method)## +#if($method.returnValue)return#{else}else#{end} +#end## +#foreach($method in $unsafeMethods) +## +## Public static methods to get calles +## @SneakyThrows - public ${unsafeMethod.returnType} ${unsafeMethod.method.name}(sun.misc.Unsafe unsafe## -#foreach(${parameterType} in ${unsafeMethod.signature}), final ${parameterType} p${foreach.index}#end) { - if (USE_SUN_MISC_UNSAFE) #if(${unsafeMethod.returnValue})return #{end}SunMiscUnsafeWrapper.${unsafeMethod.method.name}(unsafe#foreach(${parameterType} in ${unsafeMethod.signature}), p${foreach.index}#end); - #if(${unsafeMethod.returnValue})return#{else}else#{end} JdkInternalMiscUnsafeWrapper.${unsafeMethod.method.name}(unsafe#foreach(${parameterType} in ${unsafeMethod.signature}), p${foreach.index}#end); + public $method.returnType ${method.method.name}(sun.misc.Unsafe unsafe## +#foreach($parameterType in $method.signature), final $parameterType p$foreach.index#end) { + if (USE_SUN_MISC_UNSAFE) #if($method.returnValue)return #end## +SunMiscUnsafeWrapper.${method.method.name}(unsafe#foreach($parameterType in $method.signature), p$foreach.index#end); + #returnOrElse($method) ## +JdkInternalMiscUnsafeWrapper.${method.method.name}(unsafe#foreach($parameterType in $method.signature), p$foreach.index#end); } #end +## Macro for generating `UNSAFE_..._METHOD.invokeExact((UnsafeType) unsafe, ...)` +#macro(castUnsafeMethodCall $unsafeType, $method)## +UNSAFE_${method.upperCamelCaseNameWithTypeInfo}_METHOD.invokeExact((jdk.internal.misc.Unsafe) unsafe## +#foreach($parameterType in $unsafeMethod.signature), p$foreach.index#end)## +#end## +## Macro for generating `return (T) ` if needed +#macro(returnCast $method) +#if($method.returnValue)return ($method.returnType) #end +#end +## +## Method callers for sun.misc.Unsafe +## private static final class SunMiscUnsafeWrapper { -#foreach(${unsafeMethod} in ${unsafeMethods}) +#foreach($method in $unsafeMethods) @SneakyThrows - public static ${unsafeMethod.returnType} ${unsafeMethod.method.name}(final Object unsafe## -#foreach(${parameterType} in ${unsafeMethod.signature}), final ${parameterType} p${foreach.index}#end) { - #if(${unsafeMethod.returnValue})return (${unsafeMethod.returnType}) #{end}UNSAFE_${unsafeMethod.upperCamelCaseNameWithTypeInfo}_METHOD.invokeExact((sun.misc.Unsafe) unsafe#foreach(${parameterType} in ${unsafeMethod.signature}), p${foreach.index}#end); + public static $method.returnType ${method.method.name}(final Object unsafe## +#foreach($parameterType in $method.signature), final $parameterType p$foreach.index#end) { + #returnCast($method)#castUnsafeMethodCall("sun.misc.Unsafe", $method); } #end } +## +## Method callers for jdk.internal.misc +## private static final class JdkInternalMiscUnsafeWrapper { -#foreach(${unsafeMethod} in ${unsafeMethods}) +#foreach($method in $unsafeMethods) @SneakyThrows - public static ${unsafeMethod.returnType} ${unsafeMethod.method.name}(final Object unsafe## -#foreach(${parameterType} in ${unsafeMethod.signature}), final ${parameterType} p${foreach.index}#end) { - #if(${unsafeMethod.returnValue})return (${unsafeMethod.returnType}) #{end}UNSAFE_${unsafeMethod.upperCamelCaseNameWithTypeInfo}_METHOD.invokeExact((jdk.internal.misc.Unsafe) unsafe#foreach(${parameterType} in ${unsafeMethod.signature}), p${foreach.index}#end); + public static $method.returnType ${method.method.name}(final Object unsafe## +#foreach($parameterType in $method.signature), final $parameterType p$foreach.index#end) { + #returnCast($method)#castUnsafeMethodCall("jdk.internal.misc.Unsafe", $method); } #end } From 8e1843d7819bbc911337fac13f2d29da7e27c09b Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Wed, 15 Apr 2020 20:34:45 +0300 Subject: [PATCH 13/27] Update template extension --- .../UnsafeMethodsAccessGenerator.java | 2 +- ...eMethodsAccess.java.velocity => UnsafeMethodsAccess.java.vm} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename tools/unsafe-methods-access-generator/src/main/resources/templates/{UnsafeMethodsAccess.java.velocity => UnsafeMethodsAccess.java.vm} (100%) diff --git a/tools/unsafe-methods-access-generator/src/main/java/ru/progrm_jarvis/padla/tools/unsafemethodsaccessgenerator/UnsafeMethodsAccessGenerator.java b/tools/unsafe-methods-access-generator/src/main/java/ru/progrm_jarvis/padla/tools/unsafemethodsaccessgenerator/UnsafeMethodsAccessGenerator.java index b99a2c74..8d74eaba 100644 --- a/tools/unsafe-methods-access-generator/src/main/java/ru/progrm_jarvis/padla/tools/unsafemethodsaccessgenerator/UnsafeMethodsAccessGenerator.java +++ b/tools/unsafe-methods-access-generator/src/main/java/ru/progrm_jarvis/padla/tools/unsafemethodsaccessgenerator/UnsafeMethodsAccessGenerator.java @@ -45,7 +45,7 @@ public static void main(@NotNull final String... args) throws ParseException, IO engine.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName()); engine.init(); - val template = engine.getTemplate("/templates/UnsafeMethodsAccess.java.velocity"); + val template = engine.getTemplate("/templates/UnsafeMethodsAccess.java.vm"); val writer = new OutputStreamWriter(System.out); writeUnsafeMethodsAccessClass( className, packageName, template, writer diff --git a/tools/unsafe-methods-access-generator/src/main/resources/templates/UnsafeMethodsAccess.java.velocity b/tools/unsafe-methods-access-generator/src/main/resources/templates/UnsafeMethodsAccess.java.vm similarity index 100% rename from tools/unsafe-methods-access-generator/src/main/resources/templates/UnsafeMethodsAccess.java.velocity rename to tools/unsafe-methods-access-generator/src/main/resources/templates/UnsafeMethodsAccess.java.vm From fb5f9112dc090f07e0ddafc65ac7c22fa673d341 Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Wed, 15 Apr 2020 20:45:07 +0300 Subject: [PATCH 14/27] Cleanup velocity template fixing issues in it --- .../templates/UnsafeMethodsAccess.java.vm | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/tools/unsafe-methods-access-generator/src/main/resources/templates/UnsafeMethodsAccess.java.vm b/tools/unsafe-methods-access-generator/src/main/resources/templates/UnsafeMethodsAccess.java.vm index d4b48b87..6c9e52e2 100644 --- a/tools/unsafe-methods-access-generator/src/main/resources/templates/UnsafeMethodsAccess.java.vm +++ b/tools/unsafe-methods-access-generator/src/main/resources/templates/UnsafeMethodsAccess.java.vm @@ -20,11 +20,11 @@ import java.lang.invoke.MethodHandle; import static java.lang.invoke.MethodType.methodType; @UtilityClass -public class $className} { +public class $className { private final MethodHandle #foreach($method in $unsafeMethods) - UNSAFE_$method.upperCamelCaseNameWithTypeInfo}_METHOD#if($foreach.hasNext),#else;#end + UNSAFE_${method.upperCamelCaseNameWithTypeInfo}_METHOD#if($foreach.hasNext),#else;#end #end @@ -59,7 +59,7 @@ public class $className} { UNSAFE_${unsafeMethod.upperCamelCaseNameWithTypeInfo}_METHOD = unsafeClassLookup.findVirtual( unsafeClass, "$unsafeMethod.method.name", methodType(unsafeClass## -#foreach($parameterType in $unsafeMethod.signature), $parameterType.class#end) +#foreach($parameterType in $unsafeMethod.signature), ${parameterType}.class#end) ); #end## } catch (final NoSuchMethodException | IllegalAccessException e) { @@ -71,24 +71,31 @@ public class $className} { #macro(returnOrElse $method)## #if($method.returnValue)return#{else}else#{end} #end## -#foreach($method in $unsafeMethods) +## Macro for generating `, p1, p2...` method call parameters +#macro(passTrailingParameters $method)## +#foreach($parameterType in $method.signature), p$foreach.index#end +#end## +## Macro for generating `, final T1 p1, final T2 p2...` method parameters +#macro(methodParameters $method)## +#foreach($parameterType in $method.signature), final $parameterType p$foreach.index#end +#end## ## ## Public static methods to get calles ## - @SneakyThrows - public $method.returnType ${method.method.name}(sun.misc.Unsafe unsafe## -#foreach($parameterType in $method.signature), final $parameterType p$foreach.index#end) { +#foreach($method in $unsafeMethods) + public $method.returnType ${method.method.name}(Object unsafe#methodParameters($method)) { if (USE_SUN_MISC_UNSAFE) #if($method.returnValue)return #end## -SunMiscUnsafeWrapper.${method.method.name}(unsafe#foreach($parameterType in $method.signature), p$foreach.index#end); +SunMiscUnsafeWrapper.${method.method.name}(unsafe#passTrailingParameters($method)); #returnOrElse($method) ## -JdkInternalMiscUnsafeWrapper.${method.method.name}(unsafe#foreach($parameterType in $method.signature), p$foreach.index#end); +JdkInternalMiscUnsafeWrapper.${method.method.name}(unsafe#passTrailingParameters($method)); } + #end ## Macro for generating `UNSAFE_..._METHOD.invokeExact((UnsafeType) unsafe, ...)` #macro(castUnsafeMethodCall $unsafeType, $method)## -UNSAFE_${method.upperCamelCaseNameWithTypeInfo}_METHOD.invokeExact((jdk.internal.misc.Unsafe) unsafe## -#foreach($parameterType in $unsafeMethod.signature), p$foreach.index#end)## +UNSAFE_${method.upperCamelCaseNameWithTypeInfo}_METHOD.invokeExact## +((jdk.internal.misc.Unsafe) unsafe#passTrailingParameters($method))## #end## ## Macro for generating `return (T) ` if needed #macro(returnCast $method) @@ -101,8 +108,7 @@ UNSAFE_${method.upperCamelCaseNameWithTypeInfo}_METHOD.invokeExact((jdk.internal #foreach($method in $unsafeMethods) @SneakyThrows - public static $method.returnType ${method.method.name}(final Object unsafe## -#foreach($parameterType in $method.signature), final $parameterType p$foreach.index#end) { + public static $method.returnType ${method.method.name}(final Object unsafe#methodParameters($method)) { #returnCast($method)#castUnsafeMethodCall("sun.misc.Unsafe", $method); } #end @@ -115,8 +121,7 @@ UNSAFE_${method.upperCamelCaseNameWithTypeInfo}_METHOD.invokeExact((jdk.internal #foreach($method in $unsafeMethods) @SneakyThrows - public static $method.returnType ${method.method.name}(final Object unsafe## -#foreach($parameterType in $method.signature), final $parameterType p$foreach.index#end) { + public static $method.returnType ${method.method.name}(final Object unsafe#methodParameters($method)) { #returnCast($method)#castUnsafeMethodCall("jdk.internal.misc.Unsafe", $method); } #end From 4389f6ad78919692ba4ab0e55f781652131bb062 Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Thu, 16 Apr 2020 01:35:46 +0300 Subject: [PATCH 15/27] Remove redundant statics from `UnsafeInternals` --- .../ru/progrm_jarvis/javacommons/unsafe/UnsafeInternals.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/unsafe/UnsafeInternals.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/unsafe/UnsafeInternals.java index c3d12d8c..2f32940e 100644 --- a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/unsafe/UnsafeInternals.java +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/unsafe/UnsafeInternals.java @@ -22,7 +22,7 @@ public class UnsafeInternals { /** * Name of {@link #UNSAFE_CLASS} class */ - public static final String UNSAFE_CLASS_NAME, + public final String UNSAFE_CLASS_NAME, /** * Name of {@link #MAGIC_ACCESSOR_IMPL_CLASS} class */ @@ -31,7 +31,7 @@ public class UnsafeInternals { /** * Flag indicating whether or not {@link #UNSAFE_CLASS} class is available */ - public static final boolean UNSAFE_AVAILABLE, + public final boolean UNSAFE_AVAILABLE, /** * Flag indicating whether or not {@link #MAGIC_ACCESSOR_IMPL_CLASS} class is available */ From af1e20cfa890bac46bcb5216d85ef345dd57621d Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Fri, 17 Apr 2020 10:53:37 +0300 Subject: [PATCH 16/27] Add missing `final` to `UnsafeInternals` --- .../ru/progrm_jarvis/javacommons/unsafe/UnsafeInternals.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/unsafe/UnsafeInternals.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/unsafe/UnsafeInternals.java index 2f32940e..179f9cd4 100644 --- a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/unsafe/UnsafeInternals.java +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/unsafe/UnsafeInternals.java @@ -13,7 +13,7 @@ public class UnsafeInternals { /** * {@code Unsafe} Class object */ - @Nullable public Class UNSAFE_CLASS, + @Nullable public final Class UNSAFE_CLASS, /** * {@code MagicAccessorImpl} Class object */ From 96736b665ac15fe6d0dd61cd7bc82ecf77e04690 Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Fri, 17 Apr 2020 10:57:27 +0300 Subject: [PATCH 17/27] Fix imbalanced in `BooleanBinaryOperator`'s docs --- .../javacommons/util/function/BooleanBinaryOperator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanBinaryOperator.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanBinaryOperator.java index 8f7fe999..9ac4cce9 100644 --- a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanBinaryOperator.java +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanBinaryOperator.java @@ -4,7 +4,7 @@ import java.util.function.UnaryOperator; /** - * Represents an operation on a single {@code boolean} operand that produces a {@code boolean}} result. + * Represents an operation on a single {@code boolean} operand that produces a {@code boolean} result. * This is the primitive type specialization of {@link UnaryOperator} for {@code boolean}. * * @see UnaryOperator non-primitive generic equivalent From 14adf08f591fd66c71eb1f409cf110145f59f67c Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Fri, 17 Apr 2020 11:07:43 +0300 Subject: [PATCH 18/27] Add missing @code-tags to docs of `BooleanUnaryOperator` --- .../javacommons/util/function/BooleanUnaryOperator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanUnaryOperator.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanUnaryOperator.java index a5a73874..30ecb996 100644 --- a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanUnaryOperator.java +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanUnaryOperator.java @@ -39,7 +39,7 @@ default Boolean apply(final Boolean operand /* no need for explicit null-check * * * @param before the operator to provide the value to this operator * @return a composed operator that first applies the provided operator and then this one - * @throws NullPointerException if before is null + * @throws NullPointerException if {@code before} is {@code null} * * @see #andThen(BooleanUnaryOperator) behaving in opposite manner */ @@ -54,7 +54,7 @@ default Boolean apply(final Boolean operand /* no need for explicit null-check * * * @param after the operator to operate on the value provided by this operator * @return a composed operator that first applies this operator and then the provided one - * @throws NullPointerException if after is null + * @throws NullPointerException if {@code after} is {@code null} * * @see #compose(BooleanUnaryOperator) behaving in opposite manner */ From e4a038d74f4d0bca58670db26138f0c374f52a5b Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Fri, 17 Apr 2020 11:10:55 +0300 Subject: [PATCH 19/27] Add `BooleanConsumer` --- .../util/function/BooleanConsumer.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanConsumer.java diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanConsumer.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanConsumer.java new file mode 100644 index 00000000..b796f338 --- /dev/null +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/BooleanConsumer.java @@ -0,0 +1,41 @@ +package ru.progrm_jarvis.javacommons.util.function; + +import lombok.NonNull; + +import java.util.function.Consumer; + +/** + * Represents an operation that accepts a single {@code boolean} argument and returns no result. + * This is the primitive type specialization of {@link Consumer} for {@code boolean}. + * + * @see Consumer non-primitive generic equivalent + */ +@FunctionalInterface +public interface BooleanConsumer extends Consumer { + + /** + * Performs this operation on the given argument. + * + * @param value the input argument + */ + void accept(boolean value); + + @Override + default void accept(final Boolean value /* no need for explicit null-check */) { + accept(value.booleanValue()); + } + + /** + * Returns a composed consumer that performs, in sequence, this operation followed by the {@code after} operation. + * + * @param after the operation to perform after this operation + * @return a composed operator that first performs this operation and then the provided one + * @throws NullPointerException if {@code after} is {@code null} + */ + default BooleanConsumer andThen(@NonNull final BooleanConsumer after) { + return value -> { + accept(value); + after.accept(value); + }; + } +} From f55bf1eb3a031dd91480d84f8320a55e32410a03 Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Fri, 17 Apr 2020 11:11:13 +0300 Subject: [PATCH 20/27] Add `package-info.java` to `ru.progrm_jarvis.javacommons.util.function` --- .../progrm_jarvis/javacommons/util/function/package-info.java | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/package-info.java diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/package-info.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/package-info.java new file mode 100644 index 00000000..5610e458 --- /dev/null +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/util/function/package-info.java @@ -0,0 +1,4 @@ +/** + * Common functional interfaces extending behaviour of {@link java.util.function}. + */ +package ru.progrm_jarvis.javacommons.util.function; \ No newline at end of file From eb26c8c037c16a6b139b0acf5e04001b32fbeac6 Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Fri, 17 Apr 2020 11:14:39 +0300 Subject: [PATCH 21/27] Add `BooleanWrapper` --- .../primitive/wrapper/BooleanWrapper.java | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/BooleanWrapper.java diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/BooleanWrapper.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/BooleanWrapper.java new file mode 100644 index 00000000..ae2fbaf8 --- /dev/null +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/BooleanWrapper.java @@ -0,0 +1,136 @@ +package ru.progrm_jarvis.javacommons.primitive.wrapper; + +import lombok.*; +import lombok.experimental.FieldDefaults; + +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * {@link PrimitiveWrapper Primitive wrapper} of {@code boolean}. + * + * @implNote this is an abstract class for consistency with other wrappers + */ +public abstract class BooleanWrapper implements PrimitiveWrapper { + + @Override + public Class getPrimitiveClass() { + return boolean.class; + } + + @Override + public Class getWrapperClass() { + return Boolean.class; + } + + /** + * Gets the value. + * + * @return value + */ + public abstract boolean get(); + + /** + * Sets the value. + * + * @param value value to be set + */ + public abstract void set(boolean value); + + /** + * Creates new simple boolean wrapper. + * + * @param value initial value of boolean wrapper + * @return created boolean wrapper + */ + public static BooleanWrapper create(final boolean value) { + return new BooleanBooleanWrapper(value); + } + + /** + * Creates new simple boolean wrapper with initial value set to {@code 0}. + * + * @return created boolean wrapper + */ + public static BooleanWrapper create() { + return new BooleanBooleanWrapper(false); + } + + /** + * Creates new atomic boolean wrapper. + * + * @param value initial value of boolean wrapper + * @return created boolean wrapper + */ + public static BooleanWrapper createAtomic(final boolean value) { + return new AtomicBooleanWrapper(value); + } + + /** + * Creates new atomic boolean wrapper with initial value set to {@code 0}. + * + * @return created boolean wrapper + */ + public static BooleanWrapper createAtomic() { + return new AtomicBooleanWrapper(); + } + + /** + * {@link BooleanWrapper} implementation based on {@code boolean}. + */ + @ToString + @NoArgsConstructor + @AllArgsConstructor + @EqualsAndHashCode(callSuper = false) + @FieldDefaults(level = AccessLevel.PRIVATE) + private static final class BooleanBooleanWrapper extends BooleanWrapper { + + boolean value; + + @Override + public boolean get() { + return value; + } + + @Override + public void set(final boolean value) { + this.value = value; + } + } + + /** + * {@link BooleanWrapper} implementation based on {@link AtomicBoolean}. + */ + @ToString + @EqualsAndHashCode(callSuper = false) + @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) + private static final class AtomicBooleanWrapper extends BooleanWrapper { + + @NonNull AtomicBoolean value; + + /** + * Creates new atomic boolean boolean wrapper. + * + * @param value initial value + */ + public AtomicBooleanWrapper(final boolean value) { + this.value = new AtomicBoolean(value); + } + + /** + * Creates new atomic boolean boolean wrapper with initial value set to {@code 0}. + */ + public AtomicBooleanWrapper() { + this.value = new AtomicBoolean(); + } + + @Override + public boolean get() { + return value.get(); + } + + @Override + public void set(final boolean value) { + this.value.set(value); + } + } +} From 036d669f67fdc6f899cc1f685d8ad95db45ad46e Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Mon, 20 Apr 2020 14:59:29 +0300 Subject: [PATCH 22/27] Add `Numeric` interface --- .../javacommons/primitive/Numeric.java | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/Numeric.java diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/Numeric.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/Numeric.java new file mode 100644 index 00000000..b0442daa --- /dev/null +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/Numeric.java @@ -0,0 +1,49 @@ +package ru.progrm_jarvis.javacommons.primitive; + +/** + * Interface analog of {@link Number}. + */ +public interface Numeric { + + /** + * Returns the value as {@code byte}. + * + * @return value as {@code byte} + */ + byte byteValue(); + + /** + * Returns the value as {@code short}. + * + * @return value as {@code short} + */ + short shortValue(); + + /** + * Returns the value as {@code int}. + * + * @return value as {@code int} + */ + int intValue(); + + /** + * Returns the value as {@code long}. + * + * @return value as {@code long} + */ + long longValue(); + + /** + * Returns the value as {@code float}. + * + * @return value as {@code float} + */ + float floatValue(); + + /** + * Returns the value as {@code double}. + * + * @return value as {@code double} + */ + double doubleValue(); +} From 599f0df6debccf3e934bf8af4e5a97b269788aab Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Mon, 20 Apr 2020 15:09:44 +0300 Subject: [PATCH 23/27] Integrate primitive wrappers with Numeric interface --- .../primitive/wrapper/BooleanWrapper.java | 26 ++++---- .../primitive/wrapper/IntWrapper.java | 63 ++++++++++++------- .../primitive/wrapper/LongWrapper.java | 63 ++++++++++++------- .../primitive/wrapper/PrimitiveWrapper.java | 8 ++- 4 files changed, 101 insertions(+), 59 deletions(-) diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/BooleanWrapper.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/BooleanWrapper.java index ae2fbaf8..662e7f56 100644 --- a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/BooleanWrapper.java +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/BooleanWrapper.java @@ -7,18 +7,16 @@ /** * {@link PrimitiveWrapper Primitive wrapper} of {@code boolean}. - * - * @implNote this is an abstract class for consistency with other wrappers */ -public abstract class BooleanWrapper implements PrimitiveWrapper { +public interface BooleanWrapper extends PrimitiveWrapper { @Override - public Class getPrimitiveClass() { + default Class getPrimitiveClass() { return boolean.class; } @Override - public Class getWrapperClass() { + default Class getWrapperClass() { return Boolean.class; } @@ -27,14 +25,14 @@ public Class getWrapperClass() { * * @return value */ - public abstract boolean get(); + boolean get(); /** * Sets the value. * * @param value value to be set */ - public abstract void set(boolean value); + void set(boolean value); /** * Creates new simple boolean wrapper. @@ -42,7 +40,7 @@ public Class getWrapperClass() { * @param value initial value of boolean wrapper * @return created boolean wrapper */ - public static BooleanWrapper create(final boolean value) { + static BooleanWrapper create(final boolean value) { return new BooleanBooleanWrapper(value); } @@ -51,7 +49,7 @@ public static BooleanWrapper create(final boolean value) { * * @return created boolean wrapper */ - public static BooleanWrapper create() { + static BooleanWrapper create() { return new BooleanBooleanWrapper(false); } @@ -61,7 +59,7 @@ public static BooleanWrapper create() { * @param value initial value of boolean wrapper * @return created boolean wrapper */ - public static BooleanWrapper createAtomic(final boolean value) { + static BooleanWrapper createAtomic(final boolean value) { return new AtomicBooleanWrapper(value); } @@ -70,7 +68,7 @@ public static BooleanWrapper createAtomic(final boolean value) { * * @return created boolean wrapper */ - public static BooleanWrapper createAtomic() { + static BooleanWrapper createAtomic() { return new AtomicBooleanWrapper(); } @@ -82,7 +80,7 @@ public static BooleanWrapper createAtomic() { @AllArgsConstructor @EqualsAndHashCode(callSuper = false) @FieldDefaults(level = AccessLevel.PRIVATE) - private static final class BooleanBooleanWrapper extends BooleanWrapper { + final class BooleanBooleanWrapper implements BooleanWrapper { boolean value; @@ -103,7 +101,7 @@ public void set(final boolean value) { @ToString @EqualsAndHashCode(callSuper = false) @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) - private static final class AtomicBooleanWrapper extends BooleanWrapper { + final class AtomicBooleanWrapper implements BooleanWrapper { @NonNull AtomicBoolean value; @@ -120,7 +118,7 @@ public AtomicBooleanWrapper(final boolean value) { * Creates new atomic boolean boolean wrapper with initial value set to {@code 0}. */ public AtomicBooleanWrapper() { - this.value = new AtomicBoolean(); + value = new AtomicBoolean(); } @Override diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java index 5fbadf09..b92b76fb 100644 --- a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java @@ -2,6 +2,7 @@ import lombok.*; import lombok.experimental.FieldDefaults; +import ru.progrm_jarvis.javacommons.primitive.Numeric; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.IntBinaryOperator; @@ -10,15 +11,15 @@ /** * {@link PrimitiveWrapper Primitive wrapper} of {@code int}. */ -public abstract class IntWrapper extends Number implements PrimitiveWrapper { +public interface IntWrapper extends PrimitiveWrapper, Numeric { @Override - public Class getPrimitiveClass() { + default Class getPrimitiveClass() { return int.class; } @Override - public Class getWrapperClass() { + default Class getWrapperClass() { return Integer.class; } @@ -27,42 +28,42 @@ public Class getWrapperClass() { * * @return value */ - public abstract int get(); + int get(); /** * Sets the value. * * @param value value to be set */ - public abstract void set(int value); + void set(int value); /** * Gets the value after what it gets incremented. * * @return value before increment */ - public abstract int getAndIncrement(); + int getAndIncrement(); /** * Increments the value after what it is returned. * * @return value after increment */ - public abstract int incrementAndGet(); + int incrementAndGet(); /** * Gets the value after what it gets decremented. * * @return value before decrement */ - public abstract int getAndDecrement(); + int getAndDecrement(); /** * Decrements the value after what it is returned. * * @return value after decrement */ - public abstract int decrementAndGet(); + int decrementAndGet(); /** * Gets the value after what delta is added to it. @@ -70,7 +71,7 @@ public Class getWrapperClass() { * @param delta the value which should be added to the current value * @return value before addition */ - public abstract int getAndAdd(int delta); + int getAndAdd(int delta); /** * Adds the delta to the value after what it is returned. @@ -78,7 +79,7 @@ public Class getWrapperClass() { * @param delta the value which should be added to the current value * @return value after addition */ - public abstract int addAndGet(int delta); + int addAndGet(int delta); /** * Updates the current value using the specified function after what the new value is returned. @@ -86,7 +87,7 @@ public Class getWrapperClass() { * @param updateFunction function to be used for updating the value * @return value after update */ - public abstract int getAndUpdate(@NonNull IntUnaryOperator updateFunction); + int getAndUpdate(@NonNull IntUnaryOperator updateFunction); /** * Gets the value after what it gets updated using the specified function. @@ -94,7 +95,7 @@ public Class getWrapperClass() { * @param updateFunction function to be used for updating the value * @return value after update */ - public abstract int updateAndGet(@NonNull IntUnaryOperator updateFunction); + int updateAndGet(@NonNull IntUnaryOperator updateFunction); /** * Updates the current value using specified function and update value after what the new value is returned. @@ -103,7 +104,7 @@ public Class getWrapperClass() { * @param accumulatorFunction function to be used for updating the value * @return value after update */ - public abstract int getAndAccumulate(int updateValue, @NonNull IntBinaryOperator accumulatorFunction); + int getAndAccumulate(int updateValue, @NonNull IntBinaryOperator accumulatorFunction); /** * Gets the value after what it gets updated using the specified function and update value. @@ -112,7 +113,7 @@ public Class getWrapperClass() { * @param accumulatorFunction function to be used for updating the value * @return value after update */ - public abstract int accumulateAndGet(int updateValue, @NonNull IntBinaryOperator accumulatorFunction); + int accumulateAndGet(int updateValue, @NonNull IntBinaryOperator accumulatorFunction); /** * Creates new simple int wrapper. @@ -120,7 +121,7 @@ public Class getWrapperClass() { * @param value initial value of int wrapper * @return created int wrapper */ - public static IntWrapper create(final int value) { + static IntWrapper create(final int value) { return new IntIntWrapper(value); } @@ -129,7 +130,7 @@ public static IntWrapper create(final int value) { * * @return created int wrapper */ - public static IntWrapper create() { + static IntWrapper create() { return new IntIntWrapper(); } @@ -139,7 +140,7 @@ public static IntWrapper create() { * @param value initial value of int wrapper * @return created int wrapper */ - public static IntWrapper createAtomic(final int value) { + static IntWrapper createAtomic(final int value) { return new AtomicIntegerIntWrapper(value); } @@ -148,7 +149,7 @@ public static IntWrapper createAtomic(final int value) { * * @return created int wrapper */ - public static IntWrapper createAtomic() { + static IntWrapper createAtomic() { return new AtomicIntegerIntWrapper(); } @@ -160,7 +161,7 @@ public static IntWrapper createAtomic() { @AllArgsConstructor @EqualsAndHashCode(callSuper = false) @FieldDefaults(level = AccessLevel.PRIVATE) - private static final class IntIntWrapper extends IntWrapper { + final class IntIntWrapper implements IntWrapper { int value; @@ -233,6 +234,16 @@ public int accumulateAndGet(final int updateValue, @NonNull final IntBinaryOpera return value = accumulatorFunction.applyAsInt(value, updateValue); } + @Override + public byte byteValue() { + return (byte) value; + } + + @Override + public short shortValue() { + return (short) value; + } + @Override public int intValue() { return value; @@ -260,7 +271,7 @@ public double doubleValue() { @ToString @EqualsAndHashCode(callSuper = false) @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) - private static final class AtomicIntegerIntWrapper extends IntWrapper { + final class AtomicIntegerIntWrapper implements IntWrapper { @NonNull AtomicInteger value; @@ -340,6 +351,16 @@ public int accumulateAndGet(final int updateValue, @NonNull final IntBinaryOpera return value.accumulateAndGet(updateValue, accumulatorFunction); } + @Override + public byte byteValue() { + return value.byteValue(); + } + + @Override + public short shortValue() { + return value.shortValue(); + } + @Override public int intValue() { return value.intValue(); diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/LongWrapper.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/LongWrapper.java index bdc1325e..1d350058 100644 --- a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/LongWrapper.java +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/LongWrapper.java @@ -2,6 +2,7 @@ import lombok.*; import lombok.experimental.FieldDefaults; +import ru.progrm_jarvis.javacommons.primitive.Numeric; import java.util.concurrent.atomic.AtomicLong; import java.util.function.LongBinaryOperator; @@ -10,15 +11,15 @@ /** * {@link PrimitiveWrapper Primitive wrapper} of {@code long}. */ -public abstract class LongWrapper extends Number implements PrimitiveWrapper { +public interface LongWrapper extends PrimitiveWrapper, Numeric { @Override - public Class getPrimitiveClass() { + default Class getPrimitiveClass() { return long.class; } @Override - public Class getWrapperClass() { + default Class getWrapperClass() { return Long.class; } @@ -27,42 +28,42 @@ public Class getWrapperClass() { * * @return value */ - public abstract long get(); + long get(); /** * Sets the value. * * @param value value to be set */ - public abstract void set(long value); + void set(long value); /** * Gets the value after what it gets incremented. * * @return value before increment */ - public abstract long getAndIncrement(); + long getAndIncrement(); /** * Increments the value after what it is returned. * * @return value after increment */ - public abstract long incrementAndGet(); + long incrementAndGet(); /** * Gets the value after what it gets decremented. * * @return value before decrement */ - public abstract long getAndDecrement(); + long getAndDecrement(); /** * Decrements the value after what it is returned. * * @return value after decrement */ - public abstract long decrementAndGet(); + long decrementAndGet(); /** * Gets the value after what delta is added to it. @@ -70,7 +71,7 @@ public Class getWrapperClass() { * @param delta the value which should be added to the current value * @return value before addition */ - public abstract long getAndAdd(long delta); + long getAndAdd(long delta); /** * Adds the delta to the value after what it is returned. @@ -78,7 +79,7 @@ public Class getWrapperClass() { * @param delta the value which should be added to the current value * @return value after addition */ - public abstract long addAndGet(long delta); + long addAndGet(long delta); /** * Updates the current value using the specified function after what the new value is returned. @@ -86,7 +87,7 @@ public Class getWrapperClass() { * @param updateFunction function to be used for updating the value * @return value after update */ - public abstract long getAndUpdate(@NonNull LongUnaryOperator updateFunction); + long getAndUpdate(@NonNull LongUnaryOperator updateFunction); /** * Gets the value after what it gets updated using the specified function. @@ -94,7 +95,7 @@ public Class getWrapperClass() { * @param updateFunction function to be used for updating the value * @return value after update */ - public abstract long updateAndGet(@NonNull LongUnaryOperator updateFunction); + long updateAndGet(@NonNull LongUnaryOperator updateFunction); /** * Updates the current value using specified function and update value after what the new value is returned. @@ -103,7 +104,7 @@ public Class getWrapperClass() { * @param accumulatorFunction function to be used for updating the value * @return value after update */ - public abstract long getAndAccumulate(long updateValue, @NonNull LongBinaryOperator accumulatorFunction); + long getAndAccumulate(long updateValue, @NonNull LongBinaryOperator accumulatorFunction); /** * Gets the value after what it gets updated using the specified function and update value. @@ -112,7 +113,7 @@ public Class getWrapperClass() { * @param accumulatorFunction function to be used for updating the value * @return value after update */ - public abstract long accumulateAndGet(long updateValue, @NonNull LongBinaryOperator accumulatorFunction); + long accumulateAndGet(long updateValue, @NonNull LongBinaryOperator accumulatorFunction); /** * Creates new simple long wrapper. @@ -120,7 +121,7 @@ public Class getWrapperClass() { * @param value initial value of long wrapper * @return created long wrapper */ - public static LongWrapper create(final long value) { + static LongWrapper create(final long value) { return new LongLongWrapper(value); } @@ -129,7 +130,7 @@ public static LongWrapper create(final long value) { * * @return created long wrapper */ - public static LongWrapper create() { + static LongWrapper create() { return new LongLongWrapper(0); } @@ -139,7 +140,7 @@ public static LongWrapper create() { * @param value initial value of long wrapper * @return created long wrapper */ - public static LongWrapper createAtomic(final long value) { + static LongWrapper createAtomic(final long value) { return new AtomicLongLongWrapper(value); } @@ -148,7 +149,7 @@ public static LongWrapper createAtomic(final long value) { * * @return created long wrapper */ - public static LongWrapper createAtomic() { + static LongWrapper createAtomic() { return new AtomicLongLongWrapper(); } @@ -160,7 +161,7 @@ public static LongWrapper createAtomic() { @AllArgsConstructor @EqualsAndHashCode(callSuper = false) @FieldDefaults(level = AccessLevel.PRIVATE) - private static final class LongLongWrapper extends LongWrapper { + final class LongLongWrapper implements LongWrapper { long value; @@ -233,6 +234,16 @@ public long accumulateAndGet(final long updateValue, @NonNull final LongBinaryOp return value = accumulatorFunction.applyAsLong(value, updateValue); } + @Override + public byte byteValue() { + return (byte) value; + } + + @Override + public short shortValue() { + return (short) value; + } + @Override public int intValue() { return (int) value; @@ -260,7 +271,7 @@ public double doubleValue() { @ToString @EqualsAndHashCode(callSuper = false) @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) - private static final class AtomicLongLongWrapper extends LongWrapper { + final class AtomicLongLongWrapper implements LongWrapper { @NonNull AtomicLong value; @@ -340,6 +351,16 @@ public long accumulateAndGet(final long updateValue, @NonNull final LongBinaryOp return value.accumulateAndGet(updateValue, accumulatorFunction); } + @Override + public byte byteValue() { + return value.byteValue(); + } + + @Override + public short shortValue() { + return value.shortValue(); + } + @Override public int intValue() { return value.intValue(); diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/PrimitiveWrapper.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/PrimitiveWrapper.java index af21f323..dad21783 100644 --- a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/PrimitiveWrapper.java +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/PrimitiveWrapper.java @@ -2,20 +2,22 @@ /** * Mutable wrapper of a primitive type, this is mostly useful for passing these to lambdas. + * + * @param type of wrapped value */ -public interface PrimitiveWrapper { +public interface PrimitiveWrapper { /** * Returns the primitive class wrapped by this one. * * @return wrapped primitive class */ - Class getPrimitiveClass(); + Class getPrimitiveClass(); /** * Returns the {@link java.lang} primitive wrapper class corresponding to the one wrapped. * * @return related {@link java.lang} primitive wrapper */ - Class getWrapperClass(); + Class getWrapperClass(); } From 0302bc1a35631cbde5a9f1e3f48b0e21f8b2bf9c Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Sat, 25 Apr 2020 16:46:13 +0300 Subject: [PATCH 24/27] Cleanup primitive wrappers adding `getAndSet(..)` --- .../primitive/wrapper/BooleanWrapper.java | 29 +++-- .../primitive/wrapper/IntWrapper.java | 110 +++--------------- .../primitive/wrapper/LongWrapper.java | 110 +++--------------- 3 files changed, 57 insertions(+), 192 deletions(-) diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/BooleanWrapper.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/BooleanWrapper.java index 662e7f56..a78de05e 100644 --- a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/BooleanWrapper.java +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/BooleanWrapper.java @@ -1,6 +1,7 @@ package ru.progrm_jarvis.javacommons.primitive.wrapper; import lombok.*; +import lombok.experimental.Delegate; import lombok.experimental.FieldDefaults; import java.util.concurrent.atomic.AtomicBoolean; @@ -34,12 +35,21 @@ default Class getWrapperClass() { */ void set(boolean value); + /** + * Sets the value to the one given returning the previous one. + * + * @param newValue value to be set + * @return previous value + */ + boolean getAndSet(boolean newValue); + /** * Creates new simple boolean wrapper. * * @param value initial value of boolean wrapper * @return created boolean wrapper */ + static BooleanWrapper create(final boolean value) { return new BooleanBooleanWrapper(value); } @@ -93,6 +103,14 @@ public boolean get() { public void set(final boolean value) { this.value = value; } + + @Override + public boolean getAndSet(final boolean newValue) { + val oldValue = value; + value = newValue; + + return oldValue; + } } /** @@ -103,6 +121,7 @@ public void set(final boolean value) { @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) final class AtomicBooleanWrapper implements BooleanWrapper { + @Delegate(types = BooleanWrapper.class) @NonNull AtomicBoolean value; /** @@ -120,15 +139,5 @@ public AtomicBooleanWrapper(final boolean value) { public AtomicBooleanWrapper() { value = new AtomicBoolean(); } - - @Override - public boolean get() { - return value.get(); - } - - @Override - public void set(final boolean value) { - this.value.set(value); - } } } diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java index b92b76fb..f1e7aa67 100644 --- a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java @@ -1,6 +1,7 @@ package ru.progrm_jarvis.javacommons.primitive.wrapper; import lombok.*; +import lombok.experimental.Delegate; import lombok.experimental.FieldDefaults; import ru.progrm_jarvis.javacommons.primitive.Numeric; @@ -37,6 +38,14 @@ default Class getWrapperClass() { */ void set(int value); + /** + * Sets the value to the one given returning the previous one. + * + * @param newValue value to be set + * @return previous value + */ + int getAndSet(int newValue); + /** * Gets the value after what it gets incremented. * @@ -175,6 +184,14 @@ public void set(final int value) { this.value = value; } + @Override + public int getAndSet(final int newValue) { + val oldValue = value; + value = newValue; + + return oldValue; + } + @Override public int getAndIncrement() { return value++; @@ -273,6 +290,7 @@ public double doubleValue() { @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) final class AtomicIntegerIntWrapper implements IntWrapper { + @Delegate(types = IntWrapper.class) @NonNull AtomicInteger value; /** @@ -288,97 +306,7 @@ public AtomicIntegerIntWrapper(final int value) { * Creates new atomic integer int wrapper with initial value set to {@code 0}. */ public AtomicIntegerIntWrapper() { - this.value = new AtomicInteger(); - } - - @Override - public int get() { - return value.get(); - } - - @Override - public void set(final int value) { - this.value.set(value); - } - - @Override - public int getAndIncrement() { - return value.getAndIncrement(); - } - - @Override - public int incrementAndGet() { - return value.incrementAndGet(); - } - - @Override - public int getAndDecrement() { - return value.getAndDecrement(); - } - - @Override - public int decrementAndGet() { - return value.decrementAndGet(); - } - - @Override - public int getAndAdd(final int delta) { - return value.getAndAdd(delta); - } - - @Override - public int addAndGet(final int delta) { - return value.addAndGet(delta); - } - - @Override - public int getAndUpdate(@NonNull final IntUnaryOperator updateFunction) { - return value.getAndUpdate(updateFunction); - } - - @Override - public int updateAndGet(@NonNull final IntUnaryOperator updateFunction) { - return value.updateAndGet(updateFunction); - } - - @Override - public int getAndAccumulate(final int updateValue, @NonNull final IntBinaryOperator accumulatorFunction) { - return value.getAndAccumulate(updateValue, accumulatorFunction); - } - - @Override - public int accumulateAndGet(final int updateValue, @NonNull final IntBinaryOperator accumulatorFunction) { - return value.accumulateAndGet(updateValue, accumulatorFunction); - } - - @Override - public byte byteValue() { - return value.byteValue(); - } - - @Override - public short shortValue() { - return value.shortValue(); - } - - @Override - public int intValue() { - return value.intValue(); - } - - @Override - public long longValue() { - return value.longValue(); - } - - @Override - public float floatValue() { - return value.floatValue(); - } - - @Override - public double doubleValue() { - return value.doubleValue(); + value = new AtomicInteger(); } } } diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/LongWrapper.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/LongWrapper.java index 1d350058..c98067cb 100644 --- a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/LongWrapper.java +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/LongWrapper.java @@ -1,6 +1,7 @@ package ru.progrm_jarvis.javacommons.primitive.wrapper; import lombok.*; +import lombok.experimental.Delegate; import lombok.experimental.FieldDefaults; import ru.progrm_jarvis.javacommons.primitive.Numeric; @@ -37,6 +38,14 @@ default Class getWrapperClass() { */ void set(long value); + /** + * Sets the value to the one given returning the previous one. + * + * @param newValue value to be set + * @return previous value + */ + long getAndSet(long newValue); + /** * Gets the value after what it gets incremented. * @@ -175,6 +184,14 @@ public void set(final long value) { this.value = value; } + @Override + public long getAndSet(final long newValue) { + val oldValue = value; + value = newValue; + + return oldValue; + } + @Override public long getAndIncrement() { return value++; @@ -273,6 +290,7 @@ public double doubleValue() { @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) final class AtomicLongLongWrapper implements LongWrapper { + @Delegate(types = LongWrapper.class) @NonNull AtomicLong value; /** @@ -288,97 +306,7 @@ public AtomicLongLongWrapper(final long value) { * Creates new atomic long long wrapper with initial value set to {@code 0}. */ public AtomicLongLongWrapper() { - this.value = new AtomicLong(); - } - - @Override - public long get() { - return value.get(); - } - - @Override - public void set(final long value) { - this.value.set(value); - } - - @Override - public long getAndIncrement() { - return value.getAndIncrement(); - } - - @Override - public long incrementAndGet() { - return value.incrementAndGet(); - } - - @Override - public long getAndDecrement() { - return value.getAndDecrement(); - } - - @Override - public long decrementAndGet() { - return value.decrementAndGet(); - } - - @Override - public long getAndAdd(final long delta) { - return value.getAndAdd(delta); - } - - @Override - public long addAndGet(final long delta) { - return value.addAndGet(delta); - } - - @Override - public long getAndUpdate(@NonNull final LongUnaryOperator updateFunction) { - return value.getAndUpdate(updateFunction); - } - - @Override - public long updateAndGet(@NonNull final LongUnaryOperator updateFunction) { - return value.updateAndGet(updateFunction); - } - - @Override - public long getAndAccumulate(final long updateValue, @NonNull final LongBinaryOperator accumulatorFunction) { - return value.getAndAccumulate(updateValue, accumulatorFunction); - } - - @Override - public long accumulateAndGet(final long updateValue, @NonNull final LongBinaryOperator accumulatorFunction) { - return value.accumulateAndGet(updateValue, accumulatorFunction); - } - - @Override - public byte byteValue() { - return value.byteValue(); - } - - @Override - public short shortValue() { - return value.shortValue(); - } - - @Override - public int intValue() { - return value.intValue(); - } - - @Override - public long longValue() { - return value.longValue(); - } - - @Override - public float floatValue() { - return value.floatValue(); - } - - @Override - public double doubleValue() { - return value.doubleValue(); + value = new AtomicLong(); } } } From 72224f8cf9805b155bb4976313fba354eb74592a Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Sat, 25 Apr 2020 16:49:09 +0300 Subject: [PATCH 25/27] Cleanup primitive wrappers --- .../primitive/wrapper/BooleanWrapper.java | 68 ++++++++-------- .../primitive/wrapper/IntWrapper.java | 80 +++++++++---------- .../primitive/wrapper/LongWrapper.java | 80 +++++++++---------- 3 files changed, 114 insertions(+), 114 deletions(-) diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/BooleanWrapper.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/BooleanWrapper.java index a78de05e..ed93f97e 100644 --- a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/BooleanWrapper.java +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/BooleanWrapper.java @@ -11,38 +11,6 @@ */ public interface BooleanWrapper extends PrimitiveWrapper { - @Override - default Class getPrimitiveClass() { - return boolean.class; - } - - @Override - default Class getWrapperClass() { - return Boolean.class; - } - - /** - * Gets the value. - * - * @return value - */ - boolean get(); - - /** - * Sets the value. - * - * @param value value to be set - */ - void set(boolean value); - - /** - * Sets the value to the one given returning the previous one. - * - * @param newValue value to be set - * @return previous value - */ - boolean getAndSet(boolean newValue); - /** * Creates new simple boolean wrapper. * @@ -82,6 +50,38 @@ static BooleanWrapper createAtomic() { return new AtomicBooleanWrapper(); } + @Override + default Class getPrimitiveClass() { + return boolean.class; + } + + @Override + default Class getWrapperClass() { + return Boolean.class; + } + + /** + * Gets the value. + * + * @return value + */ + boolean get(); + + /** + * Sets the value. + * + * @param value value to be set + */ + void set(boolean value); + + /** + * Sets the value to the one given returning the previous one. + * + * @param newValue value to be set + * @return previous value + */ + boolean getAndSet(boolean newValue); + /** * {@link BooleanWrapper} implementation based on {@code boolean}. */ @@ -129,14 +129,14 @@ final class AtomicBooleanWrapper implements BooleanWrapper { * * @param value initial value */ - public AtomicBooleanWrapper(final boolean value) { + private AtomicBooleanWrapper(final boolean value) { this.value = new AtomicBoolean(value); } /** * Creates new atomic boolean boolean wrapper with initial value set to {@code 0}. */ - public AtomicBooleanWrapper() { + private AtomicBooleanWrapper() { value = new AtomicBoolean(); } } diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java index f1e7aa67..88773105 100644 --- a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java @@ -14,6 +14,44 @@ */ public interface IntWrapper extends PrimitiveWrapper, Numeric { + /** + * Creates new simple int wrapper. + * + * @param value initial value of int wrapper + * @return created int wrapper + */ + static IntWrapper create(final int value) { + return new IntIntWrapper(value); + } + + /** + * Creates new simple int wrapper with initial value set to {@code 0}. + * + * @return created int wrapper + */ + static IntWrapper create() { + return new IntIntWrapper(); + } + + /** + * Creates new atomic int wrapper. + * + * @param value initial value of int wrapper + * @return created int wrapper + */ + static IntWrapper createAtomic(final int value) { + return new AtomicIntegerIntWrapper(value); + } + + /** + * Creates new atomic int wrapper with initial value set to {@code 0}. + * + * @return created int wrapper + */ + static IntWrapper createAtomic() { + return new AtomicIntegerIntWrapper(); + } + @Override default Class getPrimitiveClass() { return int.class; @@ -124,44 +162,6 @@ default Class getWrapperClass() { */ int accumulateAndGet(int updateValue, @NonNull IntBinaryOperator accumulatorFunction); - /** - * Creates new simple int wrapper. - * - * @param value initial value of int wrapper - * @return created int wrapper - */ - static IntWrapper create(final int value) { - return new IntIntWrapper(value); - } - - /** - * Creates new simple int wrapper with initial value set to {@code 0}. - * - * @return created int wrapper - */ - static IntWrapper create() { - return new IntIntWrapper(); - } - - /** - * Creates new atomic int wrapper. - * - * @param value initial value of int wrapper - * @return created int wrapper - */ - static IntWrapper createAtomic(final int value) { - return new AtomicIntegerIntWrapper(value); - } - - /** - * Creates new atomic int wrapper with initial value set to {@code 0}. - * - * @return created int wrapper - */ - static IntWrapper createAtomic() { - return new AtomicIntegerIntWrapper(); - } - /** * {@link IntWrapper} implementation based on {@code int}. */ @@ -298,14 +298,14 @@ final class AtomicIntegerIntWrapper implements IntWrapper { * * @param value initial value */ - public AtomicIntegerIntWrapper(final int value) { + private AtomicIntegerIntWrapper(final int value) { this.value = new AtomicInteger(value); } /** * Creates new atomic integer int wrapper with initial value set to {@code 0}. */ - public AtomicIntegerIntWrapper() { + private AtomicIntegerIntWrapper() { value = new AtomicInteger(); } } diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/LongWrapper.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/LongWrapper.java index c98067cb..1883c2bb 100644 --- a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/LongWrapper.java +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/LongWrapper.java @@ -14,6 +14,44 @@ */ public interface LongWrapper extends PrimitiveWrapper, Numeric { + /** + * Creates new simple long wrapper. + * + * @param value initial value of long wrapper + * @return created long wrapper + */ + static LongWrapper create(final long value) { + return new LongLongWrapper(value); + } + + /** + * Creates new simple long wrapper with initial value set to {@code 0}. + * + * @return created long wrapper + */ + static LongWrapper create() { + return new LongLongWrapper(0); + } + + /** + * Creates new atomic long wrapper. + * + * @param value initial value of long wrapper + * @return created long wrapper + */ + static LongWrapper createAtomic(final long value) { + return new AtomicLongLongWrapper(value); + } + + /** + * Creates new atomic long wrapper with initial value set to {@code 0}. + * + * @return created long wrapper + */ + static LongWrapper createAtomic() { + return new AtomicLongLongWrapper(); + } + @Override default Class getPrimitiveClass() { return long.class; @@ -124,44 +162,6 @@ default Class getWrapperClass() { */ long accumulateAndGet(long updateValue, @NonNull LongBinaryOperator accumulatorFunction); - /** - * Creates new simple long wrapper. - * - * @param value initial value of long wrapper - * @return created long wrapper - */ - static LongWrapper create(final long value) { - return new LongLongWrapper(value); - } - - /** - * Creates new simple long wrapper with initial value set to {@code 0}. - * - * @return created long wrapper - */ - static LongWrapper create() { - return new LongLongWrapper(0); - } - - /** - * Creates new atomic long wrapper. - * - * @param value initial value of long wrapper - * @return created long wrapper - */ - static LongWrapper createAtomic(final long value) { - return new AtomicLongLongWrapper(value); - } - - /** - * Creates new atomic long wrapper with initial value set to {@code 0}. - * - * @return created long wrapper - */ - static LongWrapper createAtomic() { - return new AtomicLongLongWrapper(); - } - /** * {@link LongWrapper} implementation based on {@code long}. */ @@ -298,14 +298,14 @@ final class AtomicLongLongWrapper implements LongWrapper { * * @param value initial value */ - public AtomicLongLongWrapper(final long value) { + private AtomicLongLongWrapper(final long value) { this.value = new AtomicLong(value); } /** * Creates new atomic long long wrapper with initial value set to {@code 0}. */ - public AtomicLongLongWrapper() { + private AtomicLongLongWrapper() { value = new AtomicLong(); } } From 09e2df2c29290a1c9f5228f2ac8f34df5dfa7e80 Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Sat, 25 Apr 2020 16:53:42 +0300 Subject: [PATCH 26/27] Resolve compilation issues due to Lombok searching for methods from `PrimitiveWrapper` in atomics --- .../javacommons/primitive/wrapper/BooleanWrapper.java | 2 +- .../progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java | 2 +- .../javacommons/primitive/wrapper/LongWrapper.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/BooleanWrapper.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/BooleanWrapper.java index ed93f97e..1b47eb49 100644 --- a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/BooleanWrapper.java +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/BooleanWrapper.java @@ -121,7 +121,7 @@ public boolean getAndSet(final boolean newValue) { @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) final class AtomicBooleanWrapper implements BooleanWrapper { - @Delegate(types = BooleanWrapper.class) + @Delegate(types = BooleanWrapper.class, excludes = PrimitiveWrapper.class) @NonNull AtomicBoolean value; /** diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java index 88773105..2c9aaa7e 100644 --- a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/IntWrapper.java @@ -290,7 +290,7 @@ public double doubleValue() { @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) final class AtomicIntegerIntWrapper implements IntWrapper { - @Delegate(types = IntWrapper.class) + @Delegate(types = IntWrapper.class, excludes = PrimitiveWrapper.class) @NonNull AtomicInteger value; /** diff --git a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/LongWrapper.java b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/LongWrapper.java index 1883c2bb..3d07ebf5 100644 --- a/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/LongWrapper.java +++ b/java-commons/src/main/java/ru/progrm_jarvis/javacommons/primitive/wrapper/LongWrapper.java @@ -290,7 +290,7 @@ public double doubleValue() { @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) final class AtomicLongLongWrapper implements LongWrapper { - @Delegate(types = LongWrapper.class) + @Delegate(types = LongWrapper.class, excludes = PrimitiveWrapper.class) @NonNull AtomicLong value; /** From 7c67446c412c1aafb3eca4e89e0b614c6c0f1d27 Mon Sep 17 00:00:00 2001 From: progrm_jarvis Date: Sat, 25 Apr 2020 17:02:33 +0300 Subject: [PATCH 27/27] Configure Maven build for tools --- tools/pom.xml | 14 ++++++++++++++ tools/unsafe-methods-access-generator/pom.xml | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/tools/pom.xml b/tools/pom.xml index cccb988a..d99f5ac2 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -14,6 +14,20 @@ pom + + clean package + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.0 + + + + + diff --git a/tools/unsafe-methods-access-generator/pom.xml b/tools/unsafe-methods-access-generator/pom.xml index d82a9f48..dbb73730 100644 --- a/tools/unsafe-methods-access-generator/pom.xml +++ b/tools/unsafe-methods-access-generator/pom.xml @@ -10,6 +10,25 @@ unsafe-methods-access-generator + + pa + + + + maven-jar-plugin + + + + + ru.progrm_jarvis.padla.tools.unsafemethodsaccessgenerator.UnsafeMethodsAccessGenerator + + + + + + + + commons-cli