mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-02 06:29:25 +01:00
* Initial check-in of stl
git-svn-id: trunk@17233 -
This commit is contained in:
parent
736071e716
commit
a33e5eb0eb
45
.gitattributes
vendored
45
.gitattributes
vendored
@ -2295,6 +2295,51 @@ packages/fcl-res/xml/versionconsts.xml svneol=native#text/plain
|
||||
packages/fcl-res/xml/versionresource.xml svneol=native#text/plain
|
||||
packages/fcl-res/xml/versiontypes.xml svneol=native#text/plain
|
||||
packages/fcl-res/xml/winpeimagereader.xml svneol=native#text/plain
|
||||
packages/fcl-stl/Makefile svneol=native#text/plain
|
||||
packages/fcl-stl/Makefile.fpc svneol=native#text/plain
|
||||
packages/fcl-stl/doc/arrayutils.tex svneol=native#text/plain
|
||||
packages/fcl-stl/doc/deque.tex svneol=native#text/plain
|
||||
packages/fcl-stl/doc/dequeexample.pp svneol=native#text/plain
|
||||
packages/fcl-stl/doc/main.tex svneol=native#text/plain
|
||||
packages/fcl-stl/doc/makra.tex svneol=native#text/plain
|
||||
packages/fcl-stl/doc/map.tex svneol=native#text/plain
|
||||
packages/fcl-stl/doc/mapexample.pp svneol=native#text/plain
|
||||
packages/fcl-stl/doc/priorityqueue.tex svneol=native#text/plain
|
||||
packages/fcl-stl/doc/priorityqueueexample.pp svneol=native#text/plain
|
||||
packages/fcl-stl/doc/queue.tex svneol=native#text/plain
|
||||
packages/fcl-stl/doc/queueexample.pp svneol=native#text/plain
|
||||
packages/fcl-stl/doc/set.tex svneol=native#text/plain
|
||||
packages/fcl-stl/doc/setexample.pp svneol=native#text/plain
|
||||
packages/fcl-stl/doc/sortingexample.pp svneol=native#text/plain
|
||||
packages/fcl-stl/doc/stack.tex svneol=native#text/plain
|
||||
packages/fcl-stl/doc/stackexample.pp svneol=native#text/plain
|
||||
packages/fcl-stl/doc/util.tex svneol=native#text/plain
|
||||
packages/fcl-stl/doc/vector.tex svneol=native#text/plain
|
||||
packages/fcl-stl/doc/vectorexample.pp svneol=native#text/plain
|
||||
packages/fcl-stl/src/garrayutils.pp svneol=native#text/plain
|
||||
packages/fcl-stl/src/gdeque.pp svneol=native#text/plain
|
||||
packages/fcl-stl/src/ghashset.pp svneol=native#text/plain
|
||||
packages/fcl-stl/src/gmap.pp svneol=native#text/plain
|
||||
packages/fcl-stl/src/gpriorityqueue.pp svneol=native#text/plain
|
||||
packages/fcl-stl/src/gqueue.pp svneol=native#text/plain
|
||||
packages/fcl-stl/src/gset.pp svneol=native#text/plain
|
||||
packages/fcl-stl/src/gstack.pp svneol=native#text/plain
|
||||
packages/fcl-stl/src/gutil.pp svneol=native#text/plain
|
||||
packages/fcl-stl/src/gvector.pp svneol=native#text/plain
|
||||
packages/fcl-stl/tests/clean svneol=native#text/plain
|
||||
packages/fcl-stl/tests/gdequetest.pp svneol=native#text/plain
|
||||
packages/fcl-stl/tests/gmaptest.pp svneol=native#text/plain
|
||||
packages/fcl-stl/tests/gmaptestzal.pp svneol=native#text/plain
|
||||
packages/fcl-stl/tests/gpriorityqueuetest.pp svneol=native#text/plain
|
||||
packages/fcl-stl/tests/gqueuetest.pp svneol=native#text/plain
|
||||
packages/fcl-stl/tests/gsetrefcounttest.pp svneol=native#text/plain
|
||||
packages/fcl-stl/tests/gsettest.pp svneol=native#text/plain
|
||||
packages/fcl-stl/tests/gsorttest.pp svneol=native#text/plain
|
||||
packages/fcl-stl/tests/gstacktest.pp svneol=native#text/plain
|
||||
packages/fcl-stl/tests/gvectortest.pp svneol=native#text/plain
|
||||
packages/fcl-stl/tests/run-all-tests svneol=native#text/plain
|
||||
packages/fcl-stl/tests/suiteconfig.pp svneol=native#text/plain
|
||||
packages/fcl-stl/tests/testrunner.pp svneol=native#text/plain
|
||||
packages/fcl-web/Makefile svneol=native#text/plain
|
||||
packages/fcl-web/Makefile.fpc svneol=native#text/plain
|
||||
packages/fcl-web/Makefile.org svneol=native#text/plain
|
||||
|
||||
2427
packages/fcl-stl/Makefile
Normal file
2427
packages/fcl-stl/Makefile
Normal file
File diff suppressed because it is too large
Load Diff
23
packages/fcl-stl/Makefile.fpc
Normal file
23
packages/fcl-stl/Makefile.fpc
Normal file
@ -0,0 +1,23 @@
|
||||
#
|
||||
# Makefile.fpc for Free Component Library
|
||||
#
|
||||
|
||||
[package]
|
||||
name=fcl-stl
|
||||
version=2.5.1
|
||||
|
||||
[target]
|
||||
units=garrayutils gdeque gmap gpriorityqueue gqueue gset gstack gutil gvector
|
||||
|
||||
[install]
|
||||
fpcpackage=y
|
||||
|
||||
[default]
|
||||
fpcdir=../..
|
||||
|
||||
[compiler]
|
||||
options=-S2h
|
||||
sourcedir=src
|
||||
|
||||
[rules]
|
||||
.NOTPARALLEL:
|
||||
47
packages/fcl-stl/doc/arrayutils.tex
Normal file
47
packages/fcl-stl/doc/arrayutils.tex
Normal file
@ -0,0 +1,47 @@
|
||||
\chapter{TArrayUtils}
|
||||
|
||||
Set of utilities for manipulating arrays data.
|
||||
|
||||
Takes 3 arguements for specialization. First one is type of array (can be anything, which is
|
||||
accesible by [] operator, e. g. ordinary array, vector, ...), second one is type of array element.
|
||||
|
||||
%Usage example for sorting:
|
||||
|
||||
%\lstinputlisting[language=Pascal]{sortingexample.pp}
|
||||
|
||||
Members list:
|
||||
|
||||
\begin{longtable}{|m{10cm}|m{5cm}|}
|
||||
\hline
|
||||
Method & Complexity guarantees \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Description} \\ \hline\hline
|
||||
|
||||
\verb!procedure RandomShuffle(arr: TArr, size:SizeUint)! &
|
||||
O(N)\\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Shuffles elements in array in random way} \\\hline\hline
|
||||
|
||||
\end{longtable}\chapter{TOrderingArrayUtils}
|
||||
|
||||
Set of utilities for manipulating arrays data.
|
||||
|
||||
Takes 3 arguements for specialization. First one is type of array (can be anything, which is
|
||||
accesible by [] operator, e. g. ordinary array, vector, ...), second one is type of array element,
|
||||
third one is comparator class (see TPriorityQueue for definition of comparator class).
|
||||
|
||||
Usage example for sorting:
|
||||
|
||||
\lstinputlisting[language=Pascal]{sortingexample.pp}
|
||||
|
||||
Members list:
|
||||
|
||||
\begin{longtable}{|m{10cm}|m{5cm}|}
|
||||
\hline
|
||||
Method & Complexity guarantees \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Description} \\ \hline\hline
|
||||
|
||||
\verb!procedure Sort(arr: TArr, size:SizeUint)! &
|
||||
O(N log N) average and worst case. Uses QuickSort, backed up by HeapSort, when QuickSort ends up in
|
||||
using too much recursion.\\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Sort array arr, with specified size. Array indexing should be 0 based.} \\\hline\hline
|
||||
|
||||
\end{longtable}
|
||||
81
packages/fcl-stl/doc/deque.tex
Normal file
81
packages/fcl-stl/doc/deque.tex
Normal file
@ -0,0 +1,81 @@
|
||||
\chapter{TDeque}
|
||||
|
||||
Implements selfresizing array. Indexing is 0-based.
|
||||
Also implement constant time insertion from front.
|
||||
|
||||
Usage example:
|
||||
|
||||
\lstinputlisting[language=Pascal]{dequeexample.pp}
|
||||
|
||||
Memory complexity:
|
||||
Uses at most 3times bigger memory than maximal array size (this is only case during reallocation).
|
||||
Normal consumption is at most twice as maximal array size.
|
||||
|
||||
Members list:
|
||||
|
||||
\begin{longtable}{|m{10cm}|m{5cm}|}
|
||||
\hline
|
||||
Method & Complexity guarantees \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Description} \\ \hline\hline
|
||||
|
||||
\verb!Create! & O(1) \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Constructor. Creates empty array.} \\ \hline\hline
|
||||
|
||||
\verb!function Size(): SizeUInt! & O(1) \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns size of array.} \\\hline\hline
|
||||
|
||||
\verb!procedure PushBack(value: T)! & Amortized
|
||||
O(1), some operations might take O(N) time, when array needs to be reallocated, but sequence of N
|
||||
operations takes O(N) time. \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Inserts at the end of array (increases size by 1)} \\\hline\hline
|
||||
|
||||
\verb!procedure PopBack()! & O(1) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Removes element from the end of array (decreases size by 1). When array
|
||||
is empty, does nothing.} \\\hline\hline
|
||||
|
||||
\verb!procedure PushFront(value: T)! & Same as PushBack. \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Inserts at the beginning of array (increases size by 1)} \\\hline\hline
|
||||
|
||||
\verb!procedure PopFront()! & O(1) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Removes element from the beginning of array (decreases size by 1). When array
|
||||
is empty, does nothing.} \\\hline\hline
|
||||
|
||||
\verb!function IsEmpty(): boolean! & O(1) \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns true when array is empty} \\\hline\hline
|
||||
|
||||
\verb!procedure Insert(position: SizeUInt; value: T)! & O(N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Inserts value at position. When position is greater than size, puts value
|
||||
at the end of array.} \\\hline\hline
|
||||
|
||||
\verb!procedure Erase(positine: SizeUInt; value: T)! & O(N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Erases element from position. When position is outside of array does
|
||||
nothing.} \\\hline\hline
|
||||
|
||||
\verb!procedure Clear! & O(1) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Clears array (set size to zero). But doesn't free memory used by array.}
|
||||
\\\hline\hline
|
||||
|
||||
\verb!function Front: T! & O(1) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns first element from array.} \\\hline\hline
|
||||
|
||||
\verb!function Back: T! & O(1) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns last element from array.} \\\hline\hline
|
||||
|
||||
\verb!procedure Resize(num: SizeUInt)! & O(N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Changes size of array to num. Doesn't guarantte anything about value of
|
||||
newly alocated elements.} \\\hline\hline
|
||||
|
||||
\verb!procedure Reserve(num: SizeUInt)! & O(N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Alocates at least num elements for array. Usefull when you want to
|
||||
pushback big number of elements and want to avoid frequent reallocation.} \\\hline\hline
|
||||
|
||||
\verb!property item[i: SizeUInt]: T; default;! & O(1) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Property for accessing i-th element in array. Can be used just by square
|
||||
brackets (its default property).} \\\hline\hline
|
||||
|
||||
\verb!property mutable[i: SizeUInt]: T;! & O(1) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns pointer to i-th element in array. Usefull when you store records.} \\\hline
|
||||
|
||||
|
||||
|
||||
\end{longtable}
|
||||
24
packages/fcl-stl/doc/dequeexample.pp
Normal file
24
packages/fcl-stl/doc/dequeexample.pp
Normal file
@ -0,0 +1,24 @@
|
||||
uses gdeque;
|
||||
|
||||
type TDequelli = specialize TDeque<longint>;
|
||||
|
||||
var Buffer:TDequelli; i:longint;
|
||||
|
||||
begin
|
||||
Buffer := TDequelli.Create;
|
||||
{Push 5 elements at the end of array}
|
||||
for i:=1 to 5 do
|
||||
Buffer.PushBack(i);
|
||||
{change 3rd element to 47}
|
||||
Buffer[2] := 47;
|
||||
{pop last element}
|
||||
Buffer.PopBack;
|
||||
{push 3 element to front}
|
||||
for i:=1 to 3 do
|
||||
Buffer.PushFront(i*10);
|
||||
{print all elements}
|
||||
for i:=0 to Buffer.Size-1 do
|
||||
writeln(Buffer[i]);
|
||||
|
||||
Buffer.Destroy;
|
||||
end.
|
||||
63
packages/fcl-stl/doc/main.tex
Normal file
63
packages/fcl-stl/doc/main.tex
Normal file
@ -0,0 +1,63 @@
|
||||
|
||||
%% Template by Michal Forisek
|
||||
|
||||
|
||||
\documentclass[a4paper]{report}
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage{a4wide}
|
||||
\usepackage{tabularx}
|
||||
\usepackage{amsfonts}
|
||||
\usepackage{amssymb}
|
||||
\usepackage{amsmath}
|
||||
\usepackage{epsfig}
|
||||
\usepackage{color}
|
||||
\usepackage{mathrsfs}
|
||||
\usepackage{verbatim}
|
||||
\usepackage{hyperref}
|
||||
\usepackage{subfigure}
|
||||
\usepackage{float}
|
||||
\usepackage{listings}
|
||||
\usepackage{longtable}
|
||||
\input{makra.tex}
|
||||
|
||||
\renewcommand{\chaptername}{}
|
||||
\renewcommand{\thechapter}{}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\thispagestyle{empty}
|
||||
\vfill
|
||||
\vfill
|
||||
\begin{center}
|
||||
\begin{minipage}{0.8\textwidth}
|
||||
\hrule
|
||||
\bigskip\bigskip
|
||||
\centerline{\LARGE\sc FreePascal generic container library}
|
||||
\smallskip
|
||||
\centerline{(manual)}
|
||||
\smallskip
|
||||
\centerline{\url{http://code.google.com/p/stlpascal}}
|
||||
\bigskip
|
||||
\bigskip
|
||||
\bigskip\bigskip
|
||||
\hrule
|
||||
\end{minipage}
|
||||
\end{center}
|
||||
\vfill
|
||||
{~}
|
||||
\hfill version 1.0
|
||||
\eject % EOP i
|
||||
|
||||
\tableofcontents
|
||||
|
||||
\input{vector.tex}
|
||||
\input{stack.tex}
|
||||
\input{deque.tex}
|
||||
\input{queue.tex}
|
||||
\input{util.tex}
|
||||
\input{priorityqueue.tex}
|
||||
\input{arrayutils.tex}
|
||||
\input{set.tex}
|
||||
\input{map.tex}
|
||||
|
||||
\end{document}
|
||||
263
packages/fcl-stl/doc/makra.tex
Normal file
263
packages/fcl-stl/doc/makra.tex
Normal file
@ -0,0 +1,263 @@
|
||||
% vim: set fdm=marker:
|
||||
%% Original by Michal Forisek
|
||||
|
||||
|
||||
%% zakladne definicie
|
||||
\newcommand{\quoteme}[1]{\clqq#1\crqq}
|
||||
\def\todo#1{[{\color{red} TODO:} {\bf #1}]}
|
||||
\def\fixme#1{[{\color{red} FIXME:} {\bf #1}]}
|
||||
\def\verify#1{\todo{verify: #1}}
|
||||
|
||||
\def\xor{\oplus}
|
||||
\def\concat{\|}
|
||||
%\def\inr{\in_{R}}
|
||||
\def\toa #1 {\overset{#1}{\rightarrow}}
|
||||
\def\inr{\overset{\$}{\leftarrow}}
|
||||
\def\assign{\leftarrow}
|
||||
\def\send{\rightarrow}
|
||||
\def\isomorph{\cong}
|
||||
\def\nsd{NSD}
|
||||
\def\union{\cup}
|
||||
\newcommand{\unit}[1]{\ensuremath{\, \mathrm{#1}}}
|
||||
\DeclareMathOperator{\dlog}{dlog}
|
||||
|
||||
\def\compactlist{
|
||||
\setlength{\itemsep}{1pt}
|
||||
\setlength{\parskip}{0pt}
|
||||
\setlength{\parsep}{0pt}
|
||||
}
|
||||
\def\mod{\,{\rm mod}\,}
|
||||
|
||||
%%% original od Misofa:
|
||||
%% {{{
|
||||
|
||||
\catcode`\@=11
|
||||
|
||||
\def\R{{\cal R}}
|
||||
\def\cent{{c\kern-0.3em|\kern0.1em}}
|
||||
\def\N{{N}} % FIXME FIXME
|
||||
|
||||
\let\eps=\varepsilon
|
||||
|
||||
\def\relupdown#1#2#3{\mathrel{\mathop{#1}\limits^{#2}_{#3}} }
|
||||
|
||||
\let\then=\Rightarrow
|
||||
\let\neht=\Leftarrow
|
||||
|
||||
\def\krok#1{\relupdown{\Longrightarrow}{}{#1}}
|
||||
\def\thenrm{\relupdown{\Longrightarrow}{}{rm}}
|
||||
|
||||
\def\bicik{\upharpoonright}
|
||||
\def\B{{\mathbf B}}
|
||||
\def\kodTS#1{{\tt <}#1{\tt >}}
|
||||
|
||||
\newtheorem{definicia}{Definícia}[section]
|
||||
\newtheorem{HLPpoznamka}{Poznámka}[section]
|
||||
\newtheorem{HLPpriklad}{Príklad}[section]
|
||||
\newtheorem{HLPcvicenie}[HLPpriklad]{Cvičenie}
|
||||
\newtheorem{zadanie}{Úloha}[section]
|
||||
\newenvironment{poznamka}{\begin{HLPpoznamka}\rm}{\end{HLPpoznamka}}
|
||||
\newenvironment{priklad}{\begin{HLPpriklad}\rm}{\end{HLPpriklad}}
|
||||
\newenvironment{cvicenie}{\begin{HLPcvicenie}\rm}{\end{HLPcvicenie}}
|
||||
\newtheorem{veta}{Veta}[section]
|
||||
\newtheorem{lema}[veta]{Lema}
|
||||
\newtheorem{dosledok}[veta]{Dôsledok}
|
||||
\newtheorem{teza}[veta]{Téza}
|
||||
% \newtheorem{dokaz}{Dôkaz}[section]
|
||||
|
||||
\long\def\odsadene#1{
|
||||
\leftskip=\parindent
|
||||
\parindent=0pt
|
||||
\vskip-5pt
|
||||
|
||||
\parskip=5pt
|
||||
#1
|
||||
\parskip=0pt
|
||||
|
||||
\parindent=\leftskip
|
||||
\leftskip=0pt
|
||||
|
||||
} % end \odsadene
|
||||
|
||||
|
||||
|
||||
|
||||
%%%%%%%%%%% PROSTREDIE PRE PISANIE KOMENTAROV
|
||||
|
||||
%\newenvironment{komentar}{%
|
||||
%\vskip\baselineskip
|
||||
%\tabularx{0.95\textwidth}{|X|}
|
||||
%\sl
|
||||
%}
|
||||
%{\endtabularx
|
||||
%\vskip\baselineskip
|
||||
%}
|
||||
|
||||
\newenvironment{komentar}{%
|
||||
\vskip\baselineskip\noindent
|
||||
\tabularx{\textwidth}{>{\hsize=.2\hsize}X>{\hsize=1.8\hsize}X}
|
||||
\sl ~ & \sl
|
||||
}
|
||||
{\endtabularx
|
||||
\vskip\baselineskip
|
||||
}
|
||||
|
||||
%\newenvironment{komentar}{%
|
||||
%\vskip\baselineskip
|
||||
%\trivlist\vspace{-4pt}\raggedleft\item\relax\tabularx{0.9\textwidth}{X}\sl}
|
||||
%{\endtabularx\vspace{-4pt}\endtrivlist
|
||||
%\vskip\baselineskip
|
||||
%}
|
||||
|
||||
\newenvironment{dokaz}{\trivlist
|
||||
\item[\hskip \labelsep{\bfseries Dôkaz.}]}{\endtrivlist}
|
||||
|
||||
%\newenvironment{dokaz}{%
|
||||
%\vskip\baselineskip\noindent
|
||||
%\tabularx{\textwidth}{||X||}
|
||||
%\sl
|
||||
%}
|
||||
%{\endtabularx
|
||||
%\vskip\baselineskip
|
||||
%}
|
||||
|
||||
%%%%%%%%%%% PROSTREDIE PRE MOJE ITEMIZE
|
||||
|
||||
\newenvironment{myitemize}{%
|
||||
\begin{itemize}
|
||||
\itemsep-3pt
|
||||
}
|
||||
{\end{itemize}
|
||||
}
|
||||
|
||||
%%%%%%%%%%% MATICKE MAKRA
|
||||
|
||||
\font\tenrm=csr10
|
||||
|
||||
\def\eps{\varepsilon}
|
||||
% \def\R{{\mathbb R}}
|
||||
\def\lvec#1{\overrightarrow{#1}}
|
||||
\def\uhol{{\measuredangle}}
|
||||
\def\then{\Rightarrow}
|
||||
% \def\lg{{\rm lg}}
|
||||
\def\lg{\log_2}
|
||||
%\def\div{\mathbin{\rm div}}
|
||||
\def\div{{\rm div}}
|
||||
|
||||
%%%%%%%%%%% PDF
|
||||
|
||||
\newif\ifpdf
|
||||
\ifx\pdfoutput\undefined
|
||||
\pdffalse
|
||||
\else
|
||||
\pdfoutput=1 \pdftrue
|
||||
\fi
|
||||
|
||||
%%%%%%%%%%% OBRAZKY
|
||||
|
||||
\newcommand{\myincludegraphics}[2][]{\includegraphics[#1]{images/#2}}
|
||||
|
||||
%%%%%%%%%%% SLOVNICEK
|
||||
|
||||
\openout2=\jobname.slo
|
||||
|
||||
\newcommand{\definuj}[3][]{%
|
||||
\def\tmpvoid{}\def\tmpfirst{#1}%
|
||||
\ifx\tmpvoid\tmpfirst%
|
||||
{\sl #2}\label{definicia:#2}\write2{#2 & #3 & \pageref{definicia:#2} \cr}%
|
||||
\else%
|
||||
{\sl #2}\label{definicia:#2}\write2{#1 & #3 & \pageref{definicia:#2} \cr}%
|
||||
\fi}
|
||||
|
||||
\newcommand{\definujsilent}[2]{%
|
||||
\label{definicia:#1}\write2{#1 & #2 & \pageref{definicia:#1} \cr}%
|
||||
}
|
||||
|
||||
\newcommand\myglossary{
|
||||
\immediate\closeout2
|
||||
%\if@twocolumn\@restonecoltrue\onecolumn\else\@restonecolfalse\fi
|
||||
\chapter{Slovníček pojmov}
|
||||
\begin{tabular}{|l|l|r|}
|
||||
\hline
|
||||
{\bfseries slovenský pojem} & {\bfseries anglický preklad} & {\bfseries str.} \\
|
||||
\hline
|
||||
\InputIfFileExists{\jobname.srs}{}{~ & ~ & ~ \\}
|
||||
\hline
|
||||
\end{tabular}
|
||||
%\if@restonecol\twocolumn\fi
|
||||
}
|
||||
|
||||
%%%%%%%%%%% UVODZOVKY
|
||||
|
||||
\catcode`\"=13
|
||||
\def "{\begingroup\clqq\def "{\endgroup\crqq}}
|
||||
\def\dospecials{\do\ \do\\\do\{\do\}\do\$\do\&%
|
||||
\do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~\do\"}
|
||||
|
||||
%%%%%%%%%%% DANGER BENDS
|
||||
|
||||
\font\manual=manfnt % font used for the METAFONT logo, etc.
|
||||
\def\dbend{{\manual\char127}} % dangerous bend sign
|
||||
|
||||
\newlength{\bendwidth} \settowidth{\bendwidth}{\dbend} \newlength{\hangwidth}
|
||||
|
||||
\def\hangone{%
|
||||
\hangwidth=\bendwidth%
|
||||
\advance\hangwidth 5pt%
|
||||
\hangindent\hangwidth%
|
||||
}
|
||||
\def\hangtwo{%
|
||||
\hangwidth=\bendwidth%
|
||||
\multiply\hangwidth 2%
|
||||
\advance\hangwidth 6pt%
|
||||
\hangindent\hangwidth%
|
||||
}
|
||||
|
||||
\def\medbreak{\par\ifdim\lastskip<\medskipamount \removelastskip\penalty-100\medskip\fi}
|
||||
\let\endgraf=\par
|
||||
|
||||
\def\d@nger{\medbreak\begingroup\clubpenalty=10000
|
||||
%\def\d@nger{\begingroup\clubpenalty=10000
|
||||
% \def\par{\endgraf\endgroup\medbreak} \noindent\hangone\hangafter=-2
|
||||
\def\par{\endgraf\endgroup} \noindent\hangone\hangafter=-2
|
||||
\hbox to0pt{\hskip-\hangindent\dbend\hfill}}
|
||||
\outer\def\danger{\d@nger}
|
||||
|
||||
\def\dd@nger{\medbreak\begingroup\clubpenalty=10000
|
||||
% \def\par{\endgraf\endgroup\medbreak} \noindent\hangtwo\hangafter=-2
|
||||
\def\par{\endgraf\endgroup} \noindent\hangtwo\hangafter=-2
|
||||
\hbox to0pt{\hskip-\hangindent\dbend\kern1pt\dbend\hfill}}
|
||||
\outer\def\ddanger{\dd@nger}
|
||||
|
||||
\def\enddanger{\endgraf\endgroup} % omits the \medbreak
|
||||
\def\enddangerhop{\endgraf\endgroup\medbreak}
|
||||
|
||||
|
||||
|
||||
|
||||
\def\@nakedcite#1#2{{#1\if@tempswa , #2\fi}}
|
||||
\DeclareRobustCommand\nakedcite{%
|
||||
\@ifnextchar [{\@tempswatrue\@nakedcitex}{\@tempswafalse\@nakedcitex[]}}
|
||||
\def\@nakedcitex[#1]#2{%
|
||||
\let\@citea\@empty
|
||||
\@nakedcite{\@for\@citeb:=#2\do
|
||||
{\@citea\def\@citea{,\penalty\@m\ }%
|
||||
\edef\@citeb{\expandafter\@firstofone\@citeb\@empty}%
|
||||
\if@filesw\immediate\write\@auxout{\string\citation{\@citeb}}\fi
|
||||
\@ifundefined{b@\@citeb}{\mbox{\reset@font\bfseries ?}%
|
||||
\G@refundefinedtrue
|
||||
\@latex@warning
|
||||
{Citation `\@citeb' on page \thepage \space undefined}}%
|
||||
{\hbox{\csname b@\@citeb\endcsname}} }}{#1}}
|
||||
|
||||
\long\def\FIXME#1{
|
||||
\begin{center}
|
||||
\begin{minipage}{0.8\textwidth}
|
||||
{\bf FIXME:~}\sl #1
|
||||
\end{minipage}
|
||||
\end{center}
|
||||
}
|
||||
|
||||
|
||||
\catcode`\@=12
|
||||
%% }}}
|
||||
87
packages/fcl-stl/doc/map.tex
Normal file
87
packages/fcl-stl/doc/map.tex
Normal file
@ -0,0 +1,87 @@
|
||||
\chapter{TMap}
|
||||
|
||||
Implements container for ordered associative array with unique keys.
|
||||
Takes 3 arguments for specialization, first one is type of keys, second one is type of values, third
|
||||
one is comparator class for keys.
|
||||
Usage example:
|
||||
|
||||
\lstinputlisting[language=Pascal]{mapexample.pp}
|
||||
|
||||
Some methods return type TMSet.PNode. Usefull fields are Data.Key, Data.Value, for retrieving
|
||||
actual Key and Value from node. This node can be also used for navigation between elements by methods of set class.
|
||||
You can also change value in node (but not key).
|
||||
(But don't do anything else with it, you can lose data integrity.)
|
||||
|
||||
Memory complexity:
|
||||
Size of stored base + constant overhead for each stored element (3 pointers + one boolean).
|
||||
|
||||
Members list:
|
||||
|
||||
\begin{longtable}{|m{10cm}|m{5cm}|}
|
||||
\hline
|
||||
Method & Complexity guarantees \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Description} \\ \hline\hline
|
||||
|
||||
\verb!Create! & O(1) \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Constructor. Creates empty map.} \\ \hline\hline
|
||||
|
||||
\verb!function Size(): SizeUInt! & O(1) \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns number of elements in map.} \\\hline\hline
|
||||
|
||||
\verb!procedure Insert(key: TKey; value: TValue)! &
|
||||
O(lg N), N is number of elements in map \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Inserts key value pair into map. If key was already there, it will have
|
||||
new value assigned.} \\\hline\hline
|
||||
|
||||
\verb!procedure Delete(key: TKey)! &
|
||||
O(lg N) \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Deletes key (and associated value) from map. If element is not in map, nothing happens.} \\\hline\hline
|
||||
|
||||
\verb!function Find(key: T):TMSet.PNode! & O(lg N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Searches for key in map. If value is not there returns nil. Otherwise
|
||||
returns pointer to tree node (type TMSet.PNode), which can be used for retrieving data from map.} \\\hline\hline
|
||||
|
||||
\verb!function FindLess(key: T):TMSet.PNode! & O(lg N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Searches for greatest element less than key in map. If such element is not there returns nil. Otherwise
|
||||
returns pointer to tree node (type TMSet.PNode), which can be used for retrieving data from map.} \\\hline\hline
|
||||
|
||||
\verb!function FindLessEqual(key: T):TMSet.PNode! & O(lg N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Searches for greatest element less or equal than key in map. If such element is not there returns nil. Otherwise
|
||||
returns pointer to tree node (type TMSet.PNode), which can be used for retrieving data from map.} \\\hline\hline
|
||||
|
||||
\verb!function FindGreater(key: T):TMSet.PNode! & O(lg N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Searches for smallest element greater than key in map. If such element is not there returns nil. Otherwise
|
||||
returns pointer to tree node (type TMSet.PNode), which can be used for retrieving data from map.} \\\hline\hline
|
||||
|
||||
\verb!function FindGreaterEqual(key: T):TMSet.PNode! & O(lg N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Searches for smallest element greater or equal than key in map. If such element is not there returns nil. Otherwise
|
||||
returns pointer to tree node (type TMSet.PNode), which can be used for retrieving data from map.} \\\hline\hline
|
||||
|
||||
\verb!function Min:TMSet.PNode! & O(lg N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns node containing smallest key of map. If map is empty returns
|
||||
nil.} \\\hline\hline
|
||||
|
||||
\verb!function Max:TMSet.PNode! & O(lg N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns node containing largest key of map. If map is empty returns
|
||||
nil.} \\\hline\hline
|
||||
|
||||
\verb!function Next(x:TMSet.PNode):TMSet.PNode! & O(lg N) worst case, but traversal from smallest element to
|
||||
largest takes O(N) time \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns successor of x. If x is largest key of map, returns nil.} \\\hline\hline
|
||||
|
||||
\verb!function Prev(x:TMSet.PNode):TMSet.PNode! & O(lg N) worst case, but traversal from largest element to
|
||||
smallest takes O(N) time \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns predecessor of x. If x is smallest key of map, returns nil.} \\\hline\hline
|
||||
|
||||
\verb!function IsEmpty(): boolean! & O(1) \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns true when map is empty.} \\\hline
|
||||
|
||||
\verb!function GetValue(key:TKey):TValue! & O(lg N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns value associated with key. Is key isn't in map crashes.} \\\hline
|
||||
|
||||
\verb!property item[i: Key]: TValue; default;! & O(ln N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Property for accessing key i in map. Can be used just by square
|
||||
brackets (its default property).} \\\hline\hline
|
||||
|
||||
|
||||
\end{longtable}
|
||||
24
packages/fcl-stl/doc/mapexample.pp
Normal file
24
packages/fcl-stl/doc/mapexample.pp
Normal file
@ -0,0 +1,24 @@
|
||||
uses gmap, gutil;
|
||||
|
||||
type lesslli=specialize TLess<longint>;
|
||||
maplli=specialize TMap<longint, longint, lesslli>;
|
||||
|
||||
var data:maplli; i:longint; iterator:maplli.TMSet.PNode;
|
||||
|
||||
begin
|
||||
data:=maplli.Create;
|
||||
|
||||
for i:=0 to 10 do
|
||||
data[i]:=10*i;
|
||||
|
||||
{Iteration through elements}
|
||||
iterator:=data.Min;
|
||||
while iterator<>nil do begin
|
||||
writeln(iterator^.Data.Key, ' ', iterator^.Data.Value);
|
||||
iterator:=data.next(iterator);
|
||||
end;
|
||||
|
||||
writeln(data.FindLess(7)^.Data.Value);
|
||||
|
||||
data.Destroy;
|
||||
end.
|
||||
44
packages/fcl-stl/doc/priorityqueue.tex
Normal file
44
packages/fcl-stl/doc/priorityqueue.tex
Normal file
@ -0,0 +1,44 @@
|
||||
\chapter{TPriorityQueue}
|
||||
|
||||
Implements priority queue. It's container which allow insertions of elements and then retrieval of
|
||||
the biggest one.
|
||||
|
||||
For specialization it needs two arguements. First is the type T of stored element. Second one is type
|
||||
comparator class, which should have class function \verb!c(a,b: T):boolean! which return true, when
|
||||
a is stricly less then b (or in other words, a should be poped out after b).
|
||||
|
||||
Usage example:
|
||||
|
||||
\lstinputlisting[language=Pascal]{priorityqueueexample.pp}
|
||||
|
||||
Memory complexity:
|
||||
Since underlaying structure is TVector, memory complexity is same.
|
||||
|
||||
Members list:
|
||||
|
||||
\begin{longtable}{|m{10cm}|m{5cm}|}
|
||||
\hline
|
||||
Method & Complexity guarantees \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Description} \\ \hline\hline
|
||||
|
||||
\verb!Create! & O(1) \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Constructor. Creates empty priority queue.} \\ \hline\hline
|
||||
|
||||
\verb!function Size(): SizeUInt! & O(1) \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns number of elements in priority queue.} \\\hline\hline
|
||||
|
||||
\verb!procedure Push(value: T)! & Amortized
|
||||
O(lg N), some operations might take O(N) time, when underlaying array needs to be reallocated, but sequence of N
|
||||
operations takes O(N lg N) time. \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Inserts element at the back of queue.} \\\hline\hline
|
||||
|
||||
\verb!procedure Pop()! & O(lg N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Removes the biggest element from queue. If queue is empty does nothing.} \\\hline\hline
|
||||
|
||||
\verb!function IsEmpty(): boolean! & O(1) \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns true when queue is empty.} \\\hline\hline
|
||||
|
||||
\verb!function Top: T! & O(1) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns the biggest element from queue.} \\\hline
|
||||
|
||||
\end{longtable}
|
||||
30
packages/fcl-stl/doc/priorityqueueexample.pp
Normal file
30
packages/fcl-stl/doc/priorityqueueexample.pp
Normal file
@ -0,0 +1,30 @@
|
||||
{$mode objfpc}
|
||||
|
||||
uses gpriorityqueue;
|
||||
|
||||
type
|
||||
lesslli = class
|
||||
public
|
||||
class function c(a,b: longint):boolean;inline;
|
||||
end;
|
||||
|
||||
class function lesslli.c(a,b: longint):boolean;inline;
|
||||
begin
|
||||
c:=a<b;
|
||||
end;
|
||||
|
||||
type priorityqueuelli = specialize TPriorityQueue<longint, lesslli>;
|
||||
|
||||
var data:priorityqueuelli; i:longint;
|
||||
|
||||
begin
|
||||
data:=priorityqueuelli.Create;
|
||||
for i:=1 to 10 do
|
||||
data.Push(random(1000));
|
||||
while not data.IsEmpty do begin
|
||||
writeln(data.Top);
|
||||
data.Pop;
|
||||
end;
|
||||
|
||||
data.Destroy;
|
||||
end.
|
||||
39
packages/fcl-stl/doc/queue.tex
Normal file
39
packages/fcl-stl/doc/queue.tex
Normal file
@ -0,0 +1,39 @@
|
||||
\chapter{TQueue}
|
||||
|
||||
Implements queue.
|
||||
|
||||
Usage example:
|
||||
|
||||
\lstinputlisting[language=Pascal]{queueexample.pp}
|
||||
|
||||
Memory complexity:
|
||||
Since underlaying structure is TDeque, memory complexity is same.
|
||||
|
||||
Members list:
|
||||
|
||||
\begin{longtable}{|m{10cm}|m{5cm}|}
|
||||
\hline
|
||||
Method & Complexity guarantees \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Description} \\ \hline\hline
|
||||
|
||||
\verb!Create! & O(1) \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Constructor. Creates empty queue.} \\ \hline\hline
|
||||
|
||||
\verb!function Size(): SizeUInt! & O(1) \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns number of elements in queue.} \\\hline\hline
|
||||
|
||||
\verb!procedure Push(value: T)! & Amortized
|
||||
O(1), some operations might take O(N) time, when array needs to be reallocated, but sequence of N
|
||||
operations takes O(N) time \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Inserts element at the back of queue.} \\\hline\hline
|
||||
|
||||
\verb!procedure Pop()! & O(1) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Removes element from the beginning of queue. If queue is empty does nothing.} \\\hline\hline
|
||||
|
||||
\verb!function IsEmpty(): boolean! & O(1) \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns true when queue is empty.} \\\hline\hline
|
||||
|
||||
\verb!function Front: T! & O(1) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns the first element from queue.} \\\hline
|
||||
|
||||
\end{longtable}
|
||||
17
packages/fcl-stl/doc/queueexample.pp
Normal file
17
packages/fcl-stl/doc/queueexample.pp
Normal file
@ -0,0 +1,17 @@
|
||||
uses gqueue;
|
||||
|
||||
type queuelli = specialize TQueue<longint>;
|
||||
|
||||
var data:queuelli; i:longint;
|
||||
|
||||
begin
|
||||
data:=queuelli.Create;
|
||||
for i:=1 to 10 do
|
||||
data.Push(10*i);
|
||||
while not data.IsEmpty do begin
|
||||
writeln(data.Front);
|
||||
data.Pop;
|
||||
end;
|
||||
|
||||
data.Destroy;
|
||||
end.
|
||||
76
packages/fcl-stl/doc/set.tex
Normal file
76
packages/fcl-stl/doc/set.tex
Normal file
@ -0,0 +1,76 @@
|
||||
\chapter{TSet}
|
||||
|
||||
Implements container for storing ordered set of unique elements.
|
||||
Takes 2 arguments for specialization, first one is type of elements, second one is comparator class.
|
||||
Usage example:
|
||||
|
||||
\lstinputlisting[language=Pascal]{setexample.pp}
|
||||
|
||||
Some methods return type of PNode. It has field Data, which can be used for retrieving data from
|
||||
that node. This node can be also used for navigation between elements by methods of set class.
|
||||
(But don't do anything else with it, you can lose data integrity.)
|
||||
|
||||
Memory complexity:
|
||||
Size of stored base + constant overhead for each stored element (3 pointers + one boolean).
|
||||
|
||||
Members list:
|
||||
|
||||
\begin{longtable}{|m{10cm}|m{5cm}|}
|
||||
\hline
|
||||
Method & Complexity guarantees \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Description} \\ \hline\hline
|
||||
|
||||
\verb!Create! & O(1) \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Constructor. Creates empty set.} \\ \hline\hline
|
||||
|
||||
\verb!function Size(): SizeUInt! & O(1) \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns number of elements in set.} \\\hline\hline
|
||||
|
||||
\verb!procedure Insert(value: T)! &
|
||||
O(lg N), N is number of elements in set \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Inserts element into set.} \\\hline\hline
|
||||
|
||||
\verb!procedure Delete(value: T)! &
|
||||
O(lg N), N is number of elements in set \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Deletes value from set. If element is not in set, nothing happens.} \\\hline\hline
|
||||
|
||||
\verb!function Find(value: T):PNode! & O(lg N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Searches for value in set. If value is not there returns nil. Otherwise
|
||||
returns pointer to tree node (type PNode), which can be used for retrieving data from set.} \\\hline\hline
|
||||
|
||||
\verb!function FindLess(value: T):PNode! & O(lg N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Searches for greatest element less than value in set. If such element is not there returns nil. Otherwise
|
||||
returns pointer to tree node (type PNode), which can be used for retrieving data from set.} \\\hline\hline
|
||||
|
||||
\verb!function FindLessEqual(value: T):PNode! & O(lg N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Searches for greatest element less or equal than value in set. If such element is not there returns nil. Otherwise
|
||||
returns pointer to tree node (type PNode), which can be used for retrieving data from set.} \\\hline\hline
|
||||
|
||||
\verb!function FindGreater(value: T):PNode! & O(lg N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Searches for smallest element greater than value in set. If such element is not there returns nil. Otherwise
|
||||
returns pointer to tree node (type PNode), which can be used for retrieving data from set.} \\\hline\hline
|
||||
|
||||
\verb!function FindGreaterEqual(value: T):PNode! & O(lg N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Searches for smallest element greater or equal than value in set. If such element is not there returns nil. Otherwise
|
||||
returns pointer to tree node (type PNode), which can be used for retrieving data from set.} \\\hline\hline
|
||||
|
||||
\verb!function Min:PNode! & O(lg N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns node containing smallest element of set. If set is empty returns
|
||||
nil.} \\\hline\hline
|
||||
|
||||
\verb!function Max:PNode! & O(lg N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns node containing largest element of set. If set is empty returns
|
||||
nil.} \\\hline\hline
|
||||
|
||||
\verb!function Next(x:PNode):PNode! & O(lg N) worst case, but traversal from smallest element to
|
||||
largest takes O(N) time \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns successor of x. If x is largest element of set, returns nil.} \\\hline\hline
|
||||
|
||||
\verb!function Prev(x:PNode):PNode! & O(lg N) worst case, but traversal from largest element to
|
||||
smallest takes O(N) time \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns predecessor of x. If x is smallest element of set, returns nil.} \\\hline\hline
|
||||
|
||||
\verb!function IsEmpty(): boolean! & O(1) \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns true when set is empty.} \\\hline
|
||||
|
||||
\end{longtable}
|
||||
24
packages/fcl-stl/doc/setexample.pp
Normal file
24
packages/fcl-stl/doc/setexample.pp
Normal file
@ -0,0 +1,24 @@
|
||||
uses gset, gutil;
|
||||
|
||||
type lesslli=specialize TLess<longint>;
|
||||
setlli=specialize TSet<longint, lesslli>;
|
||||
|
||||
var data:setlli; i:longint; iterator:setlli.PNode;
|
||||
|
||||
begin
|
||||
data:=setlli.Create;
|
||||
|
||||
for i:=0 to 10 do
|
||||
data.insert(i);
|
||||
|
||||
{Iteration through elements}
|
||||
iterator:=data.Min;
|
||||
while iterator<>nil do begin
|
||||
writeln(iterator^.Data);
|
||||
iterator:=data.next(iterator);
|
||||
end;
|
||||
|
||||
writeln(data.FindLess(7)^.Data);
|
||||
|
||||
data.Destroy;
|
||||
end.
|
||||
20
packages/fcl-stl/doc/sortingexample.pp
Normal file
20
packages/fcl-stl/doc/sortingexample.pp
Normal file
@ -0,0 +1,20 @@
|
||||
uses garrayutils, gutil, gvector;
|
||||
|
||||
type vectorlli = specialize TVector<longint>;
|
||||
lesslli = specialize TLess<longint>;
|
||||
sortlli = specialize TOrderingArrayUtils<vectorlli, longint, lesslli>;
|
||||
|
||||
var data:vectorlli; n,i:longint;
|
||||
|
||||
begin
|
||||
randomize;
|
||||
data:=vectorlli.Create;
|
||||
read(n);
|
||||
for i:=1 to n do
|
||||
data.pushback(random(1000000000));
|
||||
sortlli.sort(data, data.size());
|
||||
for i:=1 to n do
|
||||
writeln(data[i-1]);
|
||||
|
||||
data.Destroy;
|
||||
end.
|
||||
39
packages/fcl-stl/doc/stack.tex
Normal file
39
packages/fcl-stl/doc/stack.tex
Normal file
@ -0,0 +1,39 @@
|
||||
\chapter{TStack}
|
||||
|
||||
Implements stack.
|
||||
|
||||
Usage example:
|
||||
|
||||
\lstinputlisting[language=Pascal]{stackexample.pp}
|
||||
|
||||
Memory complexity:
|
||||
Since underlaying structure is TVector, memory complexity is same.
|
||||
|
||||
Members list:
|
||||
|
||||
\begin{longtable}{|m{10cm}|m{5cm}|}
|
||||
\hline
|
||||
Method & Complexity guarantees \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Description} \\ \hline\hline
|
||||
|
||||
\verb!Create! & O(1) \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Constructor. Creates empty stack.} \\ \hline\hline
|
||||
|
||||
\verb!function Size(): SizeUInt! & O(1) \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns number of elements in stack.} \\\hline\hline
|
||||
|
||||
\verb!procedure Push(value: T)! & Amortized
|
||||
O(1), some operations might take O(N) time, when array needs to be reallocated, but sequence of N
|
||||
operations takes O(N) time \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Inserts element on the top of stack.} \\\hline\hline
|
||||
|
||||
\verb!procedure Pop()! & O(1) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Removes element from the top of stack. If stack is empty does nothing.} \\\hline\hline
|
||||
|
||||
\verb!function IsEmpty(): boolean! & O(1) \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns true when stack is empty} \\\hline\hline
|
||||
|
||||
\verb!function Top: T! & O(1) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns top element from stack.} \\\hline
|
||||
|
||||
\end{longtable}
|
||||
17
packages/fcl-stl/doc/stackexample.pp
Normal file
17
packages/fcl-stl/doc/stackexample.pp
Normal file
@ -0,0 +1,17 @@
|
||||
uses gstack;
|
||||
|
||||
type stacklli = specialize TStack<longint>;
|
||||
|
||||
var data:stacklli; i:longint;
|
||||
|
||||
begin
|
||||
data:=stacklli.Create;
|
||||
for i:=1 to 10 do
|
||||
data.Push(10*i);
|
||||
while not data.IsEmpty do begin
|
||||
writeln(data.Top);
|
||||
data.Pop;
|
||||
end;
|
||||
|
||||
data.Destroy;
|
||||
end.
|
||||
9
packages/fcl-stl/doc/util.tex
Normal file
9
packages/fcl-stl/doc/util.tex
Normal file
@ -0,0 +1,9 @@
|
||||
\chapter{TLess, TGreater}
|
||||
|
||||
Comparators classes. Can be used in PriorityQueue and Sorting as comparator functions.
|
||||
TLess is used for ordering from smallest element to largest, TGreater is used for oposite ordering.
|
||||
|
||||
%Usage example:
|
||||
|
||||
%\lstinputlisting[language=Pascal]{queueexample.pp}
|
||||
|
||||
73
packages/fcl-stl/doc/vector.tex
Normal file
73
packages/fcl-stl/doc/vector.tex
Normal file
@ -0,0 +1,73 @@
|
||||
\chapter{TVector}
|
||||
|
||||
Implements selfresizing array. Indexing is 0-based.
|
||||
|
||||
Usage example:
|
||||
|
||||
\lstinputlisting[language=Pascal]{vectorexample.pp}
|
||||
|
||||
Memory complexity:
|
||||
Uses at most 3times bigger memory than maximal array size (this is only case during reallocation).
|
||||
Normal consumption is at most twice as maximal array size.
|
||||
|
||||
Members list:
|
||||
|
||||
\begin{longtable}{|m{10cm}|m{5cm}|}
|
||||
\hline
|
||||
Method & Complexity guarantees \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Description} \\ \hline\hline
|
||||
|
||||
\verb!Create! & O(1) \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Constructor. Creates empty array.} \\ \hline\hline
|
||||
|
||||
\verb!function Size(): SizeUInt! & O(1) \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns size of array.} \\\hline\hline
|
||||
|
||||
\verb!procedure PushBack(value: T)! & Amortized
|
||||
O(1), some operations might take O(N) time, when array needs to be reallocated, but sequence of N
|
||||
operations takes O(N) time \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Inserts at the end of array (increases size by 1)} \\\hline\hline
|
||||
|
||||
\verb!procedure PopBack()! & O(1) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Removes element from the end of array (decreases size by 1). When array
|
||||
is empty, does nothing.} \\\hline\hline
|
||||
|
||||
\verb!function IsEmpty(): boolean! & O(1) \\ \hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns true when array is empty} \\\hline\hline
|
||||
|
||||
\verb!procedure Insert(position: SizeUInt; value: T)! & O(N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Inserts value at position. When position is greater than size, puts value
|
||||
at the end of array.} \\\hline\hline
|
||||
|
||||
\verb!procedure Erase(positine: SizeUInt; value: T)! & O(N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Erases element from position. When position is outside of array does
|
||||
nothing.} \\\hline\hline
|
||||
|
||||
\verb!procedure Clear! & O(1) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Clears array (set size to zero). But doesn't free memory used by array.}
|
||||
\\\hline\hline
|
||||
|
||||
\verb!function Front: T! & O(1) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns first element from array.} \\\hline\hline
|
||||
|
||||
\verb!function Back: T! & O(1) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns last element from array.} \\\hline\hline
|
||||
|
||||
\verb!procedure Resize(num: SizeUInt)! & O(N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Changes size of array to num. Doesn't guarantte anything about value of
|
||||
newly alocated elements.} \\\hline\hline
|
||||
|
||||
\verb!procedure Reserve(num: SizeUInt)! & O(N) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Alocates at least num elements for array. Usefull when you want to
|
||||
pushback big number of elements and want to avoid frequent reallocation.} \\\hline\hline
|
||||
|
||||
\verb!property item[i: SizeUInt]: T; default;! & O(1) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Property for accessing i-th element in array. Can be used just by square
|
||||
brackets (its default property).} \\\hline\hline
|
||||
|
||||
\verb!property mutable[i: SizeUInt]: T;! & O(1) \\\hline
|
||||
\multicolumn{2}{|m{15cm}|}{Returns pointer to i-th element in array. Usefull when you store records.} \\\hline
|
||||
|
||||
|
||||
|
||||
\end{longtable}
|
||||
21
packages/fcl-stl/doc/vectorexample.pp
Normal file
21
packages/fcl-stl/doc/vectorexample.pp
Normal file
@ -0,0 +1,21 @@
|
||||
uses gvector;
|
||||
|
||||
type TVectorlli = specialize TVector<longint>;
|
||||
|
||||
var Buffer:TVectorlli; i:longint;
|
||||
|
||||
begin
|
||||
Buffer := TVectorlli.Create;
|
||||
{Push 5 elements at the end of array}
|
||||
for i:=1 to 5 do
|
||||
Buffer.PushBack(i);
|
||||
{change 3rd element to 47}
|
||||
Buffer[2] := 47;
|
||||
{pop last element}
|
||||
Buffer.PopBack;
|
||||
{print all elements}
|
||||
for i:=0 to Buffer.Size-1 do
|
||||
writeln(Buffer[i]);
|
||||
|
||||
Buffer.Destroy;
|
||||
end.
|
||||
215
packages/fcl-stl/src/garrayutils.pp
Normal file
215
packages/fcl-stl/src/garrayutils.pp
Normal file
@ -0,0 +1,215 @@
|
||||
{$mode objfpc}
|
||||
|
||||
unit garrayutils;
|
||||
|
||||
interface
|
||||
|
||||
const MaxDepth=60;
|
||||
const InsertSortThreshold=16;
|
||||
|
||||
{TCompare is comparing class, which should have class method c(a,b:TValue):boolean, which returns true if a is less than b}
|
||||
type
|
||||
generic TOrderingArrayUtils<TArr, Tvalue, TCompare>=class
|
||||
private
|
||||
class procedure Sortrange(var Arr:TArr; Start,Fin,d:SizeUInt);
|
||||
class procedure HeapSort(var Arr:TArr; Start,Fin:SizeUInt);
|
||||
class procedure InsertSort(var Arr:TArr; Start,Fin:SizeUInt);
|
||||
class function Left(a:SizeUInt):SizeUInt;inline;
|
||||
class function Right(a:SizeUInt):SizeUInt;inline;
|
||||
class procedure Heapify(var Arr: TArr; Position:SizeUInt; Start,Fin:SizeUInt);
|
||||
class function Parent(a:SizeUInt):SizeUInt;inline;
|
||||
public
|
||||
class procedure Sort(var Arr: TArr; size:SizeUInt);
|
||||
end;
|
||||
|
||||
generic TArrayUtils<TArr, Tvalue>=class
|
||||
public
|
||||
class procedure RandomShuffle(Arr: TArr; size: SizeUInt);
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
class function TOrderingArrayUtils.Left(a:SizeUInt):SizeUInt;inline;
|
||||
begin
|
||||
Left:=((a+1)shl 1)-1;
|
||||
end;
|
||||
|
||||
class function TOrderingArrayUtils.Right(a:SizeUInt):SizeUInt;inline;
|
||||
begin
|
||||
Right:=(a+1) shl 1;
|
||||
end;
|
||||
|
||||
class function TOrderingArrayUtils.Parent(a:SizeUInt):SizeUInt;inline;
|
||||
begin
|
||||
Parent:=(a-1)shr 1;
|
||||
end;
|
||||
|
||||
class procedure TOrderingArrayUtils.Heapify(var Arr: TArr; Position:SizeUInt; Start,Fin:SizeUInt);
|
||||
var mpos,l,r:SizeUInt; temp:TValue;
|
||||
begin
|
||||
while(true) do
|
||||
begin
|
||||
mpos:=Position;
|
||||
l:=Left(Position-Start)+Start;
|
||||
r:=Right(Position-Start)+Start;
|
||||
if (l<Fin) AND (TCompare.c(Arr[mpos],Arr[l])) then
|
||||
mpos:=l;
|
||||
if (r<Fin) AND (TCompare.c(Arr[mpos],Arr[r])) then
|
||||
mpos:=r;
|
||||
if mpos = Position then break;
|
||||
|
||||
temp:=Arr[Position];
|
||||
Arr[Position]:=Arr[mpos];
|
||||
Arr[mpos]:=temp;
|
||||
Position:=mpos;
|
||||
end;
|
||||
end;
|
||||
|
||||
class procedure TOrderingArrayUtils.Sort(var Arr:TArr; size:SizeUInt);inline;
|
||||
begin
|
||||
Sortrange(Arr,0,size,0);
|
||||
InsertSort(Arr,0,size);
|
||||
end;
|
||||
|
||||
class procedure TOrderingArrayUtils.Sortrange(var Arr:TArr; Start,Fin,d:SizeUInt);
|
||||
var pivot,temp:Tvalue; i,j,k,l:SizeUInt;
|
||||
begin
|
||||
if (Fin-Start) <= InsertSortThreshold then
|
||||
begin
|
||||
InsertSort(Arr,Start,Fin);
|
||||
exit;
|
||||
end;
|
||||
if d>=maxdepth then
|
||||
begin
|
||||
HeapSort(Arr, Start, Fin);
|
||||
exit;
|
||||
end;
|
||||
{median of 3}
|
||||
j:=Start;
|
||||
k:=Fin-1;
|
||||
l:=(Start+Fin)div 2;
|
||||
if(TCompare.c(Arr[j],Arr[k])) and (TCompare.c(Arr[j],Arr[l])) then
|
||||
begin
|
||||
if(TCompare.c(Arr[k],Arr[l])) then
|
||||
begin
|
||||
temp:=Arr[k];
|
||||
Arr[k]:=Arr[j];
|
||||
Arr[j]:=temp;
|
||||
end else
|
||||
begin
|
||||
temp:=Arr[l];
|
||||
Arr[l]:=Arr[j];
|
||||
Arr[j]:=temp;
|
||||
end;
|
||||
end
|
||||
else if(TCompare.c(Arr[k],Arr[j])) and (TCompare.c(Arr[l],Arr[j])) then
|
||||
begin
|
||||
if(TCompare.c(Arr[l],Arr[k])) then
|
||||
begin
|
||||
temp:=Arr[k];
|
||||
Arr[k]:=Arr[j];
|
||||
Arr[j]:=temp;
|
||||
end else
|
||||
begin
|
||||
temp:=Arr[l];
|
||||
Arr[l]:=Arr[j];
|
||||
Arr[j]:=temp;
|
||||
end;
|
||||
end;
|
||||
|
||||
{partition}
|
||||
pivot:=Arr[Start];
|
||||
|
||||
i:=Start-1;
|
||||
j:=Fin;
|
||||
repeat
|
||||
repeat
|
||||
dec(j);
|
||||
until (not (TCompare.c(pivot,Arr[j])));
|
||||
|
||||
|
||||
repeat
|
||||
inc(i);
|
||||
until (not (TCompare.c(Arr[i],pivot)));
|
||||
if(i < j) then
|
||||
begin
|
||||
temp:=Arr[i];
|
||||
Arr[i]:=Arr[j];
|
||||
Arr[j]:=temp;
|
||||
end;
|
||||
until (i>=j);
|
||||
|
||||
Sortrange(Arr, Start, j+1, d+1);
|
||||
Sortrange(Arr, j+1, Fin, d+1);
|
||||
end;
|
||||
|
||||
class procedure TOrderingArrayUtils.InsertSort(var Arr:TArr; Start,Fin:SizeUInt);inline;
|
||||
var i,j:SizeUInt; temp:Tvalue;
|
||||
begin
|
||||
for i:=Start+1 to Fin-1 do
|
||||
begin
|
||||
j:=i;
|
||||
temp:=Arr[i];
|
||||
while (j>0) and (TCompare.c(temp,Arr[j-1])) do
|
||||
begin
|
||||
Arr[j]:=Arr[j-1];
|
||||
dec(j);
|
||||
end;
|
||||
Arr[j]:=temp;
|
||||
end;
|
||||
end;
|
||||
|
||||
class procedure TOrderingArrayUtils.HeapSort(var Arr: TArr; Start,Fin:SizeUInt);
|
||||
var i,cur,next,l,r,size:SizeUInt; temp:Tvalue;
|
||||
begin
|
||||
{buildHeap}
|
||||
size:=Fin-Start;
|
||||
for i:=((size div 2)-1) downto 0 do
|
||||
Heapify(Arr, i+Start, Start, Fin);
|
||||
{bottomup HeapSort}
|
||||
for i:=size-1 downto 1 do
|
||||
begin
|
||||
Fin:=Fin-1;
|
||||
cur:=Start;
|
||||
temp:=Arr[Start];
|
||||
while(true) do
|
||||
begin
|
||||
l:=Left(cur-Start)+Start;
|
||||
if l>=Fin then
|
||||
break;
|
||||
next:=l;
|
||||
r:=Right(cur-Start)+Start;
|
||||
if (r<Fin) AND (TCompare.c(Arr[l],Arr[r])) then
|
||||
next:=r;
|
||||
Arr[cur]:=Arr[next];
|
||||
cur:=next;
|
||||
end;
|
||||
Arr[cur]:=temp;
|
||||
temp:=Arr[i+Start];
|
||||
Arr[i+Start]:=Arr[cur];
|
||||
Arr[cur]:=temp;
|
||||
l:=Parent(cur-Start)+Start;
|
||||
while (cur <> 0) AND (TCompare.c(Arr[l],Arr[cur])) do
|
||||
begin
|
||||
temp:=Arr[cur];
|
||||
Arr[cur]:=Arr[l];
|
||||
Arr[l]:=temp;
|
||||
cur:=l;
|
||||
l:=Parent(cur-Start)+Start;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
class procedure TArrayUtils.RandomShuffle(Arr: TArr; size: SizeUInt);
|
||||
var i,r:SizeUInt; temp:Tvalue;
|
||||
begin
|
||||
for i:=size-1 downto 1 do begin
|
||||
r:=random(Int64(i));
|
||||
temp:=Arr[r];
|
||||
Arr[r]:=Arr[i];
|
||||
Arr[i]:=temp;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
192
packages/fcl-stl/src/gdeque.pp
Normal file
192
packages/fcl-stl/src/gdeque.pp
Normal file
@ -0,0 +1,192 @@
|
||||
{$mode objfpc}
|
||||
|
||||
unit gdeque;
|
||||
|
||||
interface
|
||||
|
||||
type
|
||||
generic TDeque<T>=class
|
||||
private
|
||||
type
|
||||
PT=^T;
|
||||
TArr=array of T;
|
||||
var
|
||||
FData:TArr;
|
||||
FDataSize:SizeUInt;
|
||||
FCapacity:SizeUInt;
|
||||
FStart:SizeUInt;
|
||||
procedure SetValue(position:SizeUInt; value:T);inline;
|
||||
function GetValue(position:SizeUInt):T;inline;
|
||||
function GetMutable(position:SizeUInt):PT;inline;
|
||||
procedure IncreaseCapacity();inline;
|
||||
public
|
||||
function Size():SizeUInt;inline;
|
||||
constructor Create();
|
||||
procedure PushBack(value:T);inline;
|
||||
procedure PushFront(value:T);inline;
|
||||
procedure PopBack();inline;
|
||||
procedure PopFront();inline;
|
||||
function Front():T;inline;
|
||||
function Back():T;inline;
|
||||
function IsEmpty():boolean;inline;
|
||||
procedure Reserve(cap:SizeUInt);inline;
|
||||
procedure Resize(cap:SizeUInt);inline;
|
||||
procedure Insert(Position:SizeUInt; Value:T);inline;
|
||||
procedure Erase(Position:SIzeUInt);inline;
|
||||
property Items[i : SizeUInt]: T read GetValue write SetValue; default;
|
||||
property Mutable[i : SizeUInt]:PT read GetMutable;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
constructor TDeque.Create();
|
||||
begin
|
||||
FDataSize:=0;
|
||||
FCapacity:=0;
|
||||
FStart:=0;
|
||||
end;
|
||||
|
||||
function TDeque.Size():SizeUInt;inline;
|
||||
begin
|
||||
Size:=FDataSize;
|
||||
end;
|
||||
|
||||
function TDeque.IsEmpty():boolean;inline;
|
||||
begin
|
||||
if Size()=0 then
|
||||
IsEmpty:=true
|
||||
else
|
||||
IsEmpty:=false;
|
||||
end;
|
||||
|
||||
procedure TDeque.PushBack(value:T);inline;
|
||||
begin
|
||||
if(FDataSize=FCapacity) then
|
||||
IncreaseCapacity;
|
||||
FData[(FStart+FDataSize)mod FCapacity]:=value;
|
||||
inc(FDataSize);
|
||||
end;
|
||||
|
||||
procedure TDeque.PopFront();inline;
|
||||
begin
|
||||
if(FDataSize>0) then
|
||||
begin
|
||||
inc(FStart);
|
||||
dec(FDataSize);
|
||||
if(FStart=FCapacity) then
|
||||
FStart:=0;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TDeque.PopBack();inline;
|
||||
begin
|
||||
if(FDataSize>0) then
|
||||
dec(FDataSize);
|
||||
end;
|
||||
|
||||
procedure TDeque.PushFront(value:T);inline;
|
||||
begin
|
||||
if(FDataSize=FCapacity) then
|
||||
IncreaseCapacity;
|
||||
if(FStart=0) then
|
||||
FStart:=FCapacity-1
|
||||
else
|
||||
dec(FStart);
|
||||
FData[FStart]:=value;
|
||||
inc(FDataSize);
|
||||
end;
|
||||
|
||||
function TDeque.Front():T;inline;
|
||||
begin
|
||||
Assert(size > 0, 'Accessing empty deque');
|
||||
Front:=FData[FStart];
|
||||
end;
|
||||
|
||||
function TDeque.Back():T;inline;
|
||||
begin
|
||||
Assert(size > 0, 'Accessing empty deque');
|
||||
Back:=FData[(FStart+FDataSize-1)mod FCapacity];
|
||||
end;
|
||||
|
||||
procedure TDeque.SetValue(position:SizeUInt; value:T);inline;
|
||||
begin
|
||||
Assert(position < size, 'Deque access out of range');
|
||||
FData[(FStart+position)mod FCapacity]:=value;
|
||||
end;
|
||||
|
||||
function TDeque.GetValue(position:SizeUInt):T;inline;
|
||||
begin
|
||||
Assert(position < size, 'Deque access out of range');
|
||||
GetValue:=FData[(FStart+position) mod FCapacity];
|
||||
end;
|
||||
|
||||
function TDeque.GetMutable(position:SizeUInt):PT;inline;
|
||||
begin
|
||||
Assert(position < size, 'Deque access out of range');
|
||||
GetMutable:=@FData[(FStart+position) mod FCapacity];
|
||||
end;
|
||||
|
||||
procedure TDeque.IncreaseCapacity;inline;
|
||||
var i,OldEnd:SizeUInt;
|
||||
begin
|
||||
OldEnd:=FCapacity;
|
||||
if(FCapacity=0) then
|
||||
FCapacity:=1
|
||||
else
|
||||
FCapacity:=FCapacity*2;
|
||||
SetLength(FData, FCapacity);
|
||||
if (FStart>0) then
|
||||
for i:=0 to FStart-1 do
|
||||
FData[OldEnd+i]:=FData[i];
|
||||
end;
|
||||
|
||||
procedure TDeque.Reserve(cap:SizeUInt);inline;
|
||||
var i,OldEnd:SizeUInt;
|
||||
begin
|
||||
if(cap<FCapacity) then
|
||||
exit
|
||||
else if(cap<=2*FCapacity) then
|
||||
IncreaseCapacity
|
||||
else
|
||||
begin
|
||||
OldEnd:=FCapacity;
|
||||
FCapacity:=cap;
|
||||
SetLength(FData, FCapacity);
|
||||
if FStart > 0 then
|
||||
for i:=0 to FStart-1 do
|
||||
FData[OldEnd+i]:=FData[i];
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TDeque.Resize(cap:SizeUInt);inline;
|
||||
begin
|
||||
Reserve(cap);
|
||||
FDataSize:=cap;
|
||||
end;
|
||||
|
||||
procedure TDeque.Insert(Position:SizeUInt; Value: T);inline;
|
||||
var i:SizeUInt;
|
||||
begin
|
||||
pushBack(Value);
|
||||
for i:=Size-1 downto Position+1 do
|
||||
begin
|
||||
Items[i]:=Items[i-1];
|
||||
end;
|
||||
Items[Position]:=Value;
|
||||
end;
|
||||
|
||||
procedure TDeque.Erase(Position:SizeUInt);inline;
|
||||
var i:SizeUInt;
|
||||
begin
|
||||
if Position <= Size then
|
||||
begin
|
||||
for i:=Position to Size-2 do
|
||||
begin
|
||||
Items[i]:=Items[i+1];
|
||||
end;
|
||||
popBack();
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
72
packages/fcl-stl/src/ghashset.pp
Normal file
72
packages/fcl-stl/src/ghashset.pp
Normal file
@ -0,0 +1,72 @@
|
||||
{$mode objfpc}
|
||||
|
||||
{unit ghashset;
|
||||
|
||||
interface}
|
||||
uses gvector;
|
||||
|
||||
const baseSize = 8;
|
||||
|
||||
|
||||
|
||||
{Thash should have one class function hash(a:T, n:longint):longint which return uniformly distributed
|
||||
value in range <0,n-1> base only on arguments}
|
||||
|
||||
type
|
||||
generic hashset<T, Thash>=class
|
||||
private type TContainer = specialize vector<T>;
|
||||
type TTable = specialize vector<TContainer>;
|
||||
var data:TTable;
|
||||
public constructor create;
|
||||
procedure insert(value:T);inline;
|
||||
function find(value:T):boolean;inline;
|
||||
end;
|
||||
|
||||
{implementation}
|
||||
|
||||
constructor hashset.create;
|
||||
var i:longint;
|
||||
begin
|
||||
data:=TTable.create;
|
||||
data.resize(8);
|
||||
for i:=0 to 7 do
|
||||
data[i]:=TContainer.create;
|
||||
end;
|
||||
|
||||
function hashset.find(value:T):boolean;inline;
|
||||
var i,h,bs:longint;
|
||||
begin
|
||||
h:=Thash.hash(value,data.size);
|
||||
bs:=data.getValue(h).size;
|
||||
for i:=0 to bs-1 do begin
|
||||
if (data.getvalue(h).getvalue(i)=value) then exit(true);
|
||||
end;
|
||||
exit(false);
|
||||
end;
|
||||
|
||||
procedure hashset.insert(value:T);inline;
|
||||
begin
|
||||
if (find(value)) then exit;
|
||||
(data[Thash.hash(value,data.size)]).pushback(value);
|
||||
end;
|
||||
|
||||
type hint=class
|
||||
class function hash(a,n:longint):longint;
|
||||
end;
|
||||
|
||||
class function hint.hash(a,n:longint):longint;
|
||||
begin
|
||||
hash:= a mod n;
|
||||
end;
|
||||
|
||||
type hsli = specialize hashset<longint, hint>;
|
||||
|
||||
var data:hsli; i,n:longint;
|
||||
|
||||
begin
|
||||
data:=hsli.create;
|
||||
for i:=0 to 10 do
|
||||
data.insert(i);
|
||||
for i:=0 to 13 do
|
||||
writeln(data.find(i));
|
||||
end.
|
||||
151
packages/fcl-stl/src/gmap.pp
Normal file
151
packages/fcl-stl/src/gmap.pp
Normal file
@ -0,0 +1,151 @@
|
||||
{$mode objfpc}
|
||||
|
||||
unit gmap;
|
||||
|
||||
interface
|
||||
|
||||
uses gset;
|
||||
|
||||
type
|
||||
generic TMapCompare<TPair, TKeyCompare>=class
|
||||
class function c(a,b :TPair):boolean;
|
||||
end;
|
||||
|
||||
generic TMap<TKey, TValue, TCompare>=class
|
||||
public
|
||||
type
|
||||
TPair=record
|
||||
Key:TKey;
|
||||
Value:TValue;
|
||||
end;
|
||||
TMCompare = specialize TMapCompare<TPair, TCompare>;
|
||||
TMSet = specialize TSet<TPair, TMCompare>;
|
||||
PTValue = ^TValue;
|
||||
PTPair = ^TPair;
|
||||
var
|
||||
private
|
||||
FSet:TMSet;
|
||||
public
|
||||
function Find(key:TKey):TMSet.PNode;inline;
|
||||
function FindLess(key:TKey):TMSet.PNode;inline;
|
||||
function FindLessEqual(key:TKey):TMSet.PNode;inline;
|
||||
function FindGreater(key:TKey):TMSet.PNode;inline;
|
||||
function FindGreaterEqual(key:TKey):TMSet.PNode;inline;
|
||||
function GetValue(key:TKey):TValue;inline;
|
||||
procedure Insert(key:TKey; value:TValue);inline;
|
||||
function Min:TMSet.PNode;inline;
|
||||
function Max:TMSet.PNode;inline;
|
||||
function Next(x:TMSet.PNode):TMSet.PNode;inline;
|
||||
function Prev(x:TMSet.PNode):TMSet.PNode;inline;
|
||||
procedure Delete(key:TKey);inline;
|
||||
function Size:SizeUInt;inline;
|
||||
function IsEmpty:boolean;inline;
|
||||
constructor Create;
|
||||
destructor Destroy;override;
|
||||
property Items[i : TKey]: TValue read GetValue write Insert; default;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
class function TMapCompare.c(a,b: TPair):boolean;
|
||||
begin
|
||||
c:= TKeyCompare.c(a.Key, b.Key);
|
||||
end;
|
||||
|
||||
constructor TMap.Create;
|
||||
begin
|
||||
FSet:=TMSet.Create;
|
||||
end;
|
||||
|
||||
destructor TMap.Destroy;
|
||||
begin
|
||||
FSet.Destroy;
|
||||
end;
|
||||
|
||||
procedure TMap.Delete(key:TKey);inline;
|
||||
var Pair:TPair;
|
||||
begin
|
||||
Pair.Key:=key;
|
||||
FSet.Delete(Pair);
|
||||
end;
|
||||
|
||||
function TMap.Find(key:TKey):TMSet.PNode;inline;
|
||||
var Pair:TPair;
|
||||
begin
|
||||
Pair.Key:=key;
|
||||
Find:=FSet.Find(Pair);
|
||||
end;
|
||||
|
||||
function TMap.FindLess(key:TKey):TMSet.PNode;inline;
|
||||
var Pair:TPair;
|
||||
begin
|
||||
Pair.Key:=key;
|
||||
FindLess:=FSet.FindLess(Pair);
|
||||
end;
|
||||
|
||||
function TMap.FindLessEqual(key:TKey):TMSet.PNode;inline;
|
||||
var Pair:TPair;
|
||||
begin
|
||||
Pair.Key:=key;
|
||||
FindLessEqual:=FSet.FindLessEqual(Pair);
|
||||
end;
|
||||
|
||||
function TMap.FindGreater(key:TKey):TMSet.PNode;inline;
|
||||
var Pair:TPair;
|
||||
begin
|
||||
Pair.Key:=key;
|
||||
FindGreater:=FSet.FindGreater(Pair);
|
||||
end;
|
||||
|
||||
function TMap.FindGreaterEqual(key:TKey):TMSet.PNode;inline;
|
||||
var Pair:TPair;
|
||||
begin
|
||||
Pair.Key:=key;
|
||||
FindGreaterEqual:=FSet.FindGreaterEqual(Pair);
|
||||
end;
|
||||
|
||||
function TMap.GetValue(key:TKey):TValue;inline;
|
||||
var Pair:TPair;
|
||||
begin
|
||||
Pair.Key:=key;
|
||||
GetValue:=FSet.Find(Pair)^.Data.Value;
|
||||
end;
|
||||
|
||||
procedure TMap.Insert(key:TKey; value:TValue);inline;
|
||||
var Pair:TPair;
|
||||
begin
|
||||
Pair.Key:=key;
|
||||
FSet.Insert(Pair)^.Data.Value := value;
|
||||
end;
|
||||
|
||||
function TMap.Min:TMSet.PNode;inline;
|
||||
begin
|
||||
Min:=FSet.Min;
|
||||
end;
|
||||
|
||||
function TMap.Max:TMSet.PNode;inline;
|
||||
begin
|
||||
Max:=FSet.Max;
|
||||
end;
|
||||
|
||||
function TMap.Next(x:TMSet.PNode):TMSet.PNode;inline;
|
||||
begin
|
||||
Next:=FSet.Next(x);
|
||||
end;
|
||||
|
||||
function TMap.Prev(x:TMSet.PNode):TMSet.PNode;inline;
|
||||
begin
|
||||
Prev:=FSet.Prev(x);
|
||||
end;
|
||||
|
||||
function TMap.Size:SizeUInt;inline;
|
||||
begin
|
||||
Size:=FSet.Size;
|
||||
end;
|
||||
|
||||
function TMap.IsEmpty:boolean;inline;
|
||||
begin
|
||||
IsEmpty:=FSet.IsEmpty;
|
||||
end;
|
||||
|
||||
end.
|
||||
129
packages/fcl-stl/src/gpriorityqueue.pp
Normal file
129
packages/fcl-stl/src/gpriorityqueue.pp
Normal file
@ -0,0 +1,129 @@
|
||||
{$mode objfpc}
|
||||
|
||||
unit gpriorityqueue;
|
||||
|
||||
interface
|
||||
|
||||
uses gvector;
|
||||
|
||||
{TCompare is comparing class, which should have class method c(a,b:T):boolean, which returns true is a is less than b}
|
||||
|
||||
type
|
||||
generic TPriorityQueue<T, TCompare>=class
|
||||
private
|
||||
type
|
||||
TContainer=specialize TVector<T>;
|
||||
var
|
||||
FData:TContainer;
|
||||
|
||||
procedure PushUp(position:SizeUInt);
|
||||
function Left(a:SizeUInt):SizeUInt;inline;
|
||||
function Right(a:SizeUInt):SizeUInt;inline;
|
||||
procedure Heapify(position:SizeUInt);
|
||||
function Parent(a:SizeUInt):SizeUInt;inline;
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy;override;
|
||||
function Top:T;inline;
|
||||
procedure Pop;inline;
|
||||
procedure Push(value:T);inline;
|
||||
function Size:SizeUInt;inline;
|
||||
function IsEmpty:boolean;inline;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
constructor TPriorityQueue.Create;
|
||||
begin
|
||||
FData:=TContainer.Create;
|
||||
end;
|
||||
|
||||
destructor TPriorityQueue.Destroy;
|
||||
begin;
|
||||
FData.Destroy;
|
||||
end;
|
||||
|
||||
function TPriorityQueue.Size:SizeUInt;inline;
|
||||
begin
|
||||
Size:=FData.Size;
|
||||
end;
|
||||
|
||||
function TPriorityQueue.IsEmpty:boolean;inline;
|
||||
begin
|
||||
IsEmpty:=FData.Size=0;
|
||||
end;
|
||||
|
||||
function TPriorityQueue.Top:T;inline;
|
||||
begin
|
||||
Top:=FData[0];
|
||||
end;
|
||||
|
||||
procedure TPriorityQueue.Pop;inline;
|
||||
begin
|
||||
if not IsEmpty then begin
|
||||
FData[0]:=FData.back;
|
||||
FData.PopBack;
|
||||
Heapify(0);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TPriorityQueue.PushUp(position:SizeUInt);
|
||||
var np:SizeUInt; temp:T;
|
||||
begin
|
||||
while(position>0) do
|
||||
begin
|
||||
np := Parent(position);
|
||||
if(TCompare.c(FData[np],FData[position])) then
|
||||
begin
|
||||
temp:=FData[np];
|
||||
FData[np]:=FData[position];
|
||||
FData[position]:=temp;
|
||||
position:=np;
|
||||
end else
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TPriorityQueue.Push(value:T);inline;
|
||||
begin
|
||||
FData.PushBack(value);
|
||||
PushUp(FData.Size-1);
|
||||
end;
|
||||
|
||||
function TPriorityQueue.Left(a:SizeUInt):SizeUInt;inline;
|
||||
begin
|
||||
Left:=((a+1)shl 1)-1;
|
||||
end;
|
||||
|
||||
function TPriorityQueue.Right(a:SizeUInt):SizeUInt;inline;
|
||||
begin
|
||||
Right:=(a+1) shl 1;
|
||||
end;
|
||||
|
||||
function TPriorityQueue.Parent(a:SizeUInt):SizeUInt;inline;
|
||||
begin
|
||||
Parent:=(a-1)shr 1;
|
||||
end;
|
||||
|
||||
procedure TPriorityQueue.Heapify(position:SizeUInt);
|
||||
var mpos,l,r:SizeUInt; temp:T;
|
||||
begin
|
||||
while(true) do
|
||||
begin
|
||||
mpos:=position;
|
||||
l:=Left(position);
|
||||
r:=Right(position);
|
||||
if (l<FData.Size) AND (TCompare.c(FData[mpos],FData[l])) then
|
||||
mpos:=l;
|
||||
if (r<FData.Size) AND (TCompare.c(FData[mpos],FData[r])) then
|
||||
mpos:=r;
|
||||
if mpos = position then break;
|
||||
|
||||
temp:=FData[position];
|
||||
FData[position]:=FData[mpos];
|
||||
FData[mpos]:=temp;
|
||||
position:=mpos;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
63
packages/fcl-stl/src/gqueue.pp
Normal file
63
packages/fcl-stl/src/gqueue.pp
Normal file
@ -0,0 +1,63 @@
|
||||
{$mode objfpc}
|
||||
|
||||
unit gqueue;
|
||||
|
||||
interface
|
||||
|
||||
uses gdeque;
|
||||
|
||||
type
|
||||
generic TQueue<T>=class
|
||||
private
|
||||
type
|
||||
TContainer = specialize TDeque<T>;
|
||||
var
|
||||
FData:TContainer;
|
||||
public
|
||||
procedure Push(value:T);inline;
|
||||
procedure Pop();inline;
|
||||
function Front():T;inline;
|
||||
function Size():SizeUInt;inline;
|
||||
function IsEmpty():boolean;inline;
|
||||
constructor Create;
|
||||
destructor Destroy;override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
constructor TQueue.Create;
|
||||
begin
|
||||
FData:=TContainer.Create;
|
||||
end;
|
||||
|
||||
destructor TQueue.Destroy;
|
||||
begin
|
||||
FData.Destroy;
|
||||
end;
|
||||
|
||||
procedure TQueue.Push(value:T);inline;
|
||||
begin
|
||||
FData.PushBack(value);
|
||||
end;
|
||||
|
||||
procedure TQueue.Pop();inline;
|
||||
begin
|
||||
FData.PopFront;
|
||||
end;
|
||||
|
||||
function TQueue.Front:T;inline;
|
||||
begin
|
||||
Front:=FData.Front;
|
||||
end;
|
||||
|
||||
function TQueue.Size:SizeUInt;inline;
|
||||
begin
|
||||
Size:=FData.Size;
|
||||
end;
|
||||
|
||||
function TQueue.IsEmpty:boolean;inline;
|
||||
begin
|
||||
IsEmpty:=FData.IsEmpty;
|
||||
end;
|
||||
|
||||
end.
|
||||
411
packages/fcl-stl/src/gset.pp
Normal file
411
packages/fcl-stl/src/gset.pp
Normal file
@ -0,0 +1,411 @@
|
||||
{$mode objfpc}
|
||||
|
||||
unit gset;
|
||||
|
||||
interface
|
||||
|
||||
const RED=true;
|
||||
const BLACK=false;
|
||||
|
||||
type
|
||||
generic TSet<T, TCompare>=class
|
||||
public
|
||||
type
|
||||
PNode=^Node;
|
||||
Node=record
|
||||
Data:T;
|
||||
Left,Right:PNode;
|
||||
Parent:PNode;
|
||||
Color:boolean;
|
||||
end;
|
||||
var
|
||||
private
|
||||
FBase:PNode;
|
||||
FSize:SizeUInt;
|
||||
|
||||
function CreateNode(Data:T):PNode;inline;
|
||||
procedure DestroyNodeAndChilds(nod:PNode);
|
||||
procedure DestroyNode(nod:PNode);
|
||||
function RotateRight(nod:PNode):PNode;inline;
|
||||
function RotateLeft(nod:PNode):PNode;inline;
|
||||
procedure FlipColors(nod:PNode);inline;
|
||||
function IsRed(nod:PNode):boolean;inline;
|
||||
function Insert(value:T; nod:PNode; var position:PNode):PNode;
|
||||
function FixUp(nod:PNode):PNode;inline;
|
||||
function MoveRedLeft(nod:PNode):PNode;inline;
|
||||
function MoveRedRight(nod:PNode):PNode;inline;
|
||||
function DeleteMin(nod:PNode):PNode;
|
||||
function Delete(value:T; nod:PNode):PNode;
|
||||
function Min(nod:PNode):PNode;inline;
|
||||
|
||||
public
|
||||
function Find(value:T):PNode;inline;
|
||||
function FindLess(value:T):PNode;inline;
|
||||
function FindLessEqual(value:T):PNode;inline;
|
||||
function FindGreater(value:T):PNode;inline;
|
||||
function FindGreaterEqual(value:T):PNode;inline;
|
||||
function Insert(value:T):PNode;inline;
|
||||
function Min:PNode;inline;
|
||||
function Max:PNode;inline;
|
||||
function Next(x:PNode):PNode;inline;
|
||||
function Prev(x:PNode):PNode;inline;
|
||||
procedure Delete(value:T);inline;
|
||||
public constructor Create;
|
||||
public destructor Destroy;override;
|
||||
function Size:SizeUInt;
|
||||
function IsEmpty:boolean;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
constructor TSet.Create;
|
||||
begin
|
||||
FBase:=nil;
|
||||
FSize:=0;
|
||||
end;
|
||||
|
||||
destructor TSet.Destroy;
|
||||
begin
|
||||
DestroyNodeAndChilds(FBase);
|
||||
end;
|
||||
|
||||
function TSet.Size:SizeUInt;
|
||||
begin
|
||||
Size:=FSize;
|
||||
end;
|
||||
|
||||
function TSet.IsEmpty:boolean;
|
||||
begin
|
||||
IsEmpty := FSize=0;
|
||||
end;
|
||||
|
||||
procedure TSet.DestroyNodeAndChilds(nod:PNode);
|
||||
begin
|
||||
if nod = nil then exit;
|
||||
DestroyNodeAndChilds(nod^.left);
|
||||
DestroyNodeAndChilds(nod^.right);
|
||||
DestroyNode(nod);
|
||||
end;
|
||||
|
||||
procedure TSet.DestroyNode(nod:PNode);
|
||||
begin
|
||||
Finalize(nod^.Data);
|
||||
dispose(nod);
|
||||
dec(FSize);
|
||||
end;
|
||||
|
||||
function TSet.CreateNode(Data:T):PNode;inline;
|
||||
var temp:PNode;
|
||||
begin
|
||||
temp:=new(PNode);
|
||||
Initialize(temp^.Data);
|
||||
temp^.Data:=Data;
|
||||
temp^.Left:=nil;
|
||||
temp^.Right:=nil;
|
||||
temp^.Parent:=nil;
|
||||
temp^.Color:=RED;
|
||||
inc(FSize);
|
||||
CreateNode:=temp;
|
||||
end;
|
||||
|
||||
function TSet.RotateRight(nod:PNode):PNode;inline;
|
||||
var temp:PNode;
|
||||
begin
|
||||
temp:=nod^.Left;
|
||||
|
||||
temp^.Parent:=nod^.Parent;
|
||||
nod^.Parent:=temp;
|
||||
|
||||
nod^.Left:=temp^.Right;
|
||||
temp^.Right:=nod;
|
||||
|
||||
if(nod^.Left<>nil) then nod^.Left^.Parent:=nod;
|
||||
|
||||
temp^.Color:=nod^.Color;
|
||||
nod^.Color:=RED;
|
||||
exit(temp);
|
||||
end;
|
||||
|
||||
function TSet.RotateLeft(nod:PNode):PNode;inline;
|
||||
var temp:PNode;
|
||||
begin
|
||||
temp:=nod^.Right;
|
||||
|
||||
temp^.Parent:=nod^.Parent;
|
||||
nod^.Parent:=temp;
|
||||
|
||||
nod^.Right:=temp^.Left;
|
||||
temp^.Left:=nod;
|
||||
|
||||
if(nod^.Right<>nil) then nod^.Right^.Parent:=nod;
|
||||
|
||||
temp^.Color:=nod^.Color;
|
||||
nod^.Color:=RED;
|
||||
exit(temp);
|
||||
end;
|
||||
|
||||
procedure TSet.FlipColors(nod:PNode);inline;
|
||||
begin
|
||||
nod^.Color:= not nod^.Color;
|
||||
nod^.Left^.Color := not nod^.Left^.Color;
|
||||
nod^.Right^.Color := not nod^.Right^.Color;
|
||||
end;
|
||||
|
||||
|
||||
function TSet.FixUp(nod:PNode):PNode;inline;
|
||||
begin
|
||||
if(IsRed(nod^.Right)) and (not IsRed(nod^.Left)) then nod := rotateLeft(nod);
|
||||
if(IsRed(nod^.Left)) and (IsRed(nod^.Left^.Left)) then nod := rotateRight(nod);
|
||||
if(IsRed(nod^.Right)) and (IsRed(nod^.Left)) then flipColors(nod);
|
||||
FixUp:=nod;
|
||||
end;
|
||||
|
||||
function TSet.MoveRedLeft(nod:PNode):PNode;inline;
|
||||
begin
|
||||
flipColors(nod);
|
||||
if (IsRed(nod^.Right^.Left)) then begin
|
||||
nod^.Right := rotateRight(nod^.Right);
|
||||
nod := rotateLeft(nod);
|
||||
flipColors(nod);
|
||||
end;
|
||||
MoveRedLeft:=nod;
|
||||
end;
|
||||
|
||||
function TSet.MoveRedRight(nod:PNode):PNode;inline;
|
||||
begin
|
||||
flipColors(nod);
|
||||
if (IsRed(nod^.Left^.Left)) then begin
|
||||
nod := rotateRight(nod);
|
||||
flipColors(nod);
|
||||
end;
|
||||
MoveRedRight:=nod;
|
||||
end;
|
||||
|
||||
function TSet.DeleteMin(nod:PNode):PNode;
|
||||
begin
|
||||
if (nod^.Left = nil) then begin
|
||||
DestroyNode(nod);
|
||||
exit(nil);
|
||||
end;
|
||||
|
||||
if ((not IsRed(nod^.Left)) and (not IsRed(nod^.Left^.Left))) then nod := MoveRedLeft(nod);
|
||||
|
||||
nod^.Left := DeleteMin(nod^.Left);
|
||||
|
||||
exit(FixUp(nod));
|
||||
end;
|
||||
|
||||
function TSet.Delete(value:T; nod:PNode):PNode;
|
||||
begin
|
||||
if (TCompare.c(value, nod^.Data)) then begin
|
||||
if (nod^.Left=nil) then exit(nod);
|
||||
if ((not IsRed(nod^.Left)) and ( not IsRed(nod^.Left^.Left))) then
|
||||
nod := MoveRedLeft(nod);
|
||||
nod^.Left := Delete(value, nod^.Left);
|
||||
end
|
||||
else begin
|
||||
if (IsRed(nod^.Left)) then begin
|
||||
nod := rotateRight(nod);
|
||||
end;
|
||||
if ((not TCompare.c(value,nod^.Data)) and (not TCompare.c(nod^.Data,value)) and (nod^.Right = nil)) then
|
||||
begin
|
||||
DestroyNode(nod);
|
||||
exit(nil);
|
||||
end;
|
||||
if (nod^.Right=nil) then exit(nod);
|
||||
if ((not IsRed(nod^.Right)) and (not IsRed(nod^.Right^.Left))) then nod := MoveRedRight(nod);
|
||||
if ((not TCompare.c(value,nod^.Data)) and (not TCompare.c(nod^.Data,value))) then begin
|
||||
nod^.Data := Min(nod^.Right)^.Data;
|
||||
nod^.Right := DeleteMin(nod^.Right);
|
||||
end
|
||||
else nod^.Right := Delete(value, nod^.Right);
|
||||
end;
|
||||
exit(FixUp(nod));
|
||||
end;
|
||||
|
||||
procedure TSet.Delete(value:T);inline;
|
||||
begin
|
||||
if(FBase<>nil) then FBase:=Delete(value, FBase);
|
||||
if(FBase<>nil) then FBase^.Color:=BLACK;
|
||||
end;
|
||||
|
||||
|
||||
function TSet.Find(value:T):PNode;inline;
|
||||
var x:PNode;
|
||||
begin
|
||||
x:=FBase;
|
||||
while(x <> nil) do begin
|
||||
if(TCompare.c(value,x^.Data)) then x:=x^.Left
|
||||
else if(TCompare.c(x^.Data,value)) then x:=x^.Right
|
||||
else exit(x);
|
||||
end;
|
||||
exit(nil);
|
||||
end;
|
||||
|
||||
function TSet.FindLess(value:T):PNode;inline;
|
||||
var x,cur:PNode;
|
||||
begin
|
||||
x:=nil;
|
||||
cur:=FBase;
|
||||
while (cur <> nil) do begin
|
||||
if (TCompare.c(cur^.Data, value)) then
|
||||
begin
|
||||
x:=cur;
|
||||
cur:=cur^.right;
|
||||
end else
|
||||
cur:=cur^.left;
|
||||
end;
|
||||
FindLess:=x;
|
||||
end;
|
||||
|
||||
function TSet.FindLessEqual(value:T):PNode;inline;
|
||||
var x,cur:PNode;
|
||||
begin
|
||||
x:=nil;
|
||||
cur:=FBase;
|
||||
while (cur <> nil) do begin
|
||||
if (not TCompare.c(value, cur^.data)) then
|
||||
begin
|
||||
x:=cur;
|
||||
cur:=cur^.right;
|
||||
end else
|
||||
cur:=cur^.left;
|
||||
end;
|
||||
FindLessEqual:=x;
|
||||
end;
|
||||
|
||||
function TSet.FindGreater(value:T):PNode;inline;
|
||||
var x,cur:PNode;
|
||||
begin
|
||||
x:=nil;
|
||||
cur:=FBase;
|
||||
while (cur <> nil) do begin
|
||||
if (TCompare.c(value, cur^.Data)) then
|
||||
begin
|
||||
x:=cur;
|
||||
cur:=cur^.left;
|
||||
end else
|
||||
cur:=cur^.right;
|
||||
end;
|
||||
FindGreater:=x;
|
||||
end;
|
||||
|
||||
function TSet.FindGreaterEqual(value:T):PNode;inline;
|
||||
var x,cur:PNode;
|
||||
begin
|
||||
x:=nil;
|
||||
cur:=FBase;
|
||||
while (cur <> nil) do begin
|
||||
if (not TCompare.c(cur^.Data, value)) then
|
||||
begin
|
||||
x:=cur;
|
||||
cur:=cur^.left;
|
||||
end else
|
||||
cur:=cur^.right;
|
||||
end;
|
||||
FindGreaterEqual:=x;
|
||||
end;
|
||||
|
||||
function TSet.Insert(value:T):PNode;inline;
|
||||
var position:PNode;
|
||||
begin
|
||||
FBase:=Insert(value, FBase, position);
|
||||
FBase^.Color:=BLACK;
|
||||
Insert:=position;
|
||||
end;
|
||||
|
||||
function TSet.Insert(value:T; nod:PNode; var position:PNode):PNode;
|
||||
begin
|
||||
if(nod=nil) then begin
|
||||
nod:=CreateNode(value);
|
||||
position:=nod;
|
||||
exit(nod);
|
||||
end;
|
||||
if(TCompare.c(value,nod^.Data)) then begin
|
||||
nod^.Left:=Insert(value, nod^.Left, position);
|
||||
nod^.Left^.Parent:=nod;
|
||||
end
|
||||
else if TCompare.c(nod^.Data,value) then begin
|
||||
nod^.Right:=Insert(value, nod^.Right, position);
|
||||
nod^.Right^.Parent:=nod;
|
||||
end
|
||||
else begin
|
||||
position:=nod;
|
||||
exit(nod);
|
||||
end;
|
||||
|
||||
if(IsRed(nod^.Right)) and (not IsRed(nod^.Left)) then nod := rotateLeft(nod);
|
||||
if(IsRed(nod^.Left)) and (IsRed(nod^.Left^.Left)) then nod := rotateRight(nod);
|
||||
if(IsRed(nod^.Right)) and (IsRed(nod^.Left)) then flipColors(nod);
|
||||
|
||||
Insert:=nod;
|
||||
end;
|
||||
|
||||
function TSet.IsRed(nod:PNode):boolean;inline;
|
||||
begin
|
||||
if(nod=nil) then exit(false);
|
||||
exit(nod^.Color);
|
||||
end;
|
||||
|
||||
function TSet.Min(nod:PNode):PNode;inline;
|
||||
var temp:PNode;
|
||||
begin
|
||||
temp:=nod;
|
||||
while(temp^.Left<>nil) do temp:=temp^.Left;
|
||||
exit(temp);
|
||||
end;
|
||||
|
||||
function TSet.Min:PNode;inline;
|
||||
begin
|
||||
if FBase=nil then exit(nil);
|
||||
Min:=Min(FBase);
|
||||
end;
|
||||
|
||||
function TSet.Max:PNode;inline;
|
||||
var temp:PNode;
|
||||
begin
|
||||
if FBase=nil then exit(nil);
|
||||
temp:=FBase;
|
||||
while(temp^.Right<>nil) do temp:=temp^.Right;
|
||||
exit(temp);
|
||||
end;
|
||||
|
||||
function TSet.Next(x:PNode):PNode;inline;
|
||||
var temp:PNode;
|
||||
begin
|
||||
if(x=nil) then exit(nil);
|
||||
if(x^.Right<>nil) then begin
|
||||
temp:=x^.Right;
|
||||
while(temp^.Left<>nil) do temp:=temp^.Left;
|
||||
end
|
||||
else begin
|
||||
temp:=x;
|
||||
while(true) do begin
|
||||
if(temp^.Parent=nil) then begin temp:=temp^.Parent; break; end;
|
||||
if(temp^.Parent^.Left=temp) then begin temp:=temp^.Parent; break; end;
|
||||
temp:=temp^.Parent;
|
||||
end;
|
||||
end;
|
||||
exit(temp);
|
||||
end;
|
||||
|
||||
function TSet.Prev(x:PNode):PNode;inline;
|
||||
var temp:PNode;
|
||||
begin
|
||||
if(x=nil) then exit(nil);
|
||||
if(x^.Left<>nil) then begin
|
||||
temp:=x^.Left;
|
||||
while(temp^.Right<>nil) do temp:=temp^.Right;
|
||||
end
|
||||
else begin
|
||||
temp:=x;
|
||||
while(true) do begin
|
||||
if(temp^.Parent=nil) then begin temp:=temp^.Parent; break; end;
|
||||
if(temp^.Parent^.Right=temp) then begin temp:=temp^.Parent; break; end;
|
||||
temp:=temp^.Parent;
|
||||
end;
|
||||
end;
|
||||
exit(temp);
|
||||
end;
|
||||
|
||||
end.
|
||||
61
packages/fcl-stl/src/gstack.pp
Normal file
61
packages/fcl-stl/src/gstack.pp
Normal file
@ -0,0 +1,61 @@
|
||||
{$mode objfpc}
|
||||
|
||||
unit gstack;
|
||||
|
||||
interface
|
||||
|
||||
uses gvector;
|
||||
|
||||
type
|
||||
generic TStack<T>=class
|
||||
private
|
||||
type TContainer= specialize TVector<T>;
|
||||
var FData:TContainer;
|
||||
public
|
||||
procedure Push(x:T);inline;
|
||||
procedure Pop();inline;
|
||||
function Top():T;inline;
|
||||
function Size():longint;inline;
|
||||
function IsEmpty():boolean;inline;
|
||||
constructor Create;
|
||||
destructor Destroy;override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
constructor TStack.Create;
|
||||
begin
|
||||
FData:=TContainer.Create;
|
||||
end;
|
||||
|
||||
destructor TStack.Destroy;
|
||||
begin
|
||||
FData.Destroy;
|
||||
end;
|
||||
|
||||
procedure TStack.Push(x:T);inline;
|
||||
begin
|
||||
FData.PushBack(x);
|
||||
end;
|
||||
|
||||
procedure TStack.Pop;inline;
|
||||
begin
|
||||
FData.PopBack;
|
||||
end;
|
||||
|
||||
function TStack.Top:T;inline;
|
||||
begin
|
||||
Top:=FData.Back;
|
||||
end;
|
||||
|
||||
function TStack.Size:longint;inline;
|
||||
begin
|
||||
Size:=FData.Size;
|
||||
end;
|
||||
|
||||
function TStack.IsEmpty:boolean;inline;
|
||||
begin
|
||||
IsEmpty:=FData.IsEmpty;
|
||||
end;
|
||||
|
||||
end.
|
||||
27
packages/fcl-stl/src/gutil.pp
Normal file
27
packages/fcl-stl/src/gutil.pp
Normal file
@ -0,0 +1,27 @@
|
||||
{$mode objfpc}
|
||||
|
||||
unit gutil;
|
||||
|
||||
interface
|
||||
|
||||
type generic TLess<T>=class
|
||||
class function c(a,b:T):boolean;inline;
|
||||
end;
|
||||
|
||||
type generic TGreater<T>=class
|
||||
class function c(a,b:T):boolean;inline;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
class function TLess.c(a,b:T):boolean;inline;
|
||||
begin
|
||||
c:=a<b;
|
||||
end;
|
||||
|
||||
class function TGreater.c(a,b:T):boolean;inline;
|
||||
begin
|
||||
c:=b<a;
|
||||
end;
|
||||
|
||||
end.
|
||||
161
packages/fcl-stl/src/gvector.pp
Normal file
161
packages/fcl-stl/src/gvector.pp
Normal file
@ -0,0 +1,161 @@
|
||||
{$mode objfpc}
|
||||
|
||||
unit gvector;
|
||||
|
||||
interface
|
||||
|
||||
type
|
||||
generic TVector<T>=class
|
||||
private
|
||||
type
|
||||
PT=^ T;
|
||||
TArr=array of T;
|
||||
var
|
||||
FCapacity:SizeUInt;
|
||||
FDataSize:SizeUInt;
|
||||
FData:TArr;
|
||||
|
||||
procedure SetValue(Position:SizeUInt; Value:T);inline;
|
||||
function GetValue(Position:SizeUInt):T;inline;
|
||||
function GetMutable(Position:SizeUInt):PT;inline;
|
||||
procedure IncreaseCapacity;inline;
|
||||
public
|
||||
constructor Create;
|
||||
function Size:SizeUInt;inline;
|
||||
procedure PushBack(Value:T);inline;
|
||||
procedure PopBack;inline;
|
||||
function IsEmpty:boolean;inline;
|
||||
procedure Insert(Position:SizeUInt; Value:T);inline;
|
||||
procedure Erase(Position:SizeUInt);inline;
|
||||
procedure Clear;inline;
|
||||
function Front:T;inline;
|
||||
function Back:T;inline;
|
||||
procedure Reserve(Num:SizeUInt);inline;
|
||||
procedure Resize(Num:SizeUInt);inline;
|
||||
|
||||
property Items[i : SizeUInt]: T read getValue write setValue; default;
|
||||
property Mutable[i : SizeUInt]: PT read getMutable;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
constructor TVector.Create();
|
||||
begin
|
||||
FCapacity:=0;
|
||||
FDataSize:=0;
|
||||
end;
|
||||
|
||||
procedure TVector.SetValue(Position:SizeUInt; Value:T);inline;
|
||||
begin
|
||||
Assert(position < size, 'Vector position out of range');
|
||||
FData[Position]:=Value;
|
||||
end;
|
||||
|
||||
function TVector.GetValue(Position:SizeUInt):T;inline;
|
||||
begin
|
||||
Assert(position < size, 'Vector position out of range');
|
||||
GetValue:=FData[Position];
|
||||
end;
|
||||
|
||||
function TVector.GetMutable(Position:SizeUInt):PT;inline;
|
||||
begin
|
||||
Assert(position < size, 'Vector position out of range');
|
||||
GetMutable:=@FData[Position];
|
||||
end;
|
||||
|
||||
function TVector.Front():T;inline;
|
||||
begin
|
||||
Assert(size > 0, 'Accessing element of empty vector');
|
||||
Front:=FData[0];
|
||||
end;
|
||||
|
||||
function TVector.Back():T;inline;
|
||||
begin
|
||||
Assert(size > 0, 'Accessing element of empty vector');
|
||||
Back:=FData[FDataSize-1];
|
||||
end;
|
||||
|
||||
function TVector.Size():SizeUInt;inline;
|
||||
begin
|
||||
Size:=FDataSize;
|
||||
end;
|
||||
|
||||
function TVector.IsEmpty():boolean;inline;
|
||||
begin
|
||||
if Size()=0 then
|
||||
IsEmpty:=true
|
||||
else
|
||||
IsEmpty:=false;
|
||||
end;
|
||||
|
||||
procedure TVector.PushBack(Value:T);inline;
|
||||
begin
|
||||
if FDataSize=FCapacity then
|
||||
IncreaseCapacity;
|
||||
FData[FDataSize]:=Value;
|
||||
inc(FDataSize);
|
||||
end;
|
||||
|
||||
procedure TVector.IncreaseCapacity();inline;
|
||||
begin
|
||||
if FCapacity=0 then
|
||||
FCapacity:=1
|
||||
else
|
||||
FCapacity:=FCapacity*2;
|
||||
SetLength(FData, FCapacity);
|
||||
end;
|
||||
|
||||
procedure TVector.PopBack();inline;
|
||||
begin
|
||||
if FDataSize>0 then
|
||||
FDataSize:=FDataSize-1;
|
||||
end;
|
||||
|
||||
procedure TVector.Insert(Position:SizeUInt; Value: T);inline;
|
||||
var i:SizeUInt;
|
||||
begin
|
||||
pushBack(Value);
|
||||
for i:=Size-1 downto Position+1 do
|
||||
begin
|
||||
FData[i]:=FData[i-1];
|
||||
end;
|
||||
FData[Position]:=Value;
|
||||
end;
|
||||
|
||||
procedure TVector.Erase(Position:SizeUInt);inline;
|
||||
var i:SizeUInt;
|
||||
begin
|
||||
if Position <= Size then
|
||||
begin
|
||||
for i:=Position to Size-2 do
|
||||
begin
|
||||
FData[i]:=FData[i+1];
|
||||
end;
|
||||
popBack();
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TVector.Clear;inline;
|
||||
begin
|
||||
FDataSize:=0;
|
||||
end;
|
||||
|
||||
procedure TVector.Reserve(Num:SizeUInt);inline;
|
||||
begin
|
||||
if(Num < FCapacity) then
|
||||
exit
|
||||
else if(Num <= 2*FCapacity) then
|
||||
IncreaseCapacity
|
||||
else begin
|
||||
SetLength(FData, Num);
|
||||
FCapacity:=Num;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TVector.Resize(Num:SizeUInt);inline;
|
||||
begin
|
||||
Reserve(Num);
|
||||
FDataSize:=Num;
|
||||
end;
|
||||
|
||||
end.
|
||||
2
packages/fcl-stl/tests/clean
Executable file
2
packages/fcl-stl/tests/clean
Executable file
@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
rm *.o *.ppu ../*.o ../*.ppu
|
||||
55
packages/fcl-stl/tests/gdequetest.pp
Normal file
55
packages/fcl-stl/tests/gdequetest.pp
Normal file
@ -0,0 +1,55 @@
|
||||
{$mode objfpc}
|
||||
|
||||
unit gdequetest;
|
||||
|
||||
interface
|
||||
|
||||
uses fpcunit, testregistry, gdeque;
|
||||
|
||||
type dequelli=specialize TDeque<longint>;
|
||||
|
||||
type TGDequeTest = class(TTestCase)
|
||||
Published
|
||||
procedure BackTest;
|
||||
procedure PushTest;
|
||||
public
|
||||
procedure Setup;override;
|
||||
private
|
||||
data:dequelli;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
procedure TGDequeTest.BackTest;
|
||||
var i:longint;
|
||||
begin
|
||||
AssertEquals('Not IsEmpty', true, data.IsEmpty);
|
||||
for i:=0 to 10 do
|
||||
data.pushback(i);
|
||||
for i:=0 to 10 do begin
|
||||
AssertEquals('Wrong data', 10-i, data.back);
|
||||
AssertEquals('Wrong size', 11-i, data.size);
|
||||
data.popback;
|
||||
end;
|
||||
AssertEquals('Not IsEmpty', true, data.IsEmpty);
|
||||
end;
|
||||
|
||||
procedure TGDequeTest.PushTest;
|
||||
var i:longint;
|
||||
begin
|
||||
for i:=6 to 10 do
|
||||
data.pushBack(i);
|
||||
for i:=5 downto 0 do
|
||||
data.pushFront(i);
|
||||
for i:=0 to 10 do
|
||||
AssertEquals('Wrong data', i, data[i]);
|
||||
end;
|
||||
|
||||
procedure TGDequeTest.Setup;
|
||||
begin
|
||||
data:=dequelli.create;
|
||||
end;
|
||||
|
||||
initialization
|
||||
RegisterTest(TGDequeTest);
|
||||
end.
|
||||
84
packages/fcl-stl/tests/gmaptest.pp
Normal file
84
packages/fcl-stl/tests/gmaptest.pp
Normal file
@ -0,0 +1,84 @@
|
||||
{$mode objfpc}
|
||||
|
||||
unit gmaptest;
|
||||
|
||||
interface
|
||||
|
||||
uses fpcunit, testregistry, gmap, gutil;
|
||||
|
||||
type lesslli=specialize TLess<longint>;
|
||||
maplli=specialize TMap<longint,longint, lesslli>;
|
||||
|
||||
type TGMapTest = class(TTestCase)
|
||||
Published
|
||||
procedure MapTest;
|
||||
public
|
||||
procedure Setup;override;
|
||||
private
|
||||
data:maplli;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
procedure TGMapTest.MapTest;
|
||||
var it:maplli.TMSet.pnode;
|
||||
begin
|
||||
data[3]:=3;
|
||||
data[5]:=5;
|
||||
data[7]:=7;
|
||||
AssertEquals('Wrong min key', 3, data.min()^.data.key);
|
||||
AssertEquals('Wrong max key', 7, data.max()^.data.key);
|
||||
AssertEquals('Wrong min val', 3, data.min()^.data.value);
|
||||
AssertEquals('Wrong max val', 7, data.max()^.data.value);
|
||||
|
||||
AssertEquals('Wrong val', 5, data[5]);
|
||||
|
||||
data.delete(3);
|
||||
AssertEquals('Wrong min key', 5, data.min()^.data.key);
|
||||
AssertEquals('Wrong max key', 7, data.max()^.data.key);
|
||||
AssertEquals('Wrong min val', 5, data.min()^.data.value);
|
||||
AssertEquals('Wrong max val', 7, data.max()^.data.value);
|
||||
|
||||
|
||||
data[3]:=3;
|
||||
data[3]:=47;
|
||||
AssertEquals('Wrong val 2', 47, data[3]);
|
||||
|
||||
if(data.find(4)<>nil) then
|
||||
AssertEquals('Found key which not there', 0, 1);
|
||||
|
||||
data[17]:=42;
|
||||
|
||||
it:=data.min;
|
||||
AssertEquals('Wrong min', 3, it^.Data.key);
|
||||
it:=data.next(it);
|
||||
AssertEquals('Wrong next', 5, it^.Data.key);
|
||||
it:=data.next(it);
|
||||
AssertEquals('Wrong next', 7, it^.Data.key);
|
||||
it:=data.next(it);
|
||||
AssertEquals('Wrong next', 17, it^.Data.key);
|
||||
it:=data.next(it);
|
||||
if(it<>nil) then
|
||||
AssertEquals('Last not nil', 0, 1);
|
||||
|
||||
it:=data.max;
|
||||
AssertEquals('Wrong max', 17, it^.Data.key);
|
||||
it:=data.prev(it);
|
||||
AssertEquals('Wrong prev', 7, it^.Data.key);
|
||||
it:=data.prev(it);
|
||||
AssertEquals('Wrong prev', 5, it^.Data.key);
|
||||
it:=data.prev(it);
|
||||
AssertEquals('Wrong prev', 3, it^.Data.key);
|
||||
it:=data.prev(it);
|
||||
if(it<>nil) then
|
||||
AssertEquals('First not nil', 0, 1);
|
||||
end;
|
||||
|
||||
procedure TGMapTest.Setup;
|
||||
begin
|
||||
data:=maplli.create;
|
||||
end;
|
||||
|
||||
initialization
|
||||
RegisterTest(TGMapTest);
|
||||
end.
|
||||
84
packages/fcl-stl/tests/gmaptestzal.pp
Normal file
84
packages/fcl-stl/tests/gmaptestzal.pp
Normal file
@ -0,0 +1,84 @@
|
||||
{$mode objfpc}
|
||||
|
||||
unit gmaptest;
|
||||
|
||||
interface
|
||||
|
||||
uses fpcunit, testregistry, gmap, gutil;
|
||||
|
||||
type lesslli=specialize TLess<longint>;
|
||||
maplli=specialize TMap<longint,longint, lesslli>;
|
||||
|
||||
type TGMapTest = class(TTestCase)
|
||||
Published
|
||||
procedure MapTest;
|
||||
public
|
||||
procedure Setup;override;
|
||||
private
|
||||
data:maplli;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
procedure TGMapTest.MapTest;
|
||||
var it:maplli.TMSet.pnode;
|
||||
begin
|
||||
data[3]:=3;
|
||||
data[5]:=5;
|
||||
data[7]:=7;
|
||||
AssertEquals('Wrong min key', 3, data.min()^.key);
|
||||
AssertEquals('Wrong max key', 7, data.max()^.key);
|
||||
AssertEquals('Wrong min val', 3, data.min()^.value);
|
||||
AssertEquals('Wrong max val', 7, data.max()^.value);
|
||||
|
||||
AssertEquals('Wrong val', 5, data[5]);
|
||||
|
||||
data.delete(3);
|
||||
AssertEquals('Wrong min key', 5, data.min()^.key);
|
||||
AssertEquals('Wrong max key', 7, data.max()^.key);
|
||||
AssertEquals('Wrong min val', 5, data.min()^.value);
|
||||
AssertEquals('Wrong max val', 7, data.max()^.value);
|
||||
|
||||
|
||||
data[3]:=3;
|
||||
data[3]:=47;
|
||||
AssertEquals('Wrong val 2', 47, data[3]);
|
||||
|
||||
if(data.find(4)<>nil) then
|
||||
AssertEquals('Found key which not there', 0, 1);
|
||||
|
||||
data[17]:=42;
|
||||
|
||||
it:=data.min;
|
||||
AssertEquals('Wrong min', 3, it^.key);
|
||||
it:=data.next(it);
|
||||
AssertEquals('Wrong next', 5, it^.key);
|
||||
it:=data.next(it);
|
||||
AssertEquals('Wrong next', 7, it^.key);
|
||||
it:=data.next(it);
|
||||
AssertEquals('Wrong next', 17, it^.key);
|
||||
it:=data.next(it);
|
||||
if(it<>nil) then
|
||||
AssertEquals('Last not nil', 0, 1);
|
||||
|
||||
it:=data.max;
|
||||
AssertEquals('Wrong max', 17, it^.key);
|
||||
it:=data.prev(it);
|
||||
AssertEquals('Wrong prev', 7, it^.key);
|
||||
it:=data.prev(it);
|
||||
AssertEquals('Wrong prev', 5, it^.key);
|
||||
it:=data.prev(it);
|
||||
AssertEquals('Wrong prev', 3, it^.key);
|
||||
it:=data.prev(it);
|
||||
if(it<>nil) then
|
||||
AssertEquals('First not nil', 0, 1);
|
||||
end;
|
||||
|
||||
procedure TGMapTest.Setup;
|
||||
begin
|
||||
data:=maplli.create;
|
||||
end;
|
||||
|
||||
initialization
|
||||
RegisterTest(TGMapTest);
|
||||
end.
|
||||
47
packages/fcl-stl/tests/gpriorityqueuetest.pp
Normal file
47
packages/fcl-stl/tests/gpriorityqueuetest.pp
Normal file
@ -0,0 +1,47 @@
|
||||
{$mode objfpc}
|
||||
|
||||
unit gpriorityqueuetest;
|
||||
|
||||
interface
|
||||
|
||||
uses fpcunit, testregistry, gpriorityqueue, gutil;
|
||||
|
||||
type lesslli=specialize TLess<longint>;
|
||||
queuelli=specialize TPriorityQueue<longint,lesslli>;
|
||||
|
||||
type TGPQueueTest = class(TTestCase)
|
||||
Published
|
||||
procedure QueueTest;
|
||||
public
|
||||
procedure Setup;override;
|
||||
private
|
||||
data:queuelli;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
procedure TGPQueueTest.QueueTest;
|
||||
var i,last:longint;
|
||||
begin
|
||||
AssertEquals('Not IsEmpty', true, data.IsEmpty);
|
||||
for i:=0 to 10 do
|
||||
data.push(random(10000));
|
||||
last:=data.top;
|
||||
data.pop;
|
||||
for i:=0 to 9 do begin
|
||||
AssertEquals('Wrong order', true, data.top<last);
|
||||
AssertEquals('Wrong size', 10-i, data.size);
|
||||
last:=data.top;
|
||||
data.pop;
|
||||
end;
|
||||
AssertEquals('Not IsEmpty', true, data.IsEmpty);
|
||||
end;
|
||||
|
||||
procedure TGPQueueTest.Setup;
|
||||
begin
|
||||
data:=queuelli.create;
|
||||
end;
|
||||
|
||||
initialization
|
||||
RegisterTest(TGPQueueTest);
|
||||
end.
|
||||
43
packages/fcl-stl/tests/gqueuetest.pp
Normal file
43
packages/fcl-stl/tests/gqueuetest.pp
Normal file
@ -0,0 +1,43 @@
|
||||
{$mode objfpc}
|
||||
|
||||
unit gqueuetest;
|
||||
|
||||
interface
|
||||
|
||||
uses fpcunit, testregistry, gqueue;
|
||||
|
||||
type TQueuelli=specialize TQueue<longint>;
|
||||
|
||||
type TGTQueueTest = class(TTestCase)
|
||||
Published
|
||||
procedure TQueueTest;
|
||||
public
|
||||
procedure Setup;override;
|
||||
private
|
||||
data:TQueuelli;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
procedure TGTQueueTest.TQueueTest;
|
||||
var i:longint;
|
||||
begin
|
||||
AssertEquals('Not IsEmpty', true, data.IsEmpty);
|
||||
for i:=0 to 10 do
|
||||
data.push(i);
|
||||
for i:=0 to 10 do begin
|
||||
AssertEquals('Wrong data', i, data.front);
|
||||
AssertEquals('Wrong size', 11-i, data.size);
|
||||
data.pop;
|
||||
end;
|
||||
AssertEquals('Not IsEmpty', true, data.IsEmpty);
|
||||
end;
|
||||
|
||||
procedure TGTQueueTest.Setup;
|
||||
begin
|
||||
data:=TQueuelli.create;
|
||||
end;
|
||||
|
||||
initialization
|
||||
RegisterTest(TGTQueueTest);
|
||||
end.
|
||||
59
packages/fcl-stl/tests/gsetrefcounttest.pp
Normal file
59
packages/fcl-stl/tests/gsetrefcounttest.pp
Normal file
@ -0,0 +1,59 @@
|
||||
{$mode objfpc}
|
||||
|
||||
unit gsetrefcounttest;
|
||||
|
||||
interface
|
||||
|
||||
uses fpcunit, testregistry, gset, gutil;
|
||||
|
||||
type
|
||||
arr = class
|
||||
a:longint;
|
||||
end;
|
||||
lll=class
|
||||
class function c(a,b: arr):boolean;
|
||||
end;
|
||||
|
||||
type setlli=specialize RBSet<arr,lll>;
|
||||
|
||||
type TGSetRefCountTest = class(TTestCase)
|
||||
Published
|
||||
procedure SetTest;
|
||||
public
|
||||
procedure Setup;override;
|
||||
private
|
||||
data:setlli;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
class function lll.c(a,b: arr):boolean;
|
||||
begin
|
||||
c:=a.a<b.a;
|
||||
end;
|
||||
|
||||
procedure TGSetRefCountTest.SetTest;
|
||||
var x:arr; i:longint;
|
||||
it:setlli.pnode;
|
||||
begin
|
||||
for i:=0 to 20000 do begin
|
||||
x:=arr.create;
|
||||
x.a:=i;
|
||||
{code should crash on this insert}
|
||||
data.insert(x);
|
||||
end;
|
||||
it:=data.min;
|
||||
while it<>nil do begin
|
||||
writeln(it^.data.a);
|
||||
it:=data.next(it);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TGSetRefCountTest.Setup;
|
||||
begin
|
||||
data:=setlli.create;
|
||||
end;
|
||||
|
||||
initialization
|
||||
RegisterTest(TGSetRefCountTest);
|
||||
end.
|
||||
110
packages/fcl-stl/tests/gsettest.pp
Normal file
110
packages/fcl-stl/tests/gsettest.pp
Normal file
@ -0,0 +1,110 @@
|
||||
{$mode objfpc}
|
||||
|
||||
unit gsettest;
|
||||
|
||||
interface
|
||||
|
||||
uses fpcunit, testregistry, gset, gutil;
|
||||
|
||||
type lesslli=specialize TLess<longint>;
|
||||
setlli=specialize TSet<longint,lesslli>;
|
||||
|
||||
type TGSetTest = class(TTestCase)
|
||||
Published
|
||||
procedure SetTest;
|
||||
public
|
||||
procedure Setup;override;
|
||||
private
|
||||
data:setlli;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
procedure TGSetTest.SetTest;
|
||||
var it:setlli.pnode;
|
||||
begin
|
||||
data.insert(3);
|
||||
data.insert(5);
|
||||
data.insert(7);
|
||||
AssertEquals('Wrong min', 3, data.min()^.data);
|
||||
AssertEquals('Wrong max', 7, data.max()^.data);
|
||||
data.delete(3);
|
||||
AssertEquals('Wrong size', 2, data.size);
|
||||
AssertEquals('Wrong min', 5, data.min()^.data);
|
||||
data.insert(3);
|
||||
data.insert(3);
|
||||
data.insert(3);
|
||||
AssertEquals('Wrong size', 3, data.size);
|
||||
AssertEquals('Wrong min', 3, data.min()^.data);
|
||||
if(data.find(4)<>nil) then
|
||||
Fail('Found key which not there');
|
||||
if(data.find(5)=nil) then
|
||||
Fail('Not found key which was there');
|
||||
|
||||
if(data.FindLess(8)^.data<>7) then
|
||||
Fail('Wrong less than 8');
|
||||
if(data.FindLess(7)^.data<>5) then
|
||||
Fail('Wrong less than 7');
|
||||
if(data.FindLess(3)<>nil) then
|
||||
Fail('Wrong less than 3');
|
||||
|
||||
if(data.FindLessEqual(8)^.data<>7) then
|
||||
Fail('Wrong less equal than 8');
|
||||
if(data.FindLessEqual(7)^.data<>7) then
|
||||
Fail('Wrong less equal than 7');
|
||||
if(data.FindLessEqual(6)^.data<>5) then
|
||||
Fail('Wrong less equal than 6');
|
||||
if(data.FindLessEqual(2)<>nil) then
|
||||
Fail('Wrong less equal than 2');
|
||||
|
||||
if(data.FindGreater(2)^.data<>3) then
|
||||
Fail('Wrong greater than 2');
|
||||
if(data.Findgreater(3)^.data<>5) then
|
||||
Fail('Wrong greater than 3');
|
||||
if(data.Findgreater(7)<>nil) then
|
||||
Fail('Wrong greater than 7');
|
||||
|
||||
if(data.FindGreaterEqual(2)^.data<>3) then
|
||||
Fail('Wrong greater equal than 2');
|
||||
if(data.FindGreaterEqual(3)^.data<>3) then
|
||||
Fail('Wrong greater equal than 3');
|
||||
if(data.FindGreaterEqual(4)^.data<>5) then
|
||||
Fail('Wrong greater equal than 4');
|
||||
if(data.FindGreaterEqual(8)<>nil) then
|
||||
Fail('Wrong greater equal than 8');
|
||||
|
||||
data.insert(17);
|
||||
|
||||
it:=data.min;
|
||||
AssertEquals('Wrong min', 3, it^.data);
|
||||
it:=data.next(it);
|
||||
AssertEquals('Wrong next', 5, it^.data);
|
||||
it:=data.next(it);
|
||||
AssertEquals('Wrong next', 7, it^.data);
|
||||
it:=data.next(it);
|
||||
AssertEquals('Wrong next', 17, it^.data);
|
||||
it:=data.next(it);
|
||||
if(it<>nil) then
|
||||
AssertEquals('Last not nil', 0, 1);
|
||||
|
||||
it:=data.max;
|
||||
AssertEquals('Wrong max', 17, it^.data);
|
||||
it:=data.prev(it);
|
||||
AssertEquals('Wrong prev', 7, it^.data);
|
||||
it:=data.prev(it);
|
||||
AssertEquals('Wrong prev', 5, it^.data);
|
||||
it:=data.prev(it);
|
||||
AssertEquals('Wrong prev', 3, it^.data);
|
||||
it:=data.prev(it);
|
||||
if(it<>nil) then
|
||||
AssertEquals('First not nil', 0, 1);
|
||||
end;
|
||||
|
||||
procedure TGSetTest.Setup;
|
||||
begin
|
||||
data:=setlli.create;
|
||||
end;
|
||||
|
||||
initialization
|
||||
RegisterTest(TGSetTest);
|
||||
end.
|
||||
52
packages/fcl-stl/tests/gsorttest.pp
Normal file
52
packages/fcl-stl/tests/gsorttest.pp
Normal file
@ -0,0 +1,52 @@
|
||||
{$mode objfpc}
|
||||
|
||||
unit gsorttest;
|
||||
|
||||
interface
|
||||
|
||||
uses fpcunit, testregistry, gvector, garrayutils, gutil;
|
||||
|
||||
type vectorlli=specialize TVector<longint>;
|
||||
lesslli=specialize TLess<longint>;
|
||||
sortlli=specialize TOrderingArrayUtils<vectorlli, longint, lesslli>;
|
||||
|
||||
type TGSortTest = class(TTestCase)
|
||||
Published
|
||||
procedure SortRandomTest;
|
||||
procedure SortZeroOneTest;
|
||||
public
|
||||
procedure Setup;override;
|
||||
private
|
||||
data:vectorlli;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
procedure TGSortTest.SortRandomTest;
|
||||
var i:longint;
|
||||
begin
|
||||
for i:=0 to 5000 do
|
||||
data.pushBack(random(10000));
|
||||
sortlli.sort(data, 5001);
|
||||
for i:=0 to 4999 do
|
||||
AssertEquals('Wrong order', false, data[i+1]<data[i]);
|
||||
end;
|
||||
|
||||
procedure TGSortTest.SortZeroOneTest;
|
||||
var i:longint;
|
||||
begin
|
||||
for i:=0 to 5000 do
|
||||
data.pushBack(random(2));
|
||||
sortlli.sort(data, 5001);
|
||||
for i:=0 to 4999 do
|
||||
AssertEquals('Wrong order', false, data[i+1]<data[i]);
|
||||
end;
|
||||
|
||||
procedure TGSortTest.Setup;
|
||||
begin
|
||||
data:=vectorlli.create;
|
||||
end;
|
||||
|
||||
initialization
|
||||
RegisterTest(TGSortTest);
|
||||
end.
|
||||
43
packages/fcl-stl/tests/gstacktest.pp
Normal file
43
packages/fcl-stl/tests/gstacktest.pp
Normal file
@ -0,0 +1,43 @@
|
||||
{$mode objfpc}
|
||||
|
||||
unit gstacktest;
|
||||
|
||||
interface
|
||||
|
||||
uses fpcunit, testregistry, gstack;
|
||||
|
||||
type TStacklli=specialize TStack<longint>;
|
||||
|
||||
type TGTStackTest = class(TTestCase)
|
||||
Published
|
||||
procedure TStackTest;
|
||||
public
|
||||
procedure Setup;override;
|
||||
private
|
||||
data:TStacklli;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
procedure TGTStackTest.TStackTest;
|
||||
var i:longint;
|
||||
begin
|
||||
AssertEquals('Not IsEmpty', true, data.IsEmpty);
|
||||
for i:=0 to 10 do
|
||||
data.push(i);
|
||||
for i:=0 to 10 do begin
|
||||
AssertEquals('Wrong data', 10-i, data.top);
|
||||
AssertEquals('Wrong size', 11-i, data.size);
|
||||
data.pop;
|
||||
end;
|
||||
AssertEquals('Not IsEmpty', true, data.IsEmpty);
|
||||
end;
|
||||
|
||||
procedure TGTStackTest.Setup;
|
||||
begin
|
||||
data:=TStacklli.create;
|
||||
end;
|
||||
|
||||
initialization
|
||||
RegisterTest(TGTStackTest);
|
||||
end.
|
||||
111
packages/fcl-stl/tests/gvectortest.pp
Normal file
111
packages/fcl-stl/tests/gvectortest.pp
Normal file
@ -0,0 +1,111 @@
|
||||
{$mode objfpc}
|
||||
|
||||
unit gvectortest;
|
||||
|
||||
interface
|
||||
|
||||
uses fpcunit, testregistry, gvector;
|
||||
|
||||
type vectorlli=specialize TVector<longint>;
|
||||
rec=record
|
||||
a,b:longint;
|
||||
end;
|
||||
vectorrec=specialize TVector<rec>;
|
||||
|
||||
type TGVectorTest = class(TTestCase)
|
||||
Published
|
||||
procedure PushBackTest;
|
||||
procedure ResizeTest;
|
||||
procedure PopbackTest;
|
||||
procedure InsertEraseTest;
|
||||
procedure MutableTest;
|
||||
public
|
||||
procedure Setup;override;
|
||||
private
|
||||
data:vectorlli;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
procedure TGVectorTest.PushBackTest;
|
||||
var i:longint;
|
||||
begin
|
||||
AssertEquals('Not IsEmpty', true, data.IsEmpty);
|
||||
for i:=0 to 10 do
|
||||
data.pushBack(i);
|
||||
for i:=0 to 10 do
|
||||
AssertEquals('Wrong data', i, data[i]);
|
||||
|
||||
AssertEquals('Wrong size', 11, data.size);
|
||||
AssertEquals('IsEmpty', false, data.IsEmpty);
|
||||
end;
|
||||
|
||||
procedure TGVectorTest.ResizeTest;
|
||||
var i:longint;
|
||||
begin
|
||||
AssertEquals('Not IsEmpty', true, data.IsEmpty);
|
||||
data.resize(50);
|
||||
AssertEquals('IsEmpty', false, data.IsEmpty);
|
||||
for i:=0 to 49 do
|
||||
data[i]:=3*i;
|
||||
for i:=0 to 49 do
|
||||
AssertEquals('Wrong data', 3*i, data[i]);
|
||||
AssertEquals('Wrong size', 50, data.size);
|
||||
end;
|
||||
|
||||
procedure TGVectorTest.PopbackTest;
|
||||
var i:longint;
|
||||
begin
|
||||
for i:=0 to 49 do begin
|
||||
data.pushBack(5*i);
|
||||
AssertEquals('Wrong end', 5*i, data.back);
|
||||
AssertEquals('Wrong front', 0, data.front);
|
||||
end;
|
||||
for i:=1 to 10 do begin
|
||||
data.popBack;
|
||||
AssertEquals('Wrong end after popback', 5*(49-i), data.back);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TGVectorTest.InsertEraseTest;
|
||||
var i:longint;
|
||||
begin
|
||||
for i:=0 to 9 do
|
||||
data.pushBack(i);
|
||||
data.insert(3,100);
|
||||
for i:=0 to 2 do
|
||||
AssertEquals('Wrong data before insert', i, data[i]);
|
||||
AssertEquals('Wrong data', 100, data[3]);
|
||||
for i:=4 to 10 do
|
||||
AssertEquals('Wrong data after insert', i-1, data[i]);
|
||||
data.erase(4);
|
||||
for i:=4 to 9 do
|
||||
AssertEquals('Wrong data after erase', i, data[i]);
|
||||
AssertEquals('Wrong data before erase', 100, data[3]);
|
||||
for i:=0 to 2 do
|
||||
AssertEquals('Wrong data before erase', i, data[i]);
|
||||
end;
|
||||
|
||||
procedure TGVectorTest.MutableTest;
|
||||
var dat:vectorrec;
|
||||
begin
|
||||
dat:=vectorrec.create;
|
||||
dat.resize(2);
|
||||
dat.mutable[0]^.a:=5;
|
||||
dat.mutable[0]^.b:=7;
|
||||
AssertEquals('Wrong data', 5, dat[0].a);
|
||||
AssertEquals('Wrong data', 7, dat[0].b);
|
||||
dat.mutable[0]^.a:=45;
|
||||
dat.mutable[0]^.b:=47;
|
||||
AssertEquals('Wrong data', 45, dat[0].a);
|
||||
AssertEquals('Wrong data', 47, dat[0].b);
|
||||
end;
|
||||
|
||||
procedure TGVectorTest.Setup;
|
||||
begin
|
||||
data:=vectorlli.create;
|
||||
end;
|
||||
|
||||
initialization
|
||||
RegisterTest(TGVectorTest);
|
||||
end.
|
||||
4
packages/fcl-stl/tests/run-all-tests
Executable file
4
packages/fcl-stl/tests/run-all-tests
Executable file
@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
rm *.o *.ppu ../*.o ../*.ppu testrunner
|
||||
fpc -Fu.. -gttt testrunner.pp -Sa
|
||||
./testrunner --all
|
||||
27
packages/fcl-stl/tests/suiteconfig.pp
Normal file
27
packages/fcl-stl/tests/suiteconfig.pp
Normal file
@ -0,0 +1,27 @@
|
||||
{$mode objfpc}
|
||||
{$h+}
|
||||
{
|
||||
This file is part of the Free Component Library (FCL)
|
||||
Copyright (c) 2004 by Dean Zobec, Michael Van Canneyt
|
||||
|
||||
a unit to register the tests to be runned.
|
||||
|
||||
See the file COPYING.FPC, included in this distribution,
|
||||
for details about the copyright.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
**********************************************************************}
|
||||
unit suiteconfig;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
gvectortest, gstacktest, gqueuetest, gdequetest, gsorttest,
|
||||
gpriorityqueuetest, gsettest, gmaptest;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
138
packages/fcl-stl/tests/testrunner.pp
Normal file
138
packages/fcl-stl/tests/testrunner.pp
Normal file
@ -0,0 +1,138 @@
|
||||
{
|
||||
This file is part of the Free Component Library (FCL)
|
||||
Copyright (c) 2004 by Dean Zobec, Michael Van Canneyt
|
||||
|
||||
an example of a console test runner of FPCUnit tests.
|
||||
|
||||
See the file COPYING.FPC, included in this distribution,
|
||||
for details about the copyright.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
}
|
||||
program testrunner;
|
||||
|
||||
{$mode objfpc}
|
||||
{$h+}
|
||||
|
||||
uses
|
||||
custapp, Classes, SysUtils, fpcunit, suiteconfig, testreport, testregistry;
|
||||
|
||||
|
||||
const
|
||||
ShortOpts = 'alh';
|
||||
Longopts: Array[1..5] of String = (
|
||||
'all','list','format:','suite:','help');
|
||||
Version = 'Version 0.2';
|
||||
|
||||
|
||||
type
|
||||
TTestRunner = Class(TCustomApplication)
|
||||
private
|
||||
FXMLResultsWriter: TXMLResultsWriter;
|
||||
protected
|
||||
procedure DoRun ; Override;
|
||||
procedure doTestRun(aTest: TTest); virtual;
|
||||
public
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
end;
|
||||
|
||||
|
||||
constructor TTestRunner.Create(AOwner: TComponent);
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
FXMLResultsWriter := TXMLResultsWriter.Create;
|
||||
end;
|
||||
|
||||
|
||||
destructor TTestRunner.Destroy;
|
||||
begin
|
||||
FXMLResultsWriter.Free;
|
||||
end;
|
||||
|
||||
|
||||
procedure TTestRunner.doTestRun(aTest: TTest);
|
||||
var
|
||||
testResult: TTestResult;
|
||||
begin
|
||||
testResult := TTestResult.Create;
|
||||
try
|
||||
testResult.AddListener(FXMLResultsWriter);
|
||||
aTest.Run(testResult);
|
||||
FXMLResultsWriter.WriteResult(testResult);
|
||||
finally
|
||||
testResult.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure TTestRunner.DoRun;
|
||||
var
|
||||
I : Integer;
|
||||
S : String;
|
||||
begin
|
||||
S:=CheckOptions(ShortOpts,LongOpts);
|
||||
If (S<>'') then
|
||||
Writeln(S);
|
||||
if HasOption('h', 'help') or (ParamCount = 0) then
|
||||
begin
|
||||
writeln(Title);
|
||||
writeln(Version);
|
||||
writeln('Usage: ');
|
||||
writeln('-l or --list to show a list of registered tests');
|
||||
writeln('default format is xml, add --format=latex to output the list as latex source');
|
||||
writeln('-a or --all to run all the tests and show the results in xml format');
|
||||
writeln('The results can be redirected to an xml file,');
|
||||
writeln('for example: ./testrunner --all > results.xml');
|
||||
writeln('use --suite=MyTestSuiteName to run only the tests in a single test suite class');
|
||||
end
|
||||
else;
|
||||
if HasOption('l', 'list') then
|
||||
begin
|
||||
if HasOption('format') then
|
||||
begin
|
||||
if GetOptionValue('format') = 'latex' then
|
||||
writeln(GetSuiteAsLatex(GetTestRegistry))
|
||||
else
|
||||
writeln(GetSuiteAsXML(GetTestRegistry));
|
||||
end
|
||||
else
|
||||
writeln(GetSuiteAsXML(GetTestRegistry));
|
||||
end;
|
||||
if HasOption('a', 'all') then
|
||||
begin
|
||||
doTestRun(GetTestRegistry)
|
||||
end
|
||||
else
|
||||
if HasOption('suite') then
|
||||
begin
|
||||
S := '';
|
||||
S:=GetOptionValue('suite');
|
||||
if S = '' then
|
||||
for I := 0 to GetTestRegistry.Tests.count - 1 do
|
||||
writeln(GetTestRegistry[i].TestName)
|
||||
else
|
||||
for I := 0 to GetTestRegistry.Tests.count - 1 do
|
||||
if GetTestRegistry[i].TestName = S then
|
||||
begin
|
||||
doTestRun(GetTestRegistry[i]);
|
||||
end;
|
||||
end;
|
||||
Terminate;
|
||||
end;
|
||||
|
||||
|
||||
var
|
||||
App: TTestRunner;
|
||||
|
||||
|
||||
begin
|
||||
App := TTestRunner.Create(nil);
|
||||
App.Initialize;
|
||||
App.Title := 'FPCUnit Console Test Case runner.';
|
||||
App.Run;
|
||||
App.Free;
|
||||
end.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user