Changeset 5e8d732
- Timestamp:
- May 30, 2017, 9:53:15 AM (8 years ago)
- 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. - Files:
-
- 2 added
- 1 deleted
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/user/user.tex
ra029714 r5e8d732 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Wed May 24 22:21:42201714 %% Update Count : 199413 %% Last Modified On : Tue May 30 09:08:16 2017 14 %% Update Count : 2072 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 135 135 136 136 \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 C11syntax.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. 139 139 \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 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. 141 141 The primary new features include parametric-polymorphic routines and types, exceptions, concurrency, and modules. 142 142 … … 147 147 instead, a programmer evolves an existing C program into \CFA by incrementally incorporating \CFA features. 148 148 New 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. 150 150 In contrast, \CFA has 30 years of hindsight and a clean starting point. 151 151 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.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. 154 154 \begin{quote2} 155 155 \begin{tabular}{@{}l@{\hspace{1.5em}}l@{\hspace{1.5em}}l@{}} 156 156 \multicolumn{1}{c@{\hspace{1.5em}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} & \multicolumn{1}{c}{\textbf{\CC}} \\ 157 157 \begin{cfa} 158 #include <fstream> 158 #include <fstream>§\indexc{fstream}§ 159 159 160 160 int main( void ) { … … 165 165 & 166 166 \begin{lstlisting} 167 #include <stdio.h> 167 #include <stdio.h>§\indexc{stdio.h}§ 168 168 169 169 int main( void ) { … … 174 174 & 175 175 \begin{lstlisting} 176 #include <iostream> 176 #include <iostream>§\indexc{iostream}§ 177 177 using namespace std; 178 178 int main() { … … 183 183 \end{tabular} 184 184 \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}).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}). 186 186 187 187 This document is a user manual for the \CFA programming language, targeted at \CFA programmers. … … 197 197 Even with all its problems, C continues to be popular because it allows writing software at virtually any level in a computer system without restriction. 198 198 For 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.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. 200 200 As well, for 30 years, C has been the number 1 and 2 most popular programming language: 201 201 \begin{center} … … 225 225 These 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. 226 226 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.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. 228 228 Without significant extension to the C programming language, it is becoming unable to cope with the needs of modern programming problems and programmers; 229 229 as a result, it will fade into disuse. 230 230 Considering 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.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. 232 232 While 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. 233 233 … … 243 243 int forty_two = identity( 42 ); §\C{// T is bound to int, forty\_two == 42}§ 244 244 \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. 246 246 \CFA{}\hspace{1pt}'s polymorphism was originally formalized by Ditchfiled~\cite{Ditchfield92}, and first implemented by Bilson~\cite{Bilson03}. 247 247 However, at that time, there was little interesting in extending C, so work did not continue. … … 262 262 A simple example is leveraging the existing type-unsafe (©void *©) C ©bsearch© to binary search a sorted floating-point array: 263 263 \begin{lstlisting} 264 void * bsearch( const void * key, const void * base, size_t nmemb, size_t size,264 void * bsearch( const void * key, const void * base, size_t dim, size_t size, 265 265 int (* compar)( const void *, const void * )); 266 266 … … 340 340 The 1999 C standard plus GNU extensions. 341 341 \item 342 {\lstset{deletekeywords={inline}} 342 343 \Indexc{-fgnu89-inline}\index{compilation option!-fgnu89-inline@{©-fgnu89-inline©}} 343 344 Use the traditional GNU semantics for inline routines in C99 mode, which allows inline routines in header files. 345 }% 344 346 \end{description} 345 347 The following new \CFA options are available: … … 412 414 \begin{cfa} 413 415 #ifndef __CFORALL__ 414 #include <stdio.h> 416 #include <stdio.h>§\indexc{stdio.h}§ §\C{// C header file}§ 415 417 #else 416 #include <fstream> 418 #include <fstream>§\indexc{fstream}§ §\C{// \CFA header file}§ 417 419 #endif 418 420 \end{cfa} … … 747 749 p2 = p1 + x; §\C{// compiler infers *p2 = *p1 + x;}§ 748 750 \end{cfa} 749 Algol68 infers the following de ferencing ©*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.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. 750 752 Unfortunately, automatic dereferencing does not work in all cases, and so some mechanism is necessary to fix incorrect choices. 751 753 … … 1421 1423 1422 1424 Given 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; 1424 1426 \Index*{Ada} supports both named and default arguments. 1425 1427 … … 1455 1457 \subsection{Type Nesting} 1456 1458 1457 \CFA allows \Index{type nesting}, and type qualification of the nested typ res (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. 1458 1460 \begin{figure} 1459 1461 \centering … … 1768 1770 \index{lvalue} 1769 1771 The 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 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.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. 1771 1773 An example of multiple assignment is: 1772 1774 \begin{cfa} … … 1861 1863 While C provides ©continue© and ©break© statements for altering control flow, both are restricted to one level of nesting for a particular control structure. 1862 1864 Unfortunately, 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}.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}. 1864 1866 For both ©continue© and ©break©, the target label must be directly associated with a ©for©, ©while© or ©do© statement; 1865 1867 for ©break©, the target label can also be associated with a ©switch©, ©if© or compound (©{}©) statement. … … 1901 1903 if ( ... ) { 1902 1904 for ( ... ) { 1903 for( ... ) {1905 while ( ... ) { 1904 1906 ... goto ®LC®; ... 1905 1907 ... goto ®LS®; ... … … 1922 1924 \end{figure} 1923 1925 1924 Both labelled ©continue© and ©break© are a ©goto©\index{goto@©goto©!restricted} restricted in the following ways: 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: 1925 1977 \begin{itemize} 1926 1978 \item … … 2249 2301 2250 2302 The 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 2251 2305 The common case is printing out a sequence of variables separated by whitespace. 2252 2306 \begin{quote2} … … 2306 2360 2307 2361 2308 The implicit separator\index{I/O 2362 The implicit separator\index{I/O!separator} character (space/blank) is a separator not a terminator. 2309 2363 The rules for implicitly adding the separator are: 2310 2364 \begin{enumerate} … … 2334 2388 2335 2389 \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]@([{=$£¥¡¿«@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]@([{=$£¥¡¿«@ 2337 2391 %$ 2338 2392 \begin{cfa}[mathescape=off] … … 2349 2403 \item 2350 2404 {\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]@,.;!?)]}%¢»@2405 A seperator does not appear after a C string ending with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[basicstyle=\tt]@,.;!?)]}%¢»@ 2352 2406 \begin{cfa}[belowskip=0pt] 2353 2407 sout | 1 | ", x" | 2 | ". x" | 3 | "; x" | 4 | "! x" | 5 | "? x" | 6 | "% x" … … 2360 2414 2361 2415 \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@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@ 2363 2417 \begin{cfa}[belowskip=0pt] 2364 2418 sout | "x`" | 1 | "`x'" | 2 | "'x\"" | 3 | "\"x:" | 4 | ":x " | 5 | " x\t" | 6 | "\tx" | endl; … … 2630 2684 2631 2685 \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).2686 Additionally, \CFA adds destructors that are called when a variable is deallocated (variable goes out of scope or object is deleted). 2633 2687 These functions take a reference to the structure as a parameter (see References for more information). 2634 2688 … … 2963 3017 Generics allow programmers to use type variables in place of concrete types so that the code can be reused with multiple types. 2964 3018 The 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.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. 2966 3020 2967 3021 2968 3022 \subsection{Generic Functions} 2969 3023 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.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. 2971 3025 The 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. 2972 3026 This means that compiled libraries can contain generic functions that can be used by programs linked with them (statically or dynamically). … … 3087 3141 3088 3142 Generic 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 }.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{}}. 3090 3144 For 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. 3091 3145 In C, something like this would have to be done using void pointers and unsafe casting. … … 3139 3193 Throwing 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. 3140 3194 The 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. 3142 3196 An exception is thrown using a throw statement, which accepts one argument. 3143 3197 … … 3345 3399 3346 3400 A 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).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). 3348 3402 After a task is allocated and initialized, its thread is spawned implicitly and begins executing in its function call method. 3349 3403 All tasks must define this function call method, with a void return value and no additional parameters, or the compiler will report an error. … … 3522 3576 \subsection{No Declarations, No Header Files} 3523 3577 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.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. 3525 3579 Header files and a preprocessor are normally used to avoid repeating code. 3526 3580 Thus, many variables, functions, and types are described twice, which exposes an opportunity for errors and causes additional maintenance work. … … 4167 4221 In developing \CFA, many other languages were consulted for ideas, constructs, and syntax. 4168 4222 Therefore, 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}.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}. 4170 4224 4171 4225 … … 4792 4846 \subsubsection[C++]{\CC} 4793 4847 4794 \Index*[C++]{\CC } is a general-purpose programming language.4848 \Index*[C++]{\CC{}} is a general-purpose programming language. 4795 4849 It has imperative, object-oriented and generic programming features, while also providing facilities for low-level memory manipulation. (Wikipedia) 4796 4850 … … 4977 5031 } 4978 5032 \end{cfa} 4979 \item[Rationale:] dropped from C11standard.\footnote{5033 \item[Rationale:] dropped from \Celeven standard.\footnote{ 4980 5034 At 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}} 4981 5035 \item[Effect on original feature:] original feature is deprecated. \\ … … 5045 5099 static struct X a = { 1, &b }; §\C{// definition}§ 5046 5100 \end{cfa} 5047 \item[Rationale:] avoids having different initialization rules for builtin types and user defined types.5101 \item[Rationale:] avoids having different initialization rules for builtin types and user-defined types. 5048 5102 \item[Effect on original feature:] change to semantics of well-defined feature. 5049 5103 \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. … … 5070 5124 \end{cfa} 5071 5125 In 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{}}. 5073 5127 Nested types are not hoisted and can be referenced using the field selection operator ``©.©'', unlike the \CC scope-resolution operator ``©::©''. 5074 5128 \item[Rationale:] ©struct© scope is crucial to \CFA as an information structuring and hiding mechanism. … … 5086 5140 struct Y; §\C{// struct Y and struct X are at the same scope}§ 5087 5141 struct X { 5088 struct Y { /* ... */ } y;5142 struct Y { /* ... */ } y; 5089 5143 }; 5090 5144 \end{cfa} … … 5108 5162 \label{s:StandardHeaders} 5109 5163 5110 C11prescribes 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: 5111 5165 \begin{quote2} 5112 \begin{tabular}{llll|l} 5166 \lstset{deletekeywords={float},deletekeywords=[2]{signal}} 5167 \begin{tabular}{@{}llll|l@{}} 5113 5168 \multicolumn{4}{c|}{C11} & \multicolumn{1}{c}{\CFA} \\ 5114 5169 \hline 5115 5170 \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} \\ 5124 5179 \end{tabular} 5125 5180 & 5126 5181 \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} \\ 5135 5190 \end{tabular} 5136 5191 & 5137 5192 \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} \\ 5146 5201 \end{tabular} 5147 5202 & 5148 5203 \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 \\ 5157 5212 \end{tabular} 5158 5213 & 5159 5214 \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 \\ 5168 5223 \end{tabular} 5169 5224 \end{tabular} … … 5177 5232 \label{s:StandardLibrary} 5178 5233 5179 The \CFA standard-library wraps explicitly-polymorphic C general-routines into implicitly-polymorphic versions. 5180 5181 5182 \subsection{malloc} 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. 5183 5256 5184 5257 \leavevmode 5185 5258 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 5259 // allocation, non-array types 5186 5260 forall( dtype T | sized(T) ) T * malloc( void );§\indexc{malloc}§ 5187 5261 forall( 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 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} 5205 5304 5206 5305 \leavevmode … … 5234 5333 5235 5334 5236 \subsection{ bsearch / qsort}5335 \subsection{Search / Sort} 5237 5336 5238 5337 \leavevmode 5239 5338 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 5240 forall( otype T | { int ?<?( T, T ); } ) // location5339 forall( otype T | { int ?<?( T, T ); } ) §\C{// location}§ 5241 5340 T * bsearch( T key, const T * arr, size_t dimension );§\indexc{bsearch}§ 5242 5341 5243 forall( otype T | { int ?<?( T, T ); } ) // position5342 forall( otype T | { int ?<?( T, T ); } ) §\C{// position}§ 5244 5343 unsigned int bsearch( T key, const T * arr, size_t dimension ); 5245 5344 … … 5249 5348 5250 5349 5251 \subsection{ abs}5350 \subsection{Absolute Value} 5252 5351 5253 5352 \leavevmode … … 5268 5367 5269 5368 5270 \subsection{ random}5369 \subsection{Random Numbers} 5271 5370 5272 5371 \leavevmode … … 5286 5385 5287 5386 5288 \subsection{ min / max / clamp / swap}5387 \subsection{Algorithms} 5289 5388 5290 5389 \leavevmode … … 5671 5770 \label{s:MultiPrecisionIntegers} 5672 5771 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. 5674 5773 The \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} .5774 The \CFA type name for multi-precision signed-integers is \Indexc{Int} and the header file is \Indexc{gmp}. 5676 5775 5677 5776 \begin{cfa} … … 5843 5942 \hline 5844 5943 \begin{cfa} 5845 #include <gmp> 5944 #include <gmp>§\indexc{gmp}§ 5846 5945 int main( void ) { 5847 5946 sout | "Factorial Numbers" | endl; 5848 Int fact ;5849 fact = 1; 5947 Int fact = 1; 5948 5850 5949 sout | 0 | fact | endl; 5851 5950 for ( unsigned int i = 1; i <= 40; i += 1 ) { … … 5857 5956 & 5858 5957 \begin{cfa} 5859 #include <gmp.h> 5958 #include <gmp.h>§\indexc{gmp.h}§ 5860 5959 int main( void ) { 5861 5960 ®gmp_printf®( "Factorial Numbers\n" ); -
src/libcfa/gmp
ra029714 r5e8d732 10 10 // Created On : Tue Apr 19 08:43:43 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon May 22 08:32:39201713 // Update Count : 1 312 // Last Modified On : Sat May 27 09:55:51 2017 13 // Update Count : 14 14 14 // 15 15 … … 22 22 23 23 // 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 ); }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 ); } 32 32 33 33 // 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 s hort 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; }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; } 47 47 48 48 // 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 ); }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 ); } 51 51 52 52 // 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 ); }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 ); } 88 88 89 89 // 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; }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; } 145 145 146 146 // 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 ) {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 ) { 150 150 Int quotient; 151 151 if ( mpz_sgn( divisor.mpz ) >= 0 ) { … … 164 164 return quotient; 165 165 } // ?/? 166 Int ?/?( Int dividend, long int divisor ) {166 static inline Int ?/?( Int dividend, long int divisor ) { 167 167 Int quotient; 168 168 if ( divisor >= 0 ) … … 174 174 return quotient; 175 175 } // ?/? 176 Int ?/?( long int dividend, Int divisor ) {176 static inline Int ?/?( long int dividend, Int divisor ) { 177 177 Int quotient; 178 178 if ( mpz_fits_slong_p( divisor.mpz ) ) … … 185 185 return quotient; 186 186 } // ?/? 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 ) {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 ) { 197 197 Int remainder; 198 198 if ( mpz_sgn( divisor.mpz ) >= 0 ) { … … 210 210 return remainder; 211 211 } // ?%? 212 Int ?%?( Int dividend, long int divisor ) {212 static inline Int ?%?( Int dividend, long int divisor ) { 213 213 Int remainder; 214 214 mpz_tdiv_r_ui( remainder.mpz, dividend.mpz, (divisor >= 0 ? divisor : -divisor)); 215 215 return remainder; 216 216 } // ?%? 217 Int ?%?( long int dividend, Int divisor ) {217 static inline Int ?%?( long int dividend, Int divisor ) { 218 218 Int remainder; 219 219 if ( mpz_fits_slong_p( divisor.mpz ) ) … … 226 226 return remainder; 227 227 } // ?%? 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; }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; } 236 236 237 237 // 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; }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; } 249 249 250 250 // I/O 251 forall( dtype istype | istream( istype ) )251 static inline forall( dtype istype | istream( istype ) ) 252 252 istype * ?|?( istype * is, Int * mp ) { 253 253 gmp_scanf( "%Zd", mp ); … … 255 255 } // ?|? 256 256 257 forall( dtype ostype | ostream( ostype ) )257 static inline forall( dtype ostype | ostream( ostype ) ) 258 258 ostype * ?|?( ostype * os, Int mp ) { 259 259 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) ); -
src/libcfa/stdlib
ra029714 r5e8d732 10 10 // Created On : Thu Jan 28 17:12:35 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed May 24 18:06:27201713 // Update Count : 1 1512 // Last Modified On : Tue May 30 09:07:35 2017 13 // Update Count : 164 14 14 // 15 15 … … 28 28 //--------------------------------------- 29 29 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 ); 30 extern "C" { void * memset( void * dest, int c, size_t size ); } // use default C routine for void * 31 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 42 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 36 60 extern "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 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 44 139 forall( 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 );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 ); 47 142 48 143 //--------------------------------------- … … 77 172 78 173 forall( otype T | { int ?<?( T, T ); } ) 79 T * bsearch( T key, const T * arr, size_t dim ension);80 81 forall( otype T | { int ?<?( T, T ); } ) 82 unsigned int bsearch( T key, const T * arr, size_t dim ension);83 84 85 forall( otype T | { int ?<?( T, T ); } ) 86 void qsort( const T * arr, size_t dim ension);174 T * bsearch( T key, const T * arr, size_t dim ); 175 176 forall( otype T | { int ?<?( T, T ); } ) 177 unsigned int bsearch( T key, const T * arr, size_t dim ); 178 179 180 forall( otype T | { int ?<?( T, T ); } ) 181 void qsort( const T * arr, size_t dim ); 87 182 88 183 //--------------------------------------- -
src/libcfa/stdlib.c
ra029714 r5e8d732 10 10 // Created On : Thu Jan 28 17:10:29 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed May 24 18:13:15201713 // Update Count : 19812 // Last Modified On : Tue May 30 09:07:56 2017 13 // Update Count : 237 14 14 // 15 15 … … 21 21 #define _XOPEN_SOURCE 600 // posix_memalign, *rand48 22 22 #include <stdlib.h> // malloc, free, calloc, realloc, memalign, posix_memalign, bsearch 23 #include <string.h> // mem set23 #include <string.h> // memcpy, memset 24 24 #include <malloc.h> // malloc_usable_size 25 25 #include <math.h> // fabsf, fabs, fabsl … … 27 27 } // extern "C" 28 28 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 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; 54 39 } // realloc 55 40 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 42 forall( dtype T, ttype Params | sized(T) | { void ?{}( T *, Params ); } ) 78 43 T * new( Params p ) { 79 44 return ((T *)malloc()){ p }; 80 45 } // new 81 46 82 forall( dtype T | { void ^?{}( T *); } ) // delete47 forall( dtype T | { void ^?{}( T * ); } ) 83 48 void delete( T * ptr ) { 84 49 if ( ptr ) { 85 ^ptr{}; 50 ^ptr{}; // run destructor 86 51 free( ptr ); 87 } 52 } // if 88 53 } // delete 89 54 90 forall( dtype T, ttype Params | { void ^?{}( T *); void delete(Params); } )55 forall( dtype T, ttype Params | { void ^?{}( T * ); void delete( Params ); } ) 91 56 void delete( T * ptr, Params rest ) { 92 57 if ( ptr ) { 93 ^ptr{}; 58 ^ptr{}; // run destructor 94 59 free( ptr ); 95 } 60 } // if 96 61 delete( rest ); 97 62 } // delete … … 242 207 243 208 forall( otype T | { int ?<?( T, T ); } ) 244 T * bsearch( T key, const T * arr, size_t dim ension) {209 T * bsearch( T key, const T * arr, size_t dim ) { 245 210 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, dim ension, sizeof(T), comp );211 return (T *)bsearch( &key, arr, dim, sizeof(T), comp ); 247 212 } // bsearch 248 213 249 214 forall( otype T | { int ?<?( T, T ); } ) 250 unsigned int bsearch( T key, const T * arr, size_t dim ension) {251 T *result = bsearch( key, arr, dim ension);252 return result ? result - arr : dim ension;// pointer subtraction includes sizeof(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) 253 218 } // bsearch 254 219 255 220 forall( otype T | { int ?<?( T, T ); } ) 256 void qsort( const T * arr, size_t dim ension) {221 void qsort( const T * arr, size_t dim ) { 257 222 int comp( const void * t1, const void * t2 ) { return *(T *)t1 < *(T *)t2 ? -1 : *(T *)t2 < *(T *)t1 ? 1 : 0; } 258 qsort( arr, dim ension, sizeof(T), comp );223 qsort( arr, dim, sizeof(T), comp ); 259 224 } // qsort 260 225
Note: See TracChangeset
for help on using the changeset viewer.