001/*
002 * Copyright (C) 2012 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.google.common.collect;
018
019import static com.google.common.collect.Iterators.getNext;
020import static com.google.common.collect.Iterators.pollNext;
021
022import com.google.common.annotations.GwtIncompatible;
023import java.util.Iterator;
024import java.util.NavigableSet;
025import java.util.SortedSet;
026import org.jspecify.annotations.Nullable;
027
028/**
029 * A navigable set which forwards all its method calls to another navigable set. Subclasses should
030 * override one or more methods to modify the behavior of the backing set as desired per the <a
031 * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
032 *
033 * <p><b>Warning:</b> The methods of {@code ForwardingNavigableSet} forward <i>indiscriminately</i>
034 * to the methods of the delegate. For example, overriding {@link #add} alone <i>will not</i> change
035 * the behavior of {@link #addAll}, which can lead to unexpected behavior. In this case, you should
036 * override {@code addAll} as well, either providing your own implementation, or delegating to the
037 * provided {@code standardAddAll} method.
038 *
039 * <p><b>{@code default} method warning:</b> This class does <i>not</i> forward calls to {@code
040 * default} methods. Instead, it inherits their default implementations. When those implementations
041 * invoke methods, they invoke methods on the {@code ForwardingNavigableSet}.
042 *
043 * <p>Each of the {@code standard} methods uses the set's comparator (or the natural ordering of the
044 * elements, if there is no comparator) to test element equality. As a result, if the comparator is
045 * not consistent with equals, some of the standard implementations may violate the {@code Set}
046 * contract.
047 *
048 * <p>The {@code standard} methods and the collection views they return are not guaranteed to be
049 * thread-safe, even when all of the methods that they depend on are thread-safe.
050 *
051 * @author Louis Wasserman
052 * @since 12.0
053 */
054@GwtIncompatible
055public abstract class ForwardingNavigableSet<E extends @Nullable Object>
056    extends ForwardingSortedSet<E> implements NavigableSet<E> {
057
058  /** Constructor for use by subclasses. */
059  protected ForwardingNavigableSet() {}
060
061  @Override
062  protected abstract NavigableSet<E> delegate();
063
064  @Override
065  public @Nullable E lower(@ParametricNullness E e) {
066    return delegate().lower(e);
067  }
068
069  /**
070   * A sensible definition of {@link #lower} in terms of the {@code descendingIterator} method of
071   * {@link #headSet(Object, boolean)}. If you override {@link #headSet(Object, boolean)}, you may
072   * wish to override {@link #lower} to forward to this implementation.
073   */
074  protected @Nullable E standardLower(@ParametricNullness E e) {
075    return getNext(headSet(e, false).descendingIterator(), null);
076  }
077
078  @Override
079  public @Nullable E floor(@ParametricNullness E e) {
080    return delegate().floor(e);
081  }
082
083  /**
084   * A sensible definition of {@link #floor} in terms of the {@code descendingIterator} method of
085   * {@link #headSet(Object, boolean)}. If you override {@link #headSet(Object, boolean)}, you may
086   * wish to override {@link #floor} to forward to this implementation.
087   */
088  protected @Nullable E standardFloor(@ParametricNullness E e) {
089    return getNext(headSet(e, true).descendingIterator(), null);
090  }
091
092  @Override
093  public @Nullable E ceiling(@ParametricNullness E e) {
094    return delegate().ceiling(e);
095  }
096
097  /**
098   * A sensible definition of {@link #ceiling} in terms of the {@code iterator} method of {@link
099   * #tailSet(Object, boolean)}. If you override {@link #tailSet(Object, boolean)}, you may wish to
100   * override {@link #ceiling} to forward to this implementation.
101   */
102  protected @Nullable E standardCeiling(@ParametricNullness E e) {
103    return getNext(tailSet(e, true).iterator(), null);
104  }
105
106  @Override
107  public @Nullable E higher(@ParametricNullness E e) {
108    return delegate().higher(e);
109  }
110
111  /**
112   * A sensible definition of {@link #higher} in terms of the {@code iterator} method of {@link
113   * #tailSet(Object, boolean)}. If you override {@link #tailSet(Object, boolean)}, you may wish to
114   * override {@link #higher} to forward to this implementation.
115   */
116  protected @Nullable E standardHigher(@ParametricNullness E e) {
117    return getNext(tailSet(e, false).iterator(), null);
118  }
119
120  @Override
121  public @Nullable E pollFirst() {
122    return delegate().pollFirst();
123  }
124
125  /**
126   * A sensible definition of {@link #pollFirst} in terms of the {@code iterator} method. If you
127   * override {@link #iterator} you may wish to override {@link #pollFirst} to forward to this
128   * implementation.
129   */
130  protected @Nullable E standardPollFirst() {
131    return pollNext(iterator());
132  }
133
134  @Override
135  public @Nullable E pollLast() {
136    return delegate().pollLast();
137  }
138
139  /**
140   * A sensible definition of {@link #pollLast} in terms of the {@code descendingIterator} method.
141   * If you override {@link #descendingIterator} you may wish to override {@link #pollLast} to
142   * forward to this implementation.
143   */
144  protected @Nullable E standardPollLast() {
145    return pollNext(descendingIterator());
146  }
147
148  @ParametricNullness
149  protected E standardFirst() {
150    return iterator().next();
151  }
152
153  @ParametricNullness
154  protected E standardLast() {
155    return descendingIterator().next();
156  }
157
158  @Override
159  public NavigableSet<E> descendingSet() {
160    return delegate().descendingSet();
161  }
162
163  /**
164   * A sensible implementation of {@link NavigableSet#descendingSet} in terms of the other methods
165   * of {@link NavigableSet}, notably including {@link NavigableSet#descendingIterator}.
166   *
167   * <p>In many cases, you may wish to override {@link ForwardingNavigableSet#descendingSet} to
168   * forward to this implementation or a subclass thereof.
169   *
170   * @since 12.0
171   */
172  protected class StandardDescendingSet extends Sets.DescendingSet<E> {
173    /** Constructor for use by subclasses. */
174    public StandardDescendingSet() {
175      super(ForwardingNavigableSet.this);
176    }
177  }
178
179  @Override
180  public Iterator<E> descendingIterator() {
181    return delegate().descendingIterator();
182  }
183
184  @Override
185  public NavigableSet<E> subSet(
186      @ParametricNullness E fromElement,
187      boolean fromInclusive,
188      @ParametricNullness E toElement,
189      boolean toInclusive) {
190    return delegate().subSet(fromElement, fromInclusive, toElement, toInclusive);
191  }
192
193  /**
194   * A sensible definition of {@link #subSet(Object, boolean, Object, boolean)} in terms of the
195   * {@code headSet} and {@code tailSet} methods. In many cases, you may wish to override {@link
196   * #subSet(Object, boolean, Object, boolean)} to forward to this implementation.
197   */
198  protected NavigableSet<E> standardSubSet(
199      @ParametricNullness E fromElement,
200      boolean fromInclusive,
201      @ParametricNullness E toElement,
202      boolean toInclusive) {
203    return tailSet(fromElement, fromInclusive).headSet(toElement, toInclusive);
204  }
205
206  /**
207   * A sensible definition of {@link #subSet(Object, Object)} in terms of the {@link #subSet(Object,
208   * boolean, Object, boolean)} method. If you override {@link #subSet(Object, boolean, Object,
209   * boolean)}, you may wish to override {@link #subSet(Object, Object)} to forward to this
210   * implementation.
211   */
212  @Override
213  protected SortedSet<E> standardSubSet(
214      @ParametricNullness E fromElement, @ParametricNullness E toElement) {
215    return subSet(fromElement, true, toElement, false);
216  }
217
218  @Override
219  public NavigableSet<E> headSet(@ParametricNullness E toElement, boolean inclusive) {
220    return delegate().headSet(toElement, inclusive);
221  }
222
223  /**
224   * A sensible definition of {@link #headSet(Object)} in terms of the {@link #headSet(Object,
225   * boolean)} method. If you override {@link #headSet(Object, boolean)}, you may wish to override
226   * {@link #headSet(Object)} to forward to this implementation.
227   */
228  protected SortedSet<E> standardHeadSet(@ParametricNullness E toElement) {
229    return headSet(toElement, false);
230  }
231
232  @Override
233  public NavigableSet<E> tailSet(@ParametricNullness E fromElement, boolean inclusive) {
234    return delegate().tailSet(fromElement, inclusive);
235  }
236
237  /**
238   * A sensible definition of {@link #tailSet(Object)} in terms of the {@link #tailSet(Object,
239   * boolean)} method. If you override {@link #tailSet(Object, boolean)}, you may wish to override
240   * {@link #tailSet(Object)} to forward to this implementation.
241   */
242  protected SortedSet<E> standardTailSet(@ParametricNullness E fromElement) {
243    return tailSet(fromElement, true);
244  }
245}