<commit_before>package etomica.atom.iterator;

import etomica.action.AtomAction;
import etomica.action.AtomsetAction;
import etomica.action.AtomsetCount;
import etomica.atom.AtomFilter;
import etomica.atom.AtomSet;
import etomica.atom.AtomSetSinglet;
import etomica.atom.IAtom;
import etomica.atom.iterator.IteratorDirective.Direction;
import etomica.box.Box;

/**
 * Wraps an AtomIterator and filters its iterates so that only those meeting
 * specified criteria are returned. Constructor is private, and new instance is
 * created using the static makeIterator method, which attempts to return an
 * iterator that implements interface of wrapped iterator.
 */
public class AtomIteratorFiltered implements AtomIterator, java.io.Serializable {

    /**
     * Returns the iterates of the given iterator that meet the critertia of the
     * given filter. Filter is final and cannot be changed after construction.
     * 
     * @param iterator
     *            the wrapped iterator
     * @param filter
     *            iterator returns only those atoms for which this filter's
     *            accept method returns true
     */
    //private so that only way to construct is via makeIterator method
    protected AtomIteratorFiltered(AtomIterator iterator, AtomFilter filter) {
        this.iterator = iterator;
        this.filter = filter;
        actionWrapper = new ActionWrapper(filter);
        atomsetActionWrapper = new AtomsetActionWrapper(filter);
        atomSetSinglet = new AtomSetSinglet();
    }

    /**
     * Wraps given iterator with a filtering iterator that attempts to implement
     * the same interfaces as the given iterator. Given iterator can implement
     * any combination of:
     * <ul>
     * <li>AtomIteratorAtomDependent
     * <li>AtomIteratorBoxDependent
     * <li>AtomsetIteratorDirectable
     * <li>AtomsetIteratorTargetable
     * <li>AtomsetIteratorBasisDependent (which extends AtomsetIteratorTargetable)
     * </ul>
     * and the returned iterator will implement the same combination of
     * interfaces. Iterator may instead implement AtomIteratorListDependent, but
     * not in combination with any of the others (if it does, an exception is
     * thrown). If given iterator implements none of these interfaces, then
     * returned iterator is simply an instance of AtomIteratorFiltered.
     * 
     * @param iterator
     *            wrapped iterator
     * @param filter
     *            AtomFilter such that only atoms for which its accept method
     *            returns true will be given by the iterator. Filter is final
     *            and cannot be changed after construction.
     * @return filtering iterator that implements the interfaces of the wrapped
     *         iterator.
     * @throws IllegalArgumentException
     *             if the given iterator implements AtomIteratorListDependent
     *             and any of the interfaces: AtomIteratorAtomDependent,
     *             AtomIteratorBoxDependent, AtomIteratorDirectable, and/or
     *             AtomIteratorTargetable
     */
    public static AtomIteratorFiltered makeIterator(AtomIterator iterator,
            AtomFilter filter) {
        int key = 0;
        if (iterator instanceof AtomIteratorAtomDependent)
            key += (1 << 0);//1
        if (iterator instanceof AtomIteratorBoxDependent)
            key += (1 << 1);//2
        if (iterator instanceof AtomsetIteratorDirectable)
            key += (1 << 2);//4
        if (iterator instanceof AtomsetIteratorTargetable)
            key += (1 << 3);//8
        boolean basis = iterator instanceof AtomsetIteratorBasisDependent;

        switch (key) {
        case 0:
            return new AtomIteratorFiltered(iterator, filter);
        case 1:
            return new AIFAtom(iterator, filter);
        case 2:
            return new AIFBox(iterator, filter);
        case 3:
            return new AIFAtomBox(iterator, filter);
        case 4:
            return new AIFDirectable(iterator, filter);
        case 5:
            return new AIFAtomDirectable(iterator, filter);
        case 6:
            return new AIFBoxDirectable(iterator, filter);
        case 7:
            return new AIFAtomBoxDirectable(iterator, filter);
        case 8:
            return basis ? new AIFBasis(iterator, filter) : new AIFTarget(iterator, filter);
        case 9:
            return basis ? new AIFAtomBasis(iterator, filter)
                    : new AIFAtomTarget(iterator, filter);
        case 10:
            return basis ? new AIFBoxBasis(iterator, filter)
                    : new AIFBoxTarget(iterator, filter);
        case 11:
            return basis ? new AIFAtomBoxBasis(iterator, filter)
                    : new AIFAtomBoxTarget(iterator, filter);
        case 12:
            return basis ? new AIFBasisDirectable(iterator, filter)
                    : new AIFTargetDirectable(iterator, filter);
        case 13:
            return basis ? new AIFAtomBasisDirectable(iterator, filter)
                    : new AIFAtomTargetDirectable(iterator, filter);
        case 14:
            return basis ? new AIFBoxBasisDirectable(iterator, filter)
                    : new AIFBoxTargetDirectable(iterator, filter);
        case 15:
            return basis ? new AIFAtomBoxBasisDirectable(iterator, filter)
                    : new AIFAtomBoxTargetDirectable(iterator, filter);
        default:
            throw new IllegalArgumentException(
                    " not ready for that kind of iterator");
        }
    }

    /**
     * Puts iterator in state ready for iteration.
     */
    public void reset() {
        iterator.reset();
    }

    /**
     * Sets iterator so that hasNext returns false.
     */
    public void unset() {
        iterator.unset();
    }

    /**
     * Returns the next atom from the iterator that meets the filter's criteria.
     */
    public IAtom nextAtom() {
        IAtom nextAtom = iterator.nextAtom();
        while (nextAtom != null && !filter.accept(nextAtom)) {
            nextAtom = iterator.nextAtom();
        }
        return nextAtom;
    }

    /**
     * Same as nextAtom.
     */
    public AtomSet next() {
        atomSetSinglet.atom = nextAtom();
        if (atomSetSinglet.atom == null) return null;
        return atomSetSinglet;
    }

    /**
     * Performs the given action on all atoms from iterator that meet the filter
     * criteria.
     */
    public void allAtoms(AtomsetAction action) {
        atomsetActionWrapper.action = action;
        iterator.allAtoms(actionWrapper);
    }

    /**
     * Performs the given action on all atoms from iterator that meet the filter
     * criteria.<commit_msg>Bug 160: Bustage fix from Atom*Action changes<commit_after>package etomica.atom.iterator;

import etomica.action.AtomAction;
import etomica.action.AtomsetAction;
import etomica.action.AtomsetCount;
import etomica.atom.AtomFilter;
import etomica.atom.AtomSet;
import etomica.atom.AtomSetSinglet;
import etomica.atom.IAtom;
import etomica.atom.iterator.IteratorDirective.Direction;
import etomica.box.Box;

/**
 * Wraps an AtomIterator and filters its iterates so that only those meeting
 * specified criteria are returned. Constructor is private, and new instance is
 * created using the static makeIterator method, which attempts to return an
 * iterator that implements interface of wrapped iterator.
 */
public class AtomIteratorFiltered implements AtomIterator, java.io.Serializable {

    /**
     * Returns the iterates of the given iterator that meet the critertia of the
     * given filter. Filter is final and cannot be changed after construction.
     * 
     * @param iterator
     *            the wrapped iterator
     * @param filter
     *            iterator returns only those atoms for which this filter's
     *            accept method returns true
     */
    //private so that only way to construct is via makeIterator method
    protected AtomIteratorFiltered(AtomIterator iterator, AtomFilter filter) {
        this.iterator = iterator;
        this.filter = filter;
        actionWrapper = new ActionWrapper(filter);
        atomsetActionWrapper = new AtomsetActionWrapper(filter);
        atomSetSinglet = new AtomSetSinglet();
    }

    /**
     * Wraps given iterator with a filtering iterator that attempts to implement
     * the same interfaces as the given iterator. Given iterator can implement
     * any combination of:
     * <ul>
     * <li>AtomIteratorAtomDependent
     * <li>AtomIteratorBoxDependent
     * <li>AtomsetIteratorDirectable
     * <li>AtomsetIteratorTargetable
     * <li>AtomsetIteratorBasisDependent (which extends AtomsetIteratorTargetable)
     * </ul>
     * and the returned iterator will implement the same combination of
     * interfaces. Iterator may instead implement AtomIteratorListDependent, but
     * not in combination with any of the others (if it does, an exception is
     * thrown). If given iterator implements none of these interfaces, then
     * returned iterator is simply an instance of AtomIteratorFiltered.
     * 
     * @param iterator
     *            wrapped iterator
     * @param filter
     *            AtomFilter such that only atoms for which its accept method
     *            returns true will be given by the iterator. Filter is final
     *            and cannot be changed after construction.
     * @return filtering iterator that implements the interfaces of the wrapped
     *         iterator.
     * @throws IllegalArgumentException
     *             if the given iterator implements AtomIteratorListDependent
     *             and any of the interfaces: AtomIteratorAtomDependent,
     *             AtomIteratorBoxDependent, AtomIteratorDirectable, and/or
     *             AtomIteratorTargetable
     */
    public static AtomIteratorFiltered makeIterator(AtomIterator iterator,
            AtomFilter filter) {
        int key = 0;
        if (iterator instanceof AtomIteratorAtomDependent)
            key += (1 << 0);//1
        if (iterator instanceof AtomIteratorBoxDependent)
            key += (1 << 1);//2
        if (iterator instanceof AtomsetIteratorDirectable)
            key += (1 << 2);//4
        if (iterator instanceof AtomsetIteratorTargetable)
            key += (1 << 3);//8
        boolean basis = iterator instanceof AtomsetIteratorBasisDependent;

        switch (key) {
        case 0:
            return new AtomIteratorFiltered(iterator, filter);
        case 1:
            return new AIFAtom(iterator, filter);
        case 2:
            return new AIFBox(iterator, filter);
        case 3:
            return new AIFAtomBox(iterator, filter);
        case 4:
            return new AIFDirectable(iterator, filter);
        case 5:
            return new AIFAtomDirectable(iterator, filter);
        case 6:
            return new AIFBoxDirectable(iterator, filter);
        case 7:
            return new AIFAtomBoxDirectable(iterator, filter);
        case 8:
            return basis ? new AIFBasis(iterator, filter) : new AIFTarget(iterator, filter);
        case 9:
            return basis ? new AIFAtomBasis(iterator, filter)
                    : new AIFAtomTarget(iterator, filter);
        case 10:
            return basis ? new AIFBoxBasis(iterator, filter)
                    : new AIFBoxTarget(iterator, filter);
        case 11:
            return basis ? new AIFAtomBoxBasis(iterator, filter)
                    : new AIFAtomBoxTarget(iterator, filter);
        case 12:
            return basis ? new AIFBasisDirectable(iterator, filter)
                    : new AIFTargetDirectable(iterator, filter);
        case 13:
            return basis ? new AIFAtomBasisDirectable(iterator, filter)
                    : new AIFAtomTargetDirectable(iterator, filter);
        case 14:
            return basis ? new AIFBoxBasisDirectable(iterator, filter)
                    : new AIFBoxTargetDirectable(iterator, filter);
        case 15:
            return basis ? new AIFAtomBoxBasisDirectable(iterator, filter)
                    : new AIFAtomBoxTargetDirectable(iterator, filter);
        default:
            throw new IllegalArgumentException(
                    " not ready for that kind of iterator");
        }
    }

    /**
     * Puts iterator in state ready for iteration.
     */
    public void reset() {
        iterator.reset();
    }

    /**
     * Sets iterator so that hasNext returns false.
     */
    public void unset() {
        iterator.unset();
    }

    /**
     * Returns the next atom from the iterator that meets the filter's criteria.
     */
    public IAtom nextAtom() {
        IAtom nextAtom = iterator.nextAtom();
        while (nextAtom != null && !filter.accept(nextAtom)) {
            nextAtom = iterator.nextAtom();
        }
        return nextAtom;
    }

    /**
     * Same as nextAtom.
     */
    public AtomSet next() {
        atomSetSinglet.atom = nextAtom();
        if (atomSetSinglet.atom == null) return null;
        return atomSetSinglet;
    }

    /**
     * Performs the given action on all atoms from iterator that meet the filter
     * criteria.
     */
    public void allAtoms(AtomsetAction action) {
        atomsetActionWrapper.action = action;
        iterator.allAtoms(atomsetActionWrapper);
    }

    /**
     * Performs the given action on all atoms from iterator that meet the filter
     * criteria.
{'fraction_non_alphanumeric': 0.06927374301675977, 'fraction_numerical': 0.0054376163873370575, 'mean_word_length': 2.2866585067319463, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3426358', 'n_tokens_mistral': 3514, 'n_tokens_neox': 3427, 'n_words': 1145}