001/*
002 * ============================================================================
003 *  Copyright © 2002-2026 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.jsonbuilder;
019
020import static org.apiguardian.api.API.Status.STABLE;
021import static org.tquadrat.foundation.jsonbuilder.JSONLiteral.FALSE;
022import static org.tquadrat.foundation.jsonbuilder.JSONLiteral.TRUE;
023
024import java.math.BigDecimal;
025import java.math.BigInteger;
026
027import org.apiguardian.api.API;
028import org.tquadrat.foundation.annotation.ClassVersion;
029import org.tquadrat.foundation.jsonbuilder.internal.JSONArrayImpl;
030import org.tquadrat.foundation.lang.value.Dimension;
031import org.tquadrat.foundation.lang.value.DimensionedValue;
032
033/**
034 *  <p>{@summary The definition of a JSON array.}</p>
035 *  <p>Basically, aa JSON array is dense, meaning that an array with the
036 *  maximum index <i><code>i</code></i> has exactly {@code i + 1} elements –
037 *  although some of these elements could be
038 *  {@link JSONLiteral#NULL null}.</p>
039 *  <p>The {@code add(T)} methods will add the given value to the end of the
040 *  array, while the {@code add(int,T)} methods will insert the given value at
041 *  the position identified by the given {@code index}; the already existing
042 *  values at that position and above will be moved to the next higher
043 *  position. If the {@code index} is equal to the
044 *  {@linkplain #size() size}
045 *  of the array, the value will be added to the end of the array. That means
046 *  that {@code add( value )} and {@code add( size(), value )} are equivalent.
047 *  A value for {@code index} that is greater than the size of the array (or
048 *  less than 0) will cause an
049 *  {@link IndexOutOfBoundsException}
050 *  to be thrown.</p>
051 *  <p>The {@code set(int,T)} methods will replace the value at the given
052 *  {@code index}; this means, that after a call to
053 *  {@link #set(int,JSONValue)}
054 *  the
055 *  {@linkplain #size() size}
056 *  of this array remains the same, while a call to
057 *  {@link #add(JSONValue)}
058 *  or
059 *  {@link #add(int,JSONValue)}
060 *  increases the array size by one.</p>
061 *  <p>Obviously must the value for the {@code index} argument of a
062 *  {@code set()} match an existing array position; otherwise an
063 *  {@link IndexOutOfBoundsException}
064 *  is thrown.</p>
065 *  <p>An instance of {@code JSONArray} is not thread-safe.</p>
066 *
067 *  @extauthor Thomas Thrien - thomas.thrien@tquadrat.org
068 *  @version $Id: JSONArray.java 1258 2026-06-04 18:33:06Z tquadrat $
069 *  @since 0.25.0
070 *
071 *  @UMLGraph.link
072 */
073@SuppressWarnings( "ClassWithTooManyMethods" )
074@ClassVersion( sourceVersion = "$Id: JSONArray.java 1258 2026-06-04 18:33:06Z tquadrat $" )
075@API( status = STABLE, since = "0.25.0" )
076public sealed interface JSONArray extends Iterable<JSONValue>, JSONValue
077    permits JSONArrayImpl
078{
079        /*---------*\
080    ====** Methods **==========================================================
081        \*---------*/
082    /**
083     *  <p>{@summary Appends the given value as a new element to the end of
084     *  this array.}</p>
085     *
086     *  @param  value   The value to add.
087     */
088    public void add( final BigDecimal value );
089
090    /**
091     *  <p>{@summary Appends the given value as a new element to the end of
092     *  this array.}</p>
093     *
094     *  @param  value   The value to add.
095     */
096    public void add( final BigInteger value );
097
098    /**
099     *  <p>{@summary Appends the given value as a new element to the end of
100     *  this array.}</p>
101     *
102     *  @param  value   The value to add.
103     */
104    public default void add( final boolean value )
105    {
106        add( value ? TRUE : FALSE );
107    }   //  add()
108
109    /**
110     *  <p>{@summary Appends the given value as a new element to the end of
111     *  this array.}</p>
112     *
113     *  @param  value   The value to add.
114     */
115    public void add( final double value );
116
117    /**
118     *  <p>{@summary Appends the given value as a new element to the end of
119     *  this array.}</p>
120     *
121     *  @param  <T> The type of the dimension for the value.
122     *  @param  value   The value.
123     *  @param  targetUnit  The dimension for the output.
124     *
125     *  @see JSONBuilder#valueOf(DimensionedValue,Dimension)
126     */
127    public <T extends Dimension> void add( final DimensionedValue<T> value, final T targetUnit );
128
129    /**
130     *  <p>{@summary Appends the given value as a new element to the end of
131     *  this array.}</p>
132     *
133     *  @param  value   The value to add.
134     */
135    public void add( final Double value );
136
137    /**
138     *  <p>{@summary Appends the given value as a new element to the end of
139     *  this array.}</p>
140     *
141     *  @param  value   The value to add.
142     */
143    public void add( final float value );
144
145    /**
146     *  <p>{@summary Appends the given value as a new element to the end of
147     *  this array.}</p>
148     *
149     *  @param  value   The value to add.
150     */
151    public void add( final Float value );
152
153    /**
154     *  <p>{@summary Appends the given value as a new element to the end of
155     *  this array.}</p>
156     *
157     *  @param  value   The value to add.
158     */
159    public void add( final int value );
160
161    /**
162     *  <p>{@summary Appends the given value as a new element to the end of
163     *  this array.}</p>
164     *
165     *  @param  value   The value to add.
166     */
167    public void add( final Integer value );
168
169    /**
170     *  <p>{@summary Appends the given value as a new element to the end of
171     *  this array.}</p>
172     *
173     *  @param  value   The value to add.
174     */
175    public void add( final JSONValue value );
176
177    /**
178     *  <p>{@summary Appends the given value as a new element to the end of
179     *  this array.}</p>
180     *
181     *  @param  value   The value to add.
182     */
183    public void add( final long value );
184
185    /**
186     *  <p>{@summary Appends the given value as a new element to the end of
187     *  this array.}</p>
188     *
189     *  @param  value   The value to add.
190     */
191    public void add( final Long value );
192
193    /**
194     *  <p>{@summary Appends the given value as a new element to the end of
195     *  this array.}</p>
196     *
197     *  @param  value   The value to add.
198     */
199    public void add( final String value );
200
201    /**
202     *  <p>{@summary Inserts the given value as a new element to the given
203     *  postion  this array and moves the other elements to a by one higher
204     *  index.}</p>
205     *  <p>If {@code index} is equals to the
206     *  {@linkplain #size() size}
207     *  of the array, the element is appended to the end of the array.</p>
208     *
209     *  @param  index   The index.
210     *  @param  value   The value to add.
211     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
212     *      than the
213     *      {@linkplain #size() size}
214     *      of the array.
215     */
216    public void add( final int index, final BigDecimal value ) throws IndexOutOfBoundsException;
217
218    /**
219     *  <p>{@summary Inserts the given value as a new element to the given
220     *  postion  this array and moves the other elements to a by one higher
221     *  index.}</p>
222     *  <p>If {@code index} is equals to the
223     *  {@linkplain #size() size}
224     *  of the array, the element is appended to the end of the array.</p>
225     *
226     *  @param  index   The index.
227     *  @param  value   The value to add.
228     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
229     *      than the
230     *      {@linkplain #size() size}
231     *      of the array.
232     */
233    public void add( final int index, final BigInteger value ) throws IndexOutOfBoundsException;
234
235    /**
236     *  <p>{@summary Inserts the given value as a new element to the given
237     *  postion  this array and moves the other elements to a by one higher
238     *  index.}</p>
239     *  <p>If {@code index} is equals to the
240     *  {@linkplain #size() size}
241     *  of the array, the element is appended to the end of the array.</p>
242     *
243     *  @param  index   The index.
244     *  @param  value   The value to add.
245     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
246     *      than the
247     *      {@linkplain #size() size}
248     *      of the array.
249     */
250    public default void add( final int index, final boolean value ) throws IndexOutOfBoundsException
251    {
252        add( index, value ? TRUE : FALSE );
253    }   //  add()
254
255    /**
256     *  <p>{@summary Inserts the given value as a new element to the given
257     *  postion of this array and moves the other elements to a by one higher
258     *  index.}</p>
259     *  <p>If {@code index} is equals to the
260     *  {@linkplain #size() size}
261     *  of the array, the element is appended to the end of the array.</p>
262     *
263     *  @param  <T> The type of the dimension for the value.
264     *  @param  index   The index.
265     *  @param  value   The value.
266     *  @param  targetUnit  The dimension for the output.
267     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
268     *      than the
269     *      {@linkplain #size() size}
270     *      of the array.
271     *
272     *  @see JSONBuilder#valueOf(DimensionedValue,Dimension)
273     */
274    public <T extends Dimension> void add( final int index, final DimensionedValue<T> value, final T targetUnit ) throws IndexOutOfBoundsException;
275
276    /**
277     *  <p>{@summary Inserts the given value as a new element to the given
278     *  postion of this array and moves the other elements to a by one higher
279     *  index.}</p>
280     *  <p>If {@code index} is equals to the
281     *  {@linkplain #size() size}
282     *  of the array, the element is appended to the end of the array.</p>
283     *
284     *  @param  index   The index.
285     *  @param  value   The value to add.
286     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
287     *      than the
288     *      {@linkplain #size() size}
289     *      of the array.
290     */
291    public void add( final int index, final double value ) throws IndexOutOfBoundsException;
292
293    /**
294     *  <p>{@summary Inserts the given value as a new element to the given
295     *  postion  this array and moves the other elements to a by one higher
296     *  index.}</p>
297     *  <p>If {@code index} is equals to the
298     *  {@linkplain #size() size}
299     *  of the array, the element is appended to the end of the array.</p>
300     *
301     *  @param  index   The index.
302     *  @param  value   The value to add.
303     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
304     *      than the
305     *      {@linkplain #size() size}
306     *      of the array.
307     */
308    public void add( final int index, final Double value ) throws IndexOutOfBoundsException;
309
310    /**
311     *  <p>{@summary Inserts the given value as a new element to the given
312     *  postion  this array and moves the other elements to a by one higher
313     *  index.}</p>
314     *  <p>If {@code index} is equals to the
315     *  {@linkplain #size() size}
316     *  of the array, the element is appended to the end of the array.</p>
317     *
318     *  @param  index   The index.
319     *  @param  value   The value to add.
320     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
321     *      than the
322     *      {@linkplain #size() size}
323     *      of the array.
324     */
325    public void add( final int index, final float value ) throws IndexOutOfBoundsException;
326
327    /**
328     *  <p>{@summary Inserts the given value as a new element to the given
329     *  postion  this array and moves the other elements to a by one higher
330     *  index.}</p>
331     *  <p>If {@code index} is equals to the
332     *  {@linkplain #size() size}
333     *  of the array, the element is appended to the end of the array.</p>
334     *
335     *  @param  index   The index.
336     *  @param  value   The value to add.
337     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
338     *      than the
339     *      {@linkplain #size() size}
340     *      of the array.
341     */
342    public void add( final int index, final Float value ) throws IndexOutOfBoundsException;
343
344    /**
345     *  <p>{@summary Inserts the given value as a new element to the given
346     *  postion  this array and moves the other elements to a by one higher
347     *  index.}</p>
348     *  <p>If {@code index} is equals to the
349     *  {@linkplain #size() size}
350     *  of the array, the element is appended to the end of the array.</p>
351     *
352     *  @param  index   The index.
353     *  @param  value   The value to add.
354     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
355     *      than the
356     *      {@linkplain #size() size}
357     *      of the array.
358     */
359    public void add( final int index, final int value ) throws IndexOutOfBoundsException;
360
361    /**
362     *  <p>{@summary Inserts the given value as a new element to the given
363     *  postion  this array and moves the other elements to a by one higher
364     *  index.}</p>
365     *  <p>If {@code index} is equals to the
366     *  {@linkplain #size() size}
367     *  of the array, the element is appended to the end of the array.</p>
368     *
369     *  @param  index   The index.
370     *  @param  value   The value to add.
371     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
372     *      than the
373     *      {@linkplain #size() size}
374     *      of the array.
375     */
376    public void add( final int index, final Integer value ) throws IndexOutOfBoundsException;
377
378    /**
379     *  <p>{@summary Inserts the given value as a new element to the given
380     *  postion  this array and moves the other elements to a by one higher
381     *  index.}</p>
382     *  <p>If {@code index} is equals to the
383     *  {@linkplain #size() size}
384     *  of the array, the element is appended to the end of the array.</p>
385     *
386     *  @param  index   The index.
387     *  @param  value   The value to add.
388     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
389     *      than the
390     *      {@linkplain #size() size}
391     *      of the array.
392     */
393    public void add( final int index, final JSONValue value ) throws IndexOutOfBoundsException;
394
395    /**
396     *  <p>{@summary Inserts the given value as a new element to the given
397     *  postion  this array and moves the other elements to a by one higher
398     *  index.}</p>
399     *  <p>If {@code index} is equals to the
400     *  {@linkplain #size() size}
401     *  of the array, the element is appended to the end of the array.</p>
402     *
403     *  @param  index   The index.
404     *  @param  value   The value to add.
405     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
406     *      than the
407     *      {@linkplain #size() size}
408     *      of the array.
409     */
410    public void add( final int index, final long value ) throws IndexOutOfBoundsException;
411
412    /**
413     *  <p>{@summary Inserts the given value as a new element to the given
414     *  postion  this array and moves the other elements to a by one higher
415     *  index.}</p>
416     *  <p>If {@code index} is equals to the
417     *  {@linkplain #size() size}
418     *  of the array, the element is appended to the end of the array.</p>
419     *
420     *  @param  index   The index.
421     *  @param  value   The value to add.
422     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
423     *      than the
424     *      {@linkplain #size() size}
425     *      of the array.
426     */
427    public void add( final int index, final Long value ) throws IndexOutOfBoundsException;
428
429    /**
430     *  <p>{@summary Inserts the given value as a new element to the given
431     *  postion  this array and moves the other elements to a by one higher
432     *  index.}</p>
433     *  <p>If {@code index} is equals to the
434     *  {@linkplain #size() size}
435     *  of the array, the element is appended to the end of the array.</p>
436     *
437     *  @param  index   The index.
438     *  @param  value   The value to add.
439     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
440     *      than the
441     *      {@linkplain #size() size}
442     *      of the array.
443     */
444    public void add( final int index, final String value ) throws IndexOutOfBoundsException;
445
446    /**
447     *  <p>{@summary Appends the given array to this one.} This mean that the
448     *  elements of the given array are added to this one.</p>
449     *
450     *  @param  array   The other array.
451     *  @return {@true} if the call to this method changed this instance.
452     */
453    @SuppressWarnings( "BooleanMethodNameMustStartWithQuestion" )
454    public boolean addAll( final JSONArray array );
455
456    /**
457     *  <p>{@summary Adds a new empty instance of {@code JSONArray} to this
458     *  array and returns that.}</p>
459     *
460     *  @return The freshly created {@code JSONArray}.
461     */
462    public JSONArray addArray();
463
464    /**
465     *  <p>{@summary Adds a new empty instance of {@code JSONArray} to this
466     *  array at the given index and returns that.}</p>
467     *
468     *  @param  index   The index.
469     *  @return The freshly created {@code JSONArray}.
470     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
471     *      than the
472     *      {@linkplain #size() size}
473     *      of the array.
474     */
475    public JSONArray addArray( final int index ) throws IndexOutOfBoundsException;
476
477    /**
478     *  <p>{@summary Adds a new empty instance of
479     *  {@link JSONObject}
480     *  to this array and returns that.}</p>
481     *
482     *  @return The freshly created {@code JSONObject}.
483     */
484    public JSONObject addObject();
485
486    /**
487     *  <p>{@summary Adds a new empty instance of
488     *  {@link JSONObject}
489     *  to this array at the given index and returns that.}</p>
490     *
491     *  @param  index   The index.
492     *  @return The freshly created {@code JSONObject}.
493     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
494     *      than the
495     *      {@linkplain #size() size}
496     *      of the array.
497     */
498    public JSONObject addObject( final int index ) throws IndexOutOfBoundsException;
499
500    /**
501     *  <p>{@summary Returns the value of the element at the specied index in
502     *  this array.}</p>
503     *
504     *  @param  index   The index of the element whose value is to be returned.
505     *  @return The element; will never be {@null}.
506     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
507     *      than or equal to the
508     *      {@linkplain #size() size}
509     *      of the array.
510     */
511    public JSONValue get( final int index ) throws IndexOutOfBoundsException;
512
513    /**
514     *  <p>{@summary Convenience method that returns the value with the
515     *  specified index as a {@code JSONArray}.}</p>
516     *
517     *  @param  index   The index of the element whose value is to be returned.
518     *  @return The value of the element with the specified index.
519     *  @throws IllegalStateException   The element is not a JSON Array.
520     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
521     *      than or equal to the
522     *      {@linkplain #size() size}
523     *      of the array.
524     */
525    public default JSONArray getArray( final int index ) throws IllegalStateException, IndexOutOfBoundsException
526    {
527        final var value = get( index );
528        final var retValue = value.asArray();
529
530        //---* Done *----------------------------------------------------------
531        return retValue;
532    }   //  getArray()
533
534    /**
535     *  <p>{@summary Convenience method that returns the value with the
536     *  specified index as a
537     *  {@link BigDecimal}.}</p>
538     *
539     *  @param  index   The index of the element whose value is to be returned.
540     *  @return The value of the element with the specified index.
541     *  @throws IllegalStateException   The element is not a number.
542     *  @throws NumberFormatException   The element is a number, but cannot be
543     *      parsed to a valid {@code BigDecimal}.
544     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
545     *      than or equal to the
546     *      {@linkplain #size() size}
547     *      of the array.
548     */
549    public default BigDecimal getBigDecimal( final int index ) throws IllegalStateException, IndexOutOfBoundsException, NumberFormatException
550    {
551        final var value = get( index );
552        final var number = value.asNumber();
553        final var retValue = number.getBigDecimal();
554
555        //---* Done *----------------------------------------------------------
556        return retValue;
557    }   //  getBigDecimal()
558
559    /**
560     *  <p>{@summary Convenience method that returns the value with the
561     *  specified index as a
562     *  {@link BigInteger}.}</p>
563     *
564     *  @param  index   The index of the element whose value is to be returned.
565     *  @return The value of the element with the specified index.
566     *  @throws IllegalStateException   The element is not a number.
567     *  @throws NumberFormatException   The element is a number, but cannot be
568     *      parsed to a valid {@code BigInteger}.
569     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
570     *      than or equal to the
571     *      {@linkplain #size() size}
572     *      of the array.
573     */
574    public default BigInteger getBigInteger( final int index ) throws IllegalStateException, IndexOutOfBoundsException, NumberFormatException
575    {
576        final var value = get( index );
577        final var number = value.asNumber();
578        final var retValue = number.getBigInteger();
579
580        //---* Done *----------------------------------------------------------
581        return retValue;
582    }   //  getBigInteger()
583
584    /**
585     *  <p>{@summary Convenience method that returns the value with the
586     *  specified index as a {@code boolean}.}</p>
587     *
588     *  @param  index   The index of the element whose value is to be returned.
589     *  @return The value of the element with the specified index.
590     *  @throws IllegalStateException   The element is not a boolean.
591     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
592     *      than or equal to the
593     *      {@linkplain #size() size}
594     *      of the array.
595     */
596    @SuppressWarnings( "BooleanMethodNameMustStartWithQuestion" )
597    public default boolean getBoolean( final int index ) throws IllegalStateException, IndexOutOfBoundsException
598    {
599        final var value = get( index );
600        final var flag = value.asBoolean();
601        final var retValue = flag.isTrue();
602
603        //---* Done *----------------------------------------------------------
604        return retValue;
605    }   //  getBoolean()
606
607    /**
608     *  <p>{@summary Convenience method that returns the value with the
609     *  specified index as a {@code double}.}</p>
610     *
611     *  @param  index   The index of the element whose value is to be returned.
612     *  @return The value of the element with the specified index.
613     *  @throws IllegalStateException   The element is not a number.
614     *  @throws NumberFormatException   The element is a number, but cannot be
615     *      parsed to a valid {@code double}.
616     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
617     *      than or equal to the
618     *      {@linkplain #size() size}
619     *      of the array.
620     */
621    public default double getDouble( final int index ) throws IllegalStateException, IndexOutOfBoundsException, NumberFormatException
622    {
623        final var value = get( index );
624        final var number = value.asNumber();
625        final var retValue = number.getDouble();
626
627        //---* Done *----------------------------------------------------------
628        return retValue;
629    }   //  getDouble()
630
631    /**
632     *  <p>{@summary Convenience method that returns the value with the
633     *  specified index as a {@code float}.}</p>
634     *
635     *  @param  index   The index of the element whose value is to be returned.
636     *  @return The value of the element with the specified index.
637     *  @throws IllegalStateException   The element is not a number.
638     *  @throws NumberFormatException   The element is a number, but cannot be
639     *      parsed to a valid {@code float}.
640     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
641     *      than or equal to the
642     *      {@linkplain #size() size}
643     *      of the array.
644     */
645    public default float getFloat( final int index ) throws IllegalStateException, IndexOutOfBoundsException, NumberFormatException
646    {
647        final var value = get( index );
648        final var number = value.asNumber();
649        final var retValue = number.getFloat();
650
651        //---* Done *----------------------------------------------------------
652        return retValue;
653    }   //  getFloat()
654
655    /**
656     *  <p>{@summary Convenience method that returns the value with the
657     *  specified index as a {@code int}.}</p>
658     *
659     *  @param  index   The index of the element whose value is to be returned.
660     *  @return The value of the element with the specified index.
661     *  @throws IllegalStateException   The element is not a number.
662     *  @throws NumberFormatException   The element is a number, but cannot be
663     *      parsed to a valid {@code int}.
664     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
665     *      than or equal to the
666     *      {@linkplain #size() size}
667     *      of the array.
668     */
669    public default int getInt( final int index ) throws IllegalStateException, IndexOutOfBoundsException, NumberFormatException
670    {
671        final var value = get( index );
672        final var number = value.asNumber();
673        final var retValue = number.getInt();
674
675        //---* Done *----------------------------------------------------------
676        return retValue;
677    }   //  getInt()
678
679    /**
680     *  <p>{@summary Convenience method that returns the value with the
681     *  specified index as a {@code long}.}</p>
682     *
683     *  @param  index   The index of the element whose value is to be returned.
684     *  @return The value of the element with the specified index.
685     *  @throws IllegalStateException   The element is not a number.
686     *  @throws NumberFormatException   The element is a number, but cannot be
687     *      parsed to a valid {@code long}.
688     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
689     *      than or equal to the
690     *      {@linkplain #size() size}
691     *      of the array.
692     */
693    public default long getLong( final int index ) throws IllegalStateException, IndexOutOfBoundsException, NumberFormatException
694    {
695        final var value = get( index );
696        final var number = value.asNumber();
697        final var retValue = number.getLong();
698
699        //---* Done *----------------------------------------------------------
700        return retValue;
701    }   //  getInt()
702
703    /**
704     *  <p>{@summary Convenience method that returns the value with the
705     *  specified index as a
706     *  {@link JSONObject}.}</p>
707     *
708     *  @param  index   The index of the element whose value is to be returned.
709     *  @return The value of the element with the specified index.
710     *  @throws IllegalStateException   The element is not a JSON Object.
711     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
712     *      than or equal to the
713     *      {@linkplain #size() size}
714     *      of the array.
715     */
716    public default JSONObject getObject( final int index ) throws IllegalStateException, IndexOutOfBoundsException
717    {
718        final var value = get( index );
719        final var retValue = value.asObject();
720
721        //---* Done *----------------------------------------------------------
722        return retValue;
723    }   //  getObject()
724
725    /**
726     *  <p>{@summary Convenience method that returns the value with the
727     *  specified index as a
728     *  {@link String}.}</p>
729     *
730     *  @param  index   The index of the element whose value is to be returned.
731     *  @return The value of the element with the specified index.
732     *  @throws IllegalStateException   The element is not a String.
733     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
734     *      than or equal to the
735     *      {@linkplain #size() size}
736     *      of the array.
737     */
738    public default String getString( final int index ) throws IllegalStateException, IndexOutOfBoundsException
739    {
740        final var value = get( index );
741        final var jsonString = value.asString();
742        final var retValue = jsonString.getString();
743
744        //---* Done *----------------------------------------------------------
745        return retValue;
746    }   //  getString()
747
748    /**
749     *  Checks whether this array has elements.
750     *
751     *  @return {@true} if the object does not have any elements,
752     *      {@false} otherwise.
753     */
754    public boolean isEmpty();
755
756    /**
757     *  <p>{@summary Removes the element with the specified index from this
758     *  array.}</p>
759     *
760     *  @param  index   The index of the element to remove.
761     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
762     *      than or equal to the
763     *      {@linkplain #size() size}
764     *      of the array.
765     */
766    public void remove( final int index ) throws IndexOutOfBoundsException;
767
768    /**
769     *  <p>{@summary Removes the first occurrence of the specified element from
770     *  this array, if it is present.} If this list does not contain the
771     *  element, it remains unchanged.</p>
772     *  <p>More formally, this method removes the element with the lowest index
773     *  {@code i} such that
774     *  {@link org.tquadrat.foundation.lang.Objects#equals(Object, Object) Objects.equals(o, get(i))}
775     *  (if such an element exists).</p>
776     *
777     *  @param  element   The element to remove.
778     */
779    public void remove( final JSONValue element );
780
781    /**
782     *  <p>{@summary Sets the value of the element with the specified index to
783     *  the JSON representation of the specified
784     *  {@link BigDecimal}
785     *  value.}</p>
786     *
787     *  @param  index   The index of the element to replace.
788     *  @param  value   The value to set to the member.
789     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
790     *      than or equal to the
791     *      {@linkplain #size() size}
792     *      of the array.
793     */
794    public void set( final int index, final BigDecimal value ) throws IndexOutOfBoundsException;
795
796    /**
797     *  <p>{@summary Sets the value of the element with the specified index to
798     *  the JSON representation of the specified
799     *  {@link BigInteger}
800     *  value.}</p>
801     *
802     *  @param  index   The index of the element to replace.
803     *  @param  value   The value to set to the member.
804     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
805     *      than or equal to the
806     *      {@linkplain #size() size}
807     *      of the array.
808     */
809    public void set( final int index, final BigInteger value ) throws IndexOutOfBoundsException;
810
811    /**
812     *  <p>{@summary Sets the value of the element with the specified index to
813     *  the JSON representation of the specified {@code boolean} value.}</p>
814     *
815     *  @param  index   The index of the element to replace.
816     *  @param  value   The value to set to the member.
817     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
818     *      than or equal to the
819     *      {@linkplain #size() size}
820     *      of the array.
821     */
822    public default void set( final int index, final boolean value ) throws IndexOutOfBoundsException
823    {
824        set( index, value ? TRUE : FALSE );
825    }   //  set()
826
827    /**
828     *  <p>{@summary Sets the value of the element with the specified index to
829     *  the JSON representation of the specified
830     *  {@link DimensionedValue}
831     *  value.}</p>
832     *
833     *  @param  <T> The type of the dimension for the value.
834     *  @param  index   The index.
835     *  @param  value   The value.
836     *  @param  targetUnit  The dimension for the output.
837     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
838     *      than or equal to the
839     *      {@linkplain #size() size}
840     *      of the array.
841     *
842     *  @see JSONBuilder#valueOf(DimensionedValue,Dimension)
843     */
844    public <T extends Dimension> void set( final int index, final DimensionedValue<T> value, final T targetUnit ) throws IndexOutOfBoundsException;
845
846    /**
847     *  <p>{@summary Sets the value of the element with the specified index to
848     *  the JSON representation of the specified {@code double} value.}</p>
849     *
850     *  @param  index   The index of the element to replace.
851     *  @param  value   The value to set to the member.
852     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
853     *      than or equal to the
854     *      {@linkplain #size() size}
855     *      of the array.
856     */
857    public void set( final int index, final double value ) throws IndexOutOfBoundsException;
858
859    /**
860     *  <p>{@summary Sets the value of the element with the specified index to
861     *  the JSON representation of the specified
862     *  {@link Double}
863     *  value.}</p>
864     *
865     *  @param  index   The index of the element to replace.
866     *  @param  value   The value to set to the member.
867     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
868     *      than or equal to the
869     *      {@linkplain #size() size}
870     *      of the array.
871     */
872    public void set( final int index, final Double value ) throws IndexOutOfBoundsException;
873
874    /**
875     *  <p>{@summary Sets the value of the element with the specified index to
876     *  the JSON representation of the specified {@code int} value.}</p>
877     *
878     *  @param  index   The index of the element to replace.
879     *  @param  value   The value to set to the member.
880     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
881     *      than or equal to the
882     *      {@linkplain #size() size}
883     *      of the array.
884     */
885    public void set( final int index, final int value ) throws IndexOutOfBoundsException;
886
887    /**
888     *  <p>{@summary Sets the value of the element with the specified index to
889     *  the JSON representation of the specified {@code float} value.}</p>
890     *
891     *  @param  index   The index of the element to replace.
892     *  @param  value   The value to set to the member.
893     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
894     *      than or equal to the
895     *      {@linkplain #size() size}
896     *      of the array.
897     */
898    public void set( final int index, final float value ) throws IndexOutOfBoundsException;
899
900    /**
901     *  <p>{@summary Sets the value of the element with the specified index to
902     *  the JSON representation of the specified
903     *  {@link Float}
904     *  value.}</p>
905     *
906     *  @param  index   The index of the element to replace.
907     *  @param  value   The value to set to the member.
908     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
909     *      than or equal to the
910     *      {@linkplain #size() size}
911     *      of the array.
912     */
913    public void set( final int index, final Float value ) throws IndexOutOfBoundsException;
914
915    /**
916     *  <p>{@summary Sets the value of the element with the specified index to
917     *  the JSON representation of the specified
918     *  {@link Integer}
919     *  value.}</p>
920     *
921     *  @param  index   The index of the element to replace.
922     *  @param  value   The value to set to the member.
923     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
924     *      than or equal to the
925     *      {@linkplain #size() size}
926     *      of the array.
927     */
928    public void set( final int index, final Integer value ) throws IndexOutOfBoundsException;
929
930    /**
931     *  <p>{@summary Sets the value of the element with the specified index to
932     *  the given
933     *  {@link JSONValue}
934     *  instance.}</p>
935     *
936     *  @param  index   The index of the element to replace.
937     *  @param  value   The value to set to the member.
938     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
939     *      than or equal to the
940     *      {@linkplain #size() size}
941     *      of the array.
942     */
943    public void set( final int index, final JSONValue value ) throws IndexOutOfBoundsException;
944
945    /**
946     *  <p>{@summary Sets the value of the element with the specified index to
947     *  the JSON representation of the specified {@code long} value.}</p>
948     *
949     *  @param  index   The index of the element to replace.
950     *  @param  value   The value to set to the member.
951     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
952     *      than or equal to the
953     *      {@linkplain #size() size}
954     *      of the array.
955     */
956    public void set( final int index, final long value ) throws IndexOutOfBoundsException;
957
958    /**
959     *  <p>{@summary Sets the value of the element with the specified index to
960     *  the JSON representation of the specified
961     *  {@link Long}
962     *  value.}</p>
963     *
964     *  @param  index   The index of the element to replace.
965     *  @param  value   The value to set to the member.
966     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
967     *      than or equal to the
968     *      {@linkplain #size() size}
969     *      of the array.
970     */
971    public void set( final int index, final Long value ) throws IndexOutOfBoundsException;
972
973    /**
974     *  <p>{@summary Sets the value of the element with the specified index to
975     *  the JSON representation of the specified
976     *  {@link String}
977     *  value.}</p>
978     *
979     *  @param  index   The index of the element to replace.
980     *  @param  value   The value to set to the member.
981     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
982     *      than or equal to the
983     *      {@linkplain #size() size}
984     *      of the array.
985     */
986    public void set( final int index, final String value ) throws IndexOutOfBoundsException;
987
988    /**
989     *  <p>{@summary Sets a new empty instance of {@code JSONArray} to this
990     *  array at the given index and returns that.}</p>
991     *
992     *  @param  index   The index.
993     *  @return The freshly created {@code JSONArray}.
994     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
995     *      than or equal to the
996     *      {@linkplain #size() size}
997     *      of the array.
998     */
999    public JSONArray setArray( final int index ) throws IndexOutOfBoundsException;
1000
1001    /**
1002     *  <p>{@summary Sets a new empty instance of
1003     *  {@link JSONObject}
1004     *  to this array at the given index and returns that.}</p>
1005     *
1006     *  @param  index   The index.
1007     *  @return The freshly created {@code JSONObject}.
1008     *  @throws IndexOutOfBoundsException   The index is less than 0 or greater
1009     *      than or equal to the
1010     *      {@linkplain #size() size}
1011     *      of the array.
1012     */
1013    public JSONObject setObject( final int index ) throws IndexOutOfBoundsException;
1014
1015    /**
1016     *  Returns the number of elements for this array.
1017     *
1018     * @return The number of members in this object.
1019     */
1020    public int size();
1021}
1022//  interface JSONObject
1023
1024/*
1025 *  End of File
1026 */