ArrayProxyMSeq.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-1.6.0).
003  * Copyright (c) 2007-2014 Franz Wilhelmstötter
004  *
005  * Licensed under the Apache License, Version 2.0 (the "License");
006  * you may not use this file except in compliance with the License.
007  * You may obtain a copy of the License at
008  *
009  *      http://www.apache.org/licenses/LICENSE-2.0
010  *
011  * Unless required by applicable law or agreed to in writing, software
012  * distributed under the License is distributed on an "AS IS" BASIS,
013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014  * See the License for the specific language governing permissions and
015  * limitations under the License.
016  *
017  * Author:
018  *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at)
019  */
020 package org.jenetics.internal.util;
021 
022 import static java.lang.Math.min;
023 import static java.lang.String.format;
024 
025 import java.util.Iterator;
026 import java.util.List;
027 import java.util.ListIterator;
028 
029 import org.jenetics.util.Factory;
030 import org.jenetics.util.Function;
031 import org.jenetics.util.ISeq;
032 import org.jenetics.util.MSeq;
033 
034 /**
035  @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
036  @since 1.4
037  @version 1.5 &mdash; <em>$Date: 2014-02-15 $</em>
038  */
039 public class ArrayProxyMSeq<T> extends ArrayProxySeq<T> implements MSeq<T> {
040 
041     public ArrayProxyMSeq(final ArrayProxy<T> proxy) {
042         super(proxy);
043     }
044 
045     @Override
046     public MSeq<T> copy() {
047         return new ArrayProxyMSeq<>(_proxy.copy());
048     }
049 
050     @Override
051     public Iterator<T> iterator() {
052         return new ArrayProxyMIterator<>(_proxy);
053     }
054 
055     @Override
056     public ListIterator<T> listIterator() {
057         return new ArrayProxyMIterator<>(_proxy);
058     }
059 
060     @Override
061     public void set(final int index, final T value) {
062         _proxy.cloneIfSealed();
063         _proxy.set(index, value);
064     }
065 
066     @Override
067     public MSeq<T> setAll(final T value) {
068         _proxy.cloneIfSealed();
069         for (int i = _proxy._start; i < _proxy._end; ++i) {
070             _proxy.__set(i, value);
071         }
072         return this;
073     }
074 
075     @Override
076     public MSeq<T> setAll(final Iterator<? extends T> it) {
077         _proxy.cloneIfSealed();
078         for (int i = _proxy._start; i < _proxy._end && it.hasNext(); ++i) {
079             _proxy.__set(i, it.next());
080         }
081         return this;
082     }
083 
084     @Override
085     public MSeq<T> setAll(final Iterable<? extends T> values) {
086         return setAll(values.iterator());
087     }
088 
089     @Override
090     public MSeq<T> setAll(final T[] values) {
091         _proxy.cloneIfSealed();
092         for (int i = 0, n = min(_proxy._length, values.length); i < n; ++i) {
093             _proxy.uncheckedSet(i, values[i]);
094         }
095         return this;
096     }
097 
098     @Override
099     public MSeq<T> fill(Factory<? extends T> factory) {
100         _proxy.cloneIfSealed();
101         for (int i = _proxy._start; i < _proxy._end; ++i) {
102             _proxy.__set(i, factory.newInstance());
103         }
104         return this;
105     }
106 
107     @Override
108     public void swap(final int i, final int j) {
109         final T temp = _proxy.get(i);
110         _proxy.uncheckedSet(i, _proxy.get(j));
111         _proxy.uncheckedSet(j, temp);
112     }
113 
114     @Override
115     public void swap(int start, int end, MSeq<T> other, int otherStart) {
116         checkIndex(start, end, otherStart, other.length());
117 
118         if (start < end) {
119             if (other instanceof ArrayProxyMSeq<?>) {
120                 swap(start, end, (ArrayProxyMSeq<T>)other, otherStart);
121             else {
122                 _proxy.cloneIfSealed();
123 
124                 for (int i = (end - start); --i >= 0;) {
125                     final T temp = _proxy.uncheckedGet(i + start);
126                     _proxy.uncheckedSet(i + start, other.get(otherStart + i));
127                     other.set(otherStart + i, temp);
128                 }
129             }
130         }
131     }
132 
133     private void swap(int start, int end, ArrayProxyMSeq<T> other, int otherStart) {
134         _proxy.swap(start, end, other._proxy, otherStart);
135     }
136 
137     private void checkIndex(
138         final int start, final int end,
139         final int otherStart, final int otherLength
140     ) {
141         _proxy.checkIndex(start, end);
142         if (otherStart < || (otherStart + (end - start)) > otherLength) {
143             throw new ArrayIndexOutOfBoundsException(format(
144                 "Invalid index range: [%d, %d)",
145                 otherStart, (otherStart + (end - start))
146             ));
147         }
148     }
149 
150     @Override
151     public MSeq<T> subSeq(final int start, final int end) {
152         return new ArrayProxyMSeq<>(_proxy.slice(start, end));
153     }
154 
155     @Override
156     public MSeq<T> subSeq(final int start) {
157         return new ArrayProxyMSeq<>(_proxy.slice(start));
158     }
159 
160     @Override
161     public <B> MSeq<B> map(Function<? super T, ? extends B> mapper) {
162         final ArrayProxyMSeq<B> array = new ArrayProxyMSeq<>(
163             new ArrayProxyImpl<B>(length())
164         );
165         for (int i = 0; i < _proxy._length; ++i) {
166             array._proxy.uncheckedSet(i, mapper.apply(_proxy.uncheckedGet(i)));
167         }
168 
169         return array;
170     }
171 
172     @Override
173     public ISeq<T> toISeq() {
174         return new ArrayProxyISeq<>(_proxy.seal());
175     }
176 
177     @Override
178     public List<T> asList() {
179         return new ArrayProxyMList<>(_proxy);
180     }
181 
182 }