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 }