Skip to content

Instantly share code, notes, and snippets.

@yutopp
Created February 1, 2012 05:08
Show Gist options
  • Save yutopp/1715224 to your computer and use it in GitHub Desktop.
Save yutopp/1715224 to your computer and use it in GitHub Desktop.
Range AdaptorみたいなものをDartで実装しようとしてナムサン
//----- 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