1+ /*
2+ * ------------------------------------------------------------------------
3+ * Copyright by KNIME AG, Zurich, Switzerland
4+ * Website: http://www.knime.com; Email: contact@knime.com
5+ *
6+ * This program is free software; you can redistribute it and/or modify
7+ * it under the terms of the GNU General Public License, Version 3, as
8+ * published by the Free Software Foundation.
9+ *
10+ * This program is distributed in the hope that it will be useful, but
11+ * WITHOUT ANY WARRANTY; without even the implied warranty of
12+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+ * GNU General Public License for more details.
14+ *
15+ * You should have received a copy of the GNU General Public License
16+ * along with this program; if not, see <http://www.gnu.org/licenses>.
17+ *
18+ * Additional permission under GNU GPL version 3 section 7:
19+ *
20+ * KNIME interoperates with ECLIPSE solely via ECLIPSE's plug-in APIs.
21+ * Hence, KNIME and ECLIPSE are both independent programs and are not
22+ * derived from each other. Should, however, the interpretation of the
23+ * GNU GPL Version 3 ("License") under any applicable laws result in
24+ * KNIME and ECLIPSE being a combined program, KNIME AG herewith grants
25+ * you the additional permission to use and propagate KNIME together with
26+ * ECLIPSE with only the license terms in place for ECLIPSE applying to
27+ * ECLIPSE and the GNU GPL Version 3 applying for KNIME, provided the
28+ * license terms of ECLIPSE themselves allow for the respective use and
29+ * propagation of ECLIPSE together with KNIME.
30+ *
31+ * Additional permission relating to nodes for KNIME that extend the Node
32+ * Extension (and in particular that are based on subclasses of NodeModel,
33+ * NodeDialog, and NodeView) and that only interoperate with KNIME through
34+ * standard APIs ("Nodes"):
35+ * Nodes are deemed to be separate and independent programs and to not be
36+ * covered works. Notwithstanding anything to the contrary in the
37+ * License, the License does not apply to Nodes, you are not required to
38+ * license Nodes under the License, and you are granted a license to
39+ * prepare and propagate Nodes, in each case even if such Nodes are
40+ * propagated with or for interoperation with KNIME. The owner of a Node
41+ * may freely choose the license terms applicable to such Node, including
42+ * when such Node is propagated with or for interoperation with KNIME.
43+ * ------------------------------------------------------------------------
44+ *
45+ */
46+ package org .rdkit .knime .nodes .twocomponentreaction2 ;
47+
48+ import java .util .Iterator ;
49+ import java .util .NoSuchElementException ;
50+
51+ /**
52+ * An iterable that iterates over all pairings of two given iterables.
53+ *
54+ * @author Carsten Haubold, KNIME GmbH, Konstanz, Germany
55+ *
56+ * @param <T> The type of the first iterable
57+ * @param <U> The type of the second iterable
58+ */
59+ class PairIterable <T , U > implements Iterable <Pair <Pair <T , Long >, Pair <U , Long >>> {
60+ private final Iterable <T > firstIterable ;
61+ private final Iterable <U > secondIterable ;
62+
63+ public PairIterable (Iterable <T > firstIterable , Iterable <U > secondIterable ) {
64+ this .firstIterable = firstIterable ;
65+ this .secondIterable = secondIterable ;
66+ }
67+
68+ @ Override
69+ public Iterator <Pair <Pair <T , Long >, Pair <U , Long >>> iterator () {
70+ return new PairIterator <>(firstIterable .iterator (), secondIterable );
71+ }
72+
73+ private static class PairIterator <T , U > implements Iterator <Pair <Pair <T , Long >, Pair <U , Long >>> {
74+ private final Iterator <T > firstIterator ;
75+ private final Iterable <U > secondIterable ;
76+ private Iterator <U > secondIterator = null ;
77+ private T currentFirst ;
78+ private Long firstIndex = 0L ;
79+ private Long secondIndex = 0L ;
80+
81+ public PairIterator (Iterator <T > firstIterator , Iterable <U > secondIterable ) {
82+ this .firstIterator = firstIterator ;
83+ this .secondIterable = secondIterable ;
84+ if (firstIterator .hasNext ()) {
85+ currentFirst = firstIterator .next ();
86+ secondIterator = secondIterable .iterator ();
87+ }
88+ }
89+
90+ @ Override
91+ public boolean hasNext () {
92+ return ((secondIterator != null && secondIterator .hasNext ())) || firstIterator .hasNext ();
93+ }
94+
95+ @ Override
96+ public Pair <Pair <T , Long >, Pair <U , Long >> next () {
97+ if (!hasNext ()) {
98+ throw new NoSuchElementException ();
99+ }
100+
101+ if (!secondIterator .hasNext ()) {
102+ currentFirst = firstIterator .next ();
103+ firstIndex ++;
104+ secondIterator = secondIterable .iterator ();
105+ secondIndex = 0L ;
106+ }
107+
108+ return new Pair <>(new Pair <>(currentFirst , firstIndex ), new Pair <>(secondIterator .next (), secondIndex ++));
109+ }
110+ }
111+ }
0 commit comments