Changes in doc/user/user.tex [dabc428:b202dc2]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/user/user.tex
rdabc428 rb202dc2 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Tue Apr 20 23:25:56202114 %% Update Count : 4 88813 %% Last Modified On : Sat Mar 27 09:55:55 2021 14 %% Update Count : 4796 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 66 66 % math escape $...$ (dollar symbol) 67 67 \input{common} % common CFA document macros 68 \setlength{\gcolumnposn}{3in}69 68 \CFAStyle % use default CFA format-style 70 69 \lstset{language=CFA} % CFA default lnaguage … … 2167 2166 \section{Enumeration} 2168 2167 2169 An \newterm{enumeration} is a compile-time mechanism to alias names to constants, like ©typedef© is a mechanism to alias names to types. 2170 Its purpose is to define a restricted-value type providing code-readability and maintenance -- changing an enum's value automatically updates all name usages during compilation. 2171 2172 An enumeration type is a set of names, each called an \newterm{enumeration constant} (shortened to \newterm{enum}) aliased to a fixed value (constant). 2173 \begin{cfa} 2174 enum Days { Mon, Tue, Wed, Thu, Fri, Sat, Sun }; // enumeration type definition, set of 7 names & values 2168 An \newterm{enumeration} is a compile-time mechanism to give names to constants. 2169 There is no runtime manifestation of an enumeration. 2170 Their purpose is code-readability and maintenance -- changing an enum's value automatically updates all name usages during compilation. 2171 2172 An enumeration defines a type containing a set of names, each called an \newterm{enumeration constant} (shortened to \newterm{enum}) with a fixed (©const©) value. 2173 \begin{cfa} 2174 enum Days { Mon, Tue, Wed, Thu, Fri, Sat, Sun }; // enumeration type definition, set of 7 names 2175 2175 Days days = Mon; // enumeration type declaration and initialization 2176 2176 \end{cfa} 2177 The set of enums are injected into the variable namespace at the definition scope.2177 The set of enums are injected into the scope of the definition and use the variable namespace. 2178 2178 Hence, enums may be overloaded with enum/variable/function names. 2179 2179 \begin{cfa} … … 2183 2183 double Bar; $\C{// overload Foo.Bar, Goo.Bar}\CRT$ 2184 2184 \end{cfa} 2185 An anonymous enumeration i njects enums with specific values into a scope.2185 An anonymous enumeration is used to inject enums with specific values into a scope: 2186 2186 \begin{cfa} 2187 2187 enum { Prime = 103, BufferSize = 1024 }; 2188 2188 \end{cfa} 2189 An enumeration is better than using C \Index{preprocessor} or constant declarations. 2190 \begin{cquote} 2191 \begin{tabular}{@{}l@{\hspace{4em}}l@{}} 2189 An enumeration is better than using the C \Index{preprocessor} 2192 2190 \begin{cfa} 2193 2191 #define Mon 0 … … 2195 2193 #define Sun 6 2196 2194 \end{cfa} 2197 & 2198 \begin{cfa} 2199 const int Mon = 0, 2200 ..., 2201 Sun = 6; 2202 \end{cfa} 2203 \end{tabular} 2204 \end{cquote} 2195 or C constant declarations 2196 \begin{cfa} 2197 const int Mon = 0, ..., Sun = 6; 2198 \end{cfa} 2205 2199 because the enumeration is succinct, has automatic numbering, can appear in ©case© labels, does not use storage, and is part of the language type-system. 2206 2200 Finally, the type of an enum is implicitly or explicitly specified and the constant value can be implicitly or explicitly specified. … … 2210 2204 \subsection{Enum type} 2211 2205 2212 The type of enums can be any type, and an enum's value comes from this type. 2213 Because an enum is a constant, it cannot appear in a mutable context, \eg ©Mon = Sun© is disallowed, and has no address (it is an rvalue). 2214 Therefore, an enum is automatically converted to its constant's base-type, \eg comparing/printing an enum compares/prints its value rather than the enum name; 2215 there is no mechanism to print the enum name. 2216 2206 While an enumeration defines a new set-type of names, its underlying enums can be any ©const© type, and an enum's value comes from this type. 2207 \CFA provides an automatic conversion from an enum to its base type, \eg comparing/printing an enum compares/prints its value rather than the enum name. 2217 2208 The default enum type is ©int©. 2218 2209 Hence, ©Days© is the set type ©Mon©, ©Tue©, ...\,, ©Sun©, while the type of each enum is ©int© and each enum represents a fixed integral value. 2219 2210 If no values are specified for an integral enum type, the enums are automatically numbered by one from left to right starting at zero. 2220 2211 Hence, the value of enum ©Mon© is 0, ©Tue© is 1, ...\,, ©Sun© is 6. 2221 If a n enum value is specified, numbering continues by one from that value for subsequent unnumbered enums.2222 I fan enum value is an expression, the compiler performs constant-folding to obtain a constant value.2223 2224 \CFA allows other integral types with associated values.2212 If a value is specified, numbering continues by one from that value. 2213 It an enum value is an expression, the compiler performs constant-folding to obtain a constant value. 2214 2215 Other integral types with associated values can be explicitly specified. 2225 2216 \begin{cfa} 2226 2217 enum( @char@ ) Letter { A @= 'A'@, B, C, I @= 'I'@, J, K }; … … 2228 2219 \end{cfa} 2229 2220 For enumeration ©Letter©, enum ©A©'s value is explicitly set to ©'A'©, with ©B© and ©C© implicitly numbered with increasing values from ©'A'©, and similarly for enums ©I©, ©J©, and ©K©. 2230 2231 Non-integral enum types must be explicitly initialized, \eg ©double© is not automatically numbered by one. 2221 Note, an enum is an immutable constant, \ie ©A = B© is disallowed; 2222 by transitivity, an enum's type is implicitly ©const©. 2223 Hence, a constant/enum cannot appear in a mutuable context nor is a constant/enum addressable (rvalue). 2224 2225 Non-integral enum types have the restriction that all enums \emph{must} be explicitly specified, \ie incrementing by one for the next enum is not done even if supported by the enum type, \eg ©double©. 2232 2226 \begin{cfa} 2233 2227 // non-integral numeric 2234 enum( @double@) Math { PI_2 = 1.570796, PI = 3.141597, E = 2.718282 }2228 enum( double ) Math { PI_2 = 1.570796, PI = 3.141597, E = 2.718282 } 2235 2229 // pointer 2236 enum( @char *@) Name { Fred = "Fred", Mary = "Mary", Jane = "Jane" };2230 enum( char * ) Name { Fred = "Fred", Mary = "Mary", Jane = "Jane" }; 2237 2231 int i, j, k; 2238 enum( @int *@) ptr { I = &i, J = &j, K = &k };2239 enum( @int &@) ref { I = i, J = j, K = k };2232 enum( int * ) ptr { I = &i, J = &j, K = &k }; 2233 enum( int & ) ref { I = i, J = j, K = k }; 2240 2234 // tuple 2241 enum( @[int, int]@) { T = [ 1, 2 ] };2235 enum( [int, int] ) { T = [ 1, 2 ] }; 2242 2236 // function 2243 2237 void f() {...} void g() {...} 2244 enum( @void (*)()@) funs { F = f, F = g };2238 enum( void (*)() ) funs { F = f, F = g }; 2245 2239 // aggregate 2246 2240 struct S { int i, j; }; 2247 enum( @S@) s { A = { 3, 4 }, B = { 7, 8 } };2241 enum( S ) s { A = { 3, 4 }, B = { 7, 8 } }; 2248 2242 // enumeration 2249 enum( @Letter@) Greek { Alph = A, Beta = B, /* more enums */ }; // alphabet intersection2243 enum( Letter ) Greek { Alph = A, Beta = B, /* more enums */ }; // alphabet intersection 2250 2244 \end{cfa} 2251 2245 Enumeration ©Greek© may have more or less enums than ©Letter©, but the enum values \emph{must} be from ©Letter©. … … 2259 2253 m = Alph; $\C{// {\color{red}disallowed}}$ 2260 2254 m = 3.141597; $\C{// {\color{red}disallowed}}$ 2261 d = m; $\C{// allowed}$ 2255 d = E; $\C{// allowed, conversion to base type}$ 2256 d = m; $\C{// {\color{red}disallowed}}$ 2262 2257 d = Alph; $\C{// {\color{red}disallowed}}$ 2263 2258 Letter l = A; $\C{// allowed}$ … … 2268 2263 2269 2264 A constructor \emph{cannot} be used to initialize enums because a constructor executes at runtime. 2270 A fallback is explicit C-style initialization using©@=©.2271 \begin{cfa} 2272 enum( struct vec3 ) Axis { Up $@$= { 1, 0, 0 }, Left $@$= { 0, 1, 0 }, Front $@$= { 0, 0, 1 }}2265 A fallback is to substitute C-style initialization overriding the constructor with ©@=©. 2266 \begin{cfa} 2267 enum( struct vec3 ) Axis { Up $@$= { 1, 0, 0 }, Left $@$= ..., Front $@$= ... } 2273 2268 \end{cfa} 2274 2269 Finally, enumeration variables are assignable and comparable only if the appropriate operators are defined for its enum type. … … 2279 2274 \Index{Plan-9}\index{inheritance!enumeration} inheritance may be used with enumerations. 2280 2275 \begin{cfa} 2281 enum( c har * ) Name2 { @inline Name@, Jack = "Jack", Jill = "Jill" };2282 enum @/* inferred */@ Name3 { @inline Name 2@, Sue = "Sue", Tom = "Tom" };2276 enum( const char * ) Name2 { @inline Name@, Jack = "Jack", Jill = "Jill" }; 2277 enum @/* inferred */@ Name3 { @inline Name@, @inline Name2@, Sue = "Sue", Tom = "Tom" }; 2283 2278 \end{cfa} 2284 2279 Enumeration ©Name2© inherits all the enums and their values from enumeration ©Name© by containment, and a ©Name© enumeration is a subtype of enumeration ©Name2©. … … 2286 2281 The enum type for the inheriting type must be the same as the inherited type; 2287 2282 hence the enum type may be omitted for the inheriting enumeration and it is inferred from the inherited enumeration, as for ©Name3©. 2288 When inheriting from integral types, automatic numbering may be used, so the inheritance placement left to right is important , \eg the placement of ©Sue© and ©Tom© before or after ©inline Name2©.2283 When inheriting from integral types, automatic numbering may be used, so the inheritance placement left to right is important. 2289 2284 2290 2285 Specifically, the inheritance relationship for ©Name©s is: … … 2306 2301 j( Fred ); j( Jill ); j( Sue ); j( 'W' ); 2307 2302 \end{cfa} 2308 Note, the validity of calls is the same for call -by-reference as for call-by-value, and ©const© restrictions are the same as for other types.2303 Note, the validity of calls is the same for call by reference as for call by value, and ©const© restrictions are the same as for other types. 2309 2304 2310 2305 Enums cannot be created at runtime, so inheritence problems, such as contra-variance do not apply. … … 2318 2313 \begin{cfa} 2319 2314 // Fred is a subset of char * 2320 enum ( char *)Fred { A = "A", B = "B", C = "C" };2315 enum char * Fred { A = "A", B = "B", C = "C" }; 2321 2316 // Jack is a subset of Fred 2322 enum ( enum Fred )Jack { W = A, Y = C};2317 enum enum Fred Jack { W = A, Y = C}; 2323 2318 // Mary is a superset of Fred 2324 2319 enum Mary { inline Fred, D = "hello" }; … … 4173 4168 4174 4169 The format of numeric input values in the same as C constants without a trailing type suffix, as the input value-type is denoted by the input variable. 4175 For © bool© type, the constants are ©true© and ©false©.4170 For ©_Bool© type, the constants are ©true© and ©false©. 4176 4171 For integral types, any number of digits, optionally preceded by a sign (©+© or ©-©), where a 4177 4172 \begin{itemize} … … 4585 4580 In C, the integer constants 0 and 1 suffice because the integer promotion rules can convert them to any arithmetic type, and the rules for pointer expressions treat constant expressions evaluating to 0 as a special case. 4586 4581 However, user-defined arithmetic types often need the equivalent of a 1 or 0 for their functions or operators, polymorphic functions often need 0 and 1 constants of a type matching their polymorphic parameters, and user-defined pointer-like types may need a null value. 4587 Defining special constants for a user-defined type is more efficient than defining a conversion to the type from © bool©.4582 Defining special constants for a user-defined type is more efficient than defining a conversion to the type from ©_Bool©. 4588 4583 4589 4584 Why just 0 and 1? Why not other integers? No other integers have special status in C. … … 5050 5045 \begin{figure} 5051 5046 \begin{cfa} 5052 #include <fstream .hfa>5053 #include @<coroutine.hfa>@5054 5055 @coroutine@Fibonacci {5047 #include <fstream> 5048 #include <coroutine> 5049 5050 coroutine Fibonacci { 5056 5051 int fn; $\C{// used for communication}$ 5057 5052 }; 5058 5059 void main( Fibonacci & fib ) with( fib ) { $\C{// called on first resume}$ 5053 void ?{}( Fibonacci * this ) { 5054 this->fn = 0; 5055 } 5056 void main( Fibonacci * this ) { 5060 5057 int fn1, fn2; $\C{// retained between resumes}$ 5061 fn = 0; fn1 = fn; $\C{// 1st case}$ 5062 @suspend;@ $\C{// restart last resume}$ 5063 fn = 1; fn2 = fn1; fn1 = fn; $\C{// 2nd case}$ 5064 @suspend;@ $\C{// restart last resume}$ 5065 for () { 5066 fn = fn1 + fn2; fn2 = fn1; fn1 = fn; $\C{// general case}$ 5067 @suspend;@ $\C{// restart last resume}$ 5068 } 5069 } 5070 int next( Fibonacci & fib ) with( fib ) { 5071 @resume( fib );@ $\C{// restart last suspend}$ 5072 return fn; 5058 this->fn = 0; $\C{// case 0}$ 5059 fn1 = this->fn; 5060 suspend(); $\C{// return to last resume}$ 5061 5062 this->fn = 1; $\C{// case 1}$ 5063 fn2 = fn1; 5064 fn1 = this->fn; 5065 suspend(); $\C{// return to last resume}$ 5066 5067 for ( ;; ) { $\C{// general case}$ 5068 this->fn = fn1 + fn2; 5069 fn2 = fn1; 5070 fn1 = this->fn; 5071 suspend(); $\C{// return to last resume}$ 5072 } // for 5073 } 5074 int next( Fibonacci * this ) { 5075 resume( this ); $\C{// transfer to last suspend}$ 5076 return this->fn; 5073 5077 } 5074 5078 int main() { 5075 5079 Fibonacci f1, f2; 5076 for ( 10 ) { $\C{// print N Fibonacci values}$ 5077 sout | next( f1 ) | next( f2 ); 5078 } 5079 } 5080 \end{cfa} 5081 \vspace*{-5pt} 5080 for ( int i = 1; i <= 10; i += 1 ) { 5081 sout | next( &f1 ) | ' ' | next( &f2 ); 5082 } // for 5083 } 5084 \end{cfa} 5082 5085 \caption{Fibonacci Coroutine} 5083 5086 \label{f:FibonacciCoroutine} … … 5105 5108 \begin{figure} 5106 5109 \begin{cfa} 5107 #include <fstream.hfa> 5108 #include @<thread.hfa>@ 5109 5110 @monitor@ AtomicCnt { int counter; }; 5111 void ?{}( AtomicCnt & c, int init = 0 ) with(c) { counter = init; } 5112 int inc( AtomicCnt & @mutex@ c, int inc = 1 ) with(c) { return counter += inc; } 5113 int dec( AtomicCnt & @mutex@ c, int dec = 1 ) with(c) { return counter -= dec; } 5114 forall( ostype & | ostream( ostype ) ) { $\C{// print any stream}$ 5115 ostype & ?|?( ostype & os, AtomicCnt c ) { return os | c.counter; } 5116 void ?|?( ostype & os, AtomicCnt c ) { (ostype &)(os | c.counter); ends( os ); } 5117 } 5118 5119 AtomicCnt global; $\C{// shared}$ 5110 #include <fstream> 5111 #include <kernel> 5112 #include <monitor> 5113 #include <thread> 5114 5115 monitor global_t { 5116 int value; 5117 }; 5118 5119 void ?{}(global_t * this) { 5120 this->value = 0; 5121 } 5122 5123 static global_t global; 5124 5125 void increment3( global_t * mutex this ) { 5126 this->value += 1; 5127 } 5128 void increment2( global_t * mutex this ) { 5129 increment3( this ); 5130 } 5131 void increment( global_t * mutex this ) { 5132 increment2( this ); 5133 } 5120 5134 5121 5135 thread MyThread {}; 5122 void main( MyThread & ) { 5123 for ( i; 100_000) {5124 inc( global );5125 dec(global );5136 5137 void main( MyThread* this ) { 5138 for(int i = 0; i < 1_000_000; i++) { 5139 increment( &global ); 5126 5140 } 5127 5141 } 5128 int main() { 5129 enum { Threads = 4 }; 5130 processor p[Threads - 1]; $\C{// + starting processor}$ 5142 int main(int argc, char* argv[]) { 5143 processor p; 5131 5144 { 5132 MyThread t[Threads];5145 MyThread f[4]; 5133 5146 } 5134 sout | global ; $\C{// print 0}$5147 sout | global.value; 5135 5148 } 5136 5149 \end{cfa} 5137 5150 \caption{Atomic-Counter Monitor} 5138 \ label{f:AtomicCounterMonitor}5151 \caption{f:AtomicCounterMonitor} 5139 5152 \end{figure} 5140 5153 … … 7307 7320 [ int, long double ] remquo( long double, long double ); 7308 7321 7322 float div( float, float, int * );$\indexc{div}$ $\C{// alternative name for remquo}$ 7323 double div( double, double, int * ); 7324 long double div( long double, long double, int * ); 7309 7325 [ int, float ] div( float, float ); 7310 7326 [ int, double ] div( double, double ); … … 7367 7383 long double _Complex log( long double _Complex ); 7368 7384 7369 int log2( unsigned int );$\indexc{log2}$ 7370 long int log2( unsigned long int ); 7371 long long int log2( unsigned long long int ) 7372 float log2( float ); 7385 float log2( float );$\indexc{log2}$ 7373 7386 double log2( double ); 7374 7387 long double log2( long double ); … … 7552 7565 \leavevmode 7553 7566 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 7554 // n / align * align7555 signed char floor( signed char n, signed char align );7556 unsigned char floor( unsigned char n, unsigned char align );7557 short int floor( short int n, short int align );7558 unsigned short int floor( unsigned short int n, unsigned short int align );7559 int floor( int n, int align );7560 unsigned int floor( unsigned int n, unsigned int align );7561 long int floor( long int n, long int align );7562 unsigned long int floor( unsigned long int n, unsigned long int align );7563 long long int floor( long long int n, long long int align );7564 unsigned long long int floor( unsigned long long int n, unsigned long long int align );7565 7566 // (n + (align - 1)) / align7567 signed char ceiling_div( signed char n, char align );7568 unsigned char ceiling_div( unsigned char n, unsigned char align );7569 short int ceiling_div( short int n, short int align );7570 unsigned short int ceiling_div( unsigned short int n, unsigned short int align );7571 int ceiling_div( int n, int align );7572 unsigned int ceiling_div( unsigned int n, unsigned int align );7573 long int ceiling_div( long int n, long int align );7574 unsigned long int ceiling_div( unsigned long int n, unsigned long int align );7575 long long int ceiling_div( long long int n, long long int align );7576 unsigned long long int ceiling_div( unsigned long long int n, unsigned long long int align );7577 7578 // floor( n + (n % align != 0 ? align - 1 : 0), align )7579 signed char ceiling( signed char n, signed char align );7580 unsigned char ceiling( unsigned char n, unsigned char align );7581 short int ceiling( short int n, short int align );7582 unsigned short int ceiling( unsigned short int n, unsigned short int align );7583 int ceiling( int n, int align );7584 unsigned int ceiling( unsigned int n, unsigned int align );7585 long int ceiling( long int n, long int align );7586 unsigned long int ceiling( unsigned long int n, unsigned long int align );7587 long long int ceiling( long long int n, long long int align );7588 unsigned long long int ceiling( unsigned long long int n, unsigned long long int align );7589 7590 7567 float floor( float );$\indexc{floor}$ 7591 7568 double floor( double ); … … 7690 7667 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 7691 7668 struct Duration { 7692 int64_t t n; $\C{// nanoseconds}$7669 int64_t tv; $\C{// nanoseconds}$ 7693 7670 }; 7694 7671 7695 7672 void ?{}( Duration & dur ); 7696 7673 void ?{}( Duration & dur, zero_t ); 7697 void ?{}( Duration & dur, timeval t )7698 void ?{}( Duration & dur, timespec t )7699 7674 7700 7675 Duration ?=?( Duration & dur, zero_t ); 7701 Duration ?=?( Duration & dur, timeval t )7702 Duration ?=?( Duration & dur, timespec t )7703 7676 7704 7677 Duration +?( Duration rhs ); … … 7722 7695 Duration ?%=?( Duration & lhs, Duration rhs ); 7723 7696 7724 bool ?==?( Duration lhs, zero_t);7725 bool ?!=?( Duration lhs, zero_t);7726 bool ?<? ( Duration lhs, zero_t);7727 bool ?<=?( Duration lhs, zero_t);7728 bool ?>? ( Duration lhs, zero_t);7729 bool ?>=?( Duration lhs, zero_t);7730 7731 bool ?==?( Duration lhs, Duration rhs);7732 bool ?!=?( Duration lhs, Duration rhs);7733 bool ?<? ( Duration lhs, Duration rhs);7734 bool ?<=?( Duration lhs, Duration rhs);7735 bool ?>? ( Duration lhs, Duration rhs);7736 bool ?>=?( Duration lhs, Duration rhs);7697 _Bool ?==?( Duration lhs, Duration rhs ); 7698 _Bool ?!=?( Duration lhs, Duration rhs ); 7699 _Bool ?<? ( Duration lhs, Duration rhs ); 7700 _Bool ?<=?( Duration lhs, Duration rhs ); 7701 _Bool ?>? ( Duration lhs, Duration rhs ); 7702 _Bool ?>=?( Duration lhs, Duration rhs ); 7703 7704 _Bool ?==?( Duration lhs, zero_t ); 7705 _Bool ?!=?( Duration lhs, zero_t ); 7706 _Bool ?<? ( Duration lhs, zero_t ); 7707 _Bool ?<=?( Duration lhs, zero_t ); 7708 _Bool ?>? ( Duration lhs, zero_t ); 7709 _Bool ?>=?( Duration lhs, zero_t ); 7737 7710 7738 7711 Duration abs( Duration rhs ); … … 7761 7734 int64_t ?`w( Duration dur ); 7762 7735 7763 double ?`dns( Duration dur );7764 double ?`dus( Duration dur );7765 double ?`dms( Duration dur );7766 double ?`ds( Duration dur );7767 double ?`dm( Duration dur );7768 double ?`dh( Duration dur );7769 double ?`dd( Duration dur );7770 double ?`dw( Duration dur );7771 7772 7736 Duration max( Duration lhs, Duration rhs ); 7773 7737 Duration min( Duration lhs, Duration rhs ); 7774 7775 forall( ostype & | ostream( ostype ) ) ostype & ?|?( ostype & os, Duration dur );7776 7738 \end{cfa} 7777 7739 … … 7784 7746 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 7785 7747 void ?{}( timeval & t ); 7786 void ?{}( timeval & t, zero_t );7787 7748 void ?{}( timeval & t, time_t sec, suseconds_t usec ); 7788 7749 void ?{}( timeval & t, time_t sec ); 7750 void ?{}( timeval & t, zero_t ); 7789 7751 void ?{}( timeval & t, Time time ); 7790 7752 … … 7792 7754 timeval ?+?( timeval & lhs, timeval rhs ); 7793 7755 timeval ?-?( timeval & lhs, timeval rhs ); 7794 bool ?==?( timeval lhs, timeval rhs );7795 bool ?!=?( timeval lhs, timeval rhs );7756 _Bool ?==?( timeval lhs, timeval rhs ); 7757 _Bool ?!=?( timeval lhs, timeval rhs ); 7796 7758 \end{cfa} 7797 7759 … … 7804 7766 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 7805 7767 void ?{}( timespec & t ); 7806 void ?{}( timespec & t, zero_t );7807 7768 void ?{}( timespec & t, time_t sec, __syscall_slong_t nsec ); 7808 7769 void ?{}( timespec & t, time_t sec ); 7770 void ?{}( timespec & t, zero_t ); 7809 7771 void ?{}( timespec & t, Time time ); 7810 7772 … … 7812 7774 timespec ?+?( timespec & lhs, timespec rhs ); 7813 7775 timespec ?-?( timespec & lhs, timespec rhs ); 7814 bool ?==?( timespec lhs, timespec rhs );7815 bool ?!=?( timespec lhs, timespec rhs );7776 _Bool ?==?( timespec lhs, timespec rhs ); 7777 _Bool ?!=?( timespec lhs, timespec rhs ); 7816 7778 \end{cfa} 7817 7779 … … 7835 7797 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 7836 7798 struct Time { 7837 uint64_t t n; $\C{// nanoseconds since UNIX epoch}$7799 uint64_t tv; $\C{// nanoseconds since UNIX epoch}$ 7838 7800 }; 7839 7801 7840 7802 void ?{}( Time & time ); 7841 7803 void ?{}( Time & time, zero_t ); 7804 7805 Time ?=?( Time & time, zero_t ); 7806 7842 7807 void ?{}( Time & time, timeval t ); 7808 Time ?=?( Time & time, timeval t ); 7809 7843 7810 void ?{}( Time & time, timespec t ); 7844 7845 Time ?=?( Time & time, zero_t );7846 Time ?=?( Time & time, timeval t );7847 7811 Time ?=?( Time & time, timespec t ); 7848 7812 … … 7854 7818 Time ?-?( Time lhs, Duration rhs ); 7855 7819 Time ?-=?( Time & lhs, Duration rhs ); 7856 bool ?==?( Time lhs, Time rhs ); 7857 bool ?!=?( Time lhs, Time rhs ); 7858 bool ?<?( Time lhs, Time rhs ); 7859 bool ?<=?( Time lhs, Time rhs ); 7860 bool ?>?( Time lhs, Time rhs ); 7861 bool ?>=?( Time lhs, Time rhs ); 7862 7863 int64_t ?`ns( Time t ); 7820 _Bool ?==?( Time lhs, Time rhs ); 7821 _Bool ?!=?( Time lhs, Time rhs ); 7822 _Bool ?<?( Time lhs, Time rhs ); 7823 _Bool ?<=?( Time lhs, Time rhs ); 7824 _Bool ?>?( Time lhs, Time rhs ); 7825 _Bool ?>=?( Time lhs, Time rhs ); 7864 7826 7865 7827 char * yy_mm_dd( Time time, char * buf ); 7866 char * ?`ymd( Time time, char * buf ); // short form 7828 char * ?`ymd( Time time, char * buf ) { // short form 7829 return yy_mm_dd( time, buf ); 7830 } // ymd 7867 7831 7868 7832 char * mm_dd_yy( Time time, char * buf ); 7869 char * ?`mdy( Time time, char * buf ); // short form 7833 char * ?`mdy( Time time, char * buf ) { // short form 7834 return mm_dd_yy( time, buf ); 7835 } // mdy 7870 7836 7871 7837 char * dd_mm_yy( Time time, char * buf ); 7872 char * ?`dmy( Time time, char * buf ); // short form 7838 char * ?`dmy( Time time, char * buf ) { // short form 7839 return dd_mm_yy( time, buf );; 7840 } // dmy 7873 7841 7874 7842 size_t strftime( char * buf, size_t size, const char * fmt, Time time ); 7875 7876 forall( ostype & | ostream( ostype ) ) ostype & ?|?( ostype & os, Time time ); 7843 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype & os, Time time ); 7877 7844 \end{cfa} 7878 7845 … … 7900 7867 \leavevmode 7901 7868 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 7902 struct Clock { $\C{// virtual clock}$ 7903 Duration offset; $\C{// offset from computer real-time}$ 7869 struct Clock { 7870 Duration offset; $\C{// for virtual clock: contains offset from real-time}$ 7871 int clocktype; $\C{// implementation only -1 (virtual), CLOCK\_REALTIME}$ 7904 7872 }; 7905 7873 7906 void ?{}( Clock & clk ); $\C{// create no offset}$ 7907 void ?{}( Clock & clk, Duration adj ); $\C{// create with offset}$ 7908 void reset( Clock & clk, Duration adj ); $\C{// change offset}$ 7909 7910 Duration resolutionHi(); $\C{// clock resolution in nanoseconds (fine)}$ 7911 Duration resolution(); $\C{// clock resolution without nanoseconds (coarse)}$ 7912 7913 Time timeHiRes(); $\C{// real time with nanoseconds}$ 7914 Time time(); $\C{// real time without nanoseconds}$ 7915 Time time( Clock & clk ); $\C{// real time for given clock}$ 7916 Time ?()( Clock & clk ); $\C{//\ \ \ \ alternative syntax}$ 7917 timeval time( Clock & clk ); $\C{// convert to C time format}$ 7918 tm time( Clock & clk ); 7919 Duration processor(); $\C{// non-monotonic duration of kernel thread}$ 7920 Duration program(); $\C{// non-monotonic duration of program CPU}$ 7921 Duration boot(); $\C{// monotonic duration since computer boot}$ 7874 void resetClock( Clock & clk ); 7875 void resetClock( Clock & clk, Duration adj ); 7876 void ?{}( Clock & clk ); 7877 void ?{}( Clock & clk, Duration adj ); 7878 7879 Duration getResNsec(); $\C{// with nanoseconds}$ 7880 Duration getRes(); $\C{// without nanoseconds}$ 7881 7882 Time getTimeNsec(); $\C{// with nanoseconds}$ 7883 Time getTime(); $\C{// without nanoseconds}$ 7884 Time getTime( Clock & clk ); 7885 Time ?()( Clock & clk ); 7886 timeval getTime( Clock & clk ); 7887 tm getTime( Clock & clk ); 7922 7888 \end{cfa} 7923 7889 … … 8090 8056 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype * os, Int mp ); 8091 8057 \end{cfa} 8092 \VRef[Figure]{f:MultiPrecisionFactorials} shows \CFA and C factorial programs using the GMP interfaces. 8058 8059 The following factorial programs contrast using GMP with the \CFA and C interfaces, where the output from these programs appears in \VRef[Figure]{f:MultiPrecisionFactorials}. 8093 8060 (Compile with flag \Indexc{-lgmp} to link with the GMP library.) 8094 8095 \begin{figure}8096 8061 \begin{cquote} 8097 8062 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}|@{\hspace{\parindentlnth}}l@{}} 8098 \multicolumn{1}{ @{}c|@{\hspace{\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{@{\hspace{\parindentlnth}}c}{\textbf{C}@{}} \\8063 \multicolumn{1}{c|@{\hspace{\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{@{\hspace{\parindentlnth}}c}{\textbf{C}} \\ 8099 8064 \hline 8100 8065 \begin{cfa} … … 8105 8070 8106 8071 sout | 0 | fact; 8107 for ( i; 40) {8072 for ( unsigned int i = 1; i <= 40; i += 1 ) { 8108 8073 fact *= i; 8109 8074 sout | i | fact; … … 8127 8092 \end{tabular} 8128 8093 \end{cquote} 8129 \small 8094 8095 \begin{figure} 8130 8096 \begin{cfa} 8131 8097 Factorial Numbers
Note: See TracChangeset
for help on using the changeset viewer.