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 }