Changeset 5e8d732


Ignore:
Timestamp:
May 30, 2017, 9:53:15 AM (8 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
d6fb3c7
Parents:
a029714 (diff), bff607e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Files:
2 added
1 deleted
4 edited

Legend:

Unmodified
Added
Removed
  • doc/user/user.tex

    ra029714 r5e8d732  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Wed May 24 22:21:42 2017
    14 %% Update Count     : 1994
     13%% Last Modified On : Tue May 30 09:08:16 2017
     14%% Update Count     : 2072
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    135135
    136136\CFA{}\index{cforall@\CFA}\footnote{Pronounced ``\Index*{C-for-all}'', and written \CFA, CFA, or \CFL.} is a modern general-purpose programming-language, designed as an evolutionary step forward for the C programming language.
    137 The syntax of the \CFA language builds from C, and should look immediately familiar to C/\Index*[C++]{\CC} programmers.
    138 % Any language feature that is not described here can be assumed to be using the standard C11 syntax.
     137The syntax of the \CFA language builds from C, and should look immediately familiar to C/\Index*[C++]{\CC{}} programmers.
     138% Any language feature that is not described here can be assumed to be using the standard \Celeven syntax.
    139139\CFA adds many modern programming-language features that directly lead to increased \emph{\Index{safety}} and \emph{\Index{productivity}}, while maintaining interoperability with existing C programs and achieving C performance.
    140 Like C, \CFA is a statically typed, procedural language with a low-overhead runtime, meaning there is no global \Index{garbage-collection}, but \Index{regional garbage-collection}\index{garbage collection!regional} is possible.
     140Like C, \CFA is a statically typed, procedural language with a low-overhead runtime, meaning there is no global \Index{garbage-collection}, but \Index{regional garbage-collection}\index{garbage-collection!regional} is possible.
    141141The primary new features include parametric-polymorphic routines and types, exceptions, concurrency, and modules.
    142142
     
    147147instead, a programmer evolves an existing C program into \CFA by incrementally incorporating \CFA features.
    148148New programs can be written in \CFA using a combination of C and \CFA features.
    149 \Index*[C++]{\CC} had a similar goal 30 years ago, but currently has the disadvantages of multiple legacy design-choices that cannot be updated and active divergence of the language model from C, requiring significant effort and training to incrementally add \CC to a C-based project.
     149\Index*[C++]{\CC{}} had a similar goal 30 years ago, but currently has the disadvantages of multiple legacy design-choices that cannot be updated and active divergence of the language model from C, requiring significant effort and training to incrementally add \CC to a C-based project.
    150150In contrast, \CFA has 30 years of hindsight and a clean starting point.
    151151
    152 Like \Index*[C++]{\CC}, there may be both an old and new ways to achieve the same effect.
    153 For example, the following programs compare the \CFA, C, nad \CC I/O mechanisms, where the programs output the same result.
     152Like \Index*[C++]{\CC{}}, there may be both an old and new ways to achieve the same effect.
     153For example, the following programs compare the \CFA, C, and \CC I/O mechanisms, where the programs output the same result.
    154154\begin{quote2}
    155155\begin{tabular}{@{}l@{\hspace{1.5em}}l@{\hspace{1.5em}}l@{}}
    156156\multicolumn{1}{c@{\hspace{1.5em}}}{\textbf{\CFA}}      & \multicolumn{1}{c}{\textbf{C}}        & \multicolumn{1}{c}{\textbf{\CC}}      \\
    157157\begin{cfa}
    158 #include <fstream>
     158#include <fstream>§\indexc{fstream}§
    159159
    160160int main( void ) {
     
    165165&
    166166\begin{lstlisting}
    167 #include <stdio.h>
     167#include <stdio.h>§\indexc{stdio.h}§
    168168
    169169int main( void ) {
     
    174174&
    175175\begin{lstlisting}
    176 #include <iostream>
     176#include <iostream>§\indexc{iostream}§
    177177using namespace std;
    178178int main() {
     
    183183\end{tabular}
    184184\end{quote2}
    185 While the \CFA I/O looks similar to the \Index*[C++]{\CC} output style, there are important differences, such as automatic spacing between variables as in \Index*{Python} (see~\VRef{s:IOLibrary}).
     185While the \CFA I/O looks similar to the \Index*[C++]{\CC{}} output style, there are important differences, such as automatic spacing between variables as in \Index*{Python} (see~\VRef{s:IOLibrary}).
    186186
    187187This document is a user manual for the \CFA programming language, targeted at \CFA programmers.
     
    197197Even with all its problems, C continues to be popular because it allows writing software at virtually any level in a computer system without restriction.
    198198For system programming, where direct access to hardware and dealing with real-time issues is a requirement, C is usually the language of choice.
    199 The TIOBE index~\cite{TIOBE} for March 2016 showed the following programming-language popularity: \Index*{Java} 20.5\%, C 14.5\%, \Index*[C++]{\CC} 6.7\%, \Csharp 4.3\%, \Index*{Python} 4.3\%, where the next 50 languages are less than 3\% each with a long tail.
     199The TIOBE index~\cite{TIOBE} for March 2016 showed the following programming-language popularity: \Index*{Java} 20.5\%, C 14.5\%, \Index*[C++]{\CC{}} 6.7\%, \Csharp 4.3\%, \Index*{Python} 4.3\%, where the next 50 languages are less than 3\% each with a long tail.
    200200As well, for 30 years, C has been the number 1 and 2 most popular programming language:
    201201\begin{center}
     
    225225These costs can be prohibitive for many companies with a large software base in C/\CC, and a significant number of programmers requiring retraining to a new programming language.
    226226
    227 The result of this project is a language that is largely backwards compatible with \Index*{C11}~\cite{C11}, but fixing some of the well known C problems and containing many modern language features.
     227The result of this project is a language that is largely backwards compatible with \Index*[C11]{\Celeven{}}~\cite{C11}, but fixing some of the well known C problems and containing many modern language features.
    228228Without significant extension to the C programming language, it is becoming unable to cope with the needs of modern programming problems and programmers;
    229229as a result, it will fade into disuse.
    230230Considering the large body of existing C code and programmers, there is significant impetus to ensure C is transformed into a modern programming language.
    231 While \Index*{C11} made a few simple extensions to the language, nothing was added to address existing problems in the language or to augment the language with modern language features.
     231While \Index*[C11]{\Celeven{}} made a few simple extensions to the language, nothing was added to address existing problems in the language or to augment the language with modern language features.
    232232While some may argue that modern language features may make C complex and inefficient, it is clear a language without modern capabilities is insufficient for the advanced programming problems existing today.
    233233
     
    243243int forty_two = identity( 42 );                 §\C{// T is bound to int, forty\_two == 42}§
    244244\end{lstlisting}
    245 % extending the C type system with parametric polymorphism and overloading, as opposed to the \Index*[C++]{\CC} approach of object-oriented extensions.
     245% extending the C type system with parametric polymorphism and overloading, as opposed to the \Index*[C++]{\CC{}} approach of object-oriented extensions.
    246246\CFA{}\hspace{1pt}'s polymorphism was originally formalized by Ditchfiled~\cite{Ditchfield92}, and first implemented by Bilson~\cite{Bilson03}.
    247247However, at that time, there was little interesting in extending C, so work did not continue.
     
    262262A simple example is leveraging the existing type-unsafe (©void *©) C ©bsearch© to binary search a sorted floating-point array:
    263263\begin{lstlisting}
    264 void * bsearch( const void * key, const void * base, size_t nmemb, size_t size,
     264void * bsearch( const void * key, const void * base, size_t dim, size_t size,
    265265                                int (* compar)( const void *, const void * ));
    266266
     
    340340The 1999 C standard plus GNU extensions.
    341341\item
     342{\lstset{deletekeywords={inline}}
    342343\Indexc{-fgnu89-inline}\index{compilation option!-fgnu89-inline@{©-fgnu89-inline©}}
    343344Use the traditional GNU semantics for inline routines in C99 mode, which allows inline routines in header files.
     345}%
    344346\end{description}
    345347The following new \CFA options are available:
     
    412414\begin{cfa}
    413415#ifndef __CFORALL__
    414 #include <stdio.h>                                              §\C{// C header file}§
     416#include <stdio.h>§\indexc{stdio.h}§    §\C{// C header file}§
    415417#else
    416 #include <fstream>                                              §\C{// \CFA header file}§
     418#include <fstream>§\indexc{fstream}§    §\C{// \CFA header file}§
    417419#endif
    418420\end{cfa}
     
    747749p2 = p1 + x;                                    §\C{// compiler infers *p2 = *p1 + x;}§
    748750\end{cfa}
    749 Algol68 infers the following deferencing ©*p2 = *p1 + x©, because adding the arbitrary integer value in ©x© to the address of ©p1© and storing the resulting address into ©p2© is an unlikely operation.
     751Algol68 infers the following dereferencing ©*p2 = *p1 + x©, because adding the arbitrary integer value in ©x© to the address of ©p1© and storing the resulting address into ©p2© is an unlikely operation.
    750752Unfortunately, automatic dereferencing does not work in all cases, and so some mechanism is necessary to fix incorrect choices.
    751753
     
    14211423
    14221424Given the \CFA restrictions above, both named and default arguments are backwards compatible.
    1423 \Index*[C++]{\CC} only supports default arguments;
     1425\Index*[C++]{\CC{}} only supports default arguments;
    14241426\Index*{Ada} supports both named and default arguments.
    14251427
     
    14551457\subsection{Type Nesting}
    14561458
    1457 \CFA allows \Index{type nesting}, and type qualification of the nested typres (see \VRef[Figure]{f:TypeNestingQualification}), where as C hoists\index{type hoisting} (refactors) nested types into the enclosing scope and has no type qualification.
     1459\CFA allows \Index{type nesting}, and type qualification of the nested types (see \VRef[Figure]{f:TypeNestingQualification}), where as C hoists\index{type hoisting} (refactors) nested types into the enclosing scope and has no type qualification.
    14581460\begin{figure}
    14591461\centering
     
    17681770\index{lvalue}
    17691771The left-hand side is a tuple of \emph{lvalues}, and the right-hand side is a tuple of \emph{expr}s.
    1770 Each \emph{expr} appearing on the righthand side of a multiple assignment statement is assigned to the corresponding \emph{lvalues} on the left-hand side of the statement using parallel semantics for each assignment.
     1772Each \emph{expr} appearing on the right-hand side of a multiple assignment statement is assigned to the corresponding \emph{lvalues} on the left-hand side of the statement using parallel semantics for each assignment.
    17711773An example of multiple assignment is:
    17721774\begin{cfa}
     
    18611863While C provides ©continue© and ©break© statements for altering control flow, both are restricted to one level of nesting for a particular control structure.
    18621864Unfortunately, this restriction forces programmers to use \Indexc{goto} to achieve the equivalent control-flow for more than one level of nesting.
    1863 To prevent having to switch to the ©goto©, \CFA extends the \Indexc{continue}\index{continue@©continue©!labelled}\index{labelled!continue@©continue©} and \Indexc{break}\index{break@©break©!labelled}\index{labelled!break@©break©} with a target label to support static multi-level exit\index{multi-level exit}\index{static multi-level exit}~\cite{Buhr85,Java}.
     1865To prevent having to switch to the ©goto©, \CFA extends the \Indexc{continue}\index{continue@\lstinline $continue$!labelled}\index{labelled!continue@©continue©} and \Indexc{break}\index{break@\lstinline $break$!labelled}\index{labelled!break@©break©} with a target label to support static multi-level exit\index{multi-level exit}\index{static multi-level exit}~\cite{Buhr85,Java}.
    18641866For both ©continue© and ©break©, the target label must be directly associated with a ©for©, ©while© or ©do© statement;
    18651867for ©break©, the target label can also be associated with a ©switch©, ©if© or compound (©{}©) statement.
     
    19011903                if ( ... ) {
    19021904                        for ( ... ) {
    1903                                 for ( ... ) {
     1905                                while ( ... ) {
    19041906                                        ... goto ®LC®; ...
    19051907                                        ... goto ®LS®; ...
     
    19221924\end{figure}
    19231925
    1924 Both labelled ©continue© and ©break© are a ©goto©\index{goto@©goto©!restricted} restricted in the following ways:
     1926\begin{comment}
     1927int main() {
     1928  LC: {
     1929          LS: switch ( 1 ) {
     1930                  case 3:
     1931                  LIF: if ( 1 ) {
     1932                          LF: for ( ;; ) {
     1933                                  LW: while ( 1 ) {
     1934                                                break LC;                       // terminate compound
     1935                                                break LS;                       // terminate switch
     1936                                                break LIF;                      // terminate if
     1937                                                continue LF;     // resume loop
     1938                                                break LF;                       // terminate loop
     1939                                                continue LW;     // resume loop
     1940                                                break LW;                 // terminate loop
     1941                                        } // while
     1942                                } // for
     1943                        } else {
     1944                                break LIF;                                       // terminate if
     1945                        } // if
     1946                } // switch
     1947        } // compound
     1948        {
     1949                switch ( 1 ) {
     1950                  case 3:
     1951                        if ( 1 ) {
     1952                                for ( ;; ) {
     1953                                        while ( 1 ) {
     1954                                                goto LCx;
     1955                                                goto LSx;
     1956                                                goto LIF;
     1957                                                goto LFC;
     1958                                                goto LFB;
     1959                                                goto LWC;
     1960                                                goto LWB;
     1961                                          LWC: ; } LWB: ;
     1962                                  LFC: ; } LFB: ;
     1963                        } else {
     1964                                goto LIF;
     1965                        } L3: ;
     1966                } LSx: ;
     1967        } LCx: ;
     1968}
     1969
     1970// Local Variables: //
     1971// tab-width: 4 //
     1972// End: //
     1973\end{comment}
     1974
     1975
     1976Both labelled ©continue© and ©break© are a ©goto©\index{goto@\lstinline $goto$!restricted} restricted in the following ways:
    19251977\begin{itemize}
    19261978\item
     
    22492301
    22502302The goal of \CFA I/O is to simplify the common cases\index{I/O!common case}, while fully supporting polymorphism and user defined types in a consistent way.
     2303The \CFA header file for the I/O library is \Indexc{fstream}.
     2304
    22512305The common case is printing out a sequence of variables separated by whitespace.
    22522306\begin{quote2}
     
    23062360
    23072361
    2308 The implicit separator\index{I/O separator} character (space/blank) is a separator not a terminator.
     2362The implicit separator\index{I/O!separator} character (space/blank) is a separator not a terminator.
    23092363The rules for implicitly adding the separator are:
    23102364\begin{enumerate}
     
    23342388
    23352389\item
    2336 A separator does not appear before a C string starting with the (extended) \Index{ASCII}\index{ASCII!extended} characters: \lstinline[mathescape=off,basicstyle=\tt]@([{=$£¥¡¿«@
     2390A separator does not appear before a C string starting with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[mathescape=off,basicstyle=\tt]@([{=$£¥¡¿«@
    23372391%$
    23382392\begin{cfa}[mathescape=off]
     
    23492403\item
    23502404{\lstset{language=CFA,deletedelim=**[is][]{¢}{¢}}
    2351 A seperator does not appear after a C string ending with the (extended) \Index{ASCII}\index{ASCII!extended} characters: \lstinline[basicstyle=\tt]@,.;!?)]}%¢»@
     2405A seperator does not appear after a C string ending with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[basicstyle=\tt]@,.;!?)]}%¢»@
    23522406\begin{cfa}[belowskip=0pt]
    23532407sout | 1 | ", x" | 2 | ". x" | 3 | "; x" | 4 | "! x" | 5 | "? x" | 6 | "% x"
     
    23602414
    23612415\item
    2362 A seperator does not appear before or after a C string begining/ending with the \Index{ASCII} quote or whitespace characters: \lstinline[basicstyle=\tt,showspaces=true]@`'": \t\v\f\r\n@
     2416A seperator does not appear before or after a C string begining/ending with the \Index*{ASCII} quote or whitespace characters: \lstinline[basicstyle=\tt,showspaces=true]@`'": \t\v\f\r\n@
    23632417\begin{cfa}[belowskip=0pt]
    23642418sout | "x`" | 1 | "`x'" | 2 | "'x\"" | 3 | "\"x:" | 4 | ":x " | 5 | " x\t" | 6 | "\tx" | endl;
     
    26302684
    26312685\CFA supports C initialization of structures, but it also adds constructors for more advanced initialization.
    2632 Additionally, \CFA adds destructors that are called when a variable is de-allocated (variable goes out of scope or object is deleted).
     2686Additionally, \CFA adds destructors that are called when a variable is deallocated (variable goes out of scope or object is deleted).
    26332687These functions take a reference to the structure as a parameter (see References for more information).
    26342688
     
    29633017Generics allow programmers to use type variables in place of concrete types so that the code can be reused with multiple types.
    29643018The type parameters can be restricted to satisfy a set of constraints.
    2965 This enables \CFA to build fully compiled generic functions and types, unlike other languages like \Index*[C++]{\CC} where templates are expanded or must be explicitly instantiated.
     3019This enables \CFA to build fully compiled generic functions and types, unlike other languages like \Index*[C++]{\CC{}} where templates are expanded or must be explicitly instantiated.
    29663020
    29673021
    29683022\subsection{Generic Functions}
    29693023
    2970 Generic functions in \CFA are similar to template functions in \Index*[C++]{\CC}, and will sometimes be expanded into specialized versions, just like in \CC.
     3024Generic functions in \CFA are similar to template functions in \Index*[C++]{\CC{}}, and will sometimes be expanded into specialized versions, just like in \CC.
    29713025The difference, however, is that generic functions in \CFA can also be separately compiled, using function pointers for callers to pass in all needed functionality for the given type.
    29723026This means that compiled libraries can contain generic functions that can be used by programs linked with them (statically or dynamically).
     
    30873141
    30883142Generic types are defined using the same mechanisms as those described above for generic functions.
    3089 This feature allows users to create types that have one or more fields that use generic parameters as types, similar to a template classes in \Index*[C++]{\CC}.
     3143This feature allows users to create types that have one or more fields that use generic parameters as types, similar to a template classes in \Index*[C++]{\CC{}}.
    30903144For example, to make a generic linked list, a placeholder is created for the type of the elements, so that the specific type of the elements in the list need not be specified when defining the list.
    30913145In C, something like this would have to be done using void pointers and unsafe casting.
     
    31393193Throwing an exception terminates execution of the current block, invokes the destructors of variables that are local to the block, and propagates the exception to the parent block.
    31403194The exception is immediately re-thrown from the parent block unless it is caught as described below.
    3141 \CFA uses keywords similar to \Index*[C++]{\CC} for exception handling.
     3195\CFA uses keywords similar to \Index*[C++]{\CC{}} for exception handling.
    31423196An exception is thrown using a throw statement, which accepts one argument.
    31433197
     
    33453399
    33463400A task may define a constructor, which will be called upon allocation and run on the caller.s thread.
    3347 A destructor may also be defined, which is called at de-allocation (when a dynamic object is deleted or when a local object goes out of scope).
     3401A destructor may also be defined, which is called at deallocation (when a dynamic object is deleted or when a local object goes out of scope).
    33483402After a task is allocated and initialized, its thread is spawned implicitly and begins executing in its function call method.
    33493403All tasks must define this function call method, with a void return value and no additional parameters, or the compiler will report an error.
     
    35223576\subsection{No Declarations, No Header Files}
    35233577
    3524 In C and \Index*[C++]{\CC}, it is necessary to declare or define every global variable, global function, and type before it is used in each file.
     3578In C and \Index*[C++]{\CC{}}, it is necessary to declare or define every global variable, global function, and type before it is used in each file.
    35253579Header files and a preprocessor are normally used to avoid repeating code.
    35263580Thus, many variables, functions, and types are described twice, which exposes an opportunity for errors and causes additional maintenance work.
     
    41674221In developing \CFA, many other languages were consulted for ideas, constructs, and syntax.
    41684222Therefore, it is important to show how these languages each compare with Do.
    4169 In this section, \CFA is compared with what the writers of this document consider to be the closest competitors of Do: \Index*[C++]{\CC}, \Index*{Go}, \Index*{Rust}, and \Index*{D}.
     4223In this section, \CFA is compared with what the writers of this document consider to be the closest competitors of Do: \Index*[C++]{\CC{}}, \Index*{Go}, \Index*{Rust}, and \Index*{D}.
    41704224
    41714225
     
    47924846\subsubsection[C++]{\CC}
    47934847
    4794 \Index*[C++]{\CC} is a general-purpose programming language.
     4848\Index*[C++]{\CC{}} is a general-purpose programming language.
    47954849It has imperative, object-oriented and generic programming features, while also providing facilities for low-level memory manipulation. (Wikipedia)
    47964850
     
    49775031}
    49785032\end{cfa}
    4979 \item[Rationale:] dropped from C11 standard.\footnote{
     5033\item[Rationale:] dropped from \Celeven standard.\footnote{
    49805034At least one type specifier shall be given in the declaration specifiers in each declaration, and in the specifier-qualifier list in each structure declaration and type name~\cite[\S~6.7.2(2)]{C11}}
    49815035\item[Effect on original feature:] original feature is deprecated. \\
     
    50455099static struct X a = { 1, &b };  §\C{// definition}§
    50465100\end{cfa}
    5047 \item[Rationale:] avoids having different initialization rules for builtin types and userdefined types.
     5101\item[Rationale:] avoids having different initialization rules for builtin types and user-defined types.
    50485102\item[Effect on original feature:] change to semantics of well-defined feature.
    50495103\item[Difficulty of converting:] the initializer for one of a set of mutually-referential file-local static objects must invoke a routine call to achieve the initialization.
     
    50705124\end{cfa}
    50715125In C, the name of the nested types belongs to the same scope as the name of the outermost enclosing structure, \ie the nested types are hoisted to the scope of the outer-most type, which is not useful and confusing.
    5072 \CFA is C \emph{incompatible} on this issue, and provides semantics similar to \Index*[C++]{\CC}.
     5126\CFA is C \emph{incompatible} on this issue, and provides semantics similar to \Index*[C++]{\CC{}}.
    50735127Nested types are not hoisted and can be referenced using the field selection operator ``©.©'', unlike the \CC scope-resolution operator ``©::©''.
    50745128\item[Rationale:] ©struct© scope is crucial to \CFA as an information structuring and hiding mechanism.
     
    50865140struct Y;                                               §\C{// struct Y and struct X are at the same scope}§
    50875141struct X {
    5088 struct Y { /* ... */ } y;
     5142        struct Y { /* ... */ } y;
    50895143};
    50905144\end{cfa}
     
    51085162\label{s:StandardHeaders}
    51095163
    5110 C11 prescribes the following standard header-files~\cite[\S~7.1.2]{C11} and \CFA adds to this list:
     5164\Celeven prescribes the following standard header-files~\cite[\S~7.1.2]{C11} and \CFA adds to this list:
    51115165\begin{quote2}
    5112 \begin{tabular}{llll|l}
     5166\lstset{deletekeywords={float},deletekeywords=[2]{signal}}
     5167\begin{tabular}{@{}llll|l@{}}
    51135168\multicolumn{4}{c|}{C11} & \multicolumn{1}{c}{\CFA}             \\
    51145169\hline
    51155170\begin{tabular}{@{}l@{}}
    5116 assert.h        \\
    5117 complex.h       \\
    5118 ctype.h         \\
    5119 errno.h         \\
    5120 fenv.h          \\
    5121 float.h         \\
    5122 inttypes.h      \\
    5123 iso646.h        \\
     5171\Indexc{assert.h}               \\
     5172\Indexc{complex.h}              \\
     5173\Indexc{ctype.h}                \\
     5174\Indexc{errno.h}                \\
     5175\Indexc{fenv.h}                 \\
     5176\Indexc{float.h}                \\
     5177\Indexc{inttypes.h}             \\
     5178\Indexc{iso646.h}               \\
    51245179\end{tabular}
    51255180&
    51265181\begin{tabular}{@{}l@{}}
    5127 limits.h        \\
    5128 locale.h        \\
    5129 math.h          \\
    5130 setjmp.h        \\
    5131 signal.h        \\
    5132 stdalign.h      \\
    5133 stdarg.h        \\
    5134 stdatomic.h     \\
     5182\Indexc{limits.h}               \\
     5183\Indexc{locale.h}               \\
     5184\Indexc{math.h}                 \\
     5185\Indexc{setjmp.h}               \\
     5186\Indexc{signal.h}               \\
     5187\Indexc{stdalign.h}             \\
     5188\Indexc{stdarg.h}               \\
     5189\Indexc{stdatomic.h}    \\
    51355190\end{tabular}
    51365191&
    51375192\begin{tabular}{@{}l@{}}
    5138 stdbool.h       \\
    5139 stddef.h        \\
    5140 stdint.h        \\
    5141 stdio.h         \\
    5142 stdlib.h        \\
    5143 stdnoreturn.h \\
    5144 string.h        \\
    5145 tgmath.h        \\
     5193\Indexc{stdbool.h}              \\
     5194\Indexc{stddef.h}               \\
     5195\Indexc{stdint.h}               \\
     5196\Indexc{stdio.h}                \\
     5197\Indexc{stdlib.h}               \\
     5198\Indexc{stdnoreturn.h}  \\
     5199\Indexc{string.h}               \\
     5200\Indexc{tgmath.h}               \\
    51465201\end{tabular}
    51475202&
    51485203\begin{tabular}{@{}l@{}}
    5149 threads.h       \\
    5150 time.h          \\
    5151 uchar.h         \\
    5152 wchar.h         \\
    5153 wctype.h        \\
    5154                         \\
    5155                         \\
    5156                         \\
     5204\Indexc{threads.h}              \\
     5205\Indexc{time.h}                 \\
     5206\Indexc{uchar.h}                \\
     5207\Indexc{wchar.h}                \\
     5208\Indexc{wctype.h}               \\
     5209                                                \\
     5210                                                \\
     5211                                                \\
    51575212\end{tabular}
    51585213&
    51595214\begin{tabular}{@{}l@{}}
    5160 unistd.h        \\
    5161 gmp.h           \\
    5162                         \\
    5163                         \\
    5164                         \\
    5165                         \\
    5166                         \\
    5167                         \\
     5215\Indexc{unistd.h}               \\
     5216\Indexc{gmp.h}                  \\
     5217                                                \\
     5218                                                \\
     5219                                                \\
     5220                                                \\
     5221                                                \\
     5222                                                \\
    51685223\end{tabular}
    51695224\end{tabular}
     
    51775232\label{s:StandardLibrary}
    51785233
    5179 The \CFA standard-library wraps explicitly-polymorphic C general-routines into implicitly-polymorphic versions.
    5180 
    5181 
    5182 \subsection{malloc}
     5234The \CFA standard-library wraps explicitly-polymorphic C routines into implicitly-polymorphic versions.
     5235
     5236
     5237\subsection{Storage Management}
     5238
     5239The storage-management routines extend their C equivalents by overloading, alternate names, providing shallow type-safety, and removing the need to specify the allocation size for non-array types.
     5240\begin{center}
     5241\begin{tabular}{@{}r|l|l|l|l@{}}
     5242                                        & fill                          & resize        & alignment     & array \\
     5243\hline
     5244©malloc©                        & no/yes                        & no/yes        & no            & no    \\
     5245©amalloc©                       & no/copy data/yes      & no/yes        & no            & yes   \\
     5246©calloc©                        & yes (0 only)          & no            & no            & yes   \\
     5247©realloc©                       & no/copy data          & yes           & no            & no    \\
     5248©memalign©                      & no/yes                        & no            & yes           & no    \\
     5249©amemalign©                     & no/yes                        & no            & yes           & yes   \\
     5250©align_alloc©           & no                            & no            & yes           & no    \\
     5251©posix_memalign©        & no                            & no            & yes           & no    \\
     5252\end{tabular}
     5253\end{center}
     5254When ©amalloc© resizes and fills, the space after the copied data from the source is set to the fill character.
     5255It is impossible to resize with alignment because the underlying ©realloc© allocates storage if more space is needed, and it does not honour alignment from the original allocation.
    51835256
    51845257\leavevmode
    51855258\begin{cfa}[aboveskip=0pt,belowskip=0pt]
     5259// allocation, non-array types
    51865260forall( dtype T | sized(T) ) T * malloc( void );§\indexc{malloc}§
    51875261forall( dtype T | sized(T) ) T * malloc( char fill );
    5188 forall( dtype T | sized(T) ) T * malloc( T * ptr, size_t size );
    5189 forall( dtype T | sized(T) ) T * malloc( T * ptr, size_t size, unsigned char fill );
    5190 forall( dtype T | sized(T) ) T * calloc( size_t nmemb );§\indexc{calloc}§
    5191 forall( dtype T | sized(T) ) T * realloc( T * ptr, size_t size );§\indexc{ato}§
    5192 forall( dtype T | sized(T) ) T * realloc( T * ptr, size_t size, unsigned char fill );
    5193 
    5194 forall( dtype T | sized(T) ) T * aligned_alloc( size_t alignment );§\indexc{ato}§
    5195 forall( dtype T | sized(T) ) T * memalign( size_t alignment );          // deprecated
    5196 forall( dtype T | sized(T) ) int posix_memalign( T ** ptr, size_t alignment );
    5197 
    5198 forall( dtype T, ttype Params | sized(T) | { void ?{}(T *, Params); } ) T * new( Params p );
    5199 forall( dtype T | { void ^?{}(T *); } ) void delete( T * ptr );
    5200 forall( dtype T, ttype Params | { void ^?{}(T *); void delete(Params); } ) void delete( T * ptr, Params rest );
    5201 \end{cfa}
    5202 
    5203 
    5204 \subsection{ato / strto}
     5262
     5263// allocation, array types
     5264forall( dtype T | sized(T) ) T * calloc( size_t dim );§\indexc{cmalloc}§
     5265forall( dtype T | sized(T) ) T * amalloc( size_t dim );§\indexc{amalloc}§  // alternate name for calloc
     5266forall( dtype T | sized(T) ) T * amalloc( size_t dim, char fill );
     5267
     5268// resize, non-array types
     5269forall( dtype T | sized(T) ) T * realloc( T * ptr, size_t size );§\indexc{realloc}§
     5270forall( dtype T | sized(T) ) T * realloc( T * ptr, size_t size, char fill );
     5271forall( dtype T | sized(T) ) T * malloc( T * ptr, size_t size );  // alternate name for realloc
     5272forall( dtype T | sized(T) ) T * malloc( T * ptr, size_t size, char fill );
     5273
     5274// resize, array types
     5275forall( dtype T | sized(T) ) T * amalloc( T * ptr, size_t dim );
     5276forall( dtype T | sized(T) ) T * amalloc( T * ptr, size_t dim, char fill );
     5277
     5278// alignment, non-array types
     5279forall( dtype T | sized(T) ) T * memalign( size_t alignment );§\indexc{memalign}§
     5280forall( dtype T | sized(T) ) T * memalign( size_t alignment, char fill );
     5281forall( dtype T | sized(T) ) T * aligned_alloc( size_t alignment );§\indexc{aligned_alloc}§
     5282forall( dtype T | sized(T) ) int posix_memalign( T ** ptr, size_t alignment );§\indexc{posix_memalign}§
     5283
     5284// alignment, array types
     5285forall( dtype T | sized(T) ) T * amemalign( size_t alignment, size_t dim );§\indexc{amemalign}§
     5286forall( dtype T | sized(T) ) T * amemalign( size_t alignment, size_t dim, char fill );
     5287
     5288// data, non-array types
     5289forall( dtype T | sized(T) ) T * memset( T * dest, char c );§\indexc{memset}§
     5290forall( dtype T | sized(T) ) T * memcpy( T * dest, const T * src );§\indexc{memcpy}§
     5291
     5292// data, array types
     5293forall( dtype T | sized(T) ) T * amemset( T * dest, size_t dim, char c );§\indexc{amemset}§
     5294forall( dtype T | sized(T) ) T * amemcpy( T * dest, const T * src, size_t dim );§\indexc{amemcpy}§
     5295
     5296// allocation/deallocation and constructor/destructor
     5297forall( dtype T, ttype Params | sized(T) | { void ?{}(T *, Params); } ) T * new( Params p );§\indexc{new}§
     5298forall( dtype T | { void ^?{}( T * ); } ) void delete( T * ptr );§\indexc{delete}§
     5299forall( dtype T, ttype Params | { void ^?{}( T * ); void delete(Params); } ) void delete( T * ptr, Params rest );
     5300\end{cfa}
     5301
     5302
     5303\subsection{Conversion}
    52055304
    52065305\leavevmode
     
    52345333
    52355334
    5236 \subsection{bsearch / qsort}
     5335\subsection{Search / Sort}
    52375336
    52385337\leavevmode
    52395338\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    5240 forall( otype T | { int ?<?( T, T ); } )        // location
     5339forall( otype T | { int ?<?( T, T ); } )        §\C{// location}§
    52415340T * bsearch( T key, const T * arr, size_t dimension );§\indexc{bsearch}§
    52425341
    5243 forall( otype T | { int ?<?( T, T ); } )        // position
     5342forall( otype T | { int ?<?( T, T ); } )        §\C{// position}§
    52445343unsigned int bsearch( T key, const T * arr, size_t dimension );
    52455344
     
    52495348
    52505349
    5251 \subsection{abs}
     5350\subsection{Absolute Value}
    52525351
    52535352\leavevmode
     
    52685367
    52695368
    5270 \subsection{random}
     5369\subsection{Random Numbers}
    52715370
    52725371\leavevmode
     
    52865385
    52875386
    5288 \subsection{min / max / clamp / swap}
     5387\subsection{Algorithms}
    52895388
    52905389\leavevmode
     
    56715770\label{s:MultiPrecisionIntegers}
    56725771
    5673 \CFA has an interface to the \Index{GMP} \Index{multi-precision} signed-integers~\cite{GMP}, similar to the \CC interface provided by GMP.
     5772\CFA has an interface to the GMP \Index{multi-precision} signed-integers~\cite{GMP}, similar to the \CC interface provided by GMP.
    56745773The \CFA interface wraps GMP routines into operator routines to make programming with multi-precision integers identical to using fixed-sized integers.
    5675 The \CFA type name for multi-precision signed-integers is \Indexc{Int}.
     5774The \CFA type name for multi-precision signed-integers is \Indexc{Int} and the header file is \Indexc{gmp}.
    56765775
    56775776\begin{cfa}
     
    58435942\hline
    58445943\begin{cfa}
    5845 #include <gmp>
     5944#include <gmp>§\indexc{gmp}§
    58465945int main( void ) {
    58475946        sout | "Factorial Numbers" | endl;
    5848         Int fact;
    5849         fact = 1;
     5947        Int fact = 1;
     5948
    58505949        sout | 0 | fact | endl;
    58515950        for ( unsigned int i = 1; i <= 40; i += 1 ) {
     
    58575956&
    58585957\begin{cfa}
    5859 #include <gmp.h>
     5958#include <gmp.h>§\indexc{gmp.h}§
    58605959int main( void ) {
    58615960        ®gmp_printf®( "Factorial Numbers\n" );
  • src/libcfa/gmp

    ra029714 r5e8d732  
    1010// Created On       : Tue Apr 19 08:43:43 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May 22 08:32:39 2017
    13 // Update Count     : 13
     12// Last Modified On : Sat May 27 09:55:51 2017
     13// Update Count     : 14
    1414//
    1515
     
    2222
    2323// constructor
    24 void ?{}( Int * this ) { mpz_init( this->mpz ); }
    25 void ?{}( Int * this, Int init ) { mpz_init_set( this->mpz, init.mpz ); }
    26 void ?{}( Int * this, zero_t ) { mpz_init_set_si( this->mpz, 0 ); }
    27 void ?{}( Int * this, one_t ) { mpz_init_set_si( this->mpz, 1 ); }
    28 void ?{}( Int * this, signed long int init ) { mpz_init_set_si( this->mpz, init ); }
    29 void ?{}( Int * this, unsigned long int init ) { mpz_init_set_ui( this->mpz, init ); }
    30 void ?{}( Int * this, const char * val ) { if ( mpz_init_set_str( this->mpz, val, 0 ) ) abort(); }
    31 void ^?{}( Int * this ) { mpz_clear( this->mpz ); }
     24static inline void ?{}( Int * this ) { mpz_init( this->mpz ); }
     25static inline void ?{}( Int * this, Int init ) { mpz_init_set( this->mpz, init.mpz ); }
     26static inline void ?{}( Int * this, zero_t ) { mpz_init_set_si( this->mpz, 0 ); }
     27static inline void ?{}( Int * this, one_t ) { mpz_init_set_si( this->mpz, 1 ); }
     28static inline void ?{}( Int * this, signed long int init ) { mpz_init_set_si( this->mpz, init ); }
     29static inline void ?{}( Int * this, unsigned long int init ) { mpz_init_set_ui( this->mpz, init ); }
     30static inline void ?{}( Int * this, const char * val ) { if ( mpz_init_set_str( this->mpz, val, 0 ) ) abort(); }
     31static inline void ^?{}( Int * this ) { mpz_clear( this->mpz ); }
    3232
    3333// assignment
    34 Int ?=?( Int * lhs, Int rhs ) { mpz_set( lhs->mpz, rhs.mpz ); return *lhs; }
    35 Int ?=?( Int * lhs, long int rhs ) { mpz_set_si( lhs->mpz, rhs ); return *lhs; }
    36 Int ?=?( Int * lhs, unsigned long int rhs ) { mpz_set_ui( lhs->mpz, rhs ); return *lhs; }
    37 Int ?=?( Int * lhs, const char * rhs ) { if ( mpz_set_str( lhs->mpz, rhs, 0 ) ) { printf( "invalid string conversion\n" ); abort(); } return *lhs; }
    38 
    39 char ?=?( char * lhs, Int rhs ) { char val = mpz_get_si( rhs.mpz ); *lhs = val; return val; }
    40 short int ?=?( short int * lhs, Int rhs ) { short int val = mpz_get_si( rhs.mpz ); *lhs = val; return val; }
    41 int ?=?( int * lhs, Int rhs ) { int val = mpz_get_si( rhs.mpz ); *lhs = val; return val; }
    42 long int ?=?( long int * lhs, Int rhs ) { long int val = mpz_get_si( rhs.mpz ); *lhs = val; return val; }
    43 unsigned char ?=?( unsigned char * lhs, Int rhs ) { unsigned char val = mpz_get_ui( rhs.mpz ); *lhs = val; return val; }
    44 unsigned short int ?=?( unsigned short int * lhs, Int rhs ) { unsigned short int val = mpz_get_ui( rhs.mpz ); *lhs = val; return val; }
    45 unsigned int ?=?( unsigned int * lhs, Int rhs ) { unsigned int val = mpz_get_ui( rhs.mpz ); *lhs = val; return val; }
    46 unsigned long int ?=?( unsigned long int * lhs, Int rhs ) { unsigned long int val = mpz_get_ui( rhs.mpz ); *lhs = val; return val; }
     34static inline Int ?=?( Int * lhs, Int rhs ) { mpz_set( lhs->mpz, rhs.mpz ); return *lhs; }
     35static inline Int ?=?( Int * lhs, long int rhs ) { mpz_set_si( lhs->mpz, rhs ); return *lhs; }
     36static inline Int ?=?( Int * lhs, unsigned long int rhs ) { mpz_set_ui( lhs->mpz, rhs ); return *lhs; }
     37static inline Int ?=?( Int * lhs, const char * rhs ) { if ( mpz_set_str( lhs->mpz, rhs, 0 ) ) { printf( "invalid string conversion\n" ); abort(); } return *lhs; }
     38
     39static inline char ?=?( char * lhs, Int rhs ) { char val = mpz_get_si( rhs.mpz ); *lhs = val; return val; }
     40static inline short int ?=?( short int * lhs, Int rhs ) { short int val = mpz_get_si( rhs.mpz ); *lhs = val; return val; }
     41static inline int ?=?( int * lhs, Int rhs ) { int val = mpz_get_si( rhs.mpz ); *lhs = val; return val; }
     42static inline long int ?=?( long int * lhs, Int rhs ) { long int val = mpz_get_si( rhs.mpz ); *lhs = val; return val; }
     43static inline unsigned char ?=?( unsigned char * lhs, Int rhs ) { unsigned char val = mpz_get_ui( rhs.mpz ); *lhs = val; return val; }
     44static inline unsigned short int ?=?( unsigned short int * lhs, Int rhs ) { unsigned short int val = mpz_get_ui( rhs.mpz ); *lhs = val; return val; }
     45static inline unsigned int ?=?( unsigned int * lhs, Int rhs ) { unsigned int val = mpz_get_ui( rhs.mpz ); *lhs = val; return val; }
     46static inline unsigned long int ?=?( unsigned long int * lhs, Int rhs ) { unsigned long int val = mpz_get_ui( rhs.mpz ); *lhs = val; return val; }
    4747
    4848// conversions
    49 long int narrow( Int val ) { return mpz_get_si( val.mpz ); }
    50 unsigned long int narrow( Int val ) { return mpz_get_ui( val.mpz ); }
     49static inline long int narrow( Int val ) { return mpz_get_si( val.mpz ); }
     50static inline unsigned long int narrow( Int val ) { return mpz_get_ui( val.mpz ); }
    5151
    5252// comparison
    53 int ?==?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) == 0; }
    54 int ?==?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) == 0; }
    55 int ?==?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) == 0; }
    56 int ?==?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) == 0; }
    57 int ?==?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) == 0; }
    58 
    59 int ?!=?( Int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); }
    60 int ?!=?( Int oper1, long int oper2 ) { return ! ( oper1 == oper2 ); }
    61 int ?!=?( long int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); }
    62 int ?!=?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 == oper2 ); }
    63 int ?!=?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); }
    64 
    65 int ?<?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) < 0; }
    66 int ?<?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) < 0; }
    67 int ?<?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) < 0; }
    68 int ?<?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) < 0; }
    69 int ?<?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) < 0; }
    70 
    71 int ?<=?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) <= 0; }
    72 int ?<=?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) <= 0; }
    73 int ?<=?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) <= 0; }
    74 int ?<=?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) <= 0; }
    75 int ?<=?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) <= 0; }
    76 
    77 int ?>?( Int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); }
    78 int ?>?( Int oper1, long int oper2 ) { return ! ( oper1 <= oper2 ); }
    79 int ?>?( long int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); }
    80 int ?>?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 <= oper2 ); }
    81 int ?>?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); }
    82 
    83 int ?>=?( Int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); }
    84 int ?>=?( Int oper1, long int oper2 ) { return ! ( oper1 < oper2 ); }
    85 int ?>=?( long int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); }
    86 int ?>=?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 < oper2 ); }
    87 int ?>=?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); }
     53static inline int ?==?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) == 0; }
     54static inline int ?==?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) == 0; }
     55static inline int ?==?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) == 0; }
     56static inline int ?==?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) == 0; }
     57static inline int ?==?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) == 0; }
     58
     59static inline int ?!=?( Int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); }
     60static inline int ?!=?( Int oper1, long int oper2 ) { return ! ( oper1 == oper2 ); }
     61static inline int ?!=?( long int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); }
     62static inline int ?!=?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 == oper2 ); }
     63static inline int ?!=?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); }
     64
     65static inline int ?<?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) < 0; }
     66static inline int ?<?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) < 0; }
     67static inline int ?<?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) < 0; }
     68static inline int ?<?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) < 0; }
     69static inline int ?<?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) < 0; }
     70
     71static inline int ?<=?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) <= 0; }
     72static inline int ?<=?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) <= 0; }
     73static inline int ?<=?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) <= 0; }
     74static inline int ?<=?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) <= 0; }
     75static inline int ?<=?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) <= 0; }
     76
     77static inline int ?>?( Int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); }
     78static inline int ?>?( Int oper1, long int oper2 ) { return ! ( oper1 <= oper2 ); }
     79static inline int ?>?( long int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); }
     80static inline int ?>?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 <= oper2 ); }
     81static inline int ?>?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); }
     82
     83static inline int ?>=?( Int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); }
     84static inline int ?>=?( Int oper1, long int oper2 ) { return ! ( oper1 < oper2 ); }
     85static inline int ?>=?( long int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); }
     86static inline int ?>=?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 < oper2 ); }
     87static inline int ?>=?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); }
    8888
    8989// arithmetic
    90 Int +?( Int oper ) { Int pos; mpz_set( pos.mpz, oper.mpz ); return pos; }
    91 Int -?( Int oper ) { Int neg; mpz_neg( neg.mpz, oper.mpz ); return neg; }
    92 Int ~?( Int oper ) { Int comp; mpz_com( comp.mpz, oper.mpz ); return comp; }
    93 
    94 Int ?&?( Int oper1, Int oper2 ) { Int conjunction; mpz_and( conjunction.mpz, oper1.mpz, oper2.mpz ); return conjunction; }
    95 Int ?&?( Int oper1, long int oper2 ) { Int conjunction, temp; mpz_set_si( temp.mpz, oper2 ); mpz_and( conjunction.mpz, oper1.mpz, temp.mpz ); return conjunction; }
    96 Int ?&?( long int oper1, Int oper2 ) { Int conjunction, temp; mpz_set_si( temp.mpz, oper1 ); mpz_and( conjunction.mpz, temp.mpz, oper2.mpz ); return conjunction; }
    97 Int ?&?( Int oper1, unsigned long int oper2 ) { Int conjunction, temp; mpz_set_ui( temp.mpz, oper2 ); mpz_and( conjunction.mpz, oper1.mpz, temp.mpz ); return conjunction; }
    98 Int ?&?( unsigned long int oper1, Int oper2 ) { Int conjunction, temp; mpz_set_ui( temp.mpz, oper1 ); mpz_and( conjunction.mpz, temp.mpz, oper2.mpz ); return conjunction; }
    99 Int ?&=?( Int * lhs, Int rhs ) { return *lhs = *lhs & rhs; }
    100 
    101 Int ?|?( Int oper1, Int oper2 ) { Int disjunction; mpz_ior( disjunction.mpz, oper1.mpz, oper2.mpz ); return disjunction; }
    102 Int ?|?( Int oper1, long int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
    103 Int ?|?( long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
    104 Int ?|?( Int oper1, unsigned long int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
    105 Int ?|?( unsigned long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
    106 Int ?|=?( Int * lhs, Int rhs ) { return *lhs = *lhs | rhs; }
    107 
    108 Int ?^?( Int oper1, Int oper2 ) { Int disjunction; mpz_xor( disjunction.mpz, oper1.mpz, oper2.mpz ); return disjunction; }
    109 Int ?^?( Int oper1, long int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
    110 Int ?^?( long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
    111 Int ?^?( Int oper1, unsigned long int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
    112 Int ?^?( unsigned long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
    113 Int ?^=?( Int * lhs, Int rhs ) { return *lhs = *lhs ^ rhs; }
    114 
    115 Int ?+?( Int addend1, Int addend2 ) { Int sum; mpz_add( sum.mpz, addend1.mpz, addend2.mpz ); return sum; }
    116 Int ?+?( Int addend1, long int addend2 ) { Int sum; if ( addend2 >= 0 ) mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); else mpz_sub_ui( sum.mpz, addend1.mpz, -addend2 ); return sum; }
    117 Int ?+?( long int addend2, Int addend1 ) { Int sum; if ( addend2 >= 0 ) mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); else mpz_sub_ui( sum.mpz, addend1.mpz, -addend2 ); return sum; }
    118 Int ?+?( Int addend1, unsigned long int addend2 ) { Int sum; mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); return sum; }
    119 Int ?+?( unsigned long int addend2, Int addend1 ) { Int sum; mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); return sum; }
    120 Int ?+=?( Int * lhs, Int rhs ) { return *lhs = *lhs + rhs; }
    121 Int ?+=?( Int * lhs, long int rhs ) { return *lhs = *lhs + rhs; }
    122 Int ?+=?( Int * lhs, unsigned long int rhs ) { return *lhs = *lhs + rhs; }
    123 Int ++?( Int * lhs ) { return *lhs += 1; }
    124 Int ?++( Int * lhs ) { Int ret = *lhs; *lhs += 1; return ret; }
    125 
    126 Int ?-?( Int minuend, Int subtrahend ) { Int diff; mpz_sub( diff.mpz, minuend.mpz, subtrahend.mpz ); return diff; }
    127 Int ?-?( Int minuend, long int subtrahend ) { Int diff; if ( subtrahend >= 0 ) mpz_sub_ui( diff.mpz, minuend.mpz, subtrahend ); else mpz_add_ui( diff.mpz, minuend.mpz, -subtrahend ); return diff; }
    128 Int ?-?( long int minuend, Int subtrahend ) { Int diff; if ( subtrahend >= 0 ) mpz_ui_sub( diff.mpz, minuend, subtrahend.mpz ); else { mpz_add_ui( diff.mpz, subtrahend.mpz, -minuend ); mpz_neg( diff.mpz, diff.mpz ); } return diff; }
    129 Int ?-?( Int minuend, unsigned long int subtrahend ) { Int diff; mpz_sub_ui( diff.mpz, minuend.mpz, subtrahend ); return diff; }
    130 Int ?-?( unsigned long int minuend, Int subtrahend ) { Int diff; mpz_ui_sub( diff.mpz, minuend, subtrahend.mpz ); return diff; }
    131 Int ?-=?( Int * lhs, Int rhs ) { return *lhs = *lhs - rhs; }
    132 Int ?-=?( Int * lhs, long int rhs ) { return *lhs = *lhs - rhs; }
    133 Int ?-=?( Int * lhs, unsigned long int rhs ) { return *lhs = *lhs - rhs; }
    134 Int --?( Int * lhs ) { return *lhs -= 1; }
    135 Int ?--( Int * lhs ) { Int ret = *lhs; *lhs -= 1; return ret; }
    136 
    137 Int ?*?( Int multiplicator, Int multiplicand ) { Int product; mpz_mul( product.mpz, multiplicator.mpz, multiplicand.mpz ); return product; }
    138 Int ?*?( Int multiplicator, long int multiplicand ) { Int product; mpz_mul_si( product.mpz, multiplicator.mpz, multiplicand ); return product; }
    139 Int ?*?( long int multiplicand, Int multiplicator ) { Int product; mpz_mul_si( product.mpz, multiplicator.mpz, multiplicand ); return product; }
    140 Int ?*?( Int multiplicator, unsigned long int multiplicand ) { Int product; mpz_mul_ui( product.mpz, multiplicator.mpz, multiplicand ); return product; }
    141 Int ?*?( unsigned long int multiplicand, Int multiplicator ) { Int product; mpz_mul_ui( product.mpz, multiplicator.mpz, multiplicand ); return product; }
    142 Int ?*=?( Int * lhs, Int rhs ) { return *lhs = *lhs * rhs; }
    143 Int ?*=?( Int * lhs, long int rhs ) { return *lhs = *lhs * rhs; }
    144 Int ?*=?( Int * lhs, unsigned long int rhs ) { return *lhs = *lhs * rhs; }
     90static inline Int +?( Int oper ) { Int pos; mpz_set( pos.mpz, oper.mpz ); return pos; }
     91static inline Int -?( Int oper ) { Int neg; mpz_neg( neg.mpz, oper.mpz ); return neg; }
     92static inline Int ~?( Int oper ) { Int comp; mpz_com( comp.mpz, oper.mpz ); return comp; }
     93
     94static inline Int ?&?( Int oper1, Int oper2 ) { Int conjunction; mpz_and( conjunction.mpz, oper1.mpz, oper2.mpz ); return conjunction; }
     95static inline Int ?&?( Int oper1, long int oper2 ) { Int conjunction, temp; mpz_set_si( temp.mpz, oper2 ); mpz_and( conjunction.mpz, oper1.mpz, temp.mpz ); return conjunction; }
     96static inline Int ?&?( long int oper1, Int oper2 ) { Int conjunction, temp; mpz_set_si( temp.mpz, oper1 ); mpz_and( conjunction.mpz, temp.mpz, oper2.mpz ); return conjunction; }
     97static inline Int ?&?( Int oper1, unsigned long int oper2 ) { Int conjunction, temp; mpz_set_ui( temp.mpz, oper2 ); mpz_and( conjunction.mpz, oper1.mpz, temp.mpz ); return conjunction; }
     98static inline Int ?&?( unsigned long int oper1, Int oper2 ) { Int conjunction, temp; mpz_set_ui( temp.mpz, oper1 ); mpz_and( conjunction.mpz, temp.mpz, oper2.mpz ); return conjunction; }
     99static inline Int ?&=?( Int * lhs, Int rhs ) { return *lhs = *lhs & rhs; }
     100
     101static inline Int ?|?( Int oper1, Int oper2 ) { Int disjunction; mpz_ior( disjunction.mpz, oper1.mpz, oper2.mpz ); return disjunction; }
     102static inline Int ?|?( Int oper1, long int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
     103static inline Int ?|?( long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
     104static inline Int ?|?( Int oper1, unsigned long int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
     105static inline Int ?|?( unsigned long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
     106static inline Int ?|=?( Int * lhs, Int rhs ) { return *lhs = *lhs | rhs; }
     107
     108static inline Int ?^?( Int oper1, Int oper2 ) { Int disjunction; mpz_xor( disjunction.mpz, oper1.mpz, oper2.mpz ); return disjunction; }
     109static inline Int ?^?( Int oper1, long int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
     110static inline Int ?^?( long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
     111static inline Int ?^?( Int oper1, unsigned long int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
     112static inline Int ?^?( unsigned long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
     113static inline Int ?^=?( Int * lhs, Int rhs ) { return *lhs = *lhs ^ rhs; }
     114
     115static inline Int ?+?( Int addend1, Int addend2 ) { Int sum; mpz_add( sum.mpz, addend1.mpz, addend2.mpz ); return sum; }
     116static inline Int ?+?( Int addend1, long int addend2 ) { Int sum; if ( addend2 >= 0 ) mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); else mpz_sub_ui( sum.mpz, addend1.mpz, -addend2 ); return sum; }
     117static inline Int ?+?( long int addend2, Int addend1 ) { Int sum; if ( addend2 >= 0 ) mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); else mpz_sub_ui( sum.mpz, addend1.mpz, -addend2 ); return sum; }
     118static inline Int ?+?( Int addend1, unsigned long int addend2 ) { Int sum; mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); return sum; }
     119static inline Int ?+?( unsigned long int addend2, Int addend1 ) { Int sum; mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); return sum; }
     120static inline Int ?+=?( Int * lhs, Int rhs ) { return *lhs = *lhs + rhs; }
     121static inline Int ?+=?( Int * lhs, long int rhs ) { return *lhs = *lhs + rhs; }
     122static inline Int ?+=?( Int * lhs, unsigned long int rhs ) { return *lhs = *lhs + rhs; }
     123static inline Int ++?( Int * lhs ) { return *lhs += 1; }
     124static inline Int ?++( Int * lhs ) { Int ret = *lhs; *lhs += 1; return ret; }
     125
     126static inline Int ?-?( Int minuend, Int subtrahend ) { Int diff; mpz_sub( diff.mpz, minuend.mpz, subtrahend.mpz ); return diff; }
     127static inline Int ?-?( Int minuend, long int subtrahend ) { Int diff; if ( subtrahend >= 0 ) mpz_sub_ui( diff.mpz, minuend.mpz, subtrahend ); else mpz_add_ui( diff.mpz, minuend.mpz, -subtrahend ); return diff; }
     128static inline Int ?-?( long int minuend, Int subtrahend ) { Int diff; if ( subtrahend >= 0 ) mpz_ui_sub( diff.mpz, minuend, subtrahend.mpz ); else { mpz_add_ui( diff.mpz, subtrahend.mpz, -minuend ); mpz_neg( diff.mpz, diff.mpz ); } return diff; }
     129static inline Int ?-?( Int minuend, unsigned long int subtrahend ) { Int diff; mpz_sub_ui( diff.mpz, minuend.mpz, subtrahend ); return diff; }
     130static inline Int ?-?( unsigned long int minuend, Int subtrahend ) { Int diff; mpz_ui_sub( diff.mpz, minuend, subtrahend.mpz ); return diff; }
     131static inline Int ?-=?( Int * lhs, Int rhs ) { return *lhs = *lhs - rhs; }
     132static inline Int ?-=?( Int * lhs, long int rhs ) { return *lhs = *lhs - rhs; }
     133static inline Int ?-=?( Int * lhs, unsigned long int rhs ) { return *lhs = *lhs - rhs; }
     134static inline Int --?( Int * lhs ) { return *lhs -= 1; }
     135static inline Int ?--( Int * lhs ) { Int ret = *lhs; *lhs -= 1; return ret; }
     136
     137static inline Int ?*?( Int multiplicator, Int multiplicand ) { Int product; mpz_mul( product.mpz, multiplicator.mpz, multiplicand.mpz ); return product; }
     138static inline Int ?*?( Int multiplicator, long int multiplicand ) { Int product; mpz_mul_si( product.mpz, multiplicator.mpz, multiplicand ); return product; }
     139static inline Int ?*?( long int multiplicand, Int multiplicator ) { Int product; mpz_mul_si( product.mpz, multiplicator.mpz, multiplicand ); return product; }
     140static inline Int ?*?( Int multiplicator, unsigned long int multiplicand ) { Int product; mpz_mul_ui( product.mpz, multiplicator.mpz, multiplicand ); return product; }
     141static inline Int ?*?( unsigned long int multiplicand, Int multiplicator ) { Int product; mpz_mul_ui( product.mpz, multiplicator.mpz, multiplicand ); return product; }
     142static inline Int ?*=?( Int * lhs, Int rhs ) { return *lhs = *lhs * rhs; }
     143static inline Int ?*=?( Int * lhs, long int rhs ) { return *lhs = *lhs * rhs; }
     144static inline Int ?*=?( Int * lhs, unsigned long int rhs ) { return *lhs = *lhs * rhs; }
    145145
    146146// some code for operators "/" and "%" taken from g++ gmpxx.h
    147 Int ?/?( Int dividend, Int divisor ) { Int quotient; mpz_tdiv_q( quotient.mpz, dividend.mpz, divisor.mpz ); return quotient; }
    148 Int ?/?( Int dividend, unsigned long int divisor ) { Int quotient; mpz_tdiv_q_ui( quotient.mpz, dividend.mpz, divisor ); return quotient; }
    149 Int ?/?( unsigned long int dividend, Int divisor ) {
     147static inline Int ?/?( Int dividend, Int divisor ) { Int quotient; mpz_tdiv_q( quotient.mpz, dividend.mpz, divisor.mpz ); return quotient; }
     148static inline Int ?/?( Int dividend, unsigned long int divisor ) { Int quotient; mpz_tdiv_q_ui( quotient.mpz, dividend.mpz, divisor ); return quotient; }
     149static inline Int ?/?( unsigned long int dividend, Int divisor ) {
    150150        Int quotient;
    151151    if ( mpz_sgn( divisor.mpz ) >= 0 ) {
     
    164164        return quotient;
    165165} // ?/?
    166 Int ?/?( Int dividend, long int divisor ) {
     166static inline Int ?/?( Int dividend, long int divisor ) {
    167167        Int quotient;
    168168    if ( divisor >= 0 )
     
    174174        return quotient;
    175175} // ?/?
    176 Int ?/?( long int dividend, Int divisor ) {
     176static inline Int ?/?( long int dividend, Int divisor ) {
    177177        Int quotient;
    178178    if ( mpz_fits_slong_p( divisor.mpz ) )
     
    185185        return quotient;
    186186} // ?/?
    187 Int ?/=?( Int * lhs, Int rhs ) { return *lhs = *lhs / rhs; }
    188 Int ?/=?( Int * lhs, long int rhs ) { return *lhs = *lhs / rhs; }
    189 Int ?/=?( Int * lhs, unsigned long int rhs ) { return *lhs = *lhs / rhs; }
    190 
    191 [ Int, Int ] div( Int dividend, Int divisor ) { Int quotient, remainder; mpz_fdiv_qr( quotient.mpz, remainder.mpz, dividend.mpz, divisor.mpz ); return [ quotient, remainder ]; }
    192 [ Int, Int ] div( Int dividend, unsigned long int divisor ) { Int quotient, remainder; mpz_fdiv_qr_ui( quotient.mpz, remainder.mpz, dividend.mpz, divisor ); return [ quotient, remainder ]; }
    193 
    194 Int ?%?( Int dividend, Int divisor ) { Int remainder; mpz_tdiv_r( remainder.mpz, dividend.mpz, divisor.mpz ); return remainder; }
    195 Int ?%?( Int dividend, unsigned long int divisor ) { Int remainder; mpz_tdiv_r_ui( remainder.mpz, dividend.mpz, divisor ); return remainder; }
    196 Int ?%?( unsigned long int dividend, Int divisor ) {
     187static inline Int ?/=?( Int * lhs, Int rhs ) { return *lhs = *lhs / rhs; }
     188static inline Int ?/=?( Int * lhs, long int rhs ) { return *lhs = *lhs / rhs; }
     189static inline Int ?/=?( Int * lhs, unsigned long int rhs ) { return *lhs = *lhs / rhs; }
     190
     191static inline [ Int, Int ] div( Int dividend, Int divisor ) { Int quotient, remainder; mpz_fdiv_qr( quotient.mpz, remainder.mpz, dividend.mpz, divisor.mpz ); return [ quotient, remainder ]; }
     192static inline [ Int, Int ] div( Int dividend, unsigned long int divisor ) { Int quotient, remainder; mpz_fdiv_qr_ui( quotient.mpz, remainder.mpz, dividend.mpz, divisor ); return [ quotient, remainder ]; }
     193
     194static inline Int ?%?( Int dividend, Int divisor ) { Int remainder; mpz_tdiv_r( remainder.mpz, dividend.mpz, divisor.mpz ); return remainder; }
     195static inline Int ?%?( Int dividend, unsigned long int divisor ) { Int remainder; mpz_tdiv_r_ui( remainder.mpz, dividend.mpz, divisor ); return remainder; }
     196static inline Int ?%?( unsigned long int dividend, Int divisor ) {
    197197        Int remainder;
    198198    if ( mpz_sgn( divisor.mpz ) >= 0 ) {
     
    210210        return remainder;
    211211} // ?%?
    212 Int ?%?( Int dividend, long int divisor ) {
     212static inline Int ?%?( Int dividend, long int divisor ) {
    213213        Int remainder;
    214214    mpz_tdiv_r_ui( remainder.mpz, dividend.mpz, (divisor >= 0 ? divisor : -divisor));
    215215        return remainder;
    216216} // ?%?
    217 Int ?%?( long int dividend, Int divisor ) {
     217static inline Int ?%?( long int dividend, Int divisor ) {
    218218        Int remainder;
    219219    if ( mpz_fits_slong_p( divisor.mpz ) )
     
    226226        return remainder;
    227227} // ?%?
    228 Int ?%=?( Int * lhs, Int rhs ) { return *lhs = *lhs % rhs; }
    229 Int ?%=?( Int * lhs, long int rhs ) { return *lhs = *lhs % rhs; }
    230 Int ?%=?( Int * lhs, unsigned long int rhs ) { return *lhs = *lhs % rhs; }
    231 
    232 Int ?<<?( Int shiften, mp_bitcnt_t shift ) { Int shifted; mpz_mul_2exp( shifted.mpz, shiften.mpz, shift ); return shifted; }
    233 Int ?<<=?( Int * lhs, mp_bitcnt_t shift ) { return *lhs = *lhs << shift; }
    234 Int ?>>?( Int shiften, mp_bitcnt_t shift ) { Int shifted; mpz_fdiv_q_2exp( shifted.mpz, shiften.mpz, shift ); return shifted; }
    235 Int ?>>=?( Int * lhs, mp_bitcnt_t shift ) { return *lhs = *lhs >> shift; }
     228static inline Int ?%=?( Int * lhs, Int rhs ) { return *lhs = *lhs % rhs; }
     229static inline Int ?%=?( Int * lhs, long int rhs ) { return *lhs = *lhs % rhs; }
     230static inline Int ?%=?( Int * lhs, unsigned long int rhs ) { return *lhs = *lhs % rhs; }
     231
     232static inline Int ?<<?( Int shiften, mp_bitcnt_t shift ) { Int shifted; mpz_mul_2exp( shifted.mpz, shiften.mpz, shift ); return shifted; }
     233static inline Int ?<<=?( Int * lhs, mp_bitcnt_t shift ) { return *lhs = *lhs << shift; }
     234static inline Int ?>>?( Int shiften, mp_bitcnt_t shift ) { Int shifted; mpz_fdiv_q_2exp( shifted.mpz, shiften.mpz, shift ); return shifted; }
     235static inline Int ?>>=?( Int * lhs, mp_bitcnt_t shift ) { return *lhs = *lhs >> shift; }
    236236
    237237// number functions
    238 Int abs( Int oper ) { Int positive; mpz_abs( positive.mpz, oper.mpz ); return positive; }
    239 Int fact( unsigned long int N ) { Int factorial; mpz_fac_ui( factorial.mpz, N ); return factorial; }
    240 Int gcd( Int oper1, Int oper2 ) { Int gcdret; mpz_gcd( gcdret.mpz, oper1.mpz, oper2.mpz ); return gcdret; }
    241 Int pow( Int base, unsigned long int exponent ) { Int power; mpz_pow_ui( power.mpz, base.mpz, exponent ); return power; }
    242 Int pow( unsigned long int base, unsigned long int exponent ) { Int power; mpz_ui_pow_ui( power.mpz, base, exponent ); return power; }
    243 void srandom( gmp_randstate_t state ) { gmp_randinit_default( state ); }
    244 Int random( gmp_randstate_t state, mp_bitcnt_t n ) { Int rand; mpz_urandomb( rand.mpz, state, n ); return rand; }
    245 Int random( gmp_randstate_t state, Int n ) { Int rand; mpz_urandomm( rand.mpz, state, n.mpz ); return rand; }
    246 Int random( gmp_randstate_t state, mp_size_t max_size ) { Int rand; mpz_random( rand.mpz, max_size ); return rand; }
    247 int sgn( Int oper ) { return mpz_sgn( oper.mpz ); }
    248 Int sqrt( Int oper ) { Int root; mpz_sqrt( root.mpz, oper.mpz ); return root; }
     238static inline Int abs( Int oper ) { Int positive; mpz_abs( positive.mpz, oper.mpz ); return positive; }
     239static inline Int fact( unsigned long int N ) { Int factorial; mpz_fac_ui( factorial.mpz, N ); return factorial; }
     240static inline Int gcd( Int oper1, Int oper2 ) { Int gcdret; mpz_gcd( gcdret.mpz, oper1.mpz, oper2.mpz ); return gcdret; }
     241static inline Int pow( Int base, unsigned long int exponent ) { Int power; mpz_pow_ui( power.mpz, base.mpz, exponent ); return power; }
     242static inline Int pow( unsigned long int base, unsigned long int exponent ) { Int power; mpz_ui_pow_ui( power.mpz, base, exponent ); return power; }
     243static inline void srandom( gmp_randstate_t state ) { gmp_randinit_default( state ); }
     244static inline Int random( gmp_randstate_t state, mp_bitcnt_t n ) { Int rand; mpz_urandomb( rand.mpz, state, n ); return rand; }
     245static inline Int random( gmp_randstate_t state, Int n ) { Int rand; mpz_urandomm( rand.mpz, state, n.mpz ); return rand; }
     246static inline Int random( gmp_randstate_t state, mp_size_t max_size ) { Int rand; mpz_random( rand.mpz, max_size ); return rand; }
     247static inline int sgn( Int oper ) { return mpz_sgn( oper.mpz ); }
     248static inline Int sqrt( Int oper ) { Int root; mpz_sqrt( root.mpz, oper.mpz ); return root; }
    249249
    250250// I/O
    251 forall( dtype istype | istream( istype ) )
     251static inline forall( dtype istype | istream( istype ) )
    252252istype * ?|?( istype * is, Int * mp ) {
    253253        gmp_scanf( "%Zd", mp );
     
    255255} // ?|?
    256256
    257 forall( dtype ostype | ostream( ostype ) )
     257static inline forall( dtype ostype | ostream( ostype ) )
    258258ostype * ?|?( ostype * os, Int mp ) {
    259259        if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
  • src/libcfa/stdlib

    ra029714 r5e8d732  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed May 24 18:06:27 2017
    13 // Update Count     : 115
     12// Last Modified On : Tue May 30 09:07:35 2017
     13// Update Count     : 164
    1414//
    1515
     
    2828//---------------------------------------
    2929
    30 forall( dtype T | sized(T) ) T * malloc( void );
    31 forall( dtype T | sized(T) ) T * malloc( char fill );
    32 forall( dtype T | sized(T) ) T * malloc( T * ptr, size_t size );
    33 forall( dtype T | sized(T) ) T * malloc( T * ptr, size_t size, unsigned char fill );
    34 extern "C" { void * calloc( size_t nmemb, size_t size ); } // use default C routine for void *
    35 forall( dtype T | sized(T) ) T * calloc( size_t nmemb );
     30extern "C" { void * memset( void * dest, int c, size_t size ); } // use default C routine for void *
     31
     32// allocation, non-array types
     33static inline forall( dtype T | sized(T) ) T * malloc( void ) {
     34        //printf( "X1\n" );
     35        return (T *)(void *)malloc( (size_t)sizeof(T) );        // C malloc
     36} // malloc
     37static inline forall( dtype T | sized(T) ) T * malloc( char fill ) {
     38        //printf( "X2\n" );
     39        T * ptr = (T *)(void *)malloc( (size_t)sizeof(T) );     // C malloc
     40    return memset( ptr, (int)fill, sizeof(T) );                 // initial with fill value
     41} // malloc
     42
     43// allocation, array types
     44extern "C" { void * calloc( size_t dim, size_t size ); } // use default C routine for void *
     45static inline forall( dtype T | sized(T) ) T * calloc( size_t dim ) {
     46        //printf( "X3\n" );
     47        return (T *)(void *)calloc( dim, sizeof(T) );           // C cmalloc
     48}
     49static inline forall( dtype T | sized(T) ) T * amalloc( size_t dim ) { // alternative name
     50        //printf( "X4\n" );
     51        return (T *)(void *)malloc( dim * (size_t)sizeof(T) ); // C malloc
     52} // amalloc
     53static inline forall( dtype T | sized(T) ) T * amalloc( size_t dim, char fill ) { // alternative name
     54        //printf( "X5\n" );
     55        T * ptr = (T *)(void *)malloc( dim * (size_t)sizeof(T) ); // C malloc
     56    return memset( ptr, (int)fill, dim * sizeof(T) );
     57} // amalloc
     58
     59// resize, non-array types
    3660extern "C" { void * realloc( void * ptr, size_t size ); } // use default C routine for void *
    37 forall( dtype T | sized(T) ) T * realloc( T * ptr, size_t size );
    38 forall( dtype T | sized(T) ) T * realloc( T * ptr, size_t size, unsigned char fill );
    39 
    40 forall( dtype T | sized(T) ) T * aligned_alloc( size_t alignment );
    41 forall( dtype T | sized(T) ) T * memalign( size_t alignment );          // deprecated
    42 forall( dtype T | sized(T) ) int posix_memalign( T ** ptr, size_t alignment );
    43 
     61static inline forall( dtype T | sized(T) ) T * realloc( T * ptr, size_t size ) {
     62        //printf( "X5.5\n" );
     63        return (T *)(void *)realloc( (void *)ptr, size );
     64}
     65forall( dtype T | sized(T) ) T * realloc( T * ptr, size_t size, char fill );
     66static inline forall( dtype T | sized(T) ) T * malloc( T * ptr, size_t size ) { // alternative name
     67        //printf( "X7\n" );
     68        return realloc( ptr, size );
     69} // malloc
     70static inline forall( dtype T | sized(T) ) T * malloc( T * ptr, size_t size, char fill ) { // alternative name
     71        //printf( "X8\n" );
     72        return realloc( ptr, size, fill );
     73} // malloc
     74
     75// resize, array types
     76static inline forall( dtype T | sized(T) ) T * amalloc( T * ptr, size_t dim ) {
     77        //printf( "X9\n" );
     78        return malloc( ptr, dim * (size_t)sizeof(T) );
     79} // amalloc
     80static inline forall( dtype T | sized(T) ) T * amalloc( T * ptr, size_t dim, char fill ) {
     81        //printf( "X10\n" );
     82        return malloc( ptr, dim * (size_t)sizeof(T), fill );
     83} // amalloc
     84
     85// alignment, non-array types
     86extern "C" { void * memalign( size_t alignment, size_t size ); } // use default C routine for void *
     87static inline forall( dtype T | sized(T) ) T * memalign( size_t alignment ) {
     88        //printf( "X11\n" );
     89        return (T *)memalign( alignment, sizeof(T) );
     90} // memalign
     91static inline forall( dtype T | sized(T) ) T * memalign( size_t alignment, char fill ) {
     92        //printf( "X12\n" );
     93    T * ptr = (T *)memalign( alignment, sizeof(T) );
     94    return memset( ptr, (int)fill, sizeof(T) );
     95} // memalign
     96static inline forall( dtype T | sized(T) ) T * aligned_alloc( size_t alignment ) {
     97        //printf( "X13\n" );
     98        return (T *)memalign( alignment, sizeof(T) );
     99} // aligned_alloc
     100extern "C" { int posix_memalign( void ** ptr, size_t alignment, size_t size ); } // use default C routine for void *
     101static inline forall( dtype T | sized(T) ) int posix_memalign( T ** ptr, size_t alignment ) {
     102        //printf( "X14\n" );
     103        return posix_memalign( (void **)ptr, alignment, sizeof(T) );
     104} // posix_memalign
     105
     106// alignment, array types
     107static inline forall( dtype T | sized(T) ) T * amemalign( size_t alignment, size_t dim ) {
     108        //printf( "X15\n" );
     109        return (T *)memalign( alignment, dim * sizeof(T) );
     110} // amemalign
     111static inline forall( dtype T | sized(T) ) T * amemalign( size_t alignment, size_t dim, char fill ) {
     112        //printf( "X16\n" );
     113    T * ptr = (T *)memalign( alignment, dim * sizeof(T) );
     114    return memset( ptr, (int)fill, dim * sizeof(T) );
     115} // amemalign
     116
     117// data, non-array types
     118static inline forall( dtype T | sized(T) ) T * memset( T * dest, char c ) {
     119        //printf( "X17\n" );
     120        return memset( dest, c, sizeof(T) );
     121} // memset
     122extern "C" { void * memcpy( void * dest, const void * src, size_t size ); } // use default C routine for void *
     123static inline forall( dtype T | sized(T) ) T * memcpy( T * dest, const T * src ) {
     124        //printf( "X18\n" );
     125        return memcpy( dest, src, sizeof(T) );
     126} // memcpy
     127
     128// data, array types
     129static inline forall( dtype T | sized(T) ) T * amemset( T * dest, size_t dim, char c ) {
     130        //printf( "X19\n" );
     131        return memset( dest, c, dim * sizeof(T) );
     132} // amemset
     133static inline forall( dtype T | sized(T) ) T * amemcpy( T * dest, const T * src, size_t dim ) {
     134        //printf( "X20\n" );
     135        return memcpy( dest, src, dim * sizeof(T) );
     136} // amemcpy
     137
     138// allocation/deallocation and constructor/destructor
    44139forall( dtype T, ttype Params | sized(T) | { void ?{}(T *, Params); } ) T * new( Params p );
    45 forall( dtype T | { void ^?{}(T *); } ) void delete( T * ptr );
    46 forall( dtype T, ttype Params | { void ^?{}(T *); void delete(Params); } ) void delete( T * ptr, Params rest );
     140forall( dtype T | { void ^?{}( T * ); } ) void delete( T * ptr );
     141forall( dtype T, ttype Params | { void ^?{}( T * ); void delete( Params ); } ) void delete( T * ptr, Params rest );
    47142
    48143//---------------------------------------
     
    77172
    78173forall( otype T | { int ?<?( T, T ); } )
    79 T * bsearch( T key, const T * arr, size_t dimension );
    80 
    81 forall( otype T | { int ?<?( T, T ); } )
    82 unsigned int bsearch( T key, const T * arr, size_t dimension );
    83 
    84 
    85 forall( otype T | { int ?<?( T, T ); } )
    86 void qsort( const T * arr, size_t dimension );
     174T * bsearch( T key, const T * arr, size_t dim );
     175
     176forall( otype T | { int ?<?( T, T ); } )
     177unsigned int bsearch( T key, const T * arr, size_t dim );
     178
     179
     180forall( otype T | { int ?<?( T, T ); } )
     181void qsort( const T * arr, size_t dim );
    87182
    88183//---------------------------------------
  • src/libcfa/stdlib.c

    ra029714 r5e8d732  
    1010// Created On       : Thu Jan 28 17:10:29 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed May 24 18:13:15 2017
    13 // Update Count     : 198
     12// Last Modified On : Tue May 30 09:07:56 2017
     13// Update Count     : 237
    1414//
    1515
     
    2121#define _XOPEN_SOURCE 600                                                               // posix_memalign, *rand48
    2222#include <stdlib.h>                                                                             // malloc, free, calloc, realloc, memalign, posix_memalign, bsearch
    23 #include <string.h>                                                                             // memset
     23#include <string.h>                                                                             // memcpy, memset
    2424#include <malloc.h>                                                                             // malloc_usable_size
    2525#include <math.h>                                                                               // fabsf, fabs, fabsl
     
    2727} // extern "C"
    2828
    29 forall( dtype T | sized(T) ) T * malloc( void ) {               // type-safe
    30     return (T *)(void *)malloc( (size_t)sizeof(T) );
    31 } // malloc
    32 
    33 forall( dtype T | sized(T) ) T * malloc( char fill ) {  // initial with fill value (like calloc)
    34         T * ptr = (T *)(void *)malloc( (size_t)sizeof(T) );
    35     return memset( ptr, (int)fill, sizeof(T) );
    36 } // malloc
    37 
    38 forall( dtype T | sized(T) ) T * malloc( T * ptr, size_t size ) { // alternative realloc
    39     return (T *)realloc( ptr, size );
    40 } // malloc
    41 
    42 forall( dtype T | sized(T) ) T * malloc( T * ptr, size_t size, unsigned char fill ) { // alternative realloc with fill value
    43     return (T *)realloc( ptr, size, fill );
    44 } // malloc
    45 
    46 
    47 forall( dtype T | sized(T) ) T * calloc( size_t nmemb ) { // type-safe array initialization with fill 0
    48     return (T *)calloc( nmemb, sizeof(T) );
    49 } // calloc
    50 
    51 
    52 forall( dtype T | sized(T) ) T * realloc( T * ptr, size_t size ) { // type-safe
    53     return (T *)(void *)realloc( (void *)ptr, size );
     29// resize, non-array types
     30forall( dtype T | sized(T) ) T * realloc( T * ptr, size_t size, char fill ) { // alternative realloc with fill value
     31        //printf( "X6\n" );
     32        size_t olen = malloc_usable_size( ptr );                        // current allocation
     33    char * nptr = (void *)realloc( (void *)ptr, size ); // C realloc
     34        size_t nlen = malloc_usable_size( nptr );                       // new allocation
     35        if ( nlen > olen ) {                                                            // larger ?
     36                memset( nptr + olen, (int)fill, nlen - olen );  // initialize added storage
     37        } //
     38    return (T *)nptr;
    5439} // realloc
    5540
    56 forall( dtype T | sized(T) ) T * realloc( T * ptr, size_t size, unsigned char fill ) { // alternative realloc with fill value
    57     char * nptr = (T *)(void *)realloc( (void *)ptr, size );
    58     size_t unused = malloc_usable_size( nptr );
    59     memset( nptr + size - unused, (int)fill, unused );  // initialize any new storage
    60     return nptr;
    61 } // realloc
    62 
    63 
    64 forall( dtype T | sized(T) ) T * aligned_alloc( size_t alignment ) { // aligned allocation
    65     return (T *)memalign( alignment, sizeof(T) );
    66 } // aligned_alloc
    67 
    68 forall( dtype T | sized(T) ) T * memalign( size_t alignment ) {
    69     return (T *)memalign( alignment, sizeof(T) );
    70 } // memalign
    71 
    72 forall( dtype T | sized(T) ) int posix_memalign( T ** ptr, size_t alignment ) {
    73     return posix_memalign( (void **)ptr, alignment, sizeof(T) );
    74 } // posix_memalign
    75 
    76 
    77 forall( dtype T, ttype Params | sized(T) | { void ?{}( T *, Params ); } ) //  new
     41// allocation/deallocation and constructor/destructor
     42forall( dtype T, ttype Params | sized(T) | { void ?{}( T *, Params ); } )
    7843T * new( Params p ) {
    7944        return ((T *)malloc()){ p };
    8045} // new
    8146
    82 forall( dtype T | { void ^?{}(T *); } )                                 // delete
     47forall( dtype T | { void ^?{}( T * ); } )
    8348void delete( T * ptr ) {
    8449        if ( ptr ) {
    85                 ^ptr{};
     50                ^ptr{};                                                                                 // run destructor
    8651                free( ptr );
    87         }
     52        } // if
    8853} // delete
    8954
    90 forall( dtype T, ttype Params | { void ^?{}(T *); void delete(Params); } )
     55forall( dtype T, ttype Params | { void ^?{}( T * ); void delete( Params ); } )
    9156void delete( T * ptr, Params rest ) {
    9257        if ( ptr ) {
    93                 ^ptr{};
     58                ^ptr{};                                                                                 // run destructor
    9459                free( ptr );
    95         }
     60        } // if
    9661        delete( rest );
    9762} // delete
     
    242207
    243208forall( otype T | { int ?<?( T, T ); } )
    244 T * bsearch( T key, const T * arr, size_t dimension ) {
     209T * bsearch( T key, const T * arr, size_t dim ) {
    245210        int comp( const void * t1, const void * t2 ) { return *(T *)t1 < *(T *)t2 ? -1 : *(T *)t2 < *(T *)t1 ? 1 : 0; }
    246         return (T *)bsearch( &key, arr, dimension, sizeof(T), comp );
     211        return (T *)bsearch( &key, arr, dim, sizeof(T), comp );
    247212} // bsearch
    248213
    249214forall( otype T | { int ?<?( T, T ); } )
    250 unsigned int bsearch( T key, const T * arr, size_t dimension ) {
    251         T *result = bsearch( key, arr, dimension );
    252         return result ? result - arr : dimension;                       // pointer subtraction includes sizeof(T)
     215unsigned int bsearch( T key, const T * arr, size_t dim ) {
     216        T *result = bsearch( key, arr, dim );
     217        return result ? result - arr : dim;                                     // pointer subtraction includes sizeof(T)
    253218} // bsearch
    254219
    255220forall( otype T | { int ?<?( T, T ); } )
    256 void qsort( const T * arr, size_t dimension ) {
     221void qsort( const T * arr, size_t dim ) {
    257222        int comp( const void * t1, const void * t2 ) { return *(T *)t1 < *(T *)t2 ? -1 : *(T *)t2 < *(T *)t1 ? 1 : 0; }
    258         qsort( arr, dimension, sizeof(T), comp );
     223        qsort( arr, dim, sizeof(T), comp );
    259224} // qsort
    260225
Note: See TracChangeset for help on using the changeset viewer.