-
-
Save yutopp/1715224 to your computer and use it in GitHub Desktop.
Range AdaptorみたいなものをDartで実装しようとしてナムサン
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//----- Iterators ----- | |
//referencable | |
interface ReferencableIterator<E> { | |
clone(); | |
E reference(); | |
/*operator equals*/ | |
bool operator==( it ); | |
} | |
//forward | |
interface ForwardIterator<E> extends ReferencableIterator<E>, Iterator<E>/*ugg*/ | |
{ | |
bool hasNext(); | |
E next(); | |
operator +( int i ); | |
} | |
//bidirectional | |
interface BidirectionalIterator<E> extends ForwardIterator<E> | |
{ | |
bool hasPrev(); | |
E prev(); | |
operator -( int i ); | |
} | |
//random access | |
interface RandomAccessIterator<E> extends BidirectionalIterator<E> | |
{ | |
E operator[]( elem ); | |
} | |
//----- Iterable Interface ----- | |
/*interface Iterable<E> { | |
ForwardIterator<E> iterator(); | |
}*/ | |
interface ReverseIterable<E> extends Iterable<E> { | |
ForwardIterator<E> reverseIterator(); | |
} | |
//------- Hobby Range ------- | |
//----- Adaptor Interface ----- | |
interface RangeAdaptor<T> | |
{ | |
apply( begin, end ); | |
} | |
//----- Adaptable Interface ----- | |
interface Adaptable<T> { | |
operator |( RangeAdaptor<T> adaptor ); | |
} | |
//----- Reversed Adaptor ----- | |
class ReverseIterator<T> implements BidirectionalIterator<T> | |
{ | |
ReverseIterator( BidirectionalIterator<T> this._it ); | |
clone() | |
=> new ReverseIterator( _it.clone() ); | |
bool hasNext() => _it.hasPrev(); | |
T next() => _it.prev(); | |
bool hasPrev() => _it.hasNext(); | |
T prev() => _it.next(); | |
T reference() => _it.reference(); | |
operator +( int i ) => new ReverseIterator( ( i < -1 || i > 1 ) ? null : _it - i ); | |
operator -( int i ) => this + -i; | |
bool operator==( ReverseIterator<T> rhs ) => _it == rhs._it; | |
final BidirectionalIterator<T> _it; | |
} | |
class ReversedRangeAdaptor<T> implements RangeAdaptor<T> | |
{ | |
apply( BidirectionalIterator<T> begin, BidirectionalIterator<T> end ) { | |
return new Range( new ReverseIterator( end - 1 ), new ReverseIterator( begin - 1 ) ); | |
} | |
} | |
reversed() => new ReversedRangeAdaptor(); | |
//----- Filtered Adaptor ----- | |
class FiltereIterator<T> implements BidirectionalIterator<T> | |
{ | |
FiltereIterator( BidirectionalIterator<T> this._it, BidirectionalIterator<T> this._end, this._pred ); | |
clone() | |
=> new FiltereIterator( _it.clone(), _end, _pred ); | |
bool hasNext() { | |
final temp = _it.clone(); | |
while( temp.hasNext() ) { | |
if ( temp == _end ) | |
break; | |
if ( _pred( temp.next() ) ) | |
return true; | |
} | |
return false; | |
} | |
T next() { | |
while( _it.hasNext() ) { | |
final temp = _it.next(); | |
if ( _pred( temp ) ) | |
return temp; | |
} | |
throw const NoMoreElementsException(); | |
} | |
bool hasPrev() { | |
final temp = _it.clone(); | |
while( temp.hasPrev() ) { | |
if ( temp == _end ) | |
break; | |
if ( _pred( temp.prev() ) ) | |
return true; | |
} | |
return false; | |
} | |
T prev() { | |
while( _it.hasPrev() ) { | |
final temp = _it.prev(); | |
if ( _pred( temp ) ) | |
return temp; | |
} | |
throw const NoMoreElementsException(); | |
} | |
T reference() => _it.reference(); | |
operator +( int i ) => new FiltereIterator( _it + i, _end + i, _pred ); | |
operator -( int i ) => this + -i; | |
bool operator==( FiltereIterator<T> rhs ) => _it == rhs._it; | |
final BidirectionalIterator<T> _it, _end; | |
final _pred; | |
} | |
class FilteredRangeAdaptor<T> implements RangeAdaptor<T> | |
{ | |
FilteredRangeAdaptor( this._pred ); | |
apply( BidirectionalIterator<T> begin, BidirectionalIterator<T> end ) { | |
return new Range( new FiltereIterator( begin, end, _pred ), new FiltereIterator( end, begin, _pred ) ); | |
} | |
final _pred; | |
} | |
filtered( pred ) => new FilteredRangeAdaptor( pred ); | |
//----- Transformed Adaptor ----- | |
class TransformIterator<T> implements BidirectionalIterator<T> | |
{ | |
TransformIterator( BidirectionalIterator<T> this._it, this._f ); | |
clone() | |
=> new TransformIterator( _it.clone(), _f ); | |
bool hasNext() => _it.hasNext(); | |
T next() => _f( _it.next() ); | |
bool hasPrev() => _it.hasPrev(); | |
T prev() => _f( _it.prev() ); | |
T reference() => _f( _it.reference() ); | |
operator +( int i ) => new TransformIterator( _it + i, _f ); | |
operator -( int i ) => this + -i; | |
bool operator==( TransformIterator<T> rhs ) => _it == rhs._it; | |
final BidirectionalIterator<T> _it; | |
final _f; | |
} | |
class TransformedRangeAdaptor<T> implements RangeAdaptor<T> | |
{ | |
TransformedRangeAdaptor( this._f ); | |
apply( BidirectionalIterator<T> begin, BidirectionalIterator<T> end ) { | |
return new Range( new TransformIterator( begin, _f ), new TransformIterator( end, _f ) ); | |
} | |
final _f; | |
} | |
transformed( f ) => new TransformedRangeAdaptor( f ); | |
//----- Sliced Adaptor ----- | |
class SlicedRangeAdaptor<T> implements RangeAdaptor<T> | |
{ | |
SlicedRangeAdaptor( int this._n, int this._m ); | |
apply( ForwardIterator<T> begin, final ForwardIterator<T> end ) { | |
for( int i=0; i<_n; ++i ) { | |
if ( begin == end ) | |
throw const NoMoreElementsException(); | |
begin.next(); | |
} | |
final int dist = _m - _n; | |
if ( dist < 0 ) | |
throw const IllegalArgumentException(); | |
ForwardIterator<T> tmp = begin.clone(); | |
for( int i=0; i<dist; ++i ) { | |
if ( tmp == end ) | |
throw const NoMoreElementsException(); | |
tmp.next(); | |
} | |
return new Range( begin, tmp ); | |
} | |
final int _n, _m; | |
} | |
sliced( int n, int m ) => new SlicedRangeAdaptor( n, m ); | |
//----- Join ----- | |
class JoinIterator<T> implements BidirectionalIterator<T> | |
{ | |
JoinIterator( BidirectionalIterator<T> this._first, BidirectionalIterator<T> this._second, [bool this._is_first = true] ); | |
clone() | |
=> new JoinIterator( _first.clone(), _second.clone(), _is_first ); | |
bool hasNext() { | |
if ( _is_first ) | |
if ( _first.hasNext() ) | |
return true; | |
/* if ( !_second.hasPrev() ) | |
_second = _second + 1;*/ | |
_is_first = false; | |
return _second.hasNext(); | |
} | |
T next() { | |
if ( !hasNext() ) | |
return null; | |
return ( _is_first ) ? _first.next() : _second.next(); | |
} | |
bool hasPrev() { | |
if ( !_is_first ) | |
if ( _second.hasPrev() ) | |
return true; | |
if ( !_first.hasNext() ) | |
_first = _first - 1; | |
_is_first = true; | |
return _first.hasPrev(); | |
} | |
T prev() { | |
if ( !hasPrev() ) | |
return null; | |
return ( _is_first ) ? _first.prev() : _second.prev(); | |
} | |
T reference() => _is_first ? _first.reference() : _second.reference(); | |
operator +( int i ) { | |
if ( i < 0 ) | |
return this - -i; | |
if ( i > 1 ) | |
return null; | |
final bool b = _first.hasNext(); | |
return new JoinIterator( b ? _first + i : _first, !b ? _second + i : _second, (_first + 1).hasNext() ); | |
} | |
operator -( int i ) { | |
if ( i < 0 ) | |
return this + -i; | |
if ( i > 1 ) | |
return null; | |
final bool b = !( _second - 1 ).hasPrev(); | |
return new JoinIterator( b ? _first - i : _first, !b ? _second - i : _second, b ); | |
} | |
bool operator==( JoinIterator<T> rhs ) | |
=> ( _is_first == rhs._is_first ) && ( _is_first ? _first == rhs._first : _second == rhs._second ); | |
BidirectionalIterator<T> _first, _second; | |
bool _is_first; | |
} | |
join( rng1, rng2 ) | |
=> new Range( | |
new JoinIterator( rng1.begin(), rng2.begin() ), | |
new JoinIterator( rng1.end() - 1, rng2.end(), false ) | |
); | |
//----- Counting Iterator ----- | |
class CountingIterator implements RandomAccessIterator<int> | |
{ | |
CountingIterator( int this._begin, int this._end, [ int this._step = 1, int this._pos = 0 ] ); | |
clone() | |
=> new CountingIterator( _begin, _end, _step, _pos ); | |
bool hasNext() => reference() < _end; | |
int next() => this[_pos++]; | |
bool hasPrev() => this[_pos] > _end; | |
int prev() => this[--_pos]; | |
int reference() => this[_pos]; | |
operator +( int i ) => new CountingIterator( _begin, _end, _step, _pos ); | |
operator -( int i ) => this + -i; | |
operator []( int elem ) => _begin + elem * _step; | |
bool operator==( CountingIterator rhs ) => reference() == rhs.reference(); | |
final int _begin, _end, _step; | |
int _pos; | |
} | |
irange( int start, int last, [ int step = 1 ] ) | |
=> new Range( new CountingIterator( start, last, step ), new CountingIterator( last, start, step ) ); | |
//----- Range Modoki!! ----- | |
class RangeIterator<T> implements BidirectionalIterator<T> | |
{ | |
RangeIterator( BidirectionalIterator<T> this._it, BidirectionalIterator<T> this._end ); | |
clone() | |
=> new RangeIterator( _it.clone(), _end.clone() ); | |
T reference() => _it.reference(); | |
bool hasNext() => _it.hasNext() && _it != _end; | |
T next() => _it.next(); | |
bool hasPrev() => _it.hasPrev(); | |
T prev() => _it.prev(); | |
operator +( int i ) => new RangeIterator( ( i < -1 || i > 1 ) ? null : _it + i, _end ); | |
operator -( int i ) => this + -i; | |
operator ==( RangeIterator<T> rhs ) => _it == rhs._it; | |
final BidirectionalIterator<T> _it, _end; | |
} | |
class Range<T> implements Iterable<T>, Adaptable<T> | |
{ | |
Range( this._begin, this._end ); | |
RangeIterator<T> iterator() => new RangeIterator( begin(), end() ); | |
operator |( RangeAdaptor<T> adaptor ) => adaptor.apply( begin(), end() ); | |
begin() => _begin; | |
end() => _end; | |
final Iterator<T> _begin, _end; | |
} | |
//------------------------------------- | |
//----- Dummy List Implementation ----- | |
class DummyList<T> implements ReverseIterable<T>, Adaptable<T> /*Collection<T>, default ListFactory<E>*/ | |
{ | |
DummyList( List<T> this._list ); | |
ForwardIterator<T> iterator() => begin(); | |
ForwardIterator<T> reverseIterator() => rbegin(); | |
operator |( RangeAdaptor<T> abaptor ) => abaptor.apply( begin(), end() ); | |
ListIterator<T> begin() => new ListIterator( _list ); | |
ListIterator<T> end() => new ListIterator.withPos( _list, _list.length ); | |
ListReverseIterator<T> rbegin() => new ListReverseIterator( _list ); | |
ListReverseIterator<T> rend() => new ListReverseIterator.withPos( _list, 0 ); | |
final List<T> _list; | |
} | |
//----- Iterator Trial Implementation For List ----- | |
// Normal | |
class ListIterator<T> implements RandomAccessIterator<T> { | |
ListIterator( List<T> list ) | |
: this.withPos( list, 0 ); | |
ListIterator.withPos( List<T> this._list, int this._pos ); | |
clone() | |
=> new ListIterator.withPos( _list, _pos ); | |
bool hasNext() => _pos < _list.length; | |
T next() { | |
if ( !hasNext() ) | |
throw const NoMoreElementsException(); | |
return _list[_pos++]; | |
} | |
bool hasPrev() { | |
return _pos >= 0; | |
} | |
T prev() { | |
if ( !hasPrev() ) | |
throw const NoMoreElementsException(); | |
return _list[_pos--]; | |
} | |
T reference() => _list[_pos]; | |
T operator[]( int elem ) => _list[elem]; | |
operator +( int i ) => new ListIterator.withPos( _list, _pos + i ); | |
operator -( int i ) => this + -i; | |
/*operator equals*/ | |
bool operator ==( ListIterator<T> rhs ) => _list === rhs._list && _pos == rhs._pos; | |
final List<T> _list; | |
int _pos; | |
} | |
// Reverse | |
class ListReverseIterator<T> implements RandomAccessIterator<T> { | |
ListReverseIterator( List<T> list ) | |
: this.withPos( list, list.length ); | |
ListReverseIterator.withPos( List<T> list, int pos ) | |
: _it = new ListIterator.withPos( list, pos - 1 ); | |
clone() | |
=> new ListReverseIterator.withPos( _it._list, _it._pos ); | |
bool hasNext() => _it.hasPrev(); | |
T next() => _it.prev(); | |
bool hasPrev() => _it.hasNext(); | |
T prev() => _it.next(); | |
T reference() => _it.reference(); | |
T operator[]( int elem ) => _it[elem]; | |
operator +( int i ) => new ListReverseIterator( _it - i ); | |
operator -( int i ) => this + -i; | |
bool operator ==( ListReverseIterator<T> rhs ) => _it == rhs._it; | |
final ListIterator<T> _it; | |
} | |
//----- Main ----- | |
void main() | |
{ | |
for( final v in join( new DummyList( [1,2,3] ), new DummyList( [4,5,6,7,8,9] ) ) | reversed() | sliced( 2, 5 ) | reversed() | sliced( 0, 2 ) | reversed() ) | |
print( v ); | |
print( "-------------------" ); | |
for( final v in [] ) | |
print( v ); | |
print( "-------------------" ); | |
//for( final v in new DummyList( [1,2] ) | reversed() | reversed() ) | |
// | |
for( final v in new DummyList( [1,2,3,4,5,6,7,8,9] ) | sliced( 2, 5 ) | reversed() | sliced( 0, 2 )/* | reversed() | reversed() | sliced( 0, 1 ) | reversed() */) | |
print( v ); | |
print( "-------------------" ); | |
for( final v in new DummyList( [1,2,3,4,5,6,7,8,9] ) | filtered( (i) => i < 5 ) | sliced( 0, 2 ) | transformed( ( i ) => i*2 ) | reversed() ) | |
print( v ); | |
print( "-------------------" ); | |
for( final v in join( irange( 0, 5 ), irange( 5, 10 ) ) | reversed() | filtered( (i) => i < 8 ) | reversed() | sliced( 1, 2 ) ) | |
print( v ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment