1 /*
2  * Hunt - A refined core library for D programming language.
3  *
4  * Copyright (C) 2018-2019 HuntLabs
5  *
6  * Website: https://www.huntlabs.net/
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module hunt.collection.AbstractQueue;
13 
14 import hunt.collection.AbstractCollection;
15 import hunt.collection.Collection;
16 import hunt.collection.Queue;
17 import hunt.Exceptions;
18 import hunt.Object;
19 
20 
21 /**
22  * This class provides skeletal implementations of some {@link Queue}
23  * operations. The implementations in this class are appropriate when
24  * the base implementation does <em>not</em> allow {@code null}
25  * elements.  Methods {@link #add add}, {@link #remove remove}, and
26  * {@link #element element} are based on {@link #offer offer}, {@link
27  * #poll poll}, and {@link #peek peek}, respectively, but throw
28  * exceptions instead of indicating failure via {@code false} or
29  * {@code null} returns.
30  *
31  * <p>A {@code Queue} implementation that extends this class must
32  * minimally define a method {@link Queue#offer} which does not permit
33  * insertion of {@code null} elements, along with methods {@link
34  * Queue#peek}, {@link Queue#poll}, {@link Collection#size}, and
35  * {@link Collection#iterator}.  Typically, additional methods will be
36  * overridden as well.  If these requirements cannot be met, consider
37  * instead subclassing {@link AbstractCollection}.
38  *
39  * <p>This class is a member of the
40  * <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework">
41  * Java Collections Framework</a>.
42  *
43  * @since 1.5
44  * @author Doug Lea
45  * @param !(E) the type of elements held in this queue
46  */
47 abstract class AbstractQueue(E) : AbstractCollection!(E), Queue!(E) {
48 
49     /**
50      * Constructor for use by subclasses.
51      */
52     protected this() {
53     }
54 
55     /**
56      * Inserts the specified element into this queue if it is possible to do so
57      * immediately without violating capacity restrictions, returning
58      * {@code true} upon success and throwing an {@code IllegalStateException}
59      * if no space is currently available.
60      *
61      * <p>This implementation returns {@code true} if {@code offer} succeeds,
62      * else throws an {@code IllegalStateException}.
63      *
64      * @param e the element to add
65      * @return {@code true} (as specified by {@link Collection#add})
66      * @throws IllegalStateException if the element cannot be added at this
67      *         time due to capacity restrictions
68      * @throws ClassCastException if the class of the specified element
69      *         prevents it from being added to this queue
70      * @throws NullPointerException if the specified element is null and
71      *         this queue does not permit null elements
72      * @throws IllegalArgumentException if some property of this element
73      *         prevents it from being added to this queue
74      */
75     override bool add(E e) {
76         if (offer(e))
77             return true;
78         else
79             throw new IllegalStateException("Queue full");
80     }
81 
82     /**
83      * Retrieves and removes the head of this queue.  This method differs
84      * from {@link #poll poll} only in that it throws an exception if this
85      * queue is empty.
86      *
87      * <p>This implementation returns the result of {@code poll}
88      * unless the queue is empty.
89      *
90      * @return the head of this queue
91      * @throws NoSuchElementException if this queue is empty
92      */
93     E remove() {
94         E x = poll();
95         static if(is(E == class) || is(E == string)) {
96             if (x is null) throw new NoSuchElementException();
97         }
98         return x;
99     }
100 
101     /**
102      * Retrieves, but does not remove, the head of this queue.  This method
103      * differs from {@link #peek peek} only in that it throws an exception if
104      * this queue is empty.
105      *
106      * <p>This implementation returns the result of {@code peek}
107      * unless the queue is empty.
108      *
109      * @return the head of this queue
110      * @throws NoSuchElementException if this queue is empty
111      */
112     E element() {
113         E x = peek();
114         
115         static if(is(E == class) || is(E == string)) {
116             if (x is null) throw new NoSuchElementException();
117         }
118         return x;
119     }
120 
121     /**
122      * Removes all of the elements from this queue.
123      * The queue will be empty after this call returns.
124      *
125      * <p>This implementation repeatedly invokes {@link #poll poll} until it
126      * returns {@code null}.
127      */
128     override void clear() {
129         static if(is(E == class) || is(E == string)) {
130             while (poll() !is null) {}
131         } else {
132             while(size()>0) {
133                 poll();
134             }
135         }
136     }
137 
138     /**
139      * Adds all of the elements in the specified collection to this
140      * queue.  Attempts to addAll of a queue to itself result in
141      * {@code IllegalArgumentException}. Further, the behavior of
142      * this operation is undefined if the specified collection is
143      * modified while the operation is in progress.
144      *
145      * <p>This implementation iterates over the specified collection,
146      * and adds each element returned by the iterator to this
147      * queue, in turn.  A runtime exception encountered while
148      * trying to add an element (including, in particular, a
149      * {@code null} element) may result in only some of the elements
150      * having been successfully added when the associated exception is
151      * thrown.
152      *
153      * @param c collection containing elements to be added to this queue
154      * @return {@code true} if this queue changed as a result of the call
155      * @throws ClassCastException if the class of an element of the specified
156      *         collection prevents it from being added to this queue
157      * @throws NullPointerException if the specified collection contains a
158      *         null element and this queue does not permit null elements,
159      *         or if the specified collection is null
160      * @throws IllegalArgumentException if some property of an element of the
161      *         specified collection prevents it from being added to this
162      *         queue, or if the specified collection is this queue
163      * @throws IllegalStateException if not all the elements can be added at
164      *         this time due to insertion restrictions
165      * @see #add(Object)
166      */
167     override bool addAll(Collection!E c) {
168         if (c is null)
169             throw new NullPointerException();
170         if (c is this)
171             throw new IllegalArgumentException();
172         bool modified = false;
173         foreach (E e ; c) {
174             if (add(e)) modified = true;
175         }
176         return modified;
177     }
178 
179     override bool opEquals(IObject o) {
180         return opEquals(cast(Object) o);
181     }
182     
183     override bool opEquals(Object o) {
184         return super.opEquals(o);
185     }
186 
187     override size_t toHash() @trusted nothrow {
188         return super.toHash();
189     }
190 
191     override string toString() {
192         return super.toString();
193     }
194 }