📄 decal.pas
字号:
}
DIterHandler = class(DBaseClass)
protected
//
// Iterator manipulation.
//
{** Subclasses must advance the given iterator. Must be implemented.
@param iterator The iterator to be advanced.
}
procedure iadvance(var iterator : DIterator); virtual; abstract;
{** Subclasses must get the object at the given iterator. Must be implemented.
@param iterator The iterator at which to get the object.
}
function iget(const iterator : DIterator) : PDObject; virtual; abstract;
{** Subclasses must determine if the two iterators are positioned at the
same element.
@param iter1 The first iterator
@param iter2 The second iterator
}
function iequals(const iter1, iter2 : DIterator) : Boolean; virtual; abstract;
{** Store an object at the given iterator. Must be implemented by subclasses.
@param iterator The position to store at.
@param obj The object to put there.
}
procedure iput(const iterator : DIterator; const obj : DObject); virtual; abstract;
{** Store an array of objects (or atomic values) in the container. DContainer
contains an implementation of this that will repeatedly call iput.
@param iterator Where to put the objects.
@param objs The objects to store.
}
procedure _iput(const iterator : DIterator; objs : array of const); virtual; abstract;
{** Move an iterator. count can be positive or negative. The default
implementation uses repeated advance or retreat functions. Containers that
support random access will be able to implement this more effectively.
@param iterator The iterator to move.
@param count How much to move it (positive or negative).}
procedure iadvanceBy(var iterator : DIterator; count : Integer); virtual; abstract;
{** Determine if the given iterator is at the start of the container.
@param iterator The iterator to test. }
function iatStart(const iterator : DIterator) : Boolean; virtual; abstract;
{** Determine if the given iterator is at the end of the container.
@param iterator The iterator to test. }
function iatEnd(const iterator : DIterator) : Boolean; virtual; abstract;
{** Returns the container associated with the iterator. If there is no
container for this iterator, it returns nil.
@param iterator The iterator whose container should be returned. }
function igetContainer(const iterator : DIterator) : DContainer; virtual; abstract;
{** Removes the item the iterator is positioned at, and returns an iterator
positioned on the item that is next. Returns an atEnd iterator if there's
no following item. }
function iremove(const iterator : DIterator) : DIterator; virtual; abstract;
{** Determines the number of positions between two iterators. For example,
if iter1 points at the second element in an array and iter2 points at the
fifth, the distance will be three.
@param iter1 The beginning iterator.
@param iter2 The ending iterator. }
function idistance(const iter1, iter2 : DIterator) : Integer; virtual; abstract;
// bidirectional
{** Moves an iterator backwards by one position. }
procedure iretreat(var iterator : DIterator); virtual; abstract;
{** Moves an iterator backwards by count positions. }
procedure iretreatBy(var iterator : DIterator; count : Integer); virtual; abstract;
{** Retrieve the item at a given offset from the current iterator position. }
function igetAt(const iterator : DIterator; offset : Integer) : PDObject; virtual; abstract;
{** Puts an item at a given offset from the current iterator position. }
procedure iputAt(const iterator : DIterator; offset : Integer; const obj : DObject); virtual; abstract;
{** Returns the integer index associated with an iterator. }
function iindex(const iterator : DIterator) : Integer; virtual; abstract;
{** Determines if iter1 is "less" (positioned earlier in the container) than
iter2. }
function iless(const iter1, iter2 : DIterator) : Boolean; virtual; abstract;
// utility
procedure iflagChange(var iterator : DIterator; oldflags : DIteratorFlags); virtual; abstract;
end;
////////////////////////////////////////////////////////////////////
//
// Iterator Adapters
//
////////////////////////////////////////////////////////////////////
{** DIterAdapter is an abstract base class for other classes that can
modify the iterator manipulation behavior of a container. }
DIterAdapter = class(DIterHandler)
protected
FTarget : DIterHandler;
//
// Iterator manipulation.
//
{** Subclasses must advance the given iterator. Must be implemented.
@param iterator The iterator to be advanced.
}
procedure iadvance(var iterator : DIterator); override;
{** Subclasses must get the object at the given iterator. Must be implemented.
@param iterator The iterator at which to get the object.
}
function iget(const iterator : DIterator) : PDObject; override;
{** Subclasses must determine if the two iterators are positioned at the
same element.
@param iter1 The first iterator
@param iter2 The second iterator
}
function iequals(const iter1, iter2 : DIterator) : Boolean; override;
{** Store an object at the given iterator. Must be implemented by subclasses.
@param iterator The position to store at.
@param obj The object to put there.
}
procedure iput(const iterator : DIterator; const obj : DObject); override;
{** Store an array of objects (or atomic values) in the container. DContainer
contains an implementation of this that will repeatedly call iput.
@param iterator Where to put the objects.
@param objs The objects to store.
}
procedure _iput(const iterator : DIterator; objs : array of const); override;
{** Move an iterator. count can be positive or negative. The default
implementation uses repeated advance or retreat functions. Containers that
support random access will be able to implement this more effectively.
@param iterator The iterator to move.
@param count How much to move it (positive or negative).}
procedure iadvanceBy(var iterator : DIterator; count : Integer); override;
function iremove(const iterator : DIterator) : DIterator; override;
function iatStart(const iterator : DIterator) : Boolean; override;
function iatEnd(const iterator : DIterator) : Boolean; override;
function igetContainer(const iterator : DIterator) : DContainer; override;
function idistance(const iter1, iter2 : DIterator) : Integer; override;
// bidirectional
procedure iretreat(var iterator : DIterator); override;
procedure iretreatBy(var iterator : DIterator; count : Integer); override;
function igetAt(const iterator : DIterator; offset : Integer) : PDObject; override;
procedure iputAt(const iterator : DIterator; offset : Integer; const obj : DObject); override;
// random
function iindex(const iterator : DIterator) : Integer; override;
function iless(const iter1, iter2 : DIterator) : Boolean; override;
procedure iflagChange(var iterator : DIterator; oldflags : DIteratorFlags); override;
public
constructor Create(var target : DIterator);
end;
{** DIterFilter adapters apply a test to underlying objects to determine
if they should be part of the adapted container. Pass a test to the
constructor. Then, each time an iterator is advanced or retreated, items
that don't pass the test will be skipped over. }
DIterFilter = class(DIterAdapter)
protected
FTest : DTest;
procedure iadvance(var iterator : DIterator); override;
procedure iretreat(var iterator : DIterator); override;
public
{** Construct a DIterFilter, using test as the filter to determine if
a given item should be part of the filtered container.
@param target An iterator representing the container or range to be filtered.
@param test The test used to determine if an item is part of the sequence or
not. Only those items that pass the test will be part of the
filtered sequence. }
constructor Create(var target : DIterator; test : DTest);
end;
{** DIterSkipper adapters skip forward or backward by an integral number of
items each time the iterator is advanced or retreated. Pass the skip
value to the constructor. }
DIterSkipper = class(DIterAdapter)
protected
FSkipBy : Integer;
procedure iadvance(var iterator : DIterator); override;
procedure iretreat(var iterator : DIterator); override;
public
constructor Create(var target : DIterator; skipBy : Integer);
end;
////////////////////////////////////////////////////////////////////
//
// Container
//
////////////////////////////////////////////////////////////////////
{** DContainer is the base class of all containers. It provides a number of
generic facilities for container usage and management. The basic iterator
manipulation routines are made virtual and abstract, forcing subclasses to
implement them. }
DContainer = class(DIterHandler)
protected
comparator : DComparator;
procedure cloneTo(newContainer : DContainer); virtual;
protected
//
// Iterator manipulation.
//
procedure _iput(const iterator : DIterator; objs : array of const); override;
{** Move an iterator. count can be positive or negative. The default
implementation uses repeated advance or retreat functions. Containers that
support random access will be able to implement this more effectively.
@param iterator The iterator to move.
@param count How much to move it (positive or negative).}
procedure iadvanceBy(var iterator : DIterator; count : Integer); override;
function iatStart(const iterator : DIterator) : Boolean; override;
function iatEnd(const iterator : DIterator) : Boolean; override;
function igetContainer(const iterator : DIterator) : DContainer; override;
function idistance(const iter1, iter2 : DIterator) : Integer; override;
// bidirectional
procedure iretreat(var iterator : DIterator); override;
procedure iretreatBy(var iterator : DIterator; count : Integer); override;
function igetAt(const iterator : DIterator; offset : Integer) : PDObject; override;
procedure iputAt(const iterator : DIterator; offset : Integer; const obj : DObject); override;
// random
function iindex(const iterator : DIterator) : Integer; override;
function iless(const iter1, iter2 : DIterator) : Boolean; override;
procedure iflagChange(var iterator : DIterator; oldflags : DIteratorFlags); override;
procedure _clear(direct : Boolean); virtual; abstract;
public
{** Add a DObject to this container. The object is copied and added to
the container.
@param obj The object to add.
}
procedure _add(const obj : DObject); virtual; abstract;
{** Add a DObject to this container. The object is NOT copied -- it
is moved into the container. Do not clear the object afterwards. }
procedure addRef(const obj : DObject); virtual;
{** Add an array of objects to the container. This call makes use of
Delphi's open array system, and as such the array can contain any type
of object. Each object will be copied into the container. }
procedure add(objs : array of const); virtual;
{** Remove all instances of an object, by value, from the container. }
procedure _remove(const obj : DObject); virtual; abstract;
{** Remove all instances of each in an array of objects, by value, from the container. }
procedure remove(objs : array of const); virtual;
{** Clear this container of all contents. Note that this does not perform
any type of free or destructor operation. If you want to free all the
objects in a container before clearing if, use the ObjFree algorithm. }
procedure clear; virtual;
{** Inform the container that "amount" items are going to be inserted.
Most containers don't have any concept of setting the capacity, but
for those that do, algorithms can call this to provide a hint to the
container about how many items are going to be inserted. }
procedure ensureCapacity(amount : Integer); virtual;
{** Request that the container use the minimum amount of memory possible
for its current contents. Note that this is only a hint to the container;
it may or may not have any effect. }
procedure trimToSize; virtual;
{** Return an iterator positioned after the last element in the container.
Note that the finish position is a valid insertion point for those containers
that can have the add operation performed. }
function finish : DIterator; virtual; abstract;
{** Return the absolute maximum number of objects that can be stored in
this container. The container does not necessarily have this space allocated;
it is just the maximum that <i>could</i> be allocated. }
function maxSize : Integer; virtual; abstract;
{** Return an iterator positioned on the first object in the container. }
function start : DIterator; virtual; abstract;
{** Return a complete copy of this container. This is a copy by value, as
all objects are stored in DContainers by value. }
function clone : DContainer; virtual;
{** Requests that this container compare two DObjects using its current
comparator. If obj1 is less than obj2, the result is negative. If they
are equal, the result is 0; otherwise it is positive. }
function binaryCompare(const obj1, obj2 : DObject) : Integer;
{** Determines if two objects are equal, using this container's current
comparator. }
function binaryTest(const obj1, obj2 : DObject) : Boolean;
{** Requests the comparator currently being used by this container. }
procedure getComparator(var compare : DComparator); virtual;
{** Retrives the current comparator of this container as a binary test,
which enables testing for equality only. }
procedure getBinaryTest(var bt : DBinaryTest); virtual;
{** Determines if this container is empty. }
function isEmpty : Boolean; virtual;
{** Determines the number of objects currently in this container. }
function size : Integer; virtual;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -