<commit_before>package org.observe.collect;

import static org.observe.ObservableDebug.d;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;

import org.observe.DefaultObservable;
import org.observe.Observable;
import org.observe.ObservableValue;
import org.observe.ObservableValueEvent;
import org.observe.Observer;
import org.observe.SimpleObservable;
import org.observe.Subscription;
import org.observe.util.ObservableUtils;
import org.qommons.IterableUtils;
import org.qommons.ReversibleCollection;
import org.qommons.Transaction;

import com.google.common.reflect.TypeToken;

/**
 * An observable ordered collection that can be reversed
 *
 * @param <E> The type of elements in the collection
 */
public interface ObservableReversibleCollection<E> extends ObservableOrderedCollection<E>, ReversibleCollection<E> {
	/**
	 * Identical to {@link #onOrderedElement(Consumer)}, except that initial elements are given to the consumer in reverse.
	 *
	 * Although a default implementation is provided, subclasses should override this method for performance where possible
	 *
	 * @param onElement The element accepter
	 * @return The unsubscribe runnable
	 */
	default Subscription onElementReverse(Consumer<? super ObservableOrderedElement<E>> onElement) {
		List<ObservableOrderedElement<E>> initElements = new ArrayList<>();
		boolean [] initialized = new boolean[1];
		Subscription ret = onOrderedElement(element -> {
			if(initialized[0])
				onElement.accept(element);
			else
				initElements.add(element);
		});
		ObservableOrderedElement<E> [] e = initElements.toArray(new ObservableOrderedElement[initElements.size()]);
		initElements.clear();
		initialized[0] = true;
		for(int i = e.length - 1; i >= 0; i--)
			onElement.accept(e[i]);
		return ret;
	}

	/** @return A collection that is identical to this one, but with its elements reversed */
	@Override
	default ObservableReversibleCollection<E> reverse() {
		return new ObservableReversedCollection<>(this);<commit_msg>Made ObservableReversibleCollection.onElementReverse abstract again and moved the default implementation to a static method that is not currently used.<commit_after>package org.observe.collect;

import static org.observe.ObservableDebug.d;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;

import org.observe.DefaultObservable;
import org.observe.Observable;
import org.observe.ObservableValue;
import org.observe.ObservableValueEvent;
import org.observe.Observer;
import org.observe.SimpleObservable;
import org.observe.Subscription;
import org.observe.util.ObservableUtils;
import org.qommons.IterableUtils;
import org.qommons.ReversibleCollection;
import org.qommons.Transaction;

import com.google.common.reflect.TypeToken;

/**
 * An observable ordered collection that can be reversed
 *
 * @param <E> The type of elements in the collection
 */
public interface ObservableReversibleCollection<E> extends ObservableOrderedCollection<E>, ReversibleCollection<E> {
	/**
	 * Identical to {@link #onOrderedElement(Consumer)}, except that initial elements are given to the consumer in reverse.
	 *
	 * Although a default implementation is provided, subclasses should override this method for performance where possible
	 *
	 * @param onElement The element accepter
	 * @return The unsubscribe runnable
	 */
	Subscription onElementReverse(Consumer<? super ObservableOrderedElement<E>> onElement);

	/**
	 * A default implementation of {@link #onElementReverse(Consumer)} that simply obtains all the elements and feeds them to the consumer
	 * in reverse. This implementation should only be used where a more performant implementation is not possible.
	 * 
	 * @param coll The collection to get the reverse elements of
	 * @param onElement The consumer for the elements
	 * @return The subscription for the elements
	 */
	static <E> Subscription defaultOnElementReverse(ObservableReversibleCollection<E> coll,
			Consumer<? super ObservableOrderedElement<E>> onElement) {
		List<ObservableOrderedElement<E>> initElements = new ArrayList<>();
		boolean [] initialized = new boolean[1];
		Subscription ret = coll.onOrderedElement(element -> {
			if(initialized[0])
				onElement.accept(element);
			else
				initElements.add(element);
		});
		ObservableOrderedElement<E> [] e = initElements.toArray(new ObservableOrderedElement[initElements.size()]);
		initElements.clear();
		initialized[0] = true;
		for(int i = e.length - 1; i >= 0; i--)
			onElement.accept(e[i]);
		return ret;
	}

	/** @return A collection that is identical to this one, but with its elements reversed */
	@Override
	default ObservableReversibleCollection<E> reverse() {
		return new ObservableReversedCollection<>(this);
{'fraction_non_alphanumeric': 0.09466303077522399, 'fraction_numerical': 0.0019477989871445266, 'mean_word_length': 5.459119496855346, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 35, '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': '5650126', 'n_tokens_mistral': 1479, 'n_tokens_neox': 1390, 'n_words': 417}