001/*
002 * ============================================================================
003 * Copyright © 2002-2022 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.Comparator;
024
025import org.apiguardian.api.API;
026import org.tquadrat.foundation.annotation.ClassVersion;
027import org.tquadrat.foundation.annotation.UtilityClass;
028import org.tquadrat.foundation.exception.PrivateConstructorForStaticClassCalledError;
029
030/**
031 *  <p>{@summary Several range checking functions.}</p>
032 *  <p>The functions in this class support range checking for various types.
033 *  This can be especially useful for scripting, but is also usable in other
034 *  contexts.</p>
035 *
036 *  @extauthor Thomas Thrien - thomas.thrien@tquadrat.org
037 *  @thanks Ben Gidley
038 *  @version $Id: RangeFunctions.java 1032 2022-04-10 17:27:44Z tquadrat $
039 *  @since 0.0.7
040 *
041 *  @UMLGraph.link
042 */
043@SuppressWarnings( "ClassWithTooManyMethods" )
044@UtilityClass
045@ClassVersion( sourceVersion = "$Id: RangeFunctions.java 1032 2022-04-10 17:27:44Z tquadrat $" )
046@API( status = STABLE, since = "0.0.7" )
047public final class RangeFunctions
048{
049        /*--------------*\
050    ====** Constructors **=====================================================
051        \*--------------*/
052    /**
053     *  No instance is allowed for this class.
054     */
055    private RangeFunctions() { throw new PrivateConstructorForStaticClassCalledError( RangeFunctions.class ); }
056
057        /*---------*\
058    ====** Methods **==========================================================
059        \*---------*/
060    /**
061     *  Returns {@code true} if {@code value} is above {@code floor}.
062     *
063     *  @param  <T> The type of the values to check.
064     *  @param  value   The value to compare.
065     *  @param  floor   The border value.
066     *  @param  include {@code true} if the border is included,
067     *      {@code false} if not.
068     *  @return {@code true} if the given value is greater than the given
069     *      border value, {@code false} otherwise. If {@code include} is
070     *      {@code true}, it will be &quot;greater or equal&quot;,
071     *      respectively.
072     */
073    public static <T> boolean isAbove( final Comparable<T> value, final T floor, final boolean include )
074    {
075        requireNonNullArgument( value, "value" );
076        requireNonNullArgument( floor, "floor" );
077
078        final var retValue = include ?
079            value.compareTo( floor ) >= 0 :
080            value.compareTo( floor ) > 0;
081
082        //---* Done *----------------------------------------------------------
083        return retValue;
084    }   //  isAbove()
085
086    /**
087     *  Returns {@code true} if {@code value} is above {@code floor}.
088     *
089     *  @param  <T> The type of the values to check.
090     *  @param  comparator  The comparator that is used for the comparison.
091     *  @param  value   The value to compare.
092     *  @param  floor   The border value.
093     *  @param  include {@code true} if the border is included,
094     *      {@code false} if not.
095     *  @return {@code true} if the given value is greater than the given
096     *      border value, {@code false} otherwise. If {@code include} is
097     *      {@code true}, it will be &quot;greater or equal&quot;,
098     *      respectively.
099     */
100    public static <T> boolean isAbove( final Comparator<T> comparator, final T value, final T floor, final boolean include )
101    {
102        requireNonNullArgument( comparator, "comparator" );
103        requireNonNullArgument( value, "value" );
104        requireNonNullArgument( floor, "floor" );
105
106        final var retValue = include ?
107            comparator.compare( value, floor ) >= 0 :
108            comparator.compare( value, floor ) > 0;
109
110        //---* Done *----------------------------------------------------------
111        return retValue;
112    }   //  isAbove()
113
114    /**
115     *  Returns {@code true} if {@code value} is above {@code floor}. If
116     *  {@code include} is {@code true}, {@code floor} is included,
117     *  otherwise it is not part of the range.
118     *
119     *  @param  <T> The type of the values to check.
120     *  @param  value   The value to compare.
121     *  @param  floor   The border value.
122     *  @return {@code true} if the given value is greater than the given
123     *      border value, {@code false} otherwise.
124     */
125    public static <T> boolean isAbove( final Comparable<T> value, final T floor )
126    {
127        final var retValue = isAbove( value, floor, false );
128
129        //---* Done *----------------------------------------------------------
130        return retValue;
131    }   //  isAbove()
132
133    /**
134     *  Returns {@code true} if {@code value} is above {@code floor}. If
135     *  {@code include} is {@code true}, {@code floor} is included,
136     *  otherwise it is not part of the range.
137     *
138     *  @param  <T> The type of the values to check.
139     *  @param  comparator  The comparator that is used for the comparison.
140     *  @param  value   The value to compare.
141     *  @param  floor   The border value.
142     *  @return {@code true} if the given value is greater than the given
143     *      border value, {@code false} otherwise.
144     */
145    public static <T> boolean isAbove( final Comparator<T> comparator, final T value, final T floor )
146    {
147        final var retValue = isAbove( comparator, value, floor, false );
148
149        //---* Done *----------------------------------------------------------
150        return retValue;
151    }   //  isAbove()
152
153    /**
154     *  Returns {@code true} if {@code value} is above {@code floor}.
155     *
156     *  @param  value   The value to compare.
157     *  @param  floor   The border value.
158     *  @return {@code true} if the given value is greater than the given
159     *      border value, {@code false} otherwise.
160     */
161    @SuppressWarnings( "CharacterComparison" )
162    public static boolean isAbove( final char value, final char floor ) { return value > floor; }
163
164    /**
165     *  Returns {@code true} if {@code value} is above {@code floor}.
166     *
167     *  @param  value   The value to compare.
168     *  @param  floor   The border value.
169     *  @return {@code true} if the given value is greater than the given
170     *      border value, {@code false} otherwise.
171     */
172    public static boolean isAbove( final double value, final double floor ) { return value > floor; }
173
174    /**
175     *  Returns {@code true} if {@code value} is above {@code floor}.
176     *
177     *  @param  value   The value to compare.
178     *  @param  floor   The border value.
179     *  @return {@code true} if the given value is greater than the given
180     *      border value, {@code false} otherwise.
181     */
182    public static boolean isAbove( final long value, final long floor ) { return value > floor; }
183
184    /**
185     *  Returns {@code true} if {@code value} is below {@code ceiling}.
186     *  If {@code include} is {@code true}, {@code ceiling} is included,
187     *  otherwise it is not part of the range.
188     *
189     *  @param  <T> The type of the values to check.
190     *  @param  value   The value to compare.
191     *  @param  ceiling The border value.
192     *  @param  include {@code true} if the border is included,
193     *      {@code false} if not.
194     *  @return {@code true} if the given value is less than the given
195     *      border value, {@code false} otherwise. If {@code include} is
196     *      {@code true}, it will be &quot;less or equal&quot;,
197     *      respectively.
198     */
199    public static <T> boolean isBelow( final Comparable<T> value, final T ceiling, final boolean include )
200    {
201        requireNonNullArgument( value, "value" );
202        requireNonNullArgument( ceiling, "ceiling" );
203
204        final var retValue = include ?
205            value.compareTo( ceiling ) <= 0 :
206            value.compareTo( ceiling ) < 0;
207
208        //---* Done *----------------------------------------------------------
209        return retValue;
210    }   //  isBelow()
211
212    /**
213     *  Returns {@code true} if {@code value} is below {@code ceiling}.
214     *  If {@code include} is {@code true}, {@code ceiling} is included,
215     *  otherwise it is not part of the range.
216     *
217     *  @param  <T> The type of the values to check.
218     *  @param  comparator  The comparator that is used for the comparison.
219     *  @param  value   The value to compare.
220     *  @param  ceiling The border value.
221     *  @param  include {@code true} if the border is included,
222     *      {@code false} if not.
223     *  @return {@code true} if the given value is less than the given
224     *      border value, {@code false} otherwise. If {@code include} is
225     *      {@code true}, it will be &quot;less or equal&quot;,
226     *      respectively.
227     */
228    public static <T> boolean isBelow( final Comparator<T> comparator, final T value, final T ceiling, final boolean include )
229    {
230        requireNonNullArgument( comparator, "comparator" );
231        requireNonNullArgument( value, "value" );
232        requireNonNullArgument( ceiling, "ceiling" );
233
234        final var retValue = include ?
235            comparator.compare( value, ceiling ) <= 0 :
236            comparator.compare( value, ceiling ) < 0;
237
238        //---* Done *----------------------------------------------------------
239        return retValue;
240    }   //  isBelow()
241
242    /**
243     *  Returns {@code true} if {@code value} is below {@code ceiling}.
244     *
245     *  @param  <T> The type of the values to check.
246     *  @param  value   The value to compare.
247     *  @param  ceiling The border value.
248     *  @return {@code true} if the given value is less than the given
249     *      border value, {@code false} otherwise.
250     */
251    public static <T> boolean isBelow( final Comparable<T> value, final T ceiling )
252    {
253        final var retValue = isBelow( value, ceiling, false );
254
255        //---* Done *----------------------------------------------------------
256        return retValue;
257    }   //  isBelow()
258
259    /**
260     *  Returns {@code true} if {@code value} is below {@code ceiling}.
261     *
262     *  @param  <T> The type of the values to check.
263     *  @param  comparator  The comparator that is used for the comparison.
264     *  @param  value   The value to compare.
265     *  @param  ceiling The border value.
266     *  @return {@code true} if the given value is less than the given
267     *      border value, {@code false} otherwise.
268     */
269    public static <T> boolean isBelow( final Comparator<T> comparator, final T value, final T ceiling )
270    {
271        final var retValue = isBelow( comparator, value, ceiling, false );
272
273        //---* Done *----------------------------------------------------------
274        return retValue;
275    }   //  isBelow()
276
277    /**
278     *  Returns {@code true} if {@code value} is below {@code ceiling}.
279     *
280     *  @param  value   The value to compare.
281     *  @param  ceiling The border value.
282     *  @return {@code true} if the given value is less than the given
283     *      border value, {@code false} otherwise.
284     */
285    @SuppressWarnings( "CharacterComparison" )
286    public static boolean isBelow( final char value, final char ceiling ) { return value < ceiling; }
287
288    /**
289     *  Returns {@code true} if {@code value} is below {@code ceiling}.
290     *
291     *  @param  value   The value to compare.
292     *  @param  ceiling The border value.
293     *  @return {@code true} if the given value is less than the given
294     *      border value, {@code false} otherwise.
295     */
296    public static boolean isBelow( final double value, final double ceiling ) { return value < ceiling; }
297
298    /**
299     *  Returns {@code true} if {@code value} is below {@code ceiling}.
300     *
301     *  @param  value   The value to compare.
302     *  @param  ceiling The border value.
303     *  @return {@code true} if the given value is less than the given
304     *      border value, {@code false} otherwise.
305     */
306    public static boolean isBelow( final long value, final long ceiling ) { return value < ceiling; }
307
308    /**
309     *  Returns {@code true} if {@code value} is between {@code floor} and
310     *  {@code ceiling}. If {@code include} is {@code true}, {@code floor}
311     *  and {@code ceiling} are included, otherwise they are not in the range.
312     *
313     *  @param  <T> The type of the values to check.
314     *  @param  value   The value to compare.
315     *  @param  floor   The lower border value.
316     *  @param  ceiling The upper border value.
317     *  @param  include {@code true} if the borders are included,
318     *      {@code false} if not.
319     *  @return {@code true} if the given value is greater than the given
320     *      lower border value and less than the given upper border value,
321     *      {@code false} otherwise. If {@code include} is
322     *      {@code true}, it will be &quot;greater or equal&quot; and
323     *      &quot;less or equal&quot;, respectively.
324     */
325    public static <T> boolean isBetween( final Comparable<T> value, final T floor, final T ceiling, final boolean include )
326    {
327        final var retValue = isAbove( value, floor, include ) && isBelow( value, ceiling, include );
328
329        //---* Done *----------------------------------------------------------
330        return retValue;
331    }   //  isBetween()
332
333    /**
334     *  Returns {@code true} if {@code value} is between {@code floor} and
335     *  {@code ceiling}. If {@code include} is {@code true}, {@code floor}
336     *  and {@code ceiling} are included, otherwise they are not in the range.
337     *
338     *  @param  <T> The type of the values to check.
339     *  @param  comparator  The comparator that is used for the comparison.
340     *  @param  value   The value to compare.
341     *  @param  floor   The lower border value.
342     *  @param  ceiling The upper border value.
343     *  @param  include {@code true} if the borders are included,
344     *      {@code false} if not.
345     *  @return {@code true} if the given value is greater than the given
346     *      lower border value and less than the given upper border value,
347     *      {@code false} otherwise. If {@code include} is
348     *      {@code true}, it will be &quot;greater or equal&quot; and
349     *      &quot;less or equal&quot;, respectively.
350     */
351    public static <T> boolean isBetween( final Comparator<T> comparator, final T value, final T floor, final T ceiling, final boolean include )
352    {
353        final var retValue = isAbove( comparator, value, floor, include ) && isBelow( comparator, value, ceiling, include );
354
355        //---* Done *----------------------------------------------------------
356        return retValue;
357    }   //  isBetween()
358
359    /**
360     *  Returns {@code true} if {@code value} is between {@code floor} and
361     *  {@code ceiling}. If {@code include} is {@code true}, {@code floor}
362     *  and {@code ceiling} are included, otherwise they are not in the range.
363     *
364     *  @param  value   The value to compare.
365     *  @param  floor   The lower border value.
366     *  @param  ceiling The upper border value.
367     *  @param  include {@code true} if the borders are included,
368     *      {@code false} if not.
369     *  @return {@code true} if the given value is greater than the given
370     *      lower border value and less than the given upper border value,
371     *      {@code false} otherwise. If {@code include} is
372     *      {@code true}, it will be &quot;greater or equal&quot; and
373     *      &quot;less or equal&quot;, respectively.
374     */
375    @SuppressWarnings( "CharacterComparison" )
376    public static boolean isBetween( final char value, final char floor, final char ceiling, final boolean include )
377    {
378        final var retValue = include ?
379            (value <= ceiling) && (value >= floor) :
380            (value < ceiling) && (value > floor);
381
382        //---* Done *----------------------------------------------------------
383        return retValue;
384    }   //  isBetween()
385
386    /**
387     *  Returns {@code true} if {@code value} is between {@code floor} and
388     *  {@code ceiling}. If {@code include} is {@code true}, {@code floor}
389     *  and {@code ceiling} are included, otherwise they are not in the range.
390     *
391     *  @param  value   The value to compare.
392     *  @param  floor   The lower border value.
393     *  @param  ceiling The upper border value.
394     *  @param  include {@code true} if the borders are included,
395     *      {@code false} if not.
396     *  @return {@code true} if the given value is greater than the given
397     *      lower border value and less than the given upper border value,
398     *      {@code false} otherwise. If {@code include} is
399     *      {@code true}, it will be &quot;greater or equal&quot; and
400     *      &quot;less or equal&quot;, respectively.
401     */
402    public static boolean isBetween( final double value, final double floor, final double ceiling, final boolean include )
403    {
404        final var retValue = include ?
405            (value <= ceiling) && (value >= floor) :
406            (value < ceiling) && (value > floor);
407
408        //---* Done *----------------------------------------------------------
409        return retValue;
410    }   //  isBetween()
411
412    /**
413     *  Returns {@code true} if {@code value} is between {@code floor} and
414     *  {@code ceiling}. If {@code include} is {@code true}, {@code floor}
415     *  and {@code ceiling} are included, otherwise they are not in the range.
416     *
417     *  @param  value   The value to compare.
418     *  @param  floor   The lower border value.
419     *  @param  ceiling The upper border value.
420     *  @param  include {@code true} if the borders are included,
421     *      {@code false} if not.
422     *  @return {@code true} if the given value is greater than the given
423     *      lower border value and less than the given upper border value,
424     *      {@code false} otherwise. If {@code include} is
425     *      {@code true}, it will be &quot;greater or equal&quot; and
426     *      &quot;less or equal&quot;, respectively.
427     */
428    public static boolean isBetween( final long value, final long floor, final long ceiling, final boolean include )
429    {
430        final var retValue = include ?
431            (value <= ceiling) && (value >= floor) :
432            (value < ceiling) && (value > floor);
433
434        //---* Done *----------------------------------------------------------
435        return retValue;
436    }   //  isBetween()
437
438    /**
439     *  Returns {@code true} if {@code value} is between {@code floor} and
440     *  {@code ceiling}.
441     *
442     *  @param  <T> The type of the values to check.
443     *  @param  value   The value to compare.
444     *  @param  floor   The lower border value.
445     *  @param  ceiling The upper border value.
446     *  @return {@code true} if the given value is greater than the given
447     *      lower border value and less than the given upper border value,
448     *      {@code false} otherwise.
449     */
450    public static <T> boolean isBetween( final Comparable<T> value, final T floor, final T ceiling )
451    {
452        final var retValue = isBetween( value, floor, ceiling, false );
453
454        //---* Done *----------------------------------------------------------
455        return retValue;
456    }   //  isBetween()
457
458    /**
459     *  Returns {@code true} if {@code value} is between {@code floor} and
460     *  {@code ceiling}.
461     *
462     *  @param  <T> The type of the values to check.
463     *  @param  comparator  The comparator that is used for the comparison.
464     *  @param  value   The value to compare.
465     *  @param  floor   The lower border value.
466     *  @param  ceiling The upper border value.
467     *  @return {@code true} if the given value is greater than the given
468     *      lower border value and less than the given upper border value,
469     *      {@code false} otherwise.
470     */
471    public static <T> boolean isBetween( final Comparator<T> comparator, final T value, final T floor, final T ceiling )
472    {
473        final var retValue = isBetween( comparator, value, floor, ceiling, false );
474
475        //---* Done *----------------------------------------------------------
476        return retValue;
477    }   //  isBetween()
478
479    /**
480     *  Returns {@code true} if {@code value} is between {@code floor} and
481     *  {@code ceiling}.
482     *
483     *  @param  value   The value to compare.
484     *  @param  floor   The lower border value.
485     *  @param  ceiling The upper border value.
486     *  @return {@code true} if the given value is greater than the given
487     *      lower border value and less than the given upper border value,
488     *      {@code false} otherwise.
489     */
490    public static boolean isBetween( final char value, final char floor, final char ceiling ) { return isBetween( value, floor, ceiling, false ); }
491
492    /**
493     *  Returns {@code true} if {@code value} is between {@code floor} and
494     *  {@code ceiling}.
495     *
496     *  @param  value   The value to compare.
497     *  @param  floor   The lower border value.
498     *  @param  ceiling The upper border value.
499     *  @return {@code true} if the given value is greater than the given
500     *      lower border value and less than the given upper border value,
501     *      {@code false} otherwise.
502     */
503    public static boolean isBetween( final double value, final double floor, final double ceiling ) { return isBetween( value, floor, ceiling, false ); }
504
505    /**
506     *  Returns {@code true} if {@code value} is between {@code floor} and
507     *  {@code ceiling}.
508     *
509     *  @param  value   The value to compare.
510     *  @param  floor   The lower border value.
511     *  @param  ceiling The upper border value.
512     *  @return {@code true} if the given value is greater than the given
513     *      lower border value and less than the given upper border value,
514     *      {@code false} otherwise.
515     */
516    public static boolean isBetween( final long value, final long floor, final long ceiling ) { return isBetween( value, floor, ceiling, false ); }
517}
518//  class RangeFunctions
519
520/*
521 *  End of File
522 */