001/*
002 * ============================================================================
003 * Copyright © 2002-2020 by Thomas Thrien.
004 * All Rights Reserved.
005 * ============================================================================
006 * Licensed to the public under the agreements of the GNU Lesser General Public
007 * License, version 3.0 (the "License"). You may obtain a copy of the License at
008 *
009 *      http://www.gnu.org/licenses/lgpl.html
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
014 * License for the specific language governing permissions and limitations
015 * under the License.
016 */
017
018package org.tquadrat.foundation.util;
019
020import static org.apiguardian.api.API.Status.STABLE;
021import static org.tquadrat.foundation.lang.Objects.requireNonNullArgument;
022
023import java.util.Set;
024import java.util.function.Consumer;
025import java.util.function.Supplier;
026
027import org.apiguardian.api.API;
028import org.tquadrat.foundation.annotation.ClassVersion;
029import org.tquadrat.foundation.util.internal.LazySetImpl;
030
031/**
032 *  The interface for a
033 *  {@link Set}
034 *  that will be initialised only when required.
035 *
036 *  @extauthor Thomas Thrien - thomas.thrien@tquadrat.org
037 *  @version $Id: LazySet.java 1032 2022-04-10 17:27:44Z tquadrat $
038 *  @since 0.0.5
039 *
040 *  @param  <E> The type of elements in this set.
041 *
042 *  @see org.tquadrat.foundation.lang.Lazy
043 *
044 *  @note   There is no implementation of a {@code map()} method in this
045 *      interface because it is assumed that this would be confusing: such a
046 *      {@code map()} method would operate on the whole list that is wrapped by
047 *      this value, and not on an entry as one would expect. Refer to
048 *      {@link org.tquadrat.foundation.lang.Lazy#map(java.util.function.Function)}.
049 *
050 *  @UMLGraph.link
051 */
052@ClassVersion( sourceVersion = "$Id: LazySet.java 1032 2022-04-10 17:27:44Z tquadrat $" )
053@API( status = STABLE, since = "0.0.5" )
054public sealed interface LazySet<E> extends Set<E>
055    permits LazySetImpl
056{
057        /*---------*\
058    ====** Methods **==========================================================
059        \*---------*/
060    /**
061     *  If this {@code LazySet} instance has been initialised already, the
062     *  provided
063     *  {@link Consumer}
064     *  will be executed; otherwise nothing happens.
065     *
066     *  @param  consumer    The consumer.
067     */
068    public void ifPresent( final Consumer<? super Set<E>> consumer );
069
070    /**
071     *  Forces the initialisation of this {@code LazySet} instance.
072     */
073    public void init();
074
075    /**
076     *  Checks whether this {@code LazySet} instance has been initialised
077     *  already.
078     *
079     *  @return {@code true} if the instance was initialised, {@code false}
080     *      otherwise.
081     */
082    public boolean isPresent();
083
084    /**
085     *  Creates a new {@code LazySet} instance that is already initialised.
086     *
087     *  @param  <E> The type of elements in this set.
088     *  @param  value   The value.
089     *  @return The new instance.
090     */
091    @API( status = STABLE, since = "0.0.5" )
092    public static <E> LazySet<E> of( final Set<E> value )
093    {
094        return new LazySetImpl<>( requireNonNullArgument( value, "value" ) );
095    }   //  of()
096
097    /**
098     *  Creates a new {@code LazySet} instance that uses the given supplier to
099     *  create the internal map, but that supplier does not provide values on
100     *  initialisation.
101     *
102     *  @param  <E> The type of elements in this set.
103     *  @param  supplier    The supplier that initialises for the new instance
104     *      of {@code LazySet} when needed.
105     *  @return The new instance.
106     */
107    @API( status = STABLE, since = "0.0.5" )
108    public static <E> LazySet<E> use( final Supplier<? extends Set<E>> supplier )
109    {
110        return new LazySetImpl<>( false, supplier );
111    }   //  use()
112
113    /**
114     *  Creates a new {@code LazySet} instance that uses the given supplier to
115     *  initialise.
116     *
117     *  @param  <E> The type of elements in this set.
118     *  @param  doPopulate  {@code true} if the provided supplier will put
119     *      entries to the set on initialisation, {@code false} if it will
120     *      create an empty set.
121     *  @param  supplier    The supplier that initialises for the new instance
122     *      of {@code LazySet} when needed.
123     *  @return The new instance.
124     */
125    @API( status = STABLE, since = "0.0.5" )
126    public static <E> LazySet<E> use( final boolean doPopulate, final Supplier<? extends Set<E>> supplier )
127    {
128        return new LazySetImpl<>( doPopulate, supplier );
129    }   //  use()
130}
131//  interface LazySet
132
133/*
134 *  End of File
135 */