Changes in / [5e8d7327:a029714]


Ignore:
Files:
1 added
2 deleted
4 edited

Legend:

Unmodified
Added
Removed
  • doc/user/user.tex

    r5e8d7327 ra029714  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Tue May 30 09:08:16 2017
    14 %% Update Count     : 2072
     13%% Last Modified On : Wed May 24 22:21:42 2017
     14%% Update Count     : 1994
    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 \Celeven 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 C11 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, and \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, nad \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>§\indexc{fstream}§
     158#include <fstream>
    159159
    160160int main( void ) {
     
    165165&
    166166\begin{lstlisting}
    167 #include <stdio.h>§\indexc{stdio.h}§
     167#include <stdio.h>
    168168
    169169int main( void ) {
     
    174174&
    175175\begin{lstlisting}
    176 #include <iostream>§\indexc{iostream}§
     176#include <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]{\Celeven{}}~\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}~\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]{\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.
     231While \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.
    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 dim, size_t size,
     264void * bsearch( const void * key, const void * base, size_t nmemb, size_t size,
    265265                                int (* compar)( const void *, const void * ));
    266266
     
    340340The 1999 C standard plus GNU extensions.
    341341\item
    342 {\lstset{deletekeywords={inline}}
    343342\Indexc{-fgnu89-inline}\index{compilation option!-fgnu89-inline@{©-fgnu89-inline©}}
    344343Use the traditional GNU semantics for inline routines in C99 mode, which allows inline routines in header files.
    345 }%
    346344\end{description}
    347345The following new \CFA options are available:
     
    414412\begin{cfa}
    415413#ifndef __CFORALL__
    416 #include <stdio.h>§\indexc{stdio.h}§    §\C{// C header file}§
     414#include <stdio.h>                                              §\C{// C header file}§
    417415#else
    418 #include <fstream>§\indexc{fstream}§    §\C{// \CFA header file}§
     416#include <fstream>                                              §\C{// \CFA header file}§
    419417#endif
    420418\end{cfa}
     
    749747p2 = p1 + x;                                    §\C{// compiler infers *p2 = *p1 + x;}§
    750748\end{cfa}
    751 Algol68 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.
     749Algol68 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.
    752750Unfortunately, automatic dereferencing does not work in all cases, and so some mechanism is necessary to fix incorrect choices.
    753751
     
    14231421
    14241422Given the \CFA restrictions above, both named and default arguments are backwards compatible.
    1425 \Index*[C++]{\CC{}} only supports default arguments;
     1423\Index*[C++]{\CC} only supports default arguments;
    14261424\Index*{Ada} supports both named and default arguments.
    14271425
     
    14571455\subsection{Type Nesting}
    14581456
    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.
     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.
    14601458\begin{figure}
    14611459\centering
     
    17701768\index{lvalue}
    17711769The left-hand side is a tuple of \emph{lvalues}, and the right-hand side is a tuple of \emph{expr}s.
    1772 Each \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.
     1770Each \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.
    17731771An example of multiple assignment is:
    17741772\begin{cfa}
     
    18631861While C provides ©continue© and ©break© statements for altering control flow, both are restricted to one level of nesting for a particular control structure.
    18641862Unfortunately, this restriction forces programmers to use \Indexc{goto} to achieve the equivalent control-flow for more than one level of nesting.
    1865 To 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}.
     1863To 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}.
    18661864For both ©continue© and ©break©, the target label must be directly associated with a ©for©, ©while© or ©do© statement;
    18671865for ©break©, the target label can also be associated with a ©switch©, ©if© or compound (©{}©) statement.
     
    19031901                if ( ... ) {
    19041902                        for ( ... ) {
    1905                                 while ( ... ) {
     1903                                for ( ... ) {
    19061904                                        ... goto ®LC®; ...
    19071905                                        ... goto ®LS®; ...
     
    19241922\end{figure}
    19251923
    1926 \begin{comment}
    1927 int 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 
    1976 Both labelled ©continue© and ©break© are a ©goto©\index{goto@\lstinline $goto$!restricted} restricted in the following ways:
     1924Both labelled ©continue© and ©break© are a ©goto©\index{goto@©goto©!restricted} restricted in the following ways:
    19771925\begin{itemize}
    19781926\item
     
    23012249
    23022250The 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.
    2303 The \CFA header file for the I/O library is \Indexc{fstream}.
    2304 
    23052251The common case is printing out a sequence of variables separated by whitespace.
    23062252\begin{quote2}
     
    23602306
    23612307
    2362 The implicit separator\index{I/O!separator} character (space/blank) is a separator not a terminator.
     2308The implicit separator\index{I/O separator} character (space/blank) is a separator not a terminator.
    23632309The rules for implicitly adding the separator are:
    23642310\begin{enumerate}
     
    23882334
    23892335\item
    2390 A separator does not appear before a C string starting with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[mathescape=off,basicstyle=\tt]@([{=$£¥¡¿«@
     2336A separator does not appear before a C string starting with the (extended) \Index{ASCII}\index{ASCII!extended} characters: \lstinline[mathescape=off,basicstyle=\tt]@([{=$£¥¡¿«@
    23912337%$
    23922338\begin{cfa}[mathescape=off]
     
    24032349\item
    24042350{\lstset{language=CFA,deletedelim=**[is][]{¢}{¢}}
    2405 A seperator does not appear after a C string ending with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[basicstyle=\tt]@,.;!?)]}%¢»@
     2351A seperator does not appear after a C string ending with the (extended) \Index{ASCII}\index{ASCII!extended} characters: \lstinline[basicstyle=\tt]@,.;!?)]}%¢»@
    24062352\begin{cfa}[belowskip=0pt]
    24072353sout | 1 | ", x" | 2 | ". x" | 3 | "; x" | 4 | "! x" | 5 | "? x" | 6 | "% x"
     
    24142360
    24152361\item
    2416 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@
     2362A 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@
    24172363\begin{cfa}[belowskip=0pt]
    24182364sout | "x`" | 1 | "`x'" | 2 | "'x\"" | 3 | "\"x:" | 4 | ":x " | 5 | " x\t" | 6 | "\tx" | endl;
     
    26842630
    26852631\CFA supports C initialization of structures, but it also adds constructors for more advanced initialization.
    2686 Additionally, \CFA adds destructors that are called when a variable is deallocated (variable goes out of scope or object is deleted).
     2632Additionally, \CFA adds destructors that are called when a variable is de-allocated (variable goes out of scope or object is deleted).
    26872633These functions take a reference to the structure as a parameter (see References for more information).
    26882634
     
    30172963Generics allow programmers to use type variables in place of concrete types so that the code can be reused with multiple types.
    30182964The type parameters can be restricted to satisfy a set of constraints.
    3019 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.
     2965This 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.
    30202966
    30212967
    30222968\subsection{Generic Functions}
    30232969
    3024 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.
     2970Generic functions in \CFA are similar to template functions in \Index*[C++]{\CC}, and will sometimes be expanded into specialized versions, just like in \CC.
    30252971The 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.
    30262972This means that compiled libraries can contain generic functions that can be used by programs linked with them (statically or dynamically).
     
    31413087
    31423088Generic types are defined using the same mechanisms as those described above for generic functions.
    3143 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{}}.
     3089This 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}.
    31443090For 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.
    31453091In C, something like this would have to be done using void pointers and unsafe casting.
     
    31933139Throwing 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.
    31943140The exception is immediately re-thrown from the parent block unless it is caught as described below.
    3195 \CFA uses keywords similar to \Index*[C++]{\CC{}} for exception handling.
     3141\CFA uses keywords similar to \Index*[C++]{\CC} for exception handling.
    31963142An exception is thrown using a throw statement, which accepts one argument.
    31973143
     
    33993345
    34003346A task may define a constructor, which will be called upon allocation and run on the caller.s thread.
    3401 A 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).
     3347A 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).
    34023348After a task is allocated and initialized, its thread is spawned implicitly and begins executing in its function call method.
    34033349All tasks must define this function call method, with a void return value and no additional parameters, or the compiler will report an error.
     
    35763522\subsection{No Declarations, No Header Files}
    35773523
    3578 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.
     3524In 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.
    35793525Header files and a preprocessor are normally used to avoid repeating code.
    35803526Thus, many variables, functions, and types are described twice, which exposes an opportunity for errors and causes additional maintenance work.
     
    42214167In developing \CFA, many other languages were consulted for ideas, constructs, and syntax.
    42224168Therefore, it is important to show how these languages each compare with Do.
    4223 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}.
     4169In 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}.
    42244170
    42254171
     
    48464792\subsubsection[C++]{\CC}
    48474793
    4848 \Index*[C++]{\CC{}} is a general-purpose programming language.
     4794\Index*[C++]{\CC} is a general-purpose programming language.
    48494795It has imperative, object-oriented and generic programming features, while also providing facilities for low-level memory manipulation. (Wikipedia)
    48504796
     
    50314977}
    50324978\end{cfa}
    5033 \item[Rationale:] dropped from \Celeven standard.\footnote{
     4979\item[Rationale:] dropped from C11 standard.\footnote{
    50344980At 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}}
    50354981\item[Effect on original feature:] original feature is deprecated. \\
     
    50995045static struct X a = { 1, &b };  §\C{// definition}§
    51005046\end{cfa}
    5101 \item[Rationale:] avoids having different initialization rules for builtin types and user-defined types.
     5047\item[Rationale:] avoids having different initialization rules for builtin types and userdefined types.
    51025048\item[Effect on original feature:] change to semantics of well-defined feature.
    51035049\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.
     
    51245070\end{cfa}
    51255071In 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.
    5126 \CFA is C \emph{incompatible} on this issue, and provides semantics similar to \Index*[C++]{\CC{}}.
     5072\CFA is C \emph{incompatible} on this issue, and provides semantics similar to \Index*[C++]{\CC}.
    51275073Nested types are not hoisted and can be referenced using the field selection operator ``©.©'', unlike the \CC scope-resolution operator ``©::©''.
    51285074\item[Rationale:] ©struct© scope is crucial to \CFA as an information structuring and hiding mechanism.
     
    51405086struct Y;                                               §\C{// struct Y and struct X are at the same scope}§
    51415087struct X {
    5142         struct Y { /* ... */ } y;
     5088struct Y { /* ... */ } y;
    51435089};
    51445090\end{cfa}
     
    51625108\label{s:StandardHeaders}
    51635109
    5164 \Celeven prescribes the following standard header-files~\cite[\S~7.1.2]{C11} and \CFA adds to this list:
     5110C11 prescribes the following standard header-files~\cite[\S~7.1.2]{C11} and \CFA adds to this list:
    51655111\begin{quote2}
    5166 \lstset{deletekeywords={float},deletekeywords=[2]{signal}}
    5167 \begin{tabular}{@{}llll|l@{}}
     5112\begin{tabular}{llll|l}
    51685113\multicolumn{4}{c|}{C11} & \multicolumn{1}{c}{\CFA}             \\
    51695114\hline
    51705115\begin{tabular}{@{}l@{}}
    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}               \\
     5116assert.h        \\
     5117complex.h       \\
     5118ctype.h         \\
     5119errno.h         \\
     5120fenv.h          \\
     5121float.h         \\
     5122inttypes.h      \\
     5123iso646.h        \\
    51795124\end{tabular}
    51805125&
    51815126\begin{tabular}{@{}l@{}}
    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}    \\
     5127limits.h        \\
     5128locale.h        \\
     5129math.h          \\
     5130setjmp.h        \\
     5131signal.h        \\
     5132stdalign.h      \\
     5133stdarg.h        \\
     5134stdatomic.h     \\
    51905135\end{tabular}
    51915136&
    51925137\begin{tabular}{@{}l@{}}
    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}               \\
     5138stdbool.h       \\
     5139stddef.h        \\
     5140stdint.h        \\
     5141stdio.h         \\
     5142stdlib.h        \\
     5143stdnoreturn.h \\
     5144string.h        \\
     5145tgmath.h        \\
    52015146\end{tabular}
    52025147&
    52035148\begin{tabular}{@{}l@{}}
    5204 \Indexc{threads.h}              \\
    5205 \Indexc{time.h}                 \\
    5206 \Indexc{uchar.h}                \\
    5207 \Indexc{wchar.h}                \\
    5208 \Indexc{wctype.h}               \\
    5209                                                 \\
    5210                                                 \\
    5211                                                 \\
     5149threads.h       \\
     5150time.h          \\
     5151uchar.h         \\
     5152wchar.h         \\
     5153wctype.h        \\
     5154                        \\
     5155                        \\
     5156                        \\
    52125157\end{tabular}
    52135158&
    52145159\begin{tabular}{@{}l@{}}
    5215 \Indexc{unistd.h}               \\
    5216 \Indexc{gmp.h}                  \\
    5217                                                 \\
    5218                                                 \\
    5219                                                 \\
    5220                                                 \\
    5221                                                 \\
    5222                                                 \\
     5160unistd.h        \\
     5161gmp.h           \\
     5162                        \\
     5163                        \\
     5164                        \\
     5165                        \\
     5166                        \\
     5167                        \\
    52235168\end{tabular}
    52245169\end{tabular}
     
    52325177\label{s:StandardLibrary}
    52335178
    5234 The \CFA standard-library wraps explicitly-polymorphic C routines into implicitly-polymorphic versions.
    5235 
    5236 
    5237 \subsection{Storage Management}
    5238 
    5239 The 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}
    5254 When ©amalloc© resizes and fills, the space after the copied data from the source is set to the fill character.
    5255 It 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.
     5179The \CFA standard-library wraps explicitly-polymorphic C general-routines into implicitly-polymorphic versions.
     5180
     5181
     5182\subsection{malloc}
    52565183
    52575184\leavevmode
    52585185\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    5259 // allocation, non-array types
    52605186forall( dtype T | sized(T) ) T * malloc( void );§\indexc{malloc}§
    52615187forall( dtype T | sized(T) ) T * malloc( char fill );
    5262 
    5263 // allocation, array types
    5264 forall( dtype T | sized(T) ) T * calloc( size_t dim );§\indexc{cmalloc}§
    5265 forall( dtype T | sized(T) ) T * amalloc( size_t dim );§\indexc{amalloc}§  // alternate name for calloc
    5266 forall( dtype T | sized(T) ) T * amalloc( size_t dim, char fill );
    5267 
    5268 // resize, non-array types
    5269 forall( dtype T | sized(T) ) T * realloc( T * ptr, size_t size );§\indexc{realloc}§
    5270 forall( dtype T | sized(T) ) T * realloc( T * ptr, size_t size, char fill );
    5271 forall( dtype T | sized(T) ) T * malloc( T * ptr, size_t size );  // alternate name for realloc
    5272 forall( dtype T | sized(T) ) T * malloc( T * ptr, size_t size, char fill );
    5273 
    5274 // resize, array types
    5275 forall( dtype T | sized(T) ) T * amalloc( T * ptr, size_t dim );
    5276 forall( dtype T | sized(T) ) T * amalloc( T * ptr, size_t dim, char fill );
    5277 
    5278 // alignment, non-array types
    5279 forall( dtype T | sized(T) ) T * memalign( size_t alignment );§\indexc{memalign}§
    5280 forall( dtype T | sized(T) ) T * memalign( size_t alignment, char fill );
    5281 forall( dtype T | sized(T) ) T * aligned_alloc( size_t alignment );§\indexc{aligned_alloc}§
    5282 forall( dtype T | sized(T) ) int posix_memalign( T ** ptr, size_t alignment );§\indexc{posix_memalign}§
    5283 
    5284 // alignment, array types
    5285 forall( dtype T | sized(T) ) T * amemalign( size_t alignment, size_t dim );§\indexc{amemalign}§
    5286 forall( dtype T | sized(T) ) T * amemalign( size_t alignment, size_t dim, char fill );
    5287 
    5288 // data, non-array types
    5289 forall( dtype T | sized(T) ) T * memset( T * dest, char c );§\indexc{memset}§
    5290 forall( dtype T | sized(T) ) T * memcpy( T * dest, const T * src );§\indexc{memcpy}§
    5291 
    5292 // data, array types
    5293 forall( dtype T | sized(T) ) T * amemset( T * dest, size_t dim, char c );§\indexc{amemset}§
    5294 forall( dtype T | sized(T) ) T * amemcpy( T * dest, const T * src, size_t dim );§\indexc{amemcpy}§
    5295 
    5296 // allocation/deallocation and constructor/destructor
    5297 forall( dtype T, ttype Params | sized(T) | { void ?{}(T *, Params); } ) T * new( Params p );§\indexc{new}§
    5298 forall( dtype T | { void ^?{}( T * ); } ) void delete( T * ptr );§\indexc{delete}§
    5299 forall( dtype T, ttype Params | { void ^?{}( T * ); void delete(Params); } ) void delete( T * ptr, Params rest );
    5300 \end{cfa}
    5301 
    5302 
    5303 \subsection{Conversion}
     5188forall( dtype T | sized(T) ) T * malloc( T * ptr, size_t size );
     5189forall( dtype T | sized(T) ) T * malloc( T * ptr, size_t size, unsigned char fill );
     5190forall( dtype T | sized(T) ) T * calloc( size_t nmemb );§\indexc{calloc}§
     5191forall( dtype T | sized(T) ) T * realloc( T * ptr, size_t size );§\indexc{ato}§
     5192forall( dtype T | sized(T) ) T * realloc( T * ptr, size_t size, unsigned char fill );
     5193
     5194forall( dtype T | sized(T) ) T * aligned_alloc( size_t alignment );§\indexc{ato}§
     5195forall( dtype T | sized(T) ) T * memalign( size_t alignment );          // deprecated
     5196forall( dtype T | sized(T) ) int posix_memalign( T ** ptr, size_t alignment );
     5197
     5198forall( dtype T, ttype Params | sized(T) | { void ?{}(T *, Params); } ) T * new( Params p );
     5199forall( dtype T | { void ^?{}(T *); } ) void delete( T * ptr );
     5200forall( dtype T, ttype Params | { void ^?{}(T *); void delete(Params); } ) void delete( T * ptr, Params rest );
     5201\end{cfa}
     5202
     5203
     5204\subsection{ato / strto}
    53045205
    53055206\leavevmode
     
    53335234
    53345235
    5335 \subsection{Search / Sort}
     5236\subsection{bsearch / qsort}
    53365237
    53375238\leavevmode
    53385239\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    5339 forall( otype T | { int ?<?( T, T ); } )        §\C{// location}§
     5240forall( otype T | { int ?<?( T, T ); } )        // location
    53405241T * bsearch( T key, const T * arr, size_t dimension );§\indexc{bsearch}§
    53415242
    5342 forall( otype T | { int ?<?( T, T ); } )        §\C{// position}§
     5243forall( otype T | { int ?<?( T, T ); } )        // position
    53435244unsigned int bsearch( T key, const T * arr, size_t dimension );
    53445245
     
    53485249
    53495250
    5350 \subsection{Absolute Value}
     5251\subsection{abs}
    53515252
    53525253\leavevmode
     
    53675268
    53685269
    5369 \subsection{Random Numbers}
     5270\subsection{random}
    53705271
    53715272\leavevmode
     
    53855286
    53865287
    5387 \subsection{Algorithms}
     5288\subsection{min / max / clamp / swap}
    53885289
    53895290\leavevmode
     
    57705671\label{s:MultiPrecisionIntegers}
    57715672
    5772 \CFA has an interface to the GMP \Index{multi-precision} signed-integers~\cite{GMP}, similar to the \CC interface provided by GMP.
     5673\CFA has an interface to the \Index{GMP} \Index{multi-precision} signed-integers~\cite{GMP}, similar to the \CC interface provided by GMP.
    57735674The \CFA interface wraps GMP routines into operator routines to make programming with multi-precision integers identical to using fixed-sized integers.
    5774 The \CFA type name for multi-precision signed-integers is \Indexc{Int} and the header file is \Indexc{gmp}.
     5675The \CFA type name for multi-precision signed-integers is \Indexc{Int}.
    57755676
    57765677\begin{cfa}
     
    59425843\hline
    59435844\begin{cfa}
    5944 #include <gmp>§\indexc{gmp}§
     5845#include <gmp>
    59455846int main( void ) {
    59465847        sout | "Factorial Numbers" | endl;
    5947         Int fact = 1;
    5948 
     5848        Int fact;
     5849        fact = 1;
    59495850        sout | 0 | fact | endl;
    59505851        for ( unsigned int i = 1; i <= 40; i += 1 ) {
     
    59565857&
    59575858\begin{cfa}
    5958 #include <gmp.h>§\indexc{gmp.h}§
     5859#include <gmp.h>
    59595860int main( void ) {
    59605861        ®gmp_printf®( "Factorial Numbers\n" );
  • src/libcfa/gmp

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

    r5e8d7327 ra029714  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 30 09:07:35 2017
    13 // Update Count     : 164
     12// Last Modified On : Wed May 24 18:06:27 2017
     13// Update Count     : 115
    1414//
    1515
     
    2828//---------------------------------------
    2929
    30 extern "C" { void * memset( void * dest, int c, size_t size ); } // use default C routine for void *
     30forall( dtype T | sized(T) ) T * malloc( void );
     31forall( dtype T | sized(T) ) T * malloc( char fill );
     32forall( dtype T | sized(T) ) T * malloc( T * ptr, size_t size );
     33forall( dtype T | sized(T) ) T * malloc( T * ptr, size_t size, unsigned char fill );
     34extern "C" { void * calloc( size_t nmemb, size_t size ); } // use default C routine for void *
     35forall( dtype T | sized(T) ) T * calloc( size_t nmemb );
     36extern "C" { void * realloc( void * ptr, size_t size ); } // use default C routine for void *
     37forall( dtype T | sized(T) ) T * realloc( T * ptr, size_t size );
     38forall( dtype T | sized(T) ) T * realloc( T * ptr, size_t size, unsigned char fill );
    3139
    32 // allocation, non-array types
    33 static 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
    37 static 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
     40forall( dtype T | sized(T) ) T * aligned_alloc( size_t alignment );
     41forall( dtype T | sized(T) ) T * memalign( size_t alignment );          // deprecated
     42forall( dtype T | sized(T) ) int posix_memalign( T ** ptr, size_t alignment );
    4243
    43 // allocation, array types
    44 extern "C" { void * calloc( size_t dim, size_t size ); } // use default C routine for void *
    45 static 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 }
    49 static 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
    53 static 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
    60 extern "C" { void * realloc( void * ptr, size_t size ); } // use default C routine for void *
    61 static 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 }
    65 forall( dtype T | sized(T) ) T * realloc( T * ptr, size_t size, char fill );
    66 static 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
    70 static 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
    76 static 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
    80 static 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
    86 extern "C" { void * memalign( size_t alignment, size_t size ); } // use default C routine for void *
    87 static inline forall( dtype T | sized(T) ) T * memalign( size_t alignment ) {
    88         //printf( "X11\n" );
    89         return (T *)memalign( alignment, sizeof(T) );
    90 } // memalign
    91 static 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
    96 static 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
    100 extern "C" { int posix_memalign( void ** ptr, size_t alignment, size_t size ); } // use default C routine for void *
    101 static 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
    107 static 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
    111 static 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
    118 static 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
    122 extern "C" { void * memcpy( void * dest, const void * src, size_t size ); } // use default C routine for void *
    123 static 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
    129 static 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
    133 static 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
    13944forall( dtype T, ttype Params | sized(T) | { void ?{}(T *, Params); } ) T * new( Params p );
    140 forall( dtype T | { void ^?{}( T * ); } ) void delete( T * ptr );
    141 forall( dtype T, ttype Params | { void ^?{}( T * ); void delete( Params ); } ) void delete( T * ptr, Params rest );
     45forall( dtype T | { void ^?{}(T *); } ) void delete( T * ptr );
     46forall( dtype T, ttype Params | { void ^?{}(T *); void delete(Params); } ) void delete( T * ptr, Params rest );
    14247
    14348//---------------------------------------
     
    17277
    17378forall( otype T | { int ?<?( T, T ); } )
    174 T * bsearch( T key, const T * arr, size_t dim );
     79T * bsearch( T key, const T * arr, size_t dimension );
    17580
    17681forall( otype T | { int ?<?( T, T ); } )
    177 unsigned int bsearch( T key, const T * arr, size_t dim );
     82unsigned int bsearch( T key, const T * arr, size_t dimension );
    17883
    17984
    18085forall( otype T | { int ?<?( T, T ); } )
    181 void qsort( const T * arr, size_t dim );
     86void qsort( const T * arr, size_t dimension );
    18287
    18388//---------------------------------------
  • src/libcfa/stdlib.c

    r5e8d7327 ra029714  
    1010// Created On       : Thu Jan 28 17:10:29 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 30 09:07:56 2017
    13 // Update Count     : 237
     12// Last Modified On : Wed May 24 18:13:15 2017
     13// Update Count     : 198
    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>                                                                             // memcpy, memset
     23#include <string.h>                                                                             // memset
    2424#include <malloc.h>                                                                             // malloc_usable_size
    2525#include <math.h>                                                                               // fabsf, fabs, fabsl
     
    2727} // extern "C"
    2828
    29 // resize, non-array types
    30 forall( 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;
     29forall( dtype T | sized(T) ) T * malloc( void ) {               // type-safe
     30    return (T *)(void *)malloc( (size_t)sizeof(T) );
     31} // malloc
     32
     33forall( 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
     38forall( dtype T | sized(T) ) T * malloc( T * ptr, size_t size ) { // alternative realloc
     39    return (T *)realloc( ptr, size );
     40} // malloc
     41
     42forall( 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
     47forall( 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
     52forall( dtype T | sized(T) ) T * realloc( T * ptr, size_t size ) { // type-safe
     53    return (T *)(void *)realloc( (void *)ptr, size );
    3954} // realloc
    4055
    41 // allocation/deallocation and constructor/destructor
    42 forall( dtype T, ttype Params | sized(T) | { void ?{}( T *, Params ); } )
     56forall( 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
     64forall( dtype T | sized(T) ) T * aligned_alloc( size_t alignment ) { // aligned allocation
     65    return (T *)memalign( alignment, sizeof(T) );
     66} // aligned_alloc
     67
     68forall( dtype T | sized(T) ) T * memalign( size_t alignment ) {
     69    return (T *)memalign( alignment, sizeof(T) );
     70} // memalign
     71
     72forall( 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
     77forall( dtype T, ttype Params | sized(T) | { void ?{}( T *, Params ); } ) //  new
    4378T * new( Params p ) {
    4479        return ((T *)malloc()){ p };
    4580} // new
    4681
    47 forall( dtype T | { void ^?{}( T * ); } )
     82forall( dtype T | { void ^?{}(T *); } )                                 // delete
    4883void delete( T * ptr ) {
    4984        if ( ptr ) {
    50                 ^ptr{};                                                                                 // run destructor
     85                ^ptr{};
    5186                free( ptr );
    52         } // if
     87        }
    5388} // delete
    5489
    55 forall( dtype T, ttype Params | { void ^?{}( T * ); void delete( Params ); } )
     90forall( dtype T, ttype Params | { void ^?{}(T *); void delete(Params); } )
    5691void delete( T * ptr, Params rest ) {
    5792        if ( ptr ) {
    58                 ^ptr{};                                                                                 // run destructor
     93                ^ptr{};
    5994                free( ptr );
    60         } // if
     95        }
    6196        delete( rest );
    6297} // delete
     
    207242
    208243forall( otype T | { int ?<?( T, T ); } )
    209 T * bsearch( T key, const T * arr, size_t dim ) {
     244T * bsearch( T key, const T * arr, size_t dimension ) {
    210245        int comp( const void * t1, const void * t2 ) { return *(T *)t1 < *(T *)t2 ? -1 : *(T *)t2 < *(T *)t1 ? 1 : 0; }
    211         return (T *)bsearch( &key, arr, dim, sizeof(T), comp );
     246        return (T *)bsearch( &key, arr, dimension, sizeof(T), comp );
    212247} // bsearch
    213248
    214249forall( otype T | { int ?<?( T, T ); } )
    215 unsigned 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)
     250unsigned 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)
    218253} // bsearch
    219254
    220255forall( otype T | { int ?<?( T, T ); } )
    221 void qsort( const T * arr, size_t dim ) {
     256void qsort( const T * arr, size_t dimension ) {
    222257        int comp( const void * t1, const void * t2 ) { return *(T *)t1 < *(T *)t2 ? -1 : *(T *)t2 < *(T *)t1 ? 1 : 0; }
    223         qsort( arr, dim, sizeof(T), comp );
     258        qsort( arr, dimension, sizeof(T), comp );
    224259} // qsort
    225260
Note: See TracChangeset for help on using the changeset viewer.