io.qt.core.AbstractIterator Maven / Gradle / Ivy
/****************************************************************************
**
** Copyright (C) 2009-2024 Dr. Peter Droste, Omix Visualization GmbH & Co. KG. All rights reserved.
**
** This file is part of Qt Jambi.
**
** $BEGIN_LICENSE$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
** $END_LICENSE$
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
package io.qt.core;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.function.Function;
import io.qt.QtObject;
import io.qt.QtUninvokable;
abstract class AbstractIterator extends QtObject{
private final static Function, java.util.Iterator>> iteratorFactory;
private final static Function, java.util.Iterator>> diteratorFactory;
static {
if(Boolean.getBoolean("io.qt.enable-concurrent-container-modification-check")) {
@SuppressWarnings("unchecked")
Function, java.util.Iterator>> _iteratorFactory = CheckingIncrementalIterator::new;
@SuppressWarnings("unchecked")
Function, java.util.Iterator>> _diteratorFactory = CheckingDecrementalIterator::new;
iteratorFactory = _iteratorFactory;
diteratorFactory = _diteratorFactory;
}else {
@SuppressWarnings("unchecked")
Function, java.util.Iterator>> _iteratorFactory = IncrementalIterator::new;
@SuppressWarnings("unchecked")
Function, java.util.Iterator>> _diteratorFactory = DecrementalIterator::new;
iteratorFactory = _iteratorFactory;
diteratorFactory = _diteratorFactory;
}
}
private final QtObject owner;
private final Function> beginSupplier;
private final Function> endSupplier;
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
AbstractIterator(QtObject owner) {
super((QPrivateConstructor)null);
this.owner = owner;
if(owner instanceof AbstractSequentialContainer) {
if(isConstant()) {
endSupplier = (Function)(Function>)AbstractSequentialContainer::constEnd;
beginSupplier = (Function)(Function>)AbstractSequentialContainer::constBegin;
}else if(owner instanceof AbstractList) {
endSupplier = (Function)(Function>)AbstractList::end;
beginSupplier = (Function)(Function>)AbstractList::begin;
}else {// there are no mutable iterators in QSet
endSupplier = null;
beginSupplier = null;
}
}else if(owner instanceof AbstractAssociativeContainer) {
if(isConstant()) {
endSupplier = (Function)(Function>)AbstractAssociativeContainer::constEnd;
beginSupplier = (Function)(Function>)AbstractAssociativeContainer::constBegin;
}else {
endSupplier = (Function)(Function>)AbstractAssociativeContainer::end;
beginSupplier = (Function)(Function>)AbstractAssociativeContainer::begin;
}
}else if(owner instanceof AbstractMultiAssociativeContainer) {
if(isConstant()) {
endSupplier = (Function)(Function>)AbstractMultiAssociativeContainer::constEnd;
beginSupplier = (Function)(Function>)AbstractMultiAssociativeContainer::constBegin;
}else {
endSupplier = (Function)(Function>)AbstractMultiAssociativeContainer::end;
beginSupplier = (Function)(Function>)AbstractMultiAssociativeContainer::begin;
}
}else {
BeginEndFunctions functions = findBeginEndSuppliers(owner);
beginSupplier = (Function)(isConstant() ? functions.constBegin : functions.begin);
endSupplier = (Function)(isConstant() ? functions.constEnd : functions.end);
}
}
/**
* Specifies if this type is constant iterator.
*/
boolean isConstant() {
return true;
}
/**
* Returns the container's end iterator.
*/
@QtUninvokable
final AbstractIterator end(){
return endSupplier==null ? null : endSupplier.apply(owner);
}
/**
* Returns the container's begin iterator.
*/
@QtUninvokable
final AbstractIterator begin(){
return beginSupplier==null ? null : beginSupplier.apply(owner);
}
@QtUninvokable
private static native boolean operator_equal(long __this__nativeId, long o);
/**
* Compares this iterator with other object.
*/
@Override
@QtUninvokable
public boolean equals(Object other) {
if (other instanceof AbstractIterator) {
AbstractIterator> iter = (AbstractIterator>) other;
if(owner==iter.owner)
return operator_equal(QtJambi_LibraryUtilities.internal.nativeId(this), QtJambi_LibraryUtilities.internal.nativeId(iter));
}
return false;
}
private static class IncrementalIterator implements java.util.Iterator{
final AbstractIterator nativeIterator;
final AbstractIterator end;
private boolean hasNext;
IncrementalIterator(AbstractIterator nativeIterator) {
super();
this.nativeIterator = nativeIterator;
end = nativeIterator.end();
hasNext = end!=null && !nativeIterator.equals(end);
}
@Override
public boolean hasNext() {
return hasNext;
}
@Override
public E next() {
checkNext();
E e = nativeIterator._value();
nativeIterator.increment();
hasNext = end!=null && !nativeIterator.equals(end);
return e;
}
void checkNext() {
if(!hasNext)
throw new NoSuchElementException();
}
}
private static class CheckingIncrementalIterator extends IncrementalIterator{
CheckingIncrementalIterator(AbstractIterator nativeIterator) {
super(nativeIterator);
}
void checkNext() {
super.checkNext();
if(end!=null && !end.equals(nativeIterator.end()))
throw new ConcurrentModificationException();
}
}
private static class DecrementalIterator implements java.util.Iterator{
final AbstractIterator nativeIterator;
final AbstractIterator begin;
private boolean hasNext;
public DecrementalIterator(AbstractIterator nativeIterator) {
super();
this.nativeIterator = nativeIterator;
begin = nativeIterator.begin();
hasNext = begin!=null && !nativeIterator.equals(begin);
}
@Override
public boolean hasNext() {
return hasNext;
}
@Override
public E next() {
checkNext();
nativeIterator.decrement();
hasNext = begin!=null && !nativeIterator.equals(begin);
E e = nativeIterator._value();
return e;
}
void checkNext() {
if(!hasNext)
throw new NoSuchElementException();
}
}
private static class CheckingDecrementalIterator extends DecrementalIterator{
public CheckingDecrementalIterator(AbstractIterator nativeIterator) {
super(nativeIterator);
}
void checkNext() {
super.checkNext();
if(begin!=null && !begin.equals(nativeIterator.begin()))
throw new ConcurrentModificationException();
}
}
/**
* Returns a java iterator over the containers entries between this and end.
*/
@SuppressWarnings("unchecked")
@QtUninvokable
final java.util.Iterator toJavaIterator(){
return (java.util.Iterator)iteratorFactory.apply(this);
}
/**
* Returns a descending java iterator over the containers entries between this and end.
*/
@SuppressWarnings("unchecked")
@QtUninvokable
final java.util.Iterator toJavaDescendingIterator(){
return (java.util.Iterator)diteratorFactory.apply(this);
}
/**
* Advances the iterator to the next item in the container.
*/
@QtUninvokable
final void increment() {
increment(QtJambi_LibraryUtilities.internal.nativeId(this));
}
@QtUninvokable
static native void increment(long __this__nativeId);
/**
* Advances the iterator to the previous item in the container.
*/
@QtUninvokable
final void decrement() {
decrement(QtJambi_LibraryUtilities.internal.nativeId(this));
}
@QtUninvokable
static native void decrement(long __this__nativeId);
/**
* Returns the current item's value.
*/
@QtUninvokable
final T _value() {
return value(QtJambi_LibraryUtilities.internal.nativeId(this));
}
@QtUninvokable
static native T value(long __this__nativeId);
/**
* Returns the value at iterator's position in the container or emptiness in case of end
.
*/
@QtUninvokable
public final Optional value() {
return !isValid() ? Optional.empty() : Optional.ofNullable(_value());
}
/**
* Returns the current item's value if item is valid
* or throws NoSuchElementException otherwise.
*/
@QtUninvokable
final T checkedValue() throws NoSuchElementException {
if(isValid()) {
return _value();
}else {
throw new NoSuchElementException();
}
}
@QtUninvokable
private static native boolean canLess(long __this__nativeId);
@QtUninvokable
private static native boolean lessThan(long __this__nativeId, long other);
/**
* Returns {@code true} if iterator is valid, i.e. it is less end.
*/
@QtUninvokable
final boolean isValid() {
long nativeId = QtJambi_LibraryUtilities.internal.nativeId(this);
if(nativeId==0)
return false;
AbstractIterator> end = end();
if(canLess(nativeId)) {
try {
return lessThan(nativeId, QtJambi_LibraryUtilities.internal.nativeId(end));
} catch (Exception e) {
}
}
return owner!=end.owner || !operator_equal(nativeId, QtJambi_LibraryUtilities.internal.nativeId(end));
}
private static class BeginEndFunctions{
BeginEndFunctions(
Function> constBegin,
Function> constEnd,
Function> begin,
Function> end) {
super();
this.begin = begin;
this.end = end;
this.constBegin = constBegin;
this.constEnd = constEnd;
}
final Function> begin;
final Function> end;
final Function> constBegin;
final Function> constEnd;
}
private static final Map, BeginEndFunctions> endMethodHandles = Collections.synchronizedMap(new HashMap<>());
private static BeginEndFunctions findBeginEndSuppliers(QtObject beginOwner) {
return endMethodHandles.computeIfAbsent(QtJambi_LibraryUtilities.internal.getClass(beginOwner), cls -> {
Method beginMethod = null;
Method constBeginMethod = null;
Method endMethod = null;
Method constEndMethod = null;
while ((endMethod == null && constEndMethod == null
&& beginMethod == null && constBeginMethod == null)
&& cls!=null && cls != QtObject.class) {
Method methods[] = cls.getDeclaredMethods();
for (Method method : methods) {
if (method.getParameterCount() == 0
&& AbstractIterator.class.isAssignableFrom(method.getReturnType())) {
if(method.getName().equals("begin")) {
beginMethod = method;
}else if(method.getName().equals("end")) {
endMethod = method;
}else if(method.getName().equals("constEnd")) {
constEndMethod = method;
}else if(method.getName().equals("constBegin")) {
constBeginMethod = method;
}
}
if(endMethod != null && constEndMethod != null
&& beginMethod != null && constBeginMethod != null) {
break;
}
}
cls = cls.getSuperclass();
}
if(constBeginMethod==null && beginMethod!=null) {
if(beginMethod.getReturnType()!=QSequentialIterator.class
&& beginMethod.getReturnType()!=QAssociativeIterator.class) {
constBeginMethod = beginMethod;
beginMethod = null;
}
}
if(constEndMethod==null && endMethod!=null) {
if(endMethod.getReturnType()!=QSequentialIterator.class
&& endMethod.getReturnType()!=QAssociativeIterator.class) {
constEndMethod = endMethod;
endMethod = null;
}
}
if (endMethod != null || constEndMethod != null)
return new BeginEndFunctions(CoreUtility.functionFromMethod(constBeginMethod),
CoreUtility.functionFromMethod(constEndMethod),
CoreUtility.functionFromMethod(beginMethod),
CoreUtility.functionFromMethod(endMethod));
else return new BeginEndFunctions(null,null,null,null);
});
}
private static class CoreUtility extends io.qt.internal.CoreUtility{
protected static Function functionFromMethod(Method method){
return io.qt.internal.CoreUtility.functionFromMethod(method);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy