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  * @author Doug Lea
44  * @param (E) the type of elements held in this queue
45  */
46 abstract class AbstractQueue(E) : AbstractCollection!(E), Queue!(E) {
47 
48     /**
49      * Constructor for use by subclasses.
50      */
51     protected this() {
52     }
53 
54     /**
55      * Inserts the specified element into this queue if it is possible to do so
56      * immediately without violating capacity restrictions, returning
57      * {@code true} upon success and throwing an {@code IllegalStateException}
58      * if no space is currently available.
59      *
60      * <p>This implementation returns {@code true} if {@code offer} succeeds,
61      * else throws an {@code IllegalStateException}.
62      *
63      * @param e the element to add
64      * @return {@code true} (as specified by {@link Collection#add})
65      * @throws IllegalStateException if the element cannot be added at this
66      *         time due to capacity restrictions
67      * @throws ClassCastException if the class of the specified element
68      *         prevents it from being added to this queue
69      * @throws NullPointerException if the specified element is null and
70      *         this queue does not permit null elements
71      * @throws IllegalArgumentException if some property of this element
72      *         prevents it from being added to this queue
73      */
74     override bool add(E e) {
75         if (offer(e))
76             return true;
77         else
78             throw new IllegalStateException("Queue full");
79     }
80 
81     /**
82      * Retrieves and removes the head of this queue.  This method differs
83      * from {@link #poll poll} only in that it throws an exception if this
84      * queue is empty.
85      *
86      * <p>This implementation returns the result of {@code poll}
87      * unless the queue is empty.
88      *
89      * @return the head of this queue
90      * @throws NoSuchElementException if this queue is empty
91      */
92     E remove() {
93         E x = poll();
94         static if(is(E == class) || is(E == string)) {
95             if (x is null) throw new NoSuchElementException();
96         }
97         return x;
98     }
99 
100     /**
101      * Retrieves, but does not remove, the head of this queue.  This method
102      * differs from {@link #peek peek} only in that it throws an exception if
103      * this queue is empty.
104      *
105      * <p>This implementation returns the result of {@code peek}
106      * unless the queue is empty.
107      *
108      * @return the head of this queue
109      * @throws NoSuchElementException if this queue is empty
110      */
111     E element() {
112         E x = peek();
113         
114         static if(is(E == class) || is(E == string)) {
115             if (x is null) throw new NoSuchElementException();
116         }
117         return x;
118     }
119 
120     /**
121      * Removes all of the elements from this queue.
122      * The queue will be empty after this call returns.
123      *
124      * <p>This implementation repeatedly invokes {@link #poll poll} until it
125      * returns {@code null}.
126      */
127     override void clear() {
128         static if(is(E == class) || is(E == string)) {
129             while (poll() !is null) {}
130         } else {
131             while(size()>0) {
132                 poll();
133             }
134         }
135     }
136 
137     /**
138      * Adds all of the elements in the specified collection to this
139      * queue.  Attempts to addAll of a queue to itself result in
140      * {@code IllegalArgumentException}. Further, the behavior of
141      * this operation is undefined if the specified collection is
142      * modified while the operation is in progress.
143      *
144      * <p>This implementation iterates over the specified collection,
145      * and adds each element returned by the iterator to this
146      * queue, in turn.  A runtime exception encountered while
147      * trying to add an element (including, in particular, a
148      * {@code null} element) may result in only some of the elements
149      * having been successfully added when the associated exception is
150      * thrown.
151      *
152      * @param c collection containing elements to be added to this queue
153      * @return {@code true} if this queue changed as a result of the call
154      * @throws ClassCastException if the class of an element of the specified
155      *         collection prevents it from being added to this queue
156      * @throws NullPointerException if the specified collection contains a
157      *         null element and this queue does not permit null elements,
158      *         or if the specified collection is null
159      * @throws IllegalArgumentException if some property of an element of the
160      *         specified collection prevents it from being added to this
161      *         queue, or if the specified collection is this queue
162      * @throws IllegalStateException if not all the elements can be added at
163      *         this time due to insertion restrictions
164      * @see #add(Object)
165      */
166     override bool addAll(Collection!E c) {
167         if (c is null)
168             throw new NullPointerException();
169         if (c is this)
170             throw new IllegalArgumentException();
171         bool modified = false;
172         foreach (E e ; c) {
173             if (add(e)) modified = true;
174         }
175         return modified;
176     }
177 
178     override bool opEquals(IObject o) {
179         return opEquals(cast(Object) o);
180     }
181     
182     override bool opEquals(Object o) {
183         return super.opEquals(o);
184     }
185 
186     override size_t toHash() @trusted nothrow {
187         return super.toHash();
188     }
189 
190     override string toString() {
191         return super.toString();
192     }
193 }