Clover coverage report - PLT Utilities Test Coverage (plt-20120304-r5436)
Coverage timestamp: Sat Mar 3 2012 22:01:56 CST
file stats: LOC: 225   Methods: 33
NCLOC: 92   Classes: 3
 
 Source file Conditionals Statements Methods TOTAL
ConsList.java 0% 63.9% 66.7% 63.4%
coverage coverage
 1    /*BEGIN_COPYRIGHT_BLOCK*
 2   
 3    PLT Utilities BSD License
 4   
 5    Copyright (c) 2007-2010 JavaPLT group at Rice University
 6    All rights reserved.
 7   
 8    Developed by: Java Programming Languages Team
 9    Rice University
 10    http://www.cs.rice.edu/~javaplt/
 11   
 12    Redistribution and use in source and binary forms, with or without modification, are permitted
 13    provided that the following conditions are met:
 14   
 15    - Redistributions of source code must retain the above copyright notice, this list of conditions
 16    and the following disclaimer.
 17    - Redistributions in binary form must reproduce the above copyright notice, this list of
 18    conditions and the following disclaimer in the documentation and/or other materials provided
 19    with the distribution.
 20    - Neither the name of the JavaPLT group, Rice University, nor the names of the library's
 21    contributors may be used to endorse or promote products derived from this software without
 22    specific prior written permission.
 23   
 24    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
 25    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 26    FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND
 27    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 28    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 29    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 30    IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 31    OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 32   
 33    *END_COPYRIGHT_BLOCK*/
 34   
 35    package edu.rice.cs.plt.collect;
 36   
 37    import java.io.Serializable;
 38    import java.util.Iterator;
 39    import java.util.NoSuchElementException;
 40    import edu.rice.cs.plt.iter.AbstractIterable;
 41    import edu.rice.cs.plt.iter.SizedIterable;
 42    import edu.rice.cs.plt.iter.EmptyIterator;
 43    import edu.rice.cs.plt.iter.ReadOnlyIterator;
 44    import edu.rice.cs.plt.lambda.Predicate;
 45    import edu.rice.cs.plt.lambda.Lambda;
 46    import edu.rice.cs.plt.object.Composite;
 47   
 48    /**
 49    * <p>A Lisp- or Scheme-style immutable list. A {@code ConsList} is either an {@link Empty}
 50    * or a {@link Nonempty}; operations may be defined on the lists by implementing {@link ConsVisitor}.
 51    * While {@link edu.rice.cs.plt.iter.ComposedIterable} provides similar facilities for creating
 52    * lists, {@code ConsList}s provide a more efficient means of <em>decomposing</em> lists --
 53    * because there is no {@code rest} operation on {@code Iterable}s in general, the only way to
 54    * produce an {@code Iterable} sublist of an {@code Iterable} is to make a copy. With a
 55    * well-designed {@code ConsList}, on the other hand, producing a sublist is trivial.</p>
 56    *
 57    * <p>This class also defines a few static convenience methods to simplify
 58    * client code. A static import ({@code import static edu.rice.cs.plt.collect.ConsList.*})
 59    * will eliminate the need for explicit name qualifiers when using these methods.</p>
 60    */
 61    public abstract class ConsList<T> extends AbstractIterable<T> implements SizedIterable<T>, Composite, Serializable {
 62   
 63    public abstract <Ret> Ret apply(ConsVisitor<? super T, ? extends Ret> visitor);
 64   
 65    public abstract Iterator<T> iterator();
 66   
 67    /** Whether this is an empty ConsList. */
 68    public abstract boolean isEmpty();
 69   
 70    /** Compute the size of the list. Note that this is a linear &mdash; not constant-time &mdash; operation. */
 71    public abstract int size();
 72   
 73    /**
 74    * Compute the size of the list, up to a given bound. Note that this is a linear &mdash; not
 75    * constant-time &mdash; operation.
 76    */
 77    public abstract int size(int bound);
 78   
 79    /** Return {@code false}: cons lists are not infinite. */
 80  0 public boolean isInfinite() { return false; }
 81   
 82    /** Return {@code true}: cons lists have a fixed size. */
 83  0 public boolean hasFixedSize() { return true; }
 84   
 85    /** Return {@code true}: cons lists are immutable. */
 86  0 public boolean isStatic() { return true; }
 87   
 88  0 public int compositeHeight() { return size(); }
 89  0 public int compositeSize() { return size() + 1; /* add 1 for empty */ }
 90   
 91    /** Create an empty list (via {@link Empty#make}) */
 92  38 public static <T> Empty<T> empty() { return Empty.<T>make(); }
 93   
 94    /** Create a nonempty list (via {@link ConsList#ConsList()}) */
 95  146 public static <T> Nonempty<T> cons(T first, ConsList<? extends T> rest) {
 96  146 return new Nonempty<T>(first, rest);
 97    }
 98   
 99    /** Create a singleton nonempty list (via {@link ConsList#ConsList()}) */
 100  26 public static <T> Nonempty<T> singleton(T value) {
 101  26 return new Nonempty<T>(value, Empty.<T>make());
 102    }
 103   
 104    /** Attempt to access the first of the given list (throws an exception in the empty case). */
 105  0 public static <T> T first(ConsList<? extends T> list) { return list.apply(ConsVisitor.<T>first()); }
 106   
 107    /** Attempt to access the rest of the given list (throws an exception in the empty case). */
 108  0 public static <T> ConsList<? extends T> rest(ConsList<? extends T> list) { return list.apply(ConsVisitor.<T>rest()); }
 109   
 110    /** Reverse the given list */
 111  4 public static <T> ConsList<? extends T> reverse(ConsList<? extends T> list) {
 112  4 return list.apply(ConsVisitor.<T>reverse());
 113    }
 114   
 115    /** Append {@code l2} to the end of {@code l1} */
 116  10 public static <T> ConsList<? extends T> append(ConsList<? extends T> l1, ConsList<? extends T> l2) {
 117  10 return l1.apply(ConsVisitor.append(l2));
 118    }
 119   
 120    /** Filter the given list according to a predicate */
 121  8 public static <T> ConsList<? extends T> filter(ConsList<? extends T> list, Predicate<? super T> pred) {
 122  8 return list.apply(ConsVisitor.<T>filter(pred));
 123    }
 124   
 125    /** Map the given list according to a lambda */
 126  5 public static <S, T> ConsList<? extends T> map(ConsList<? extends S> list,
 127    Lambda<? super S, ? extends T> lambda) {
 128  5 return list.apply(ConsVisitor.map(lambda));
 129    }
 130   
 131   
 132    /**
 133    * The empty variant of a {@code ConsList}. Instances are made available via {@link #make}.
 134    */
 135    public static class Empty<T> extends ConsList<T> {
 136   
 137    /** Force use of {@link #make} */
 138  1 private Empty() {}
 139   
 140    private static final Empty<Void> INSTANCE = new Empty<Void>();
 141   
 142    /**
 143    * Creates an empty list. The result is a singleton, cast (unsafe formally, but safe in
 144    * practice) to the appropriate type
 145    */
 146  64 @SuppressWarnings("unchecked")
 147  64 public static <T> Empty<T> make() { return (Empty<T>) INSTANCE; }
 148   
 149    /** Invoke the {@code forEmpty} case of a visitor */
 150  41 public <Ret> Ret apply(ConsVisitor<? super T, ? extends Ret> visitor) {
 151  41 return visitor.forEmpty();
 152    }
 153   
 154    /** Return an empty iterator */
 155  2 public Iterator<T> iterator() { return EmptyIterator.make(); }
 156   
 157    /** Return {@code true}. */
 158  32 public boolean isEmpty() { return true; }
 159   
 160    /** Return {@code 0} */
 161  56 public int size() { return 0; }
 162   
 163    /** Return {@code 0} */
 164  0 public int size(int bound) { return 0; }
 165   
 166    }
 167   
 168   
 169    /**
 170    * The nonempty variant of a {@code ConsList}. Contains a <em>first</em> value of the element
 171    * type and a <em>rest</em> which is another list.
 172    */
 173    public static class Nonempty<T> extends ConsList<T> {
 174   
 175    private final T _first;
 176    private final ConsList<? extends T> _rest;
 177   
 178  172 public Nonempty(T first, ConsList<? extends T> rest) {
 179  172 _first = first;
 180  172 _rest = rest;
 181    }
 182   
 183  0 public T first() { return _first; }
 184   
 185  0 public ConsList<? extends T> rest() { return _rest; }
 186   
 187    /** Invoke the {@code forNonempty} case of a visitor */
 188  176 public <Ret> Ret apply(ConsVisitor<? super T, ? extends Ret> visitor) {
 189  176 return visitor.forNonempty(_first, _rest);
 190    }
 191   
 192    /** Create an iterator to traverse the list */
 193  54 public Iterator<T> iterator() {
 194  54 return new ReadOnlyIterator<T>() {
 195    private ConsList<? extends T> _current = Nonempty.this;
 196   
 197  98 public boolean hasNext() { return !_current.isEmpty(); }
 198   
 199  130 public T next() {
 200  130 return _current.apply(new ConsVisitor<T, T>() {
 201  6 public T forEmpty() { throw new NoSuchElementException(); }
 202  124 public T forNonempty(T first, ConsList<? extends T> rest) {
 203  124 _current = rest;
 204  124 return first;
 205    }
 206    });
 207    }
 208    };
 209    }
 210   
 211    /** Return {@code false}. */
 212  74 public boolean isEmpty() { return false; }
 213   
 214    /** Return {@code 1 + rest.size()}. */
 215  124 public int size() { return 1 + _rest.size(); }
 216   
 217    /** Return {@code 1 + rest.size(bound - 1)}, or {@code 0} if {@code bound == 0}. */
 218  0 public int size(int bound) {
 219  0 if (bound == 0) { return 0; }
 220  0 else { return 1 + _rest.size(bound - 1); }
 221    }
 222   
 223    }
 224   
 225    }