001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
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,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.commons.lang;
018
019import static org.apache.juneau.commons.utils.AssertionUtils.*;
020import static org.apache.juneau.commons.utils.Utils.*;
021
022import java.util.concurrent.atomic.*;
023
024/**
025 * A simple mutable short value.
026 *
027 * <p>
028 * This class extends {@link Value}&lt;{@link Short}&gt; and adds a convenience method for incrementing
029 * the value, which is useful for counting operations in lambdas and loops.
030 *
031 * <h5 class='section'>Notes:</h5><ul>
032 *    <li class='note'>
033 *       This class is <b>not thread-safe</b>. For concurrent access, use {@link AtomicInteger} instead.
034 * </ul>
035 *
036 * <h5 class='section'>Example:</h5>
037 * <p class='bjava'>
038 *    <jc>// Create a counter</jc>
039 *    ShortValue <jv>counter</jv> = ShortValue.<jsm>create</jsm>();
040 *
041 *    <jc>// Use in a lambda to count valid items</jc>
042 *    list.forEach(<jv>x</jv> -&gt; {
043 *       <jk>if</jk> (<jv>x</jv>.isValid()) {
044 *          <jv>counter</jv>.getAndIncrement();
045 *       }
046 *    });
047 *
048 *    <jsm>log</jsm>(<js>"Valid items: "</js> + <jv>counter</jv>.get());
049 * </p>
050 *
051 * <h5 class='section'>See Also:</h5><ul>
052 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauCommonsLang">Lang Package</a>
053 * </ul>
054 */
055public class ShortValue extends Value<Short> {
056
057   /**
058    * Creates a new short value initialized to <c>0</c>.
059    *
060    * <h5 class='section'>Example:</h5>
061    * <p class='bjava'>
062    *    ShortValue <jv>counter</jv> = ShortValue.<jsm>create</jsm>();
063    *    <jsm>assertEquals</jsm>(0, <jv>counter</jv>.get());
064    * </p>
065    *
066    * @return A new short value.
067    */
068   public static ShortValue create() {
069      return of((short)0);
070   }
071
072   /**
073    * Creates a new short value with the specified initial value.
074    *
075    * <h5 class='section'>Example:</h5>
076    * <p class='bjava'>
077    *    ShortValue <jv>counter</jv> = ShortValue.<jsm>of</jsm>((<jk>short</jk>)42);
078    *    <jsm>assertEquals</jsm>(42, <jv>counter</jv>.get());
079    * </p>
080    *
081    * @param value The initial value.
082    * @return A new short value.
083    */
084   public static ShortValue of(Short value) {
085      return new ShortValue(value);
086   }
087
088   /**
089    * Constructor.
090    *
091    * @param value The initial value.
092    */
093   public ShortValue(Short value) {
094      super(value);
095   }
096
097   /**
098    * Adds the specified value to the current value.
099    *
100    * <h5 class='section'>Example:</h5>
101    * <p class='bjava'>
102    *    ShortValue <jv>value</jv> = ShortValue.<jsm>of</jsm>((<jk>short</jk>)10);
103    *    <jv>value</jv>.add((<jk>short</jk>)5);
104    *    <jsm>assertEquals</jsm>(15, <jv>value</jv>.get());
105    * </p>
106    *
107    * @param x The value to add.
108    * @return This object.
109    */
110   public ShortValue add(Short x) {
111      var v = get();
112      set((short)((v == null ? 0 : v) + (x == null ? 0 : x)));
113      return this;
114   }
115
116   /**
117    * Adds the specified value to the current value and returns the new value.
118    *
119    * <h5 class='section'>Example:</h5>
120    * <p class='bjava'>
121    *    ShortValue <jv>value</jv> = ShortValue.<jsm>of</jsm>((<jk>short</jk>)10);
122    *    <jk>short</jk> <jv>result</jv> = <jv>value</jv>.addAndGet((<jk>short</jk>)5);  <jc>// Returns 15</jc>
123    *    <jsm>assertEquals</jsm>(15, <jv>value</jv>.get());
124    * </p>
125    *
126    * @param x The value to add.
127    * @return The new value after addition.
128    */
129   public Short addAndGet(Short x) {
130      var v = get();
131      var result = (short)((v == null ? 0 : v) + (x == null ? 0 : x));
132      set(result);
133      return result;
134   }
135
136   /**
137    * Decrements the value by 1.
138    *
139    * <h5 class='section'>Example:</h5>
140    * <p class='bjava'>
141    *    ShortValue <jv>counter</jv> = ShortValue.<jsm>of</jsm>((<jk>short</jk>)5);
142    *    <jv>counter</jv>.decrement();
143    *    <jsm>assertEquals</jsm>(4, <jv>counter</jv>.get());
144    * </p>
145    *
146    * @return This object.
147    */
148   public ShortValue decrement() {
149      var v = get();
150      set((short)((v == null ? 0 : v) - 1));
151      return this;
152   }
153
154   /**
155    * Decrements the value by 1 and returns the new value.
156    *
157    * <h5 class='section'>Example:</h5>
158    * <p class='bjava'>
159    *    ShortValue <jv>counter</jv> = ShortValue.<jsm>of</jsm>((<jk>short</jk>)5);
160    *    <jk>short</jk> <jv>result</jv> = <jv>counter</jv>.decrementAndGet();  <jc>// Returns 4</jc>
161    *    <jsm>assertEquals</jsm>(4, <jv>counter</jv>.get());
162    * </p>
163    *
164    * @return The decremented value.
165    */
166   public Short decrementAndGet() {
167      var v = get();
168      var result = (short)((v == null ? 0 : v) - 1);
169      set(result);
170      return result;
171   }
172
173   /**
174    * Returns the current value and then increments it.
175    *
176    * <h5 class='section'>Example:</h5>
177    * <p class='bjava'>
178    *    ShortValue <jv>counter</jv> = ShortValue.<jsm>of</jsm>((<jk>short</jk>)5);
179    *    <jk>short</jk> <jv>current</jv> = <jv>counter</jv>.getAndIncrement();  <jc>// Returns 5</jc>
180    *    <jk>short</jk> <jv>next</jv> = <jv>counter</jv>.get();                <jc>// Returns 6</jc>
181    * </p>
182    *
183    * @return The value before it was incremented.
184    */
185   public short getAndIncrement() {
186      var v = get();
187      set(v == null ? 1 : (short)(v + 1));
188      return v == null ? 0 : v;
189   }
190
191   /**
192    * Increments the value by 1.
193    *
194    * <h5 class='section'>Example:</h5>
195    * <p class='bjava'>
196    *    ShortValue <jv>counter</jv> = ShortValue.<jsm>of</jsm>((<jk>short</jk>)5);
197    *    <jv>counter</jv>.increment();
198    *    <jsm>assertEquals</jsm>(6, <jv>counter</jv>.get());
199    * </p>
200    *
201    * @return This object.
202    */
203   public ShortValue increment() {
204      var v = get();
205      set((short)((v == null ? 0 : v) + 1));
206      return this;
207   }
208
209   /**
210    * Increments the value by 1 and returns the new value.
211    *
212    * <h5 class='section'>Example:</h5>
213    * <p class='bjava'>
214    *    ShortValue <jv>counter</jv> = ShortValue.<jsm>of</jsm>((<jk>short</jk>)5);
215    *    <jk>short</jk> <jv>result</jv> = <jv>counter</jv>.incrementAndGet();  <jc>// Returns 6</jc>
216    *    <jsm>assertEquals</jsm>(6, <jv>counter</jv>.get());
217    * </p>
218    *
219    * @return The incremented value.
220    */
221   public Short incrementAndGet() {
222      var v = get();
223      var result = (short)((v == null ? 0 : v) + 1);
224      set(result);
225      return result;
226   }
227
228   /**
229    * Checks if the current value is equal to the specified value.
230    *
231    * <p>
232    * Uses {@link org.apache.juneau.commons.utils.Utils#eq(Object, Object)} for deep equality comparison, which handles nulls safely.
233    *
234    * <h5 class='section'>Example:</h5>
235    * <p class='bjava'>
236    *    ShortValue <jv>value</jv> = ShortValue.<jsm>of</jsm>((<jk>short</jk>)42);
237    *    <jsm>assertTrue</jsm>(<jv>value</jv>.is((<jk>short</jk>)42));
238    *    <jsm>assertFalse</jsm>(<jv>value</jv>.is((<jk>short</jk>)43));
239    * </p>
240    *
241    * @param value The value to compare to.
242    * @return <jk>true</jk> if the current value is equal to the specified value.
243    */
244   public boolean is(Short value) {
245      return eq(get(), value);
246   }
247
248   /**
249    * Checks if the current value matches any of the specified values.
250    *
251    * <p>
252    * Uses {@link org.apache.juneau.commons.utils.Utils#eq(Object, Object)} for deep equality comparison of each value.
253    *
254    * <h5 class='section'>Example:</h5>
255    * <p class='bjava'>
256    *    ShortValue <jv>value</jv> = ShortValue.<jsm>of</jsm>((<jk>short</jk>)5);
257    *    <jsm>assertTrue</jsm>(<jv>value</jv>.isAny((<jk>short</jk>)3, (<jk>short</jk>)5, (<jk>short</jk>)7));
258    *    <jsm>assertFalse</jsm>(<jv>value</jv>.isAny((<jk>short</jk>)1, (<jk>short</jk>)2));
259    * </p>
260    *
261    * @param values The values to compare to.
262    * @return <jk>true</jk> if the current value matches any of the specified values.
263    */
264   public boolean isAny(Short...values) {
265      assertArgNotNull("values", values);
266      var current = get();
267      for (var value : values)
268         if (eq(current, value))
269            return true;
270      return false;
271   }
272}