/**
  * Returns a memoized (caching) version of this {@link ThrowableShortUnaryOperator}. Whenever it
  * is called, the mapping between the input parameter and the return value is preserved in a
  * cache, making subsequent calls returning the memoized value instead of computing the return
  * value again.
  *
  * <p>Unless the operator and therefore the used cache will be garbage-collected, it will keep all
  * memoized values forever.
  *
  * @return A memoized (caching) version of this {@code ThrowableShortUnaryOperator}.
  * @implSpec This implementation does not allow the input parameter or return value to be {@code
  *     null} for the resulting memoized operator, as the cache used internally does not permit
  *     {@code null} keys or values.
  * @implNote The returned memoized operator can be safely used concurrently from multiple threads
  *     which makes it thread-safe.
  */
 @Nonnull
 default ThrowableShortUnaryOperator<X> memoized() {
   if (isMemoized()) {
     return this;
   } else {
     final Map<Short, Short> cache = new ConcurrentHashMap<>();
     final Object lock = new Object();
     return (ThrowableShortUnaryOperator<X> & Memoized)
         (value) -> {
           final short returnValue;
           synchronized (lock) {
             returnValue =
                 cache.computeIfAbsent(value, ThrowableFunction.of(this::applyAsShortThrows));
           }
           return returnValue;
         };
   }
 }
 /**
  * Returns a memoized (caching) version of this {@link ThrowableBiByteToIntFunction}. Whenever it
  * is called, the mapping between the input parameters and the return value is preserved in a
  * cache, making subsequent calls returning the memoized value instead of computing the return
  * value again.
  *
  * <p>Unless the function and therefore the used cache will be garbage-collected, it will keep all
  * memoized values forever.
  *
  * @return A memoized (caching) version of this {@code ThrowableBiByteToIntFunction}.
  * @implSpec This implementation does not allow the input parameters or return value to be {@code
  *     null} for the resulting memoized function, as the cache used internally does not permit
  *     {@code null} keys or values.
  * @implNote The returned memoized function can be safely used concurrently from multiple threads
  *     which makes it thread-safe.
  */
 @Nonnull
 default ThrowableBiByteToIntFunction<X> memoized() {
   if (isMemoized()) {
     return this;
   } else {
     final Map<Pair<Byte, Byte>, Integer> cache = new ConcurrentHashMap<>();
     final Object lock = new Object();
     return (ThrowableBiByteToIntFunction<X> & Memoized)
         (value1, value2) -> {
           final int returnValue;
           synchronized (lock) {
             returnValue =
                 cache.computeIfAbsent(
                     Pair.of(value1, value2),
                     ThrowableFunction.of(key -> applyAsIntThrows(key.getLeft(), key.getRight())));
           }
           return returnValue;
         };
   }
 }
 /**
  * Returns a memoized (caching) version of this {@link ThrowableObjCharToDoubleFunction}. Whenever
  * it is called, the mapping between the input parameters and the return value is preserved in a
  * cache, making subsequent calls returning the memoized value instead of computing the return
  * value again.
  *
  * <p>Unless the function and therefore the used cache will be garbage-collected, it will keep all
  * memoized values forever.
  *
  * @return A memoized (caching) version of this {@code ThrowableObjCharToDoubleFunction}.
  * @implSpec This implementation does not allow the input parameters or return value to be {@code
  *     null} for the resulting memoized function, as the cache used internally does not permit
  *     {@code null} keys or values.
  * @implNote The returned memoized function can be safely used concurrently from multiple threads
  *     which makes it thread-safe.
  */
 @Nonnull
 default ThrowableObjCharToDoubleFunction<T, X> memoized() {
   if (isMemoized()) {
     return this;
   } else {
     final Map<Pair<T, Character>, Double> cache = new ConcurrentHashMap<>();
     final Object lock = new Object();
     return (ThrowableObjCharToDoubleFunction<T, X> & Memoized)
         (t, value) -> {
           final double returnValue;
           synchronized (lock) {
             returnValue =
                 cache.computeIfAbsent(
                     Pair.of(t, value),
                     ThrowableFunction.of(
                         key -> applyAsDoubleThrows(key.getLeft(), key.getRight())));
           }
           return returnValue;
         };
   }
 }
 /**
  * Returns a memoized (caching) version of this {@link ThrowableBiCharToShortFunction}. Whenever
  * it is called, the mapping between the input parameters and the return value is preserved in a
  * cache, making subsequent calls returning the memoized value instead of computing the return
  * value again.
  *
  * <p>Unless the function and therefore the used cache will be garbage-collected, it will keep all
  * memoized values forever.
  *
  * @return A memoized (caching) version of this {@code ThrowableBiCharToShortFunction}.
  * @implSpec This implementation does not allow the input parameters or return value to be {@code
  *     null} for the resulting memoized function, as the cache used internally does not permit
  *     {@code null} keys or values.
  * @implNote The returned memoized function can be safely used concurrently from multiple threads
  *     which makes it thread-safe.
  */
 @Nonnull
 default ThrowableBiCharToShortFunction<X> memoized() {
   if (isMemoized()) {
     return this;
   } else {
     final Map<Pair<Character, Character>, Short> cache = new ConcurrentHashMap<>();
     final Object lock = new Object();
     return (ThrowableBiCharToShortFunction<X> & Memoized)
         (value1, value2) -> {
           final short returnValue;
           synchronized (lock) {
             returnValue =
                 cache.computeIfAbsent(
                     Pair.of(value1, value2),
                     ThrowableFunction.of(
                         key -> applyAsShortThrows(key.getLeft(), key.getRight())));
           }
           return returnValue;
         };
   }
 }
 /**
  * Returns a memoized (caching) version of this {@link ThrowableObjBiBooleanToByteFunction}.
  * Whenever it is called, the mapping between the input parameters and the return value is
  * preserved in a cache, making subsequent calls returning the memoized value instead of computing
  * the return value again.
  *
  * <p>Unless the function and therefore the used cache will be garbage-collected, it will keep all
  * memoized values forever.
  *
  * @return A memoized (caching) version of this {@code ThrowableObjBiBooleanToByteFunction}.
  * @implSpec This implementation does not allow the input parameters or return value to be {@code
  *     null} for the resulting memoized function, as the cache used internally does not permit
  *     {@code null} keys or values.
  * @implNote The returned memoized function can be safely used concurrently from multiple threads
  *     which makes it thread-safe.
  */
 @Nonnull
 default ThrowableObjBiBooleanToByteFunction<T, X> memoized() {
   if (isMemoized()) {
     return this;
   } else {
     final Map<Triple<T, Boolean, Boolean>, Byte> cache = new ConcurrentHashMap<>();
     final Object lock = new Object();
     return (ThrowableObjBiBooleanToByteFunction<T, X> & Memoized)
         (t, value1, value2) -> {
           final byte returnValue;
           synchronized (lock) {
             returnValue =
                 cache.computeIfAbsent(
                     Triple.of(t, value1, value2),
                     ThrowableFunction.of(
                         key ->
                             applyAsByteThrows(key.getLeft(), key.getMiddle(), key.getRight())));
           }
           return returnValue;
         };
   }
 }
 /**
  * Returns a memoized (caching) version of this {@link ThrowableTriByteToFloatFunction}. Whenever
  * it is called, the mapping between the input parameters and the return value is preserved in a
  * cache, making subsequent calls returning the memoized value instead of computing the return
  * value again.
  *
  * <p>Unless the function and therefore the used cache will be garbage-collected, it will keep all
  * memoized values forever.
  *
  * @return A memoized (caching) version of this {@code ThrowableTriByteToFloatFunction}.
  * @implSpec This implementation does not allow the input parameters or return value to be {@code
  *     null} for the resulting memoized function, as the cache used internally does not permit
  *     {@code null} keys or values.
  * @implNote The returned memoized function can be safely used concurrently from multiple threads
  *     which makes it thread-safe.
  */
 @Nonnull
 default ThrowableTriByteToFloatFunction<X> memoized() {
   if (isMemoized()) {
     return this;
   } else {
     final Map<Triple<Byte, Byte, Byte>, Float> cache = new ConcurrentHashMap<>();
     final Object lock = new Object();
     return (ThrowableTriByteToFloatFunction<X> & Memoized)
         (value1, value2, value3) -> {
           final float returnValue;
           synchronized (lock) {
             returnValue =
                 cache.computeIfAbsent(
                     Triple.of(value1, value2, value3),
                     ThrowableFunction.of(
                         key ->
                             applyAsFloatThrows(key.getLeft(), key.getMiddle(), key.getRight())));
           }
           return returnValue;
         };
   }
 }