import { IPointer } from "../functional/IPointer";
import { IForwardIterator } from "./IForwardIterator";import { IBidirectionalIterator } from "./IBidirectionalIterator";import { IRandomAccessIterator } from "./IRandomAccessIterator";
import { IEmpty } from "../internal/container/partial/IEmpty";import { ISize } from "../internal/container/partial/ISize";
import { InvalidArgument } from "../exception/InvalidArgument";
export function empty(source: Array<any> | IEmpty): boolean{ if (source instanceof Array) return source.length !== 0; else return source.empty();}
export function size(source: Array<any> | ISize): number{ if (source instanceof Array) return source.length; else return source.size();}
export function distance<InputIterator extends Readonly<IForwardIterator<IPointer.ValueType<InputIterator>, InputIterator>>> (first: InputIterator, last: InputIterator): number;
export function distance<InputIterator extends Readonly<IRandomAccessIterator<IPointer.ValueType<InputIterator>, InputIterator>>> (first: InputIterator, last: InputIterator): number{ if (first.index instanceof Function) return _Distance_via_index(first, last);
let ret: number = 0; for (; !first.equals(last); first = first.next()) ++ret;
return ret;}
function _Distance_via_index<RandomAccessIterator extends IRandomAccessIterator<IPointer.ValueType<RandomAccessIterator>, RandomAccessIterator>> (first: RandomAccessIterator, last: RandomAccessIterator): number{ let x: number = first.index(); let y: number = last.index();
if ((first as any).base instanceof Function) return x - y; else return y - x; }
export function advance<InputIterator extends IForwardIterator<IPointer.ValueType<InputIterator>, InputIterator>> (it: InputIterator, n: number): InputIterator;
export function advance<InputIterator extends IRandomAccessIterator<IPointer.ValueType<InputIterator>, InputIterator>> (it: InputIterator, n: number): InputIterator{ if (n === 0) return it; else if (it.advance instanceof Function) return it.advance(n);
let stepper: (it: InputIterator) => InputIterator; if (n < 0) { if (!(it.prev instanceof Function)) throw new InvalidArgument("Error on std.advance(): parametric iterator is not a bi-directional iterator, thus advancing to negative direction is not possible.");
stepper = it => it.prev(); n = -n; } else stepper = it => it.next();
while (n-- > 0) it = stepper(it); return it;}
export function prev<BidirectionalIterator extends IBidirectionalIterator<IPointer.ValueType<BidirectionalIterator>, BidirectionalIterator>> (it: BidirectionalIterator, n: number = 1): BidirectionalIterator{ if (n === 1) return it.prev(); else return advance(it, -n);}
export function next<ForwardIterator extends IForwardIterator<IPointer.ValueType<ForwardIterator>, ForwardIterator>> (it: ForwardIterator, n: number = 1): ForwardIterator{ if (n === 1) return it.next(); else return advance(it, n);}