SproutsFactory.java
package sprouts.impl;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import sprouts.*;
import java.util.Comparator;
import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.regex.Pattern;
/**
* Creates instances of the various types of the Sprouts library, like its
* persistent data structures (see {@link Tuple}, {@link Association}, {@link ValueSet})
* or reactive properties ({@link Val}, {@link Var}, {@link Vals}, {@link Vars}).<br>
* This interface allows you to plug in your own implementations of the Sprouts
* properties and collections, through the {@link Sprouts#setFactory(SproutsFactory)} method.<br>
* <p>
* All other (static) factory methods on the various Sprouts
* types delegate to this API for instantiation.
* <b>So please be careful when plugging a custom implementation!</b>
* </p>
*/
public interface SproutsFactory
{
/**
* Creates a delegate for when a {@link Val}/{@link Var} property
* changes its value or is explicitly triggered to propagate the
* event to all derived {@link Viewable} instances and their {@link Action}s.
*
* @param source The source property for which the delegate is created.
* @param channel The channel on which the change event was triggered (see {@link Val#fireChange(Channel)}).
* @param change The type of change that occurred in the property, which may
* also be {@link SingleChange#NONE} if the change was triggered
* explicitly without any actual change in the value.
* @param newValue The new value of the property after the change.
* @param oldValue The old value of the property before the change.
* @return A delegate for the given {@link Val} property.
* @param <T> The item type of the property for which the delegate is created.
*/
<T> ValDelegate<T> delegateOf(
Val<T> source,
Channel channel,
SingleChange change,
@Nullable T newValue,
@Nullable T oldValue
);
/**
* Creates a delegate for when a {@link Vals}/{@link Vars} property list
* to be specifically designed as a context object passed to {@link Action}s
* registered on {@link Viewable}s, like for example through the
* {@link Viewable#onChange(Channel, Action)} method.
*
* @param source The source property for which the delegate is created.
* @param changeType The type of change that occurred in the property.
* @param index The (start) index at which the change occurred.
* @param newValues The new values of the property after the change.
* @param oldValues The old values of the property before the change.
* @return A delegate for the given {@link Vals} property.
* @param <T> The type of the property for which the delegate is created.
*/
<T> ValsDelegate<T> delegateOf(
Vals<T> source,
SequenceChange changeType,
int index,
Vals<T> newValues,
Vals<T> oldValues
);
/**
* A factory method to create a new {@link Event} instance.
* An {@link Event} can be triggered using the {@link Event#fire()} method,
* and it will notify all {@link Action}s registered on {@link Observer}s
* derived from the {@link Event} instance through the
* {@link Event#observable()} method.
*
* @return A new {@link Event} instance with the default executor.
*/
Event event();
/**
* A factory method to create a new {@link Event} instance with the given executor.
* An {@link Event} can be triggered using the {@link Event#fire()} method,
* and it will notify all {@link Action}s registered on {@link Observer}s
* derived from the {@link Event} instance through the
* {@link Event#observable()} method.
*
* @param executor The executor to be used for the event. It must not be {@code null}.
* @return A new {@link Event} instance with the specified executor.
*/
Event eventOf( Event.Executor executor );
/**
* Creates a nullable {@link Maybe} instance of the given type with the specified item.
* @param type The type of the item to be wrapped in the {@link Maybe}. It must not be {@code null}.
* @param item The item to be wrapped in the {@link Maybe}. It can be {@code null}.
* @return A {@link Maybe} instance containing the item, or an empty {@link Maybe} if the item is {@code null}.
* @param <T> The type of the item to be wrapped in the {@link Maybe}.
*/
default <T> Maybe<@Nullable T> maybeOfNullable( Class<T> type, @Nullable T item ) {
return valOfNullable( type, item );
}
/**
* Creates a {@link Maybe} instance of the given type with a {@code null} item.
* The {@link Maybe#isEmpty()} method of the returned instance will <b>always</b>
* return {@code true}, indicating that the {@link Maybe} does not contain a value.
*
* @param type The type of the item to be wrapped in the {@link Maybe}.
* It must not be {@code null}.
* @return A {@link Maybe} instance containing a {@code null} item.
* @param <T> The type of the item to be wrapped in the {@link Maybe}.
*/
default <T> Maybe<@Nullable T> maybeOfNull( Class<T> type ) {
return valOfNull( type );
}
/**
* Creates a {@link Maybe} instance from a non-nullable item.
* The {@link Maybe#isPresent()} method of the returned instance will <b>always</b>
* return {@code true}, indicating that the {@link Maybe} contains a value.
*
* @param item The item to be wrapped in the {@link Maybe}. It must not be {@code null}.
* @return A {@link Maybe} instance containing the item.
* @param <T> The type of the item to be wrapped in the {@link Maybe}.
*/
default <T> Maybe<T> maybeOf( T item ) {
return valOf( item );
}
/**
* Creates a non-empty {@link Maybe} copy from the supplied {@link Maybe}.
* The supplied {@link Maybe} must not contain a null item.
* So if the factory call was successful, then the {@link Maybe#isPresent()} method of the
* returned instance will <b>always</b> return {@code true},
* indicating that the {@link Maybe} contains a value.
* The returned instance is effectively an immutable copy of the supplied {@link Maybe}.
*
* @param toBeCopied The {@link Maybe} instance to be copied. It must not be {@code null} and it
* also must not contain a {@code null} value.
* @return A new {@link Maybe} instance containing the value from the given {@link Maybe}.
* @param <T> The type of the item to be wrapped in the {@link Maybe}.
*/
default <T> Maybe<T> maybeOf( Maybe<T> toBeCopied ) {
Objects.requireNonNull(toBeCopied);
return valOf( toBeCopied.orElseThrowUnchecked() );
}
/**
* Creates a potentially empty {@link Maybe} copy from the supplied {@link Maybe},
* which may or may not contain a null item.
* The returned instance is effectively an immutable copy of the supplied {@link Maybe}.
*
* @param toBeCopied The {@link Maybe} instance to be copied.
* @return A new {@link Maybe} instance containing the value from the given {@link Maybe},
* or an empty {@link Maybe} if the value is {@code null}.
* @param <T> The type of the item to be wrapped in the {@link Maybe}.
* @throws NullPointerException if {@code toBeCopied} is {@code null}.
* (However, the item in the supplied {@link Maybe} can be {@code null}.)
*/
default <T extends @Nullable Object> Maybe<@Nullable T> maybeOfNullable( Maybe<T> toBeCopied ) {
Objects.requireNonNull(toBeCopied);
return valOfNullable( toBeCopied.type(), toBeCopied.orElseNull() );
}
/**
* Creates a new {@link Val} property from a type class and an item which may or may not be null.
* The resulting property may or may not be empty (see {@link Val#isEmpty()}.
* @param type The type of the item to be wrapped in the {@link Val}, which must not be null.
* @param item The item to be wrapped in the {@link Val}. It can be {@code null}.
* @return A {@link Val} instance containing the item, or an empty {@link Val} if the item is {@code null}.
* @param <T> The type of the item to be wrapped in the {@link Val} property.
* @throws NullPointerException if {@code type} is {@code null}.
*/
<T> Val<@Nullable T> valOfNullable( Class<T> type, @Nullable T item );
/**
* Creates an empty {@link Val} property from the given type class.
* The {@link Val#isEmpty()} method of the returned instance will <b>always</b>
* return {@code true}, indicating that the {@link Val} does not contain a value.
*
* @param type The type of the item to be wrapped in the {@link Val}. It must not be {@code null}.
* @return An immutable and empty {@link Val} instance containing a {@code null} item.
* @param <T> The type of the item to be wrapped in the {@link Val}.
*/
<T> Val<@Nullable T> valOfNull( Class<T> type );
/**
* Creates a non-null {@link Val} instance of the given non-null item.
* The {@link Val#isPresent()} method of the returned instance will <b>always</b>
* return {@code true}, indicating that the {@link Val} does contain a value.
*
* @param item The item to be wrapped in the {@link Val}. It must not be {@code null}.
* @return An immutable and non-empty {@link Val} instance containing the item.
* @param <T> The type of the item to be wrapped in the {@link Val}.
* @throws NullPointerException if {@code item} is {@code null}.
*/
<T> Val<T> valOf( T item );
/**
* Creates a non-empty {@link Val} copy from the supplied {@link Val}.
* The supplied {@link Val} must not contain a null item.
* So if the factory call was successful, then the {@link Val#isPresent()} method of the
* returned instance will <b>always</b> return {@code true},
* indicating that the {@link Val} contains a value.
* The returned instance is effectively an immutable copy of the supplied {@link Val}.
* @param toBeCopied The {@link Val} instance to be copied. It must not be {@code null} and it
* must not contain a {@code null} value.
* @return A new {@link Val} instance containing the value from the given {@link Val}.
* @param <T> The type of the item to be wrapped in the {@link Val}.
* @throws NullPointerException if {@code toBeCopied} is {@code null}.
*/
<T> Val<T> valOf( Val<T> toBeCopied );
/**
* Creates a nullable {@link Val} instance of the given type by copying the value from another {@link Val}.
* @param toBeCopied The {@link Val} instance to be copied. It must not be {@code null},
* however, the value in the {@link Val} can be {@code null}.
* @return A new {@link Val} instance containing the value from the given {@link Val}, or an empty {@link Val} if the value is {@code null}.
* @param <T> The type of the item to be wrapped in the {@link Val}.
* @throws NullPointerException if {@code toBeCopied} is {@code null}.
*/
<T extends @Nullable Object> Val<@Nullable T> valOfNullable( Val<T> toBeCopied );
/**
* Creates a {@link Viewable} instance of the given {@link Val}.
* You can register observers on the returned {@link Viewable} to receive updates
* when the value of the {@link Val} changes.
*
* @param source The source {@link Val} for which the view is created.
* @return A {@link Viewable} instance that wraps the given {@link Val}. The source may not be {@code null}.
* @param <T> The type of the item in the {@link Val}.
* @throws NullPointerException if {@code source} is {@code null}.
*/
<T extends @Nullable Object> Viewable<T> viewOf( Val<T> source );
/**
* Creates a non-null {@link Viewable} instance which is a composite of two {@link Val} instances
* whose values are combined using the specified combiner function. You may register observers
* on the resulting viewable to receive updates when the values of either of the
* two {@link Val} instances change.
*
* @param first The first {@link Val} to be combined into a {@link Viewable} composite.
* @param second The second {@link Val} to be combined into a {@link Viewable} composite.
* @param combiner The function that combines the values of the two {@link Val} instances into a single value.
* @return A {@link Viewable} instance that combines the values of the two {@link Val} instances using the specified combiner function.
* @param <T> The type of the first {@link Val} value.
* @param <U> The type of the second {@link Val} value.
* @throws NullPointerException if any of the supplied parameters are {@code null}.
*/
<T extends @Nullable Object, U extends @Nullable Object> Viewable<@NonNull T> viewOf(Val<T> first, Val<U> second, BiFunction<T, U, @NonNull T> combiner );
/**
* Creates a nullable {@link Viewable} instance which is a composite of two {@link Val} instances
* whose values are combined using the specified combiner function. You may register observers
* on the resulting viewable to receive updates when the values of either of the
* two {@link Val} instances change.
*
* @param first The first {@link Val} to be combined into a {@link Viewable} composite.
* @param second The second {@link Val} to be combined into a {@link Viewable} composite.
* @param combiner The function that combines the values of the two {@link Val} instances into a single value.
* @return A {@link Viewable} instance that combines the values of the two {@link Val} instances using the specified combiner function.
* @param <T> The type of the first {@link Val} value.
* @param <U> The type of the second {@link Val} value.
* @throws NullPointerException if any of the supplied parameters are {@code null}.
*/
<T extends @Nullable Object, U extends @Nullable Object> Viewable<@Nullable T> viewOfNullable( Val<T> first, Val<U> second, BiFunction<T, U, @Nullable T> combiner );
/**
* Creates a non-nullable {@link Viewable} instance of the given type which is a composite of two {@link Val}
* instances whose values are combined using the specified combiner function. You may register observers
* on the resulting viewable to receive updates when the values of either of the
* two {@link Val} instances change.
*
* @param type The type of the resulting {@link Viewable}.
* @param first The first {@link Val} to be combined into a {@link Viewable} composite.
* @param second The second {@link Val} to be combined into a {@link Viewable} composite.
* @param combiner The function that combines the values of the two {@link Val} instances into a single value.
* @return A {@link Viewable} instance that combines the values of the two {@link Val} instances using the specified combiner function.
* @param <T> The type of the first {@link Val} value.
* @param <U> The type of the second {@link Val} value.
* @param <R> The type of the resulting {@link Viewable}.
* @throws NullPointerException if any of the supplied parameters are {@code null}.
*/
<T extends @Nullable Object, U extends @Nullable Object, R> Viewable<R> viewOf(Class<R> type, Val<T> first, Val<U> second, BiFunction<T,U,R> combiner);
/**
* Creates a nullable {@link Viewable} instance of the given type which is a composite of two {@link Val}
* instances whose values are combined using the specified combiner function. You may register observers
* on the resulting viewable to receive updates when the values of either of the
* two {@link Val} instances change.
*
* @param type The type of the resulting {@link Viewable}.
* @param first The first {@link Val} to be combined into a {@link Viewable} composite.
* @param second The second {@link Val} to be combined into a {@link Viewable} composite.
* @param combiner The function that combines the values of the two {@link Val} instances into a single value.
* @return A {@link Viewable} instance that combines the values of the two {@link Val} instances using the specified combiner function.
* @param <T> The type of the first {@link Val} value.
* @param <U> The type of the second {@link Val} value.
* @param <R> The type of the resulting {@link Viewable}.
* @throws NullPointerException if any of the supplied parameters are {@code null}.
*/
<T extends @Nullable Object, U extends @Nullable Object, R> Viewable<@Nullable R> viewOfNullable(Class<R> type, Val<T> first, Val<U> second, BiFunction<T, U, @Nullable R> combiner);
/**
* Creates a {@link Viewables} instance of the given {@link Vals}.
* You can register observers on the returned {@link Viewables} to receive updates
* when the items in the {@link Vals} change.
*
* @param source The source {@link Vals} for which the view is created.
* @return A {@link Viewables} instance that wraps the given {@link Vals}.
* @param <T> The type of the items in the {@link Vals}.
* @throws NullPointerException if {@code source} is {@code null}.
*/
<T extends @Nullable Object> Viewables<T> viewOf( Vals<T> source );
/**
* Creates a mapped {@link Viewables} instance of the given {@link Vals} with specified null and error objects.
* This is useful when you want to provide default values for the {@link Viewables} when the source
* property contains a {@code null} value or an error occurs during mapping.
*
* @param nullObject The default value to be used when the source value is null.
* @param errorObject The default value to be used when an error occurs during mapping.
* @param source The source {@link Vals} for which the view is created.
* @return A {@link Viewables} instance that wraps the given {@link Vals} with specified null and error objects.
* @param mapper The function that maps the source value to the resulting value.
* @param <T> The type of the items in the {@link Vals}.
* @param <U> The type of the items in the resulting {@link Viewables}.
* @throws NullPointerException if any of the supplied parameters are {@code null}.
*/
<T extends @Nullable Object, U> Viewables<U> viewOf( U nullObject, U errorObject, Vals<T> source, Function<T, @Nullable U> mapper );
/**
* Creates a mapped {@link Viewable} instance of the given type which is a
* view of the value of the specified source {@link Val} mapped to a different type
* using the provided mapper function.<br>
* You can register observers on the returned {@link Viewable} to receive updates
* when the value of the source property changes.
*
* @param type The type class to which the source value will be mapped into the resulting {@link Viewable}.
* @param source The source {@link Val} for which the view is created.
* @param mapper The function that maps the source value to the resulting value in the {@link Viewable}.
* @return A {@link Viewable} instance which is a view of the specified source {@link Val} mapped to the given type.
* @param <T> The type parameter to which the source value will be mapped in the resulting {@link Viewable}.
* @param <U> The type of the value in the source {@link Val}.
* @throws NullPointerException if any of the supplied parameters are {@code null}.
*/
<T extends @Nullable Object, U extends @Nullable Object> Viewable<T> viewOf( Class<T> type, Val<U> source, Function<U, T> mapper );
/**
* Creates a {@link Viewable} instance where he item of a supplied source {@link Val} is mapped to a different
* (non-null) type using the provided mapper function as well as an error and null object in case the source value
* is {@code null} or an error occurs during mapping.<br>
* You can register {@link Action}s or {@link Observer}s
* on the returned {@link Viewable} to receive updates when the value of the source property changes.
* This method is useful when you want a mapped {@link Viewable} with a default/fallback values in case
* the source property contains a {@code null} value or an error occurs during mapping.
*
* @param nullObject The default value to be used when the source value is null.
* @param errorObject The default value to be used when an error occurs during mapping.
* @param source The source {@link Val} for which the view is created.
* @param mapper The function that maps the source value to the resulting value in the {@link Viewable} returned by this method.
* @return A {@link Viewable} instance that dynamically maps the source value
* or alternatively uses the specified null and error objects.
* @param <T> The type of the item in the source {@link Val} to be mapped. It can be nullable.
* @param <U> The type of the item to map to in the resulting {@link Viewable}.
* It may never be {@code null} in the resulting {@link Viewable}.
* @throws NullPointerException if any of the supplied parameters are {@code null}.
*/
<T extends @Nullable Object, U extends @Nullable Object> Viewable<U> viewOf( U nullObject, U errorObject, Val<T> source, Function<T, @Nullable U> mapper );
/**
* Creates a {@link Viewable} instance of the given nullable type which is a
* view of the value of the specified source {@link Val} mapped to a different
* (nullable) type using the provided mapper function.<br>
* You can register observers on the returned {@link Viewable} to receive updates
* when the value of the source property changes.
*
* @param type The type class to which the source value will be mapped into the resulting {@link Viewable}.
* This argument may not be {@code null} (Although the resulting {@link Viewable} can contain {@code null} values).
* @param source The source {@link Val} for which the view is created.
* @param mapper The function that maps the source value to the resulting value in the {@link Viewable}.
* @return A {@link Viewable} instance which is a view of the specified source {@link Val} mapped to the given (nullable) type.
* @param <T> The type parameter to which the source value will be mapped in the resulting {@link Viewable}. It can be nullable.
* @param <U> The type of the value in the source {@link Val}. It can also be nullable.
* @throws NullPointerException if any of the supplied parameters are {@code null}.
*/
<T extends @Nullable Object, U extends @Nullable Object> Viewable<@Nullable U> viewOfNullable( Class<U> type, Val<T> source, Function<T, @Nullable U> mapper );
/**
* A factory method for creating a {@link Lens} based {@link Var} property, which is a zoomed in handle
* to a field variable of a non-null {@link Class} of a non-nullable type {@code B} that is a member
* part of the source property item type {@code T}.<br>
* The resulting {@link Var} can be mutated, and the changes will be propagated
* to the source property value through the lens.<br>
* Both {@code T} and {@code B} are expected to be data types with value semantics,
* meaning they should be immutable and have proper {@code equals} and {@code hashCode} implementations.
* We recommend using record types for {@code T} and {@code B} to reliably ensure value semantics.
*
* @param source The source {@link Var} from which the lens is created.
* @param lens The lens that defines how to access the field of type {@code B} in the source property value {@code T}.
* @return A {@link Var} instance that represents the field of type {@code B} in the source property value {@code T}.
* @param <T> The type of the source property value, which is expected to be non-nullable.
* @param <B> The type of the field in the source property value {@code T}, which can be nullable.
*/
<T extends @Nullable Object, B extends @NonNull Object> Var<B> lensOf( Var<T> source, Lens<T, B> lens );
/**
* A factory method for creating a {@link Lens} based {@link Var} property, which is a zoomed in handle
* to a field variable of a non-null {@link Class} of a non-nullable type {@code B} that is a member
* part of the source property item type {@code T}.<br>
* The resulting {@link Var} can be mutated, and the changes will be propagated
* to the source property value through the lens.<br>
* If the item in the source property value {@code T} is {@code null}, then the resulting {@link Var} will
* use the provided {@code nullObject} as a default value. If you want to create a lens property
* which can store {@code null} values, use the {@link #lensOfNullable(Class, Var, Lens)} method instead.<br>
* Both {@code T} and {@code B} are expected to be data types with value semantics,
* meaning they should be immutable and have proper {@code equals} and {@code hashCode} implementations.
* We recommend using record types for {@code T} and {@code B} to reliably ensure value semantics.
*
* @param source The source {@link Var} from which the lens is created.
* @param nullObject The default value to be used when the source value is null.
* @param lens The lens that defines how to access the field of type {@code B} in the source property value {@code T}.
* This lens property may never store {@code null} values.
* @return A {@link Var} instance that represents the field of type {@code B} in the source property value {@code T}.
* @param <T> The type of the source property value, which is expected to be non-nullable.
* @param <B> The type of the field in the source property value {@code T}, which can be nullable.
*/
<T extends @Nullable Object, B extends @NonNull Object> Var<B> lensOf( Var<T> source, B nullObject, Lens<T, B> lens);
/**
* A factory method for creating a {@link Lens} based {@link Var} property, which is a zoomed in handle
* to a field variable of a non-null {@link Class} of a nullable type {@code B} that is a member part
* of the source property item type {@code T}.<br>
* If you want to create a lens property which can never store {@code null} values,
* use the {@link #lensOf(Var, Object, Lens)} factory method instead.<br>
* The resulting {@link Var} can be mutated, and the changes will be propagated
* to the source property value through the lens.<br>
* <p>
* Both {@code T} and {@code B} are expected to be data types with value semantics,
* so they should be immutable and have proper {@code equals} and {@code hashCode} implementations.
* We recommend using record types for {@code T} and {@code B} to reliably ensure value semantics.
*
* @param type The type of the resulting {@link Var}.
* @param source The source {@link Var} from which the lens is created.
* @param lens The lens that defines how to access the field of type {@code B} in the source property value {@code T}.
* @return A {@link Var} instance that represents the field of type {@code B} in the source property value {@code T}.
* @param <T> The type of the source property value, which is expected to be non-nullable.
* @param <B> The type of the field in the source property value {@code T}, which can be nullable.
*/
<T extends @Nullable Object, B extends @Nullable Object> Var<B> lensOfNullable( Class<B> type, Var<T> source, Lens<T, B> lens );
/**
* Creates a {@link Var} property instance from a given non-null {@link Class} of a nullable type and
* as well as an item of that type, which therefore may be {@code null}.
* The resulting property is nullable, meaning it can hold a value of the given type or be {@code null}.
* If you want to create a property which can never hold {@code null} values,
* use {@link #varOf(Class, Object)} instead of this method.
*
* @param type The type of the item to be wrapped in the {@link Var}, which must not be {@code null}.
* @param item The item to be wrapped in the {@link Var}. It can be {@code null}.
* @return A {@link Var} instance containing the item, or an empty {@link Var} if the item is {@code null}.
* @param <T> The type of the item to be wrapped in the {@link Var}.
* @throws NullPointerException if {@code type} is {@code null}.
*/
<T> Var<@Nullable T> varOfNullable( Class<T> type, @Nullable T item );
/**
* Creates an empty {@link Var} instance (storing a {@code null} item) of the given type.
* If you want to create a property which can never hold {@code null} values,
* use {@link #varOf(Class, Object)} instead of this method.
*
* @param type The type of the item to be wrapped in the {@link Var}, which must not be {@code null}.
* @return A {@link Var} instance containing a {@code null} item.
* @param <T> The type of the item to be wrapped in the {@link Var}.
* @throws NullPointerException if {@code type} is {@code null}.
*/
<T> Var<@Nullable T> varOfNull( Class<T> type );
/**
* Creates a {@link Var} property instance from a given non-nullable item, where the
* {@link Var#type()} is inferred from the type of the item.
*
* @param item The item to be wrapped in the {@link Var}. It must not be {@code null}.
* @return A {@link Var} instance containing the item.
* @param <T> The type of the item to be wrapped in the {@link Var}.
* @throws NullPointerException if {@code item} is {@code null}.
*/
<T> Var<T> varOf( T item );
/**
* Creates a {@link Var} property instance of the given non-nullable type with the specified non-null item.
* The resulting property is non-nullable, meaning it can only hold a value of the given type and cannot be {@code null}.
* The supplied item must be a subtype of the specified {@code type}.
*
* @param type The type of the item to be wrapped in the {@link Var}.
* @param item The item to be wrapped in the {@link Var}. It must not be {@code null} and it
* must be a subtype of the specified {@code type}.
* @return A non-nullable {@link Var} instance containing the item.
* @param <T> The type of the item to be wrapped in the {@link Var}.
* @param <V> The type of the item to be wrapped in the {@link Var}, which must be a subtype of {@code T}.
* @throws NullPointerException if {@code type} or {@code item} is {@code null}.
*/
<T, V extends T> Var<T> varOf( Class<T> type, V item );
/**
* A factory method which creates an empty {@link Vals} instance dedicated
* to hold properties storing non-nullable items of the specified type.
*
* @param type The type of the items to be wrapped in the {@link Vals}. It must not be {@code null}.
* @return A {@link Vals} instance that can hold items of the specified type.
* @param <T> The type of the items to be wrapped in the {@link Vals}.
* @throws NullPointerException if {@code type} is {@code null}.
*/
<T> Vals<T> valsOf( Class<T> type );
/**
* This factory method creates a {@link Vals} instance from a type class
* and an array of {@link Val} properties, each wrapping a non-nullable item of the specified type.
* A property list can store multiple {@link Val} properties wrapping non-nullable items of the specified type.
*
* @param type The type of the items to be wrapped in the {@link Vals}. It must not be {@code null}.
* @param vars An array of {@link Val} properties to be wrapped in the {@link Vals}.
* Properties in the array cannot be {@code null}, and their items also cannot be {@code null}.
* @return A {@link Vals} instance that can hold the specified items of the given type.
* @param <T> The non-nullable type of the items to be wrapped in the {@link Vals}.
* @throws NullPointerException if {@code type} or {@code vars} is {@code null}.
*/
@SuppressWarnings("unchecked")
<T> Vals<T> valsOf( Class<T> type, Val<T>... vars );
/**
* A factory method for creating a {@link Vals} property list from one or more {@link Val} properties,
* which are all instances of the same type and may not be {@code null}.
* The {@link Vals#type()} is inferred from the type of the first properties {@link Val#type()}.
* If you want to create a property list which can hold {@code null}s,
* use {@link #valsOfNullable(Class, Val...)} instead of this method.
*
* @param first The first {@link Val} to be wrapped in the {@link Vals}. It must not be {@code null}
* and it must not contain a {@code null} item ({@link Val#allowsNull()} must return {@code false}).
* @param rest Additional {@link Val} items to be wrapped in the {@link Vals}. They are not permitted to be {@code null},
* and they also may not contain {@code null} items ({@link Val#allowsNull()} must return {@code false}).
* @return A {@link Vals} instance that can hold the specified items of the inferred type.
* @param <T> The type of the items to be wrapped in the {@link Vals}.
* @throws NullPointerException if {@code first} or any item in {@code rest} is {@code null}.
*/
@SuppressWarnings("unchecked")
<T> Vals<T> valsOf( Val<T> first, Val<T>... rest );
/**
* A factory method for creating a {@link Vals} property list from one or more items,
* which are all instances of the same type and may not be {@code null}.
* The {@link Vals#type()} is inferred from the type of the first item.
* If you want to create a property list which can hold {@code null}s,
* use {@link #valsOfNullable(Class, Object...)} instead of this method.
*
* @param first The first item to be wrapped in the {@link Vals}. It must not be {@code null}.
* @param rest Additional items to be wrapped in the {@link Vals}. They can be {@code null}.
* @return A {@link Vals} instance that can hold the specified items of the inferred type.
* @param <T> The type of the items to be wrapped in the {@link Vals}.
* @throws NullPointerException if {@code first} or {@code rest} is {@code null},
* or if any item in {@code rest} is {@code null}.
*/
@SuppressWarnings("unchecked")
<T> Vals<T> valsOf( T first, T... rest );
/**
* A factory method for creating a {@link Vals} property list from a type class
* and an array of items, which are all instances of the given type and may not be {@code null}.
* The resulting {@link Vals} can hold multiple values of the specified type.
* If you want to create a property list which can hold {@code null} references,
* use {@link #valsOfNullable(Class, Object...)} instead of this method.
*
* @param type The type class of the items to be wrapped in the {@link Vals}. It must not be {@code null}.
* @param items An array of items to be wrapped in the {@link Vals}. The items themselves cannot be {@code null}.
* @return A {@link Vals} instance that can hold the specified items of the given type.
* @param <T> The type of the items to be wrapped in the {@link Vals}.
* @throws NullPointerException if {@code type} or {@code items} is {@code null}.
*/
@SuppressWarnings("unchecked")
<T> Vals<T> valsOf( Class<T> type, T... items );
/**
* Creates a {@link Vals} property list from a type class and an
* iterable of {@link Val} properties, each wrapping a non-nullable item of the specified type.
* A property list can store multiple {@link Val} properties wrapping non-nullable items of the specified type.
*
* @param type The type of the items to be wrapped in the {@link Vals}. It must not be {@code null}.
* @param properties An iterable of {@link Val} properties to be wrapped in the {@link Vals}.
* Properties in the iterable cannot be {@code null}, and their items cannot be {@code null}.
* @return A {@link Vals} instance that can hold the specified items of the given type.
* @param <T> The non-nullable type of the items to be wrapped in the {@link Vals}.
* @throws NullPointerException if {@code type} or {@code properties} is {@code null}.
*/
<T> Vals<T> valsOf( Class<T> type, Iterable<Val<T>> properties );
/**
* Creates a {@link Vals} property list of the given type with the specified items
* from another {@link Vals} instance. A property list can store multiple
* {@link Val} properties wrapping non-nullable items of the specified type.
*
* @param type The type of the items to be wrapped in the {@link Vals}. It must not be {@code null}.
* @param vals The items to be wrapped in the {@link Vals}.
* Items in properties of the {@link Vals} are not permitted to be {@code null}.
* @return A {@link Vals} instance that can hold the specified items of the given (non-nullable) type.
* @param <T> The non-nullable type of the items to be wrapped in the {@link Vals}.
* @throws NullPointerException if {@code type} or {@code vals} is {@code null}.
*/
<T> Vals<T> valsOf( Class<T> type, Vals<T> vals );
/**
* This factory method instantiates an empty {@link Vals} instance from a type class
* of a nullable type {@code T}.
* The resulting {@link Vals} can hold multiple properties wrapping either
* instances of the specified type {@code T} or {@code null} references.
* If you want to create a property list which can never hold {@code null}s,
* use {@link #valsOf(Class)} instead of this method.
*
* @param type The type class of the nullable items to be wrapped in the {@link Vals}. It must not be {@code null}.
* @return A {@link Vals} instance that can hold items of the specified nullable type.
* @param <T> The nullable type of the items to be wrapped in the {@link Vals}.
* @throws NullPointerException if {@code type} is {@code null}.
*/
<T> Vals<@Nullable T> valsOfNullable( Class<T> type );
/**
* Creates a {@link Vals} property list of {@link Val} properties from a type class and an
* array of properties, holding nullable items which are all instances of the given type or {@code null}.
* So every {@link Val} property in the resulting {@link Vals} is permitted to hold a {@code null} reference
* and may therefore report {@link Val#isEmpty()} as {@code true}.
*
* @param type The type class of the nullable items to be wrapped in the {@link Vals}. It must not be {@code null}.
* @param vals An array of {@link Val}s to be wrapped in the {@link Vals}. The properties themselves cannot be {@code null},
* but the items they hold can be {@code null}.
* @return A {@link Vals} instance that can hold the specified items of the given type, including {@code null} values.
* @param <T> The type of the items to be wrapped in the {@link Vals}.
* @throws NullPointerException if {@code type} or {@code vals} is {@code null}, or if any
* of the {@link Val} properties in {@code vals} array is {@code null}.
* (Note that the items in the {@link Val} properties are permitted to be {@code null}!)
*/
@SuppressWarnings("unchecked")
<T> Vals<@Nullable T> valsOfNullable( Class<T> type, Val<@Nullable T>... vals );
/**
* Creates a {@link Vals} property list of {@link Val} properties from a type class and an
* array of items, which are all instances of the given type or {@code null}.
* Every {@link Val} property in the resulting {@link Vals} is permitted to hold a {@code null} reference,
* in which case it will report {@link Val#isEmpty()} as {@code true}.
* If you want to create a property list which can never hold {@code null}s,
* use {@link #valsOf(Class, Object...)} instead of this method.
*
* @param type The type class of the nullable items to be wrapped in the {@link Vals}. It must not be {@code null}.
* @param items An array of items to be wrapped in the {@link Vals}. The items themselves can be {@code null},
* but the array is not permitted to be {@code null} itself.
* @return A {@link Vals} instance that can hold the specified items of the given type, including {@code null} values.
* @param <T> The type of the items to be wrapped in the {@link Vals}.
* @throws NullPointerException if {@code type} or the {@code items} array is {@code null}.
*/
<T> Vals<@Nullable T> valsOfNullable( Class<T> type, @Nullable T... items );
/**
* Creates a {@link Vals} property list of {@link Val} properties from one or more
* {@link Val} properties, which are all instances of the same type and may hold {@code null} values.
* The {@link Vals#type()} is inferred from the type of the first properties {@link Val#type()}.
* If you want to create a property list which can never hold {@code null}s,
* use {@link #valsOf(Class, Val...)} instead of this method.
*
* @param first The first {@link Val} to be wrapped in the {@link Vals}. It must not be {@code null}
* and it may contain a {@code null} item ({@link Val#allowsNull()} may return {@code true}).
* @param rest Additional {@link Val} items to be wrapped in the {@link Vals}. They are not permitted to be {@code null},
* but they may contain {@code null} items ({@link Val#allowsNull()} may return {@code true}).
* @return A {@link Vals} instance that can hold the specified items of the inferred type, including nullable values.
* @param <T> The type of the items to be wrapped in the {@link Vals}.
* @throws NullPointerException if {@code first} or {@code rest} is {@code null},
* as well as if any item in {@code rest} is {@code null}.
*/
@SuppressWarnings("unchecked")
<T> Vals<@Nullable T> valsOfNullable( Val<@Nullable T> first, Val<@Nullable T>... rest );
/**
* This factory method creates a {@link Vals} property list from a type class representing a nullable type {@code T}
* and another {@link Vals} instance, which contains nullable items being compatible with the specified type {@code T}.
* A property list can store multiple {@link Val} properties wrapping nullable items of the specified type.
*
* @param type The type of the items to be wrapped in the {@link Vals}. It must not be {@code null}.
* @param vals The items to be wrapped in the {@link Vals}. Items in properties of the {@link Vals} are permitted to be {@code null}.
* @return A {@link Vals} instance that can hold the specified items of the given (nullable) type.
* @param <T> The nullable type of the items to be wrapped in the {@link Vals}.
* @throws NullPointerException if {@code type} or {@code vals} is {@code null}.
*/
<T> Vals<@Nullable T> valsOfNullable(Class<T> type, Vals<@Nullable T> vals);
/**
* Creates a list of non-nullable properties from the supplied type and vararg values.
* This factory method requires that the type be specified because the
* compiler cannot infer the type from a potentially empty vararg array.
*
* @param type the type of the properties.
* @param vars the properties to add to the new Vars instance.
* @param <T> the type of the properties.
* @return a new {@code Vars} instance.
* @throws NullPointerException if {@code type} is {@code null}, or {@code vars} is {@code null}.
* @throws IllegalArgumentException if any property allows {@code null}.
*/
@SuppressWarnings("unchecked")
<T> Vars<T> varsOf( Class<T> type, Var<T>... vars );
/**
* Creates an empty list of non-nullable properties from the supplied type.
* This factory method requires that the type be specified because the
* compiler cannot infer the type from a potentially empty vararg array.
*
* @param type the type of the properties.
* This is used to check if the item is of the correct type.
* @param <T> the type of the properties.
* @return a new {@code Vars} instance.
* @throws NullPointerException if {@code type} is {@code null}.
*/
<T> Vars<T> varsOf( Class<T> type );
/**
* Creates a list of non-nullable properties from one or more non-nullable properties.
*
* @param first the first property to add to the new Vars instance.
* @param rest the remaining properties to add to the new Vars instance.
* @param <T> the type of the properties.
* @return a new {@code Vars} instance.
* @throws NullPointerException if {@code first} is {@code null}, or {@code rest} is {@code null}.
* @throws IllegalArgumentException if any property allows {@code null}.
*/
@SuppressWarnings("unchecked")
<T> Vars<T> varsOf( Var<T> first, Var<T>... rest );
/**
* Creates a list of non-nullable properties from one or more non-null values.
*
* @param first the first value to add to the new Vars instance.
* @param rest the remaining values to add to the new Vars instance.
* @param <T> the type of the values.
* @return a new {@code Vars} instance.
* @throws NullPointerException if {@code first} is {@code null}, or {@code rest} is {@code null}.
* @throws IllegalArgumentException if any value in {@code rest} is {@code null}.
*/
@SuppressWarnings("unchecked")
<T> Vars<T> varsOf( T first, T... rest );
/**
* Creates a list of non-nullable properties from the supplied type and values.
* This factory method requires that the type be specified because the
* compiler cannot infer the type from the values.
*
* @param type the type of the properties.
* @param items the values to be wrapped by properties and then added to the new Vars instance.
* The values may not be null.
* @param <T> the type of the values.
* @return a new {@code Vars} instance.
* @throws NullPointerException if {@code type} is {@code null}, or {@code items} is {@code null}.
*/
@SuppressWarnings("unchecked")
<T> Vars<T> varsOf( Class<T> type, T... items );
/**
* Creates a list of non-nullable properties from the supplied type and iterable of values.
* This factory method requires that the type be specified because the
* compiler cannot infer the type from a potentially empty iterable.
*
* @param type the type of the properties.
* @param vars the iterable of values.
* @param <T> the type of the properties.
* @return a new {@code Vars} instance.
* @throws NullPointerException if {@code type} is {@code null}, or {@code vars} is {@code null}.
* @throws IllegalArgumentException if any property in {@code vars} allows {@code null}.
*/
<T> Vars<T> varsOf( Class<T> type, Iterable<Var<T>> vars );
/**
* Creates a list of nullable properties from the supplied type and varargs properties.
* This factory method requires that the type be specified because the
* compiler cannot infer the type from the null values.
*
* @param type the type of the properties.
* @param vars the properties to add to the new Vars instance.
* The properties may be nullable properties, but they may not be null themselves.
* @param <T> the type of the properties.
* @return a new {@code Vars} instance.
* @throws NullPointerException if {@code type} is {@code null}, or {@code vars} is {@code null}.
*/
@SuppressWarnings("unchecked")
<T> Vars<@Nullable T> varsOfNullable( Class<T> type, Var<@Nullable T>... vars );
/**
* Creates an empty list of nullable properties from the supplied type.
* This factory method requires that the type be specified because the
* compiler cannot infer the type from a potentially empty vararg array.
*
* @param type the type of the properties.
* This is used to check if the item is of the correct type.
* @param <T> the type of the properties.
* @return a new {@code Vars} instance.
* @throws NullPointerException if {@code type} is {@code null}.
*/
<T> Vars<@Nullable T> varsOfNullable( Class<T> type );
/**
* Creates a list of nullable properties from the supplied type and values.
* This factory method requires that the type be specified because the
* compiler cannot infer the type from the null values.
*
* @param type the type of the properties.
* @param values the values to be wrapped by properties and then added to the new Vars instance.
* The values may be null.
* @param <T> the type of the values.
* @return a new {@code Vars} instance.
*/
@SuppressWarnings("unchecked")
<T> Vars<@Nullable T> varsOfNullable( Class<T> type, @Nullable T... values );
/**
* Creates a list of nullable properties from the supplied properties.
*
* @param first the first property to add to the new Vars instance.
* @param rest the remaining properties to add to the new Vars instance.
* @param <T> the type of the properties.
* @return a new {@code Vars} instance.
*/
@SuppressWarnings("unchecked")
<T> Vars<@Nullable T> varsOfNullable( Var<@Nullable T> first, Var<@Nullable T>... rest );
/**
* Creates a list of nullable properties from the supplied type and iterable of values.
* This factory method requires that the type be specified because the
* compiler cannot infer the type from a potentially empty iterable.
*
* @param type the type of the properties.
* @param vars the iterable of values.
* @param <T> the type of the properties.
* @return a new {@code Vars} instance.
*/
<T> Vars<@Nullable T> varsOfNullable(Class<T> type, Iterable<Var<@Nullable T>> vars);
/**
* Creates an immutable tuple of non-nullable items from the supplied type and vararg values.
* This factory method requires the type to be specified, because the
* compiler cannot infer the type from a potentially empty vararg array.
*
* @param type the type of the items in the tuple.
* @param maybes the items to add to the new {@code Tuple} instance.
* @param <T> the type of the items in the tuple.
* @return a new {@code Tuple} instance.
* @throws NullPointerException if {@code type} is {@code null}, or {@code vec} is {@code null}.
* @throws IllegalArgumentException if any {@link Maybe} allows {@code null}.
*/
@SuppressWarnings("unchecked")
<T> Tuple<T> tupleOf( Class<T> type, Maybe<T>... maybes );
/**
* Creates an empty tuple of non-nullable items from the supplied type.
* This factory method requires the type to be specified, because the
* compiler cannot infer the type from a potentially empty vararg array.
*
* @param type the type of the items in the tuple.
* This is used to check if the item is of the correct type.
* @param <T> the type of the items in the tuple.
* @return a new {@code Tuple} instance.
* @throws NullPointerException if {@code type} is {@code null}.
*/
<T> Tuple<T> tupleOf( Class<T> type );
/**
* Creates an immutable tuple of non-nullable items from one or more non-nullable items
* wrapped by {@link Maybe} properties.
*
* @param first the first {@link Maybe} to add to the new {@code Tuple} instance.
* @param rest the remaining items to add to the new {@code Tuple} instance.
* @param <T> the type of the items in the tuple.
* @return a new {@code Tuple} instance.
* @throws NullPointerException if {@code first} is {@code null}, or {@code rest} is {@code null}.
* @throws IllegalArgumentException if any {@link Maybe} allows {@code null}.
*/
@SuppressWarnings("unchecked")
default <T> Tuple<T> tupleOf( Maybe<T> first, Maybe<T>... rest ) {
T[] items = (T[]) new Object[rest.length + 1];
items[0] = first.orElseNull();
for (int i = 0; i < rest.length; i++) {
items[i + 1] = rest[i].orElseNull();
}
return tupleOf(Util.expectedClassFromItem(first.orElseThrowUnchecked()), items);
}
/**
* Creates an immutable tuple of non-nullable items from one or more non-null items.
* At least one non-null item must be provided to this factory method.
*
* @param first the first value to add to the new {@code Tuple} instance.
* @param rest the remaining values to add to the new {@code Tuple} instance.
* @param <T> the type of the values.
* @return a new {@code Tuple} instance.
* @throws NullPointerException if {@code first} is {@code null}, or {@code rest} is {@code null}.
* @throws IllegalArgumentException if any value in {@code rest} is {@code null}.
*/
@SuppressWarnings("unchecked")
<T> Tuple<T> tupleOf( T first, T... rest );
/**
* Creates an immutable, non-nullable {@code Tuple<Float>} from a
* primitive array of floats. The returned tuple will contain
* the floats as a single dense array of primitives.<br>
* Note that in order to guarantee immutability,
* the array of floats is copied.
*
* @param floats The floats to use as a basis for the new tuple.
* @return a new {@code Tuple} instance backed by a single primitive array of floats.
* @throws NullPointerException if {@code floats} is {@code null}.
*/
Tuple<Float> tupleOf( float... floats );
/**
* Creates an immutable, non-nullable {@code Tuple<Double>} from a
* primitive array of doubles. The returned tuple will contain
* the doubles as a single dense array of primitives.<br>
* Note that in order to guarantee immutability,
* the array of doubles is copied.
*
* @param doubles The doubles to use as a basis for the new tuple.
* @return a new {@code Tuple} instance backed by a single primitive array of doubles.
* @throws NullPointerException if {@code doubles} is {@code null}.
*/
Tuple<Double> tupleOf( double... doubles );
/**
* Creates an immutable tuple of non-nullable items from a primitive array of integers.
* The returned tuple will contain the integers as a single dense array of primitives.<br>
* Note that in order to guarantee immutability,
* the array of integers is copied.
*
* @param ints The integers to use as a basis for the new tuple.
* @return a new {@code Tuple} instance backed by a single primitive array of integers.
* @throws NullPointerException if {@code ints} is {@code null}.
*/
Tuple<Integer> tupleOf( int... ints );
/**
* Creates an immutable tuple of non-nullable items from a primitive array of bytes.
* The returned tuple will contain the bytes as a single dense array of primitives.<br>
* Note that in order to guarantee immutability,
* the array of bytes is copied.
*
* @param bytes The bytes to use as a basis for the new tuple.
* @return a new {@code Tuple} instance backed by a single primitive array of bytes.
* @throws NullPointerException if {@code bytes} is {@code null}.
*/
Tuple<Byte> tupleOf( byte... bytes );
/**
* Creates an immutable tuple of non-nullable items from a primitive array of longs.
* The returned tuple will contain the longs as a single dense array of primitives.<br>
* Note that in order to guarantee immutability,
* the array of longs is copied.
*
* @param longs The longs to use as a basis for the new tuple.
* @return a new {@code Tuple} instance backed by a single primitive array of longs.
* @throws NullPointerException if {@code longs} is {@code null}.
*/
Tuple<Long> tupleOf( long... longs );
/**
* Creates an immutable tuple of non-nullable items from the supplied type and values.
* This factory method requires the type to be specified, because the
* compiler cannot infer the type from the values.
*
* @param type the type of the items in the tuple.
* @param items the values to be wrapped by items and then added to the new {@code Tuple} instance.
* The values may not be null.
* @param <T> the type of the values.
* @return a new {@code Tuple} instance.
* @throws NullPointerException if {@code type} is {@code null}, or {@code items} is {@code null}.
*/
@SuppressWarnings("unchecked")
<T> Tuple<T> tupleOf( Class<T> type, T... items );
/**
* Creates an immutable tuple of non-nullable items from the supplied type and iterable of values.
* This factory method requires the type to be specified, because the
* compiler cannot infer the type from a potentially empty iterable.
*
* @param type the type of the items in the tuple.
* @param iterable the iterable of values.
* @param <T> the type of the items in the tuple.
* @return a new {@code Tuple} instance.
* @throws NullPointerException if {@code type} is {@code null}, or {@code vec} is {@code null}.
* @throws IllegalArgumentException if any {@link Maybe} in {@code vec} allows {@code null}.
*/
<T> Tuple<T> tupleOf( Class<T> type, Iterable<T> iterable );
/**
* Creates an immutable tuple of nullable items from the supplied type and varargs items.
* This factory method requires the type to be specified, because the
* compiler cannot infer the type from the null values.
*
* @param type the type of the items in the tuple.
* @param maybes the items to add to the new {@code Tuple} instance.
* The items may be nullable items, but they may not be null themselves.
* @param <T> the type of the items in the tuple.
* @return a new {@code Tuple} instance.
* @throws NullPointerException if {@code type} is {@code null}, or {@code vec} is {@code null}.
*/
@SuppressWarnings("unchecked")
default <T> Tuple<@Nullable T> tupleOfNullable( Class<T> type, Maybe<@Nullable T>... maybes ) {
T[] items = (T[]) new Object[maybes.length];
for (int i = 0; i < maybes.length; i++) {
items[i] = maybes[i].orElseNull();
}
return tupleOfNullable(type, items);
}
/**
* Creates an empty tuple of nullable items from the supplied type.
* This factory method requires the type to be specified, because the
* compiler cannot infer the type from a potentially empty vararg array.
*
* @param type the type of the items in the tuple.
* This is used to check if the item is of the correct type.
* @param <T> the type of the items in the tuple.
* @return a new {@code Tuple} instance.
* @throws NullPointerException if {@code type} is {@code null}.
*/
<T> Tuple<@Nullable T> tupleOfNullable( Class<T> type );
/**
* Creates an immutable tuple of nullable items from the supplied type and values.
* This factory method requires the type to be specified, because the
* compiler cannot infer the type from the null values.
*
* @param type the type of the items in the tuple.
* @param items The items to be stored by the new {@code Tuple} instance.
* The values may be null.
* @param <T> the type of the values.
* @return a new {@code Tuple} instance.
*/
@SuppressWarnings("unchecked")
<T> Tuple<@Nullable T> tupleOfNullable( Class<T> type, @Nullable T... items );
/**
* Creates an immutable tuple of nullable items from the supplied items.
*
* @param first the first {@link Maybe} to add to the new {@code Tuple} instance.
* @param rest the remaining items to add to the new {@code Tuple} instance.
* @param <T> the type of the items in the tuple.
* @return a new {@code Tuple} instance.
*/
@SuppressWarnings("unchecked")
default <T> Tuple<@Nullable T> tupleOfNullable( Maybe<@Nullable T> first, Maybe<@Nullable T>... rest ) {
T[] items = (T[]) new Object[rest.length + 1];
items[0] = first.orElseNull();
for (int i = 0; i < rest.length; i++) {
items[i + 1] = rest[i].orElseNull();
}
return tupleOfNullable(first.type(), items);
}
/**
* Creates an immutable tuple of nullable items from the supplied type and iterable of values.
* This factory method requires the type to be specified, because the
* compiler cannot infer the type from a potentially empty iterable.
*
* @param type the type of the items in the tuple.
* @param iterable the iterable of values.
* @param <T> the type of the items in the tuple.
* @return a new {@code Tuple} instance.
*/
<T> Tuple<@Nullable T> tupleOfNullable( Class<T> type, Iterable<@Nullable T> iterable );
/**
* Creates a new association between keys and values
* with the given key and value types. An association
* knows the types of its keys and values, and so
* you can only put keys and values of the defined types
* into the association. This creates an empty association
* primed without any order of their key-value pairs.<br>
*
* @param keyType The type of the keys in the association.
* @param valueType The type of the values in the association.
* @param <K> The type of the keys in the association, which must be immutable.
* @param <V> The type of the values in the association, which should be immutable.
* @return A new association between keys and values.
*/
<K, V> Association<K, V> associationOf( Class<K> keyType, Class<V> valueType );
/**
* Creates a new linked association between keys and values
* with the given key and value types, where the order of
* key-value pairs in this type of association is based on
* the order in which the pairs are added to the association.
* An association always knows the types of its keys and values,
* and so you can only put keys and values of the defined types
* into the association.
*
* @param keyType The type of the keys in the association.
* @param valueType The type of the values in the association.
* @param <K> The type of the keys in the association, which must be immutable.
* @param <V> The type of the values in the association, which should be immutable.
* @return A new linked association between keys and values, where
* the order of key-value pairs is preserved in the order they are added.
*/
<K, V> Association<K, V> associationOfLinked( Class<K> keyType, Class<V> valueType );
/**
* Creates a new association between keys and values
* with the given key and value types, where the key-value pairs
* are sorted using the supplied comparator.
* An association knows the types of its keys and values,
* and so you can only put keys and values of the defined types
* into the association.
*
* @param keyType The type of the keys in the association.
* @param valueType The type of the values in the association.
* @param comparator The comparator to use for sorting the keys in the association.
* @param <K> The type of the keys in the association, which must be immutable.
* @param <V> The type of the values in the association, which should be immutable.
* @return A new sorted association between keys and values.
*/
<K, V> Association<K, V> associationOfSorted(Class<K> keyType, Class<V> valueType, Comparator<K> comparator );
/**
* Creates a new association between keys and values
* with the given key and value types, where the keys
* are sorted in natural order.
* An association knows the types of its keys and values,
* and so you can only put keys and values of the defined types
* into the association.
*
* @param keyType The type of the keys in the association.
* @param valueType The type of the values in the association.
* @param <K> The type of the keys in the association, which must be immutable.
* @param <V> The type of the values in the association, which should be immutable.
* @return A new sorted association between keys and values.
*/
<K extends Comparable<K>, V> Association<K, V> associationOfSorted( Class<K> keyType, Class<V> valueType );
/**
* Creates a new value set specifically for holding elements of the supplied type.
* A value set knows the types of its elements, and so
* you can only add elements which are of the same type or a subtype of the
* type of the value set.
*
* @param type The type of the elements in the value set.
* @param <E> The type of the elements in the value set, which must be an immutable value type.
* @return A new value set specific to the given element type.
*/
<E> ValueSet<E> valueSetOf( Class<E> type );
/**
* Creates a new value set specifically for holding elements of the supplied type,
* and where the order of the elements is defined by the insertion order.
* Which means that during iteration over the value set,
* the elements will be returned in the order they were added.
* A value set knows the types of its elements, and so
* you can only add elements which are of the same type or a subtype of the
* type of the value set.
*
* @param type The type of the elements in the value set.
* @param <E> The type of the elements in the value set, which must be an immutable value type.
* @return A new linked value set specific to the given element type.
*/
<E> ValueSet<E> valueSetOfLinked( Class<E> type );
/**
* Creates a new value set specifically for holding elements of the supplied type,
* but with an explicit order defined by the supplied comparator.
* A value set knows the types of its elements and values, and so
* you can only add elements which are of the same type or a subtype of the
* type of the value set.<br>
* Here is an example demonstrating how this method may be used
* to create a set with string elements sorted by their length:<br>
* <pre>{@code
* ValueSet.ofSorted(
* String.class,
* Comparator.comparing(String::length)
* );
* }</pre>
*
* @param type The type of the elements in the value set.
* @param comparator The comparator to use for sorting the elements in the value set.
* @param <E> The type of the elements in the value set, which must be an immutable value type.
* @return A new sorted value set specific to the given element type.
*/
<E> ValueSet<E> valueSetOfSorted( Class<E> type, Comparator<E> comparator );
/**
* Creates a new value set specifically for holding elements of the supplied type,
* elements are sorted based on the natural ordering of the elements
* (which are expected to implement {@link Comparable}).
* A value set knows the types of its elements and values, and so
* you can only add elements which are of the same type or a subtype of the
* specified element type of the value set.
*
* @param type The type of the elements in the value set.
* @param <E> The type of the elements in the value set, which must be an immutable value type.
* @return A new sorted value set specific to the given element type.
*/
<E extends Comparable<? super E>> ValueSet<E> valueSetOfSorted( Class<E> type );
/**
* The default id for properties which do not have an id explicitly specified.
* The id of a property is used to identify it in the system or as part of a view model
* and convert it into other data formats like key/value based data stores.
*
* @return The default id for properties which do not have an id explicitly specified.
* This must never return {@code null} and it is recommended to be a constant
* or cached object due to this method being called frequently.
*/
String defaultId();
/**
* The regex {@link Pattern} used to validate property ids.
* All ids must match this pattern.
*
* @return The regex {@link Pattern} used to validate property ids.
* This must never return {@code null} and it is recommended to be a constant
* or cached object due to this method being called frequently.
*/
Pattern idPattern();
/**
* The default channel used for change events.
* This channel is used to give events a chanel when no channel is explicitly specified.
*
* @return The default channel used for change events.
* This must never return {@code null} and it is recommended to be a constant
* or cached object due to this method being called frequently.
*/
Channel defaultChannel();
/**
* The default channel used for {@link Observable} events,
* registered through the {@link Observable#subscribe(Observer)} method.
*
* @return The default channel used for change events.
* This must never return {@code null} and it is recommended to be a constant
* or cached object due to this method being called frequently.
*/
Channel defaultObservableChannel();
}