This commit is contained in:
jeanlemotan
2024-07-02 18:10:39 +02:00
commit 48ab06b1d9
733 changed files with 321088 additions and 0 deletions
+110
View File
@@ -0,0 +1,110 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<Title>EAAlignment</title>
<link type="text/css" rel="stylesheet" href="UTFDoc.css">
<meta name="author" content="Paul Pedriana">
</head>
<body bgcolor="#FFFFFF">
<h1>EAAlignment</h1>
<h2>Introduction</h2>
<p>EAAlignment provides a number of utilities for working with variable alignment. These include:</p>
<blockquote>
<table border="1">
<tr>
<td><strong>Entity</strong></td>
<td><strong>Description</strong></td>
</tr>
<tr>
<td>EAAlignOf(type)</td>
<td valign="top">Macro which returns the alignment of the given type as a constant expression. </td>
</tr>
<tr>
<td>AlignOf&lt;T&gt;</td>
<td valign="top">Template which returns the alignment of the given type. </td>
</tr>
<tr>
<td>AlignAddressUp<br>
AlignAddressDown</td>
<td valign="top">Function which aligns an arbitrary address up or down to the next user-supplied power of two. </td>
</tr>
<tr>
<td>AlignObjectUp<br>
AlignObjectDown</td>
<td valign="top">Function which aligns an arbitrary object up or down to the next user-supplied power of two. </td>
</tr>
<tr>
<td>GetAlignment<br>
IsAddressAligned<br>
IsObjectAligned&lt;T&gt;<br>
IsAligned&lt;T&gt;<br></td>
<td valign="top">Gets information about alignment. </td>
</tr>
<tr>
<td>AlignedType</td>
<td valign="top">Template which portably allows the re-typing of a class to have a specific alignment. </td>
</tr>
<tr>
<td>AlignedArray</td>
<td valign="top">Template which implements an array of an arbitrary class with a given alignment.</td>
</tr>
<tr>
<td>AlignedObject</td>
<td valign="top">Template which implements an instance of an arbitrary class with a given alignment.</td>
</tr>
<tr>
<td>ReadMisalignedUint16<br>
ReadMisalignedUint32<br>
ReadMisalignedUint64</td>
<td valign="top">Function which safely and portably reads potentially misaligned memory. </td>
</tr>
<tr>
<td>WriteMisalignedUint16<br>
WriteMisalignedUint32<br>
WriteMisalignedUint64</td>
<td valign="top">Function which safely and portably writes potentially misaligned memory. </td>
</tr>
</table>
</blockquote>
<p>We'll discuss some of these briefly.</p>
<h2>EAAlignOf</h2>
<p>EAAlignOf is your basic macro for retrieving the alignment of an object by its type. Recent versions of EABase define EA_ALIGN_OF, so EAAlignOf is currently a duplication of the EABase functionality. </p>
<p>Example usage: </p>
<pre class="code-example">printf(&quot;Alignment of type 'int' is %u.\n&quot;, (unsigned)EAAlignOf(int)); </pre>
<h2>AlignedType</h2>
<p> This class makes an aligned typedef for a given class based on a user-supplied class and alignment. This class exists because of a weakness in VC++ whereby it can only accept __declspec(align) and thus EA_PREFIX_ALIGN usage via an integer literal (e.g. &quot;16&quot;) and not an otherwise equivalent constant integral expression (e.g. sizeof Foo).</p>
<p>Example usage: </p>
<pre class="code-example">const size_t kAlignment = 32; <span class="code-example-comment">// Note that in this case the alignment is defined elsewhere as a non-literal.</span><br>
AlignedType&lt;Widget, kAlignment&gt;::Type widgetAlign128;<br>
widgetAlign128.DoSomething();</pre>
<h2>ReadMisaligned16/32/64</h2>
<p>ReadMisaligned reads an unsigned integer from a possibly non-aligned address. The MIPS processor on the PS2, for example, cannot read a 32-bit value from an unaligned address. This function can be used to make reading such misaligned data portable.. </p>
<p>Example usage: </p>
<pre class="code-example">void DoSomeReading(const char* pData)
{
uint16_t x = ReadMisalignedUint16(pData);
pData += sizeof(uint16_t);
uint32_t y = ReadMisalignedUint32(pData);
pData += sizeof(uint32_t);
uint64_t z = ReadMisalignedUint64(pData);
pData += sizeof(uint64_t);
...
}</pre>
<hr>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p> </p>
</body></html>
+151
View File
@@ -0,0 +1,151 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<title>EABitTricks</title>
<link type="text/css" rel="stylesheet" href="UTFDoc.css">
<meta name="author" content="Paul Pedriana">
</head>
<body bgcolor="#FFFFFF">
<h1>EABitTricks</h1>
<h2>Introduction</h2>
<p>EABitTricks provides a number of integer bit-manipulation utilities that are
very fast and simple. For example, it is well-known that (x * 2) can be also
accomplished with (x << 1). And while this example may not be useful in practice,
there are many more such tricks which have real use, particularly for speeding
up code. Some of these tricks may seem odd or even useless, but it turns out
that there are surprising uses for many of these.</p>
<h2>Notes</h2>
<ul>
<li>Twos-complement integer storage is assumed. Nearly all modern processors
use twos-complement storage.</li>
<li>Some tricks assume that right shifts of signed values preserve the sign.
While nearly all modern processors and C/C++ compilers support this, some
primitive processors don't. By preserving sign, we mean that signed binary
(10000000 >> 1) gives (11000000). </li>
<li>Only 'tricky' efficient solutions are provided. Obvious brute force loops
to do useful things aren't included. We attempt to use branchless and loopless
logic where possible.</li>
<li>We don't cover magic number tricks for simplifying multiplication and division
by constants. For example (x * 17) can also be quickly accomplished with ((x
<< 4) + x). Optimized integer multiplication and division tricks such as this
is something for a separate library.</li>
<li>We don't cover floating point tricks. That is something for a separate library.
</li>
<li>Implementations here are written as standalone functions for readability.
However, the user may find that it's better in some cases to copy the implementation
to a macro or to simply copy the implementation directly inline into source
code. EABitTricks is meant to be a reference for copy and paste as much as
it is meant to be used as-is.</li>
<li>Many of these functions are templated instead of taking a given integer
type such as uint32_t. The reason for this is that we want 64 bit support
and that can be had automatically in most cases by the use of templates. The
generated code will be exactly as fast as the case when templates are not
used.</li>
</ul>
<h2>Example usage </h2>
<p>All examples presume a <font face="Courier New, Courier, mono" size="-1">#include
&quot;Foundation/EABitTricks.h&quot;</font> and assume the using of <font face="Courier New, Courier, mono" size="-1">namespace
EA</font>.</p>
<p>TurnOffLowestBit</p>
<pre class="code-example">int16_t i16 = 0x0005; <span class="code-example-comment">// i16 =&gt; 000000101</span>
i16 = TurnOffLowestBit(i16); <span class="code-example-comment">// i16 =&gt; 000000100</span></pre>
IsolateSingle0And1Bits
<pre class="code-example">uint32_t u32 = 0xabababab; <span class="code-example-comment"> // u32 =&gt; 10101011101010111010101110101011</span>
u32 = IsolateSingle0And1Bits(0xabababab); <span class="code-example-comment">// u32 =&gt; 11111100011111000111110001111100</span></pre>
RoundUpToPowerOf2
<pre class="code-example">uint32_t u32 = 66; <span class="code-example-comment">// u32 =&gt; 66 (01000010)</span>
u32 = RoundUpToPowerOf2(u32); <span class="code-example-comment">// u32 =&gt; 128 (10000000)</span></pre>
<p> UnsignedMultiplyWouldOverflow</p>
<pre class="code-example">bool b = UnsignedMultiplyWouldOverflow(0xffffffff, 0xffffffff); <span class="code-example-comment">// b =&gt; true</span> </pre>
<h2>Interface</h2>
<p>The following is a simple listing of EABitTricks functions as of January 2006.
For an up to date listing of current functionality, see EABitTricks.h. Also,
the EABitTricks.h file has documentation and example usage for each function.</p>
<p>Bit manipulation</p>
<pre class="code-example">T TurnOffLowestBit(T x);
T IsolateLowestBit(T x);
T IsolateLowest0Bit(T x);
T GetTrailing0Bits(T x);
T GetTrailing1And0Bits(T x);
T PropogateLowestBitDownward(T x);
T TurnOffLowestContiguousBits(T x);
T TurnOnLowest0Bit(T x);
uint32_t GetNextWithEqualBitCount(uint32_t x);
uint32_t IsolateSingleBits(uint32_t x);
uint32_t IsolateSingle0Bits(uint32_t x);
uint32_t IsolateSingle0And1Bits(uint32_t x);
int32_t ShiftRightSigned(int32_t x, uint32_t n);
uint32_t CountTrailing0Bits(uint32_t x);
uint32_t CountLeading0Bits(uint32_t x);
uint32_t CountBits(uint32_t x);
uint32_t CountBits64(uint64_t x);
uint32_t RotateLeft(uint32_t x, uint32_t n);
uint32_t RotateRight(uint32_t x, uint32_t n);
uint32_t ReverseBits(uint32_t x);
uint32_t IsolateHighestBit(uint32_t x);
uint32_t IsolateHighest0Bit(uint32_t x);
uint32_t PropogateHighestBitDownward(uint32_t x);
uint32_t GetHighestContiguous0Bits(uint32_t x);
T GetBitwiseEquivalence(T x, T y);
bool AreLessThan2BitsSet(int32_t x);
T GetHighestBit(T t);
</pre>
<p>Alignment / Power of 2</p>
<pre class="code-example">bool IsPowerOf2(T x);
uint32_t RoundUpToPowerOf2(uint32_t x);
bool IsMultipleOf(T x);
bool IsPowerOf2Minus1(T x);
uint32_t GetHighestBitPowerOf2(uint32_t x);
bool CrossesPowerOf2(T x, T y, T n);
bool CrossesPowerOf2(T x, T y);
T GetNextGreaterEven(T x);<br>T GetNextGreaterOdd(T x);
T RoundUpTo(T x);
int32_t RoundUpToEx(T x);
T RoundDownTo(T x);
T RoundDownToEx(T x);
uint32_t Log2(uint32_t x);</pre>
<p>Overflow</p>
<pre class="code-example">bool SignedAdditionWouldOverflow(T x, T y);
bool SignedSubtractionWouldOverflow(T x, T y);
bool UnsignedAdditionWouldOverflow(T x, T y);
bool UnsignedSubtractionWouldOverflow(T x, T y);
bool UnsignedMultiplyWouldOverflow(uint32_t x, uint32_t y);
bool SignedMultiplyWouldOverflow(int32_t x, int32_t y);
bool UnsignedDivisionWouldOverflow(uint32_t x, uint32_t y);
bool SignedDivisionWouldOverflow(int32_t x, int32_t y);
int GetAverage(int32_t x, int32_t y);
int GetAverage_Ceiling(int32_t x, int32_t y);</pre>
<p>Miscellaneous</p>
<pre class="code-example">int32_t GetParity(uint32_t32_t x);
bool GetIsBigEndian();
int32_t ToggleBetween0And1(int32_t x);
T ToggleBetweenint32_tegers(T x, T a, T b);
bool IsBetween0AndValue(int32_t x, int32_t a);
void ExchangeValues(T& x, T& y);
T FloorMod(T n, T mod);
int32_t GetSign(int32_t32_t x);
int32_t GetSignEx(int32_t32_t x);
int32_t SignExtend12(int32_t32_t x);
int32_t SignExtend24(int32_t32_t x);
bool IsUnsigned(T x);
#define EAIsUnsigned(x)
bool IsTwosComplement();
bool IsOnesComplement();
bool IsSignMagnitude();
bool IsOffsetBinary();
#define EAArrayCount(array);</pre>
<hr>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p> </p>
</body></html>
@@ -0,0 +1,107 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<Title>EAByteCrackers</title>
<link type="text/css" rel="stylesheet" href="UTFDoc.css">
<meta name="author" content="Paul Pedriana">
</head>
<body bgcolor="#FFFFFF">
<h1>EAByteCrackers</h1>
<h2>Introduction</h2>
<p>EAByteCrackers is a small utility header file that provides macros for breaking down integers into component bytes and for building up integers from component
bytes. These are particularly useful because working with signed values creates opportunities for mistakes, and the macros present in EAByteCrackers remove such
possibilities for error. You can run into this need for dealing with signed values when working with Windows &quot;winproc&quot; message packing, for example.</p>
<h2>Conventions</h2>
<p>Components within an integer are numbered 0-N with 0 referring to the least significant component. Thus, the 32 bit value 0x12345678 consists of byte 0 = 0x78,
byte 1 = 0x56, byte 2 = 0x34, and byte 3 = 0x12. This is done like so because the index of the byte is thus equal to its numerical shift within the integer. It
also means that byte 2 of a uint32_t refers to the same value as byte 2 of a uint64_t. For example:</p>
<pre class="code-example">uint16_t u16 = UINT16_5_FROM_UINT64(0x887766554433221100); <font color="#0066FF">// u16 becomes 0x55</font></pre>
<p>Similarly, we have this:</p>
<pre class="code-example">uint32_t u32 = UINT32_FROM_UINT8(0x33, 0x22, 0x11, 0x00); <font color="#0066FF">// u32 becomes 0x33221100</font></pre>
<p>In the macros, the terms b, w, d, and q are used.</p>
<ul>
<li>b means 8 bit byte</li>
<li>w means 16 bit word</li>
<li>d means 32 bit dword</li>
<li>q means 64 bit quadword</li>
</ul>
<h2>Example usage </h2>
<p>Basic usage:</p>
<pre class="code-example">// Integer breakdown
uint8_t u8 = UINT8_0_FROM_UINT16(0x1100); <font color="#0066FF">// u8 becomes 0x00</font>
uint8_t u8 = UINT8_2_FROM_UINT64(0x7766554433221100); <font color="#0066FF">// u8 becomes 0x22</font>
uint16_t u16 = UINT16_3_FROM_UINT64(0x7766554433221100); <font color="#0066FF">// u16 becomes 0x7766</font>
// Integer build up
uint16_t u16 = UINT16_FROM_UINT8(0x11, 0x00); <font color="#0066FF">// u16 becomes 0x1100</font>
uint32_t u32 = UINT32_FROM_UINT8(0x33, 0x22, 0x11, 0x00); <font color="#0066FF">// u32 becomes 0x33221100</font></pre>
<p></p>
<p>How to safely convert a 32 bit value to two signed 16 bit values:</p>
<pre class="code-example">int16_t n0 = (int16_t)UINT16_0_FROM_UINT32(0x1000ffff); <font color="#0066FF">// n0 becomes -1</font>
int16_t n1 = (int16_t)UINT16_1_FROM_UINT32(0x1000ffff); <font color="#0066FF">// n1 becomes 4096</font></pre>
<p>How to build up a uint64_t from a uint32_t and two uint16_t values:</p>
<pre class="code-example">uint64_t u64 = UINT64_FROM_UINT32(0x77665544, UINT32_FROM_UINT16(0x3322, 0x1100)); <font color="#0066FF">// u64 becomes 0x7766554433221100</font>
</pre>
<h2>Interface</h2>
<pre class="code-example"><span class="code-example-comment">// uint8_t byte manipulators</span>
#define UINT8_0_FROM_UINT16(w)
#define UINT8_1_FROM_UINT16(w)
#define UINT8_0_FROM_UINT32(d)
#define UINT8_1_FROM_UINT32(d)
#define UINT8_2_FROM_UINT32(d)
#define UINT8_3_FROM_UINT32(d)
#define UINT8_0_FROM_UINT64(q)
#define UINT8_1_FROM_UINT64(q)
#define UINT8_2_FROM_UINT64(q)
#define UINT8_3_FROM_UINT64(q)
#define UINT8_4_FROM_UINT64(q)
#define UINT8_5_FROM_UINT64(q)
#define UINT8_6_FROM_UINT64(q)
#define UINT8_7_FROM_UINT64(q)
<span class="code-example-comment">// uint16_t byte manipulators</span>
#define UINT16_0_FROM_UINT32(d)
#define UINT16_1_FROM_UINT32(d)
#define UINT16_0_FROM_UINT64(q)
#define UINT16_1_FROM_UINT64(q)
#define UINT16_2_FROM_UINT64(q)
#define UINT16_3_FROM_UINT64(q)
#define UINT16_FROM_UINT8(b1, b0)
<span class="code-example-comment">// uint32_t byte manipulators</span>
#define UINT32_2_FROM_UINT64(q)
#define UINT32_1_FROM_UINT64(q)
#define UINT32_FROM_UINT8(b3, b2, b1, b0)
#define UINT32_FROM_UINT16(w1, w0)
<span class="code-example-comment">// uint64_t byte manipulators</span>
#define UINT64_FROM_UINT8(b7, b6, b5, b4, b3, b2, b1, b0)
#define UINT64_FROM_UINT16(w3, w2, w1, w0)
#define UINT64_FROM_UINT32(d1, d0)
</pre>
<p></p>
<hr>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
</body></html>
+235
View File
@@ -0,0 +1,235 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<Title>EAString</title>
<link type="text/css" rel="stylesheet" href="UTFDoc.css">
<meta name="author" content="Paul Pedriana">
</head>
<body bgcolor="#FFFFFF">
<h1>EAString</h1>
<h2>Introduction</h2>
<p>EACRT stands for EA C Runtime. EACRT implements an extensive suite of C string functionality in a portable way. Some of this functionality is the same as what
is present in the C standard and in common (but non-portable) extensions to the C standard. EACRT presents a consistent portable interface to its functionality
in both 8 bit and 16 bit string form.</p>
<p>The C language provides various functions which work with non-portable data types, such as long. EACRT defines all significant data types in terms of portable
types such as int32_t and int64_t. </p>
<p>Additionally, the EACRT versions of functions are usually faster than the C runtime library versions, usually because the EACRT versions minimize cache misses
and branching, whereas typical C runtime libraries optimize for the smallest memory footprint with little or no regard to other performance characteristics.</p>
<p>C-style printf functionality is separate from EACRT and is found in <a href="EASprintf.html">EASprintf</a>. Memcpy functionality (which comes from the C string.h
header file) is present in <a href="Memcpy.html">EAMemcpy</a>. However, EACRT has a few mem functions itself.</p>
<p>In some cases, EACRT simply #defines its function to be the same as the equivalent C function. This is done when the equivalent C function is known to be present
and known to conform to the C/C++ language standard correctly.</p>
<h2>Extension functions</h2>
<p> EACRT provides extended functionality that isn't found in conventional C libraries, but it useful nevertheless.</p>
<table width="100%" border="1" cellpadding="3">
<tr>
<td><b>Function</b></td>
<td><b>Description</b></td>
<td><b>Signature</b></td>
</tr>
<tr>
<td>Strlcat</td>
<td>Safe variation of strncat</td>
<td><font size="-1">char_t* Strlcat(char_t* pDestination, const char_t* pSource, size_t n); </font></td>
</tr>
<tr>
<td>Strlcpy</td>
<td>Safe variation of strcpy</td>
<td><font size="-1">char_t* Strlcpy(char_t* pDestination, const char_t* pSource, size_t n); </font></td>
</tr>
<tr>
<td>Stristr</td>
<td>Case insensitive version of strstr (find string within string)</td>
<td><font size="-1">char_t* Stristr(const char_t* pString, const char_t* pSubString);</font></td>
</tr>
<tr>
<td>FtoaEnglish</td>
<td>
<p>Float to ascii; always use English numeric format, regardless of the current locale.</p>
</td>
<td><font size="-1">char_t* FtoaEnglish(double dValue, char_t* pResult, int nInputLength, int nPrecision, bool bExponentEnabled); </font></td>
</tr>
<tr>
<td>AtofEnglish</td>
<td>Ascii to float; always use English numeric format, regardless of the current locale.</td>
<td><font size="-1">double AtofEnglish(const char_t* pString); </font></td>
</tr>
<tr>
<td> StrtodEnglish</td>
<td>Same as strtod, but always use English numeric format, regardless of the current locale.</td>
<td><font size="-1">double StrtodEnglish(const char_t* pString, char_t** ppStringEnd);</font></td>
</tr>
<tr>
<td>Memset16</td>
<td>Sets 16 bit values in memory (as opposed to memset's 8 bit values)</td>
<td><font size="-1">uint16_t* Memset16(void* pDestination, uint16_t c, size_t count); </font></td>
</tr>
<tr>
<td>Memset32</td>
<td>Sets 32 bit values in memory (as opposed to memset's 8 bit values)</td>
<td><font size="-1"> uint32_t* Memset32(void* pDestination, uint32_t c, size_t count);</font></td>
</tr>
<tr>
<td>Memset64</td>
<td>Sets 64 bit values in memory (as opposed to memset's 8 bit values)</td>
<td><font size="-1">uint64_t* Memset64(void* pDestination, uint64_t c, size_t count);</font></td>
</tr>
<tr>
<td>MemsetN</td>
<td>Sets arbitrarily sized values in memory.</td>
<td><font size="-1">void* MemsetN (void* pDestination, const void* pSource, size_t sourceBytes, size_t count); </font></td>
</tr>
<tr>
<td>EcvtBuf</td>
<td>Base function for converting a float to a %e string.</td>
<td>
<p><font size="-1">char_t* EcvtBuf(double dValue, int nDigitCount, int* decimalPos, int* sign, char_t* buffer); </font></p>
</td>
</tr>
<tr>
<td>FcvtBuf</td>
<td>Base function for converting a float to a %f string.</td>
<td><font size="-1">char_t* FcvtBuf(double dValue, int nDigitCountAfterDecimal, int* decimalPos, int* sign, char_t* buffer); </font></td>
</tr>
</table>
<p>&nbsp;</p>
<h2>Example usage </h2>
<p>We provide a random smattering of example code here.</p>
<pre class="code-example">char16_t buffer[32] = L"hello ";
Strcat16(buffer, L"world");
</pre>
<p>Strlcat:</p>
<pre class="code-example">char buffer[32];
Strlcpy8(buffer, "Hello ", sizeof(buffer));
Strlcat8(buffer, "world", sizeof(buffer));
</pre>
<p>U64toa:</p>
<pre class="code-example">char buffer[32];
U64toa8(UINT64_C(12345678901234567890), buffer, 16);
</pre>
<p>AtoI32:</p>
<pre class="code-example">int32_t x = AtoI328(&quot;1234567890&quot;);
</pre>
<p>StrtodEnglish:</p>
<pre class="code-example">const char16_t* pString = L"12345.678 123.456 1.23456";
while(*pString)
{
double value = StrtodEnglish16(pString, &pString);
printf("Field = %f\n, value);
}
</pre>
<p>Memset16:</p>
<pre class="code-example">uint16_t buffer[50];
Memset16(buffer, 0x1234, 50);
</pre>
<h2>Interface</h2>
<p>In each of the functions below, there is an char8_t and char16_t version. The actual function that EACRT implements is one with an 8 or 16 appended to the function names listed below. Thus below we have <span class="code-example-span">Strcat(char_t*, char_t*)</span>, and thus EACRT presents <span class="code-example-span">Strcat8(char8_t*, char8_t*)</span> and <span class="code-example-span">Strcat16(char16_t*, char16_t*)</span>.</p>
<p>See EACRT.h for per-function documentation.</p>
<pre class="code-example">char_t* Strcat(char_t* pDestination, const char_t* pSource);
char_t* Strncat(char_t* pDestination, const char_t* pSource, size_t n);
char_t* Strlcat(char_t* pDestination, const char_t* pSource, size_t n);
char_t* Strcpy(char_t* pDestination, const char_t* pSource);
char_t* Strncpy(char_t* pDestination, const char_t* pSource, size_t n);
char_t* Strlcpy(char_t* pDestination, const char_t* pSource, size_t n);
size_t Strlen(const char_t* pString);
size_t Strxfrm(char_t* pDest, const char_t* pSource, size_t n);
char_t* Strdup(const char_t* pString);
int Isalnum(char_t c);
int Isalpha(char_t c);
int Isdigit(char_t c);
int Isxdigit(char_t c);
int Isgraph(char_t c);
int Islower(char_t c);
int Isprint(char_t c);
int Ispunct(char_t c);
int Isspace(char_t c);
int Iscntrl(char_t c);
int Isascii(char_t c);
int Toupper(char_t c);
int Tolower(char_t c);
char_t* Strlwr(char_t* pString);
char_t* Strupr(char_t* pString);
char_t* Strchr(const char_t* pString, char_t c);
size_t Strcspn(const char_t* pString1, const char_t* pString2);
char_t* Strpbrk(const char_t* pString1, const char_t* pString2);
char_t* Strrchr(const char_t* pString, char_t c);
size_t Strspn(const char_t* pString, const char_t* pSubString);
char_t* Strstr(const char_t* pString, const char_t* pSubString);
char_t* Stristr(const char_t* pString, const char_t* pSubString);
char_t* Strtok(char_t* pString, const char_t* pTokens, char_t** pContext);
char_t* Strset(char_t* pString, char_t c);
char_t* Strnset(char_t* pString, char_t c, size_t n);
char_t* Strrev(char_t* pString);
int Strcmp(const char_t* pString1, const char_t* pString2);
int Strncmp(const char_t* pString1, const char_t* pString2, size_t n);
int Stricmp(const char_t* pString1, const char_t* pString2);
int Strnicmp(const char_t* pString1, const char_t* pString2, size_t n);
int Strcoll(const char_t* pString1, const char_t* pString2);
int Strncoll(const char_t* pString1, const char_t* pString2, size_t n);
int Stricoll(const char_t* pString1, const char_t* pString2);
int Strnicoll(const char_t* pString1, const char_t* pString1, size_t n);
char_t* EcvtBuf(double dValue, int nDigitCount, int* decimalPos, int* sign, char_t* buffer);
char_t* FcvtBuf(double dValue, int nDigitCountAfterDecimal, int* decimalPos, int* sign, char_t* buffer);
char_t* I32toa(int32_t nValue, char_t* pResult, int nBase);
char_t* U32toa(uint32_t nValue, char_t* pResult, int nBase);
char_t* I64toa(int64_t nValue, char_t* pBuffer, int nBase);
char_t* U64toa(uint64_t nValue, char_t* pBuffer, int nBase);
double Strtod(const char_t* pString, char_t** ppStringEnd);
double StrtodEnglish(const char_t* pString, char_t** ppStringEnd);
int64_t StrtoI64(const char_t* pString, char_t** ppStringEnd, int nBase);
uint64_t StrtoU64(const char_t* pString, char_t** ppStringEnd, int nBase);
int32_t StrtoI32(const char_t* pString, char_t** ppStringEnd, int nBase);
uint32_t StrtoU32(const char_t* pString, char_t** ppStringEnd, int nBase);
int32_t AtoI32(const char_t* pString);
uint32_t AtoU32(const char_t* pString);
int64_t AtoI64(const char_t* pString);
uint64_t AtoU64(const char_t* pString);
double Atof(const char_t* pString);
double AtofEnglish(const char_t* pString);
char_t* Ftoa(double dValue, char_t* pResult, int nInputLength, int nPrecision, bool bExponentEnabled);
char_t* FtoaEnglish(double dValue, char_t* pResult, int nInputLength, int nPrecision, bool bExponentEnabled);
uint8_t* Memset8 (void* pDestination, uint8_t c, size_t count);
uint16_t* Memset16(void* pDestination, uint16_t c, size_t count);
uint32_t* Memset32(void* pDestination, uint32_t c, size_t count);
uint64_t* Memset64(void* pDestination, uint64_t c, size_t count);
void* MemsetN (void* pDestination, const void* pSource, size_t sourceBytes, size_t count);
const char_t* Memchr(const char_t* pString, char_t c, size_t n);
int Memcmp(const char_t* pString1, const char_t* pString2, size_t n);
char_t* Memcpy(char_t* pDestination, const char_t* pSource, size_t n);
char_t* Memmove(char_t* pDestination, const char_t* pSource, size_t n);
char_t* Memset(char_t* pString, char_t c, size_t n);
</pre>
<hr>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p> </p>
</body></html>
+353
View File
@@ -0,0 +1,353 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<title>EADateTime</title>
<link type="text/css" rel="stylesheet" href="UTFDoc.css">
<meta name="author" content="Paul Pedriana">
</head>
<body bgcolor="#FFFFFF">
<h1>EADateTime</h1>
<h2>Introduction</h2>
<p>EADateTime provides a unified implementation of date, time, and calendar functionality.
The DateTime class represents date and time in a single class. Unlike other
date/time systems, this class doesn't have a strictly limited resolution, due
to its use of 64 bits (instead of 32 bits) of storage for the date/time value.
</p>
<p> EADateTime supports the modern Gregorian calendar correctly, including such
concepts as leap years. You can, for example, use EADateTime to implement proper
calendar functionality for your application.</p>
<p>The C standard library provides some time and date functionality, but it is
slow, has some limitations, is not very easy to use, and isn't supported by
all C/C++ compilers. Writing a calendar application with the C time and date
functions would be possible, but would be tedious and error-prone.</p>
<p>EADateTime does not support the formatting of date and time strings for display
to a users. Such functionality is outside the scope of this class, primarily
due to the issue of multiple string encodings (e.g. ASCII and Unicode) and due
to the existence of multiple locales (e.g. English and French) which use different
formats for time and date strings. A separate module -- EALocale -- exists which
implements string formatting of dates and times. You can use that module and
EADateTime together to implement locale-savvy times, dates, and calendars.</p>
<h2>Example usage </h2>
<p>All examples presume a <font face="Courier New, Courier, mono" size="-1">#include
&quot;Foundation/EADateTime.h&quot;</font> and assume the using of <font face="Courier New, Courier, mono" size="-1">namespace
EA</font>.</p>
<p>Basic usage of class DateTime:</p>
<pre class="code-example">DateTime dt; // Sets dt to the current date and time.
uint32_t year = dt.GetParameter(kParameterYear); // Get the current year.
dt.SetParameter(kParameterMonth, kMonthAugust); // Set month to August.
dt.AddTime(kParameterDayOfYear, 77); // Add 77 days.</pre>
<p>Comparison of DateTime instances:</p>
<pre class="code-example">DateTime dtD(2008, kMonthDecember, 25); // Sets dt to Christmas 2008.
DateTime dtH(2008, kMonthOctober, 31); // Sets dt to Halloween 2008.
if(dtH &lt; dtD)
printf(&quot;Halloween occurs before Christmas.&quot;);
else
printf(&quot;Christmas occurs before Halloween.&quot;);</pre>
<blockquote></blockquote>
<p>How to save and restore a DateTime to and from disk:</p>
<pre><span class="code-example">DateTime dt;
uint64_t n = dt.GetSeconds(); // Get the absolute time in seconds. This alone fully represents a DateTime.
WriteToDisk64(ToBigEndian(n)); // Hypthetical disk writing function and endian conversion function.
n = FromBigEndian(ReadFromDisk64()); // Hypothetical disk reading function and endian conversion function.
dt = DateTime(n); // Restore the saved value to a DateTime instance.</span></pre>
<p>Usage of standalone EADateTime utility functions, which are independent of
class DateTime: </p>
<pre class="code-example">bool b = IsLeapYear(2015);
uint32_t n = GetDaysInYear(1974);
uint32_t d = GetDaysInMonth(kMonthMarch, 2007);
int64_t nSeconds = GetDaylightSavingsBias();</pre>
<h2></h2>
Conversion of C time to DateTime:
<pre class="code-example">#include &lt;time.h&gt;
tm time;
asctime(&amp;ascTime); // Get C time.
DateTime dt;
TmToDateTime(time, dt); // Convert to DateTime.</pre>
<h2>Interface</h2>
<p>The following is defined in EADateTime.h. The latest versions of these definitions
can be found in the current version of EADateTime.h</p>
<p>Enumerations</p>
<pre class="code-example">enum Month
{
kMonthUnknown = 0,
kMonthJanuary = 1,
kMonthFebruary = 2,
kMonthMarch = 3,
kMonthApril = 4,
kMonthMay = 5,
kMonthJune = 6,
kMonthJuly = 7,
kMonthAugust = 8,
kMonthSeptember = 9,
kMonthOctober = 10,
kMonthNovember = 11,
kMonthDecember = 12
};
enum DayOfMonth
{
kDayOfMonthUnknown = 0,
kDayOfMonthMin = 1,
kDayOfMonthMax = 31 <font color="#999999">/// The actual max month is dependent on which month is being referred to.</font>
};
enum DayOfWeek
{
kDayOfWeekUnknown = 0,
kDayOfWeekSunday = 1,
kDayOfWeekMonday = 2,
kDayOfWeekTuesday = 3,
kDayOfWeekWednesday = 4,
kDayOfWeekThursday = 5,
kDayOfWeekFriday = 6,
kDayOfWeekSaturday = 7
};
<span class="code-example-comment">/// TimeFrame
</span>enum TimeFrame
{
kTimeFrameUnknown = 0, <font color="#999999">/// Unspecified time frame.</font>
kTimeFrameUTC = 1, <font color="#999999">/// Universal Coordinated Time. This is the time based on the time zone at Greenwich, England.</font>
kTimeFrameLocal = 2 <font color="#999999">/// Same time as current machine.</font>
};
<span class="code-example-comment">/// TimeZone
/// Standard time zone definitions, with their values corresponding to the nmuber of hours they are
/// off relative to UTC (Universal Coordinated Time, which is the time at Greenwich England).
/// Note, for example, that kTimeZonePacific is -8 hours relative to Greenwich, England.
</span>enum TimeZone
{
kTimeZoneEniwetok = -12,
kTimeZoneSamoa = -11,
kTimeZoneHawaii = -10,
kTimeZoneAlaska = -9,
kTimeZonePacific = -8,
kTimeZoneMountain = -7,
kTimeZoneCentral = -6,
kTimeZoneEastern = -5,
kTimeZoneAltantic = -4,
kTimeZoneBrazilia = -3,
kTimeZoneMidAtlantic = -2,
kTimeZoneAzores = -1,
kTimeZoneGreenwich = 0,
kTimeZoneRome = +1,
kTimeZoneIsrael = +2,
kTimeZoneMoscow = +3,
kTimeZoneBaku = +4,
kTimeZoneNewDelhi = +5,
kTimeZoneDhakar = +6,
kTimeZoneBangkok = +7,
kTimeZoneHongKong = +8,
kTimeZoneTokyo = +9,
kTimeZoneSydney = +10,
kTimeZoneMagadan = +11,
kTimeZoneWellington = +12
};
<span class="code-example-comment">/// Epoch
/// The use of an epoch is to provide a timeframe with which to work.
/// Most of the time you don't need to know about this.
</span>enum Epoch
{
kEpochUnknown = 0,
kEpochJulian = 1, <font color="#999999">/// Began at noon, January 1, 4712 BC.</font>
kEpochModifiedJulian = 2, <font color="#999999">/// Began at midnight, November 17, 1858. Exactly 2,400,000.5 days after Julian epoch began.</font>
kEpochGregorian = 3, <font color="#999999">/// Began at midnight, September 14, 1752.</font>
kEpoch1900 = 4, <font color="#999999">/// Began at midnight, January 1, 1900.</font>
kEpoch1950 = 5, <font color="#999999">/// Began at midnight, January 1, 1950.</font>
kEpoch1970 = 6, <font color="#999999">/// Began at midnight, January 1, 1970. Same epoch used by C runtime library and Unix OS.</font>
kEpoch2000 = 7 <font color="#999999">/// Began at midnight, January 1, 2000.</font>
};
enum Era
{
kEraUnknown = 0,
kEraBC = 1,
kEraAD = 2
};
<span class="code-example-comment">/// Parameter
/// Defines a date or time parameter.
</span>enum Parameter
{
kParameterUnknown = 0,
kParameterYear = 1, <font color="#999999">/// Refers to full year value, such as 1994, 2006, etc. but not a two digit value such as 94 or 04. The valid range is 0-INT_MAX.</font>
kParameterMonth = 2, <font color="#999999">/// Refers to month of year, starting with 1 for January. The valid range is 1-12.</font>
kParameterWeekOfYear = 3, <font color="#999999">/// Refers to the week of the year, starting with 1 for the week of January 1. The valid range is 1-52.</font>
kParameterWeekOfMonth = 4, <font color="#999999">/// Refers to the week of the month, starting with 1 for the first week. The valid range is 1-5.</font>
kParameterDayOfYear = 5, <font color="#999999">/// Refers to a day of the year, starting with 1 for January 1st. The valid range is 1-366.</font>
kParameterDayOfMonth = 6, <font color="#999999">/// Refers to the day of the month, starting with 1 for the first of the month. The valid range is 1-31.</font>
kParameterDayOfWeek = 7, <font color="#999999">/// Refers to the day of the week, starting with 1 for Sunday. The valid range is 1-7.</font>
kParameterHour = 8, <font color="#999999">/// Refers to the hour of a day in 24 hour format, starting with 0 for midnight. The valid range is 0-23.</font>
kParameterMinute = 9, <font color="#999999">/// Refers to the minute of the hour, starting with 0 for the first minute. The valid range is 0-59.</font>
kParameterSecond = 10, <font color="#999999">/// Refers to the second of the minute, starting with 0 for the first second. The valid range is 0-59.</font>
};
<span class="code-example-comment">/// Conversions
/// Defines useful conversion multipliers between seconds, minutes, hours, and days.
/// Conversions are not defined for some entities (e.g. days per year) because the
/// value changes based on the particular year.
</span>enum Conversions
{
kSecondsPerMinute = 60,
kSecondsPerHour = 3600,
kSecondsPerDay = 86400,
kMinutesPerHour = 60,
kMinutesPerDay = 1440,
kHoursPerDay = 24,
kDaysPerWeek = 7,
kWeeksPerYear = 52,
kMonthsPerYear = 12
};
</pre>
<p>DateTime</p>
<pre class="code-example">class DateTime
{
public:
static const uint32_t kValueDefault = 0xffffffff;
static const uint32_t kValueIgnored = 0xffffffff;
public:
DateTime(TimeFrame timeFrame = kTimeFrameLocal);
DateTime(int64_t nSeconds) : mnSeconds(nSeconds);
DateTime(const DateTime& dateTime) : mnSeconds(dateTime.mnSeconds);
<span class="code-example-comment"> /// DateTime
/// Constructs a DateTime class object from some standard parameters.
/// To construct a DateTime class with a different set of parameter types,
/// you'll need to use the Set function or in odd cases do manual calculations.
</span> DateTime(uint32_t nYear, uint32_t nMonth, uint32_t nDayOfMonth,
uint32_t nHour = 0, uint32_t nMinute = 0, uint32_t nSecond = 0);
<span class="code-example-comment"> /// operator=
</span> DateTime& operator=(const DateTime& dateTime);
<span class="code-example-comment"> /// Compare
/// This function compares this object with another DateTime object and
/// returns an integer result.The return value is the same as with the
/// strcmp string comparison function. If this object is less than the
/// argument dateTime, the return value is < 0. Comparison operators are
/// defined outside this class, though they use the Compare function to do their work.
</span> int Compare(const DateTime& dateTime, bool bCompareDate = true, bool bCompareTime = true) const;
<span class="code-example-comment"> /// GetParameter
/// Gets the given parameter. If you want to get the year, you would call Get(kParameterYear).
</span> uint32_t GetParameter(Parameter parameter) const;
<span class="code-example-comment"> /// SetParameter
/// Sets the given parameter. If you want to set the year to 1999, you would
/// call Set(kParameterYear, 1999).
</span> void SetParameter(Parameter parameter, uint32_t nValue);
<span class="code-example-comment"> /// Set
/// Sets the time based on the current time. If the timeFrame is kTimeFrameUTC,
/// the time is set to what the current UTC time is, which will be a fixed number
/// of hours off of what the current local time is.
</span> void Set(TimeFrame timeFrame = kTimeFrameLocal);
<span class="code-example-comment"> /// Set
/// Sets the time based on various inputs. If any input is kValueIgnored (uint32_t)-1,
/// then the input is ignored and the current value is used. If any of the cyclic
/// inputs is beyond its valid range, the modulo of the value is used and the division
/// of the value is added to the next higher bracket. For example, if the input nMinute
/// is 65, then the minute used is 5 and 1 is added to the current hour value.
</span> void Set(uint32_t nYear, uint32_t nMonth, uint32_t nDayOfMonth, uint32_t nHour,
uint32_t nMinute, uint32_t nSecond);
<span class="code-example-comment"> /// AddTime
/// Allows you to increment (or decrement) the given parameter by the given amount.
</span> void AddTime(Parameter parameter, int32_t nValue);
<span class="code-example-comment"> /// IsDST
/// Returns true if the time is daylight savings time. This function assumes that DST is valid
/// for the given current locale; some locales within the United States don't observe DST.
</span> bool IsDST() const;
<span class="code-example-comment"> /// GetSeconds
/// Returns the DateTime internal representation.
</span> int64_t GetSeconds() const;
};</pre>
<blockquote></blockquote>
<p>Utility</p>
<pre class="code-example"><span class="code-example-comment">/// IsLeapYear
/// Returns true if the given year is a leap year.
</span>bool IsLeapYear(uint32_t nYear);
<span class="code-example-comment">/// GetDaysInYear
/// Returns the number of days in the given year. The value will vary based on whether
/// the year is a leap year or not.
</span>uint16_t GetDaysInYear(uint32_t nYear);
<span class="code-example-comment">/// GetDaysInMonth
/// Returns the number of days in the given month. The value will vary based on the
/// month and based on whether the year is a leap year. The input nMonth takes one
/// of enum Month or an integer equivalent.
</span>uint8_t GetDaysInMonth(uint32_t nMonth, uint32_t nYear);
<span class="code-example-comment">/// GetDayOfYear
/// The input nMonth takes one of enum Month or an integer equivalent.
/// The input nDayOfMonth takes an integer consistent with enum DayOfMonth.
</span>uint32_t GetDayOfYear(uint32_t nMonth, uint32_t nDayOfMonth, uint32_t nYear);
<span class="code-example-comment">/// Convert4DigitTo2DigitYear
/// Note that two-digit years bring a number of problems; they are best used for text
/// display only and not for any internal processing.
</span>inline int Convert4DigitTo2DigitYear(int nYear4);
<span class="code-example-comment">/// Convert2DigitTo4DigitYear
/// This code returns a year in the 1900s if the input year is > 30 but returns
/// a year in the 2000s if the year is &lt;= 30. This is merely a guess and in fact there
/// really is no good way to reliably convert a two digit year to a four digit year.
</span>inline int Convert2DigitTo4DigitYear(int nYear2);
<span class="code-example-comment">/// GetCurrent
/// Returns the current year, month, hour, etc.
</span>uint32_t GetCurrent(Parameter parameter);
<span class="code-example-comment">/// GetDaylightSavingsBias
/// Returns the number of seconds that the current time is daylight savings adjusted from
/// the conventional time. Adding this value to the conventional time yields the time when
/// adjusted for daylight savings.
</span>int64_t GetDaylightSavingsBias();
<span class="code-example-comment">/// GetTimeZoneBias
/// Returns the number of seconds that the local time zone is off of UTC.
/// Adding this value to the current UTC yields the current local time.
</span>int64_t GetTimeZoneBias();
<span class="code-example-comment">/// DateTimeToTm
/// Converts a DateTime to a C tm struct.
</span>void DateTimeToTm(const DateTime& dateTime, tm& time);
<span class="code-example-comment">/// TmToDateTime
/// Converts a C tm struct to a DateTime.
</span>void TmToDateTime(const tm& time, DateTime& dateTime);</pre>
<blockquote></blockquote>
<hr>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p> </p>
</body></html>
+514
View File
@@ -0,0 +1,514 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<title>EAFixedPoint</title>
<meta name="author" content="Paul Pedriana">
<link type="text/css" rel="stylesheet" href="UTFDoc.css">
</head>
<body bgcolor="#FFFFFF">
<h1>EAFixedPoint</h1>
<h2> <span style="font-weight: bold;">Introduction</span> </h2>
<p>The EAFixedPoint module implements fixed point math via classic C macros and
functions and via a more advanced implementation using C++ classes. The C++
classes constitute a fairly complete implementation of a fixed point C++ numerical
data type that acts much like the built-in float and double data types. </p>
<p>The following code freely mixes the SFixed16 (signed 16:16 fixed point) data
type with other numerical data types:</p>
<pre><span style="font-family: monospace;"><span class="code-example">SFixed16_16 a(1), b(2), c(3);<br>float f(4.5f);<br>double d(3.2);<br>int i(6);
<br>a = b * f;<br>a = (c / d) + b + f;<br>a = c / d * (b % i) + f / c;<br>a = i * -c / (b++);<br>a = sin(a) + pow(b, d) * sqrt(a);<br>a = log(a) / log(f);</span></span></pre>
<p></p>
<p>Fixed point math has a number of uses:</p>
<ul>
<li>Improved precision over floating point math.</li>
<li>Improved speed over floating point math, particularly with respect to division.</li>
<li>Consistent behaviour across CPUs, especially during network play when two
different machines must behave identically but FPU behaviour may differ.</li>
</ul>
<p>Information about fixed point can be found on the Internet by simply searching
for &quot;fixed point&quot; with your favorite search site.</p>
<h2>Fixed point vs. floating point </h2>
<p>Fixed point</p>
<blockquote>
<p>+ Can be very fast. Fixed point
math executes at the same speed as integer math. Fixed to int conversions
are much faster float to int.<br>
+ Executes concurrently with floating point math, due its use of integer math.<br>
&#150; Limited range. Fixed point16:16 numbers are between -32767 and +32767.
The fractional part is accurate to 1 / 65536. <br>
&#150; Harder to code in high-level languages.</p>
</blockquote>
<p>Floating point</p>
<blockquote>
<p>+ Large range. The range for floating point numbers is typically in excess
of 1e-100 to 1e+100 and have an accuracy of about 13 decimal places. <br>
+ Executes concurrently with integer math.<br>
&#150; Can be slower. Generally
fast for addition and multiplication but may be slower for division and float
to int conversions. </p>
</blockquote>
<h2>Fixed point precision </h2>
<p>The C++ fixed point classes provide varying precision via the use of template
parameter constants. EAFixedPoint provides the following predefined C++ fixed
point types</p>
<table width="100%" border="1">
<tr>
<td><b>Type</b></td>
<td><b>Signed</b></td>
<td><b>Integral type</b></td>
<td><b>Precision</b></td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">SFixed24_8</font></td>
<td>signed</td>
<td>32</td>
<td>24 bits of integer, 8 bits of fraction</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">UFixed24_8</font></td>
<td>unsigned</td>
<td>32</td>
<td>24 bits of integer, 8 bits of fraction</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">SFixed22_10</font></td>
<td>signed</td>
<td>32</td>
<td>22 bits of integer, 10 bits of fraction</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">UFixed22_10</font></td>
<td>unsigned</td>
<td>32</td>
<td>22 bits of integer, 10 bits of fraction</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">SFixed20_12</font></td>
<td>signed</td>
<td>32</td>
<td>20 bits of integer, 12 bits of fraction</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">UFixed20_12</font></td>
<td>unsigned</td>
<td>32</td>
<td>20 bits of integer, 12 bits of fraction</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">SFixed18_14</font></td>
<td>signed</td>
<td>32</td>
<td>18 bits of integer, 14 bits of fraction</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">UFixed18_14</font></td>
<td>unsigned</td>
<td>32</td>
<td>18 bits of integer, 14 bits of fraction</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">SFixed16_16</font></td>
<td>signed</td>
<td>32</td>
<td>16 bits of integer, 16 bits of fraction</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">UFixed16_16</font></td>
<td>unsigned</td>
<td>32</td>
<td>16 bits of integer, 16 bits of fraction</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">SFixed14_18</font></td>
<td>signed</td>
<td>32</td>
<td>14 bits of integer, 18 bits of fraction</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">UFixed14_18</font></td>
<td>unsigned</td>
<td>32</td>
<td>14 bits of integer, 18 bits of fraction</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">SFixed12_20</font></td>
<td>signed</td>
<td>32</td>
<td>12 bits of integer, 20 bits of fraction</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">UFixed12_20</font></td>
<td>unsigned</td>
<td>32</td>
<td>12 bits of integer, 20 bits of fraction</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">SFixed10_22</font></td>
<td>signed</td>
<td>32</td>
<td>10 bits of integer, 22 bits of fraction</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">UFixed10_22</font></td>
<td>unsigned</td>
<td>32</td>
<td>10 bits of integer, 22 bits of fraction</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">SFixed8_24</font></td>
<td>signed</td>
<td>32</td>
<td>8 bits of integer, 24 bits of fraction</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">UFixed8_24</font></td>
<td>unsigned</td>
<td>32</td>
<td>8 bits of integer, 24 bits of fraction</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">SFixed48_16</font></td>
<td>signed</td>
<td>64</td>
<td>48 bits of integer, 16 bits of fraction.</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">UFixed48_16</font></td>
<td>unsigned</td>
<td>64</td>
<td>48 bits of integer, 16 bits of fraction.</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">SFixed44_20</font></td>
<td>signed</td>
<td>64</td>
<td>44 bits of integer, 20 bits of fraction.</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">UFixed44_20</font></td>
<td>unsigned</td>
<td>64</td>
<td>44 bits of integer, 20 bits of fraction.</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">SFixed40_24</font></td>
<td>signed</td>
<td>64</td>
<td>40 bits of integer, 24 bits of fraction.</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">UFixed40_24</font></td>
<td>unsigned</td>
<td>64</td>
<td>40 bits of integer, 24 bits of fraction.</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">SFixed36_28</font></td>
<td>signed</td>
<td>64</td>
<td>36 bits of integer, 28 bits of fraction.</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">UFixed36_28</font></td>
<td>unsigned</td>
<td>64</td>
<td>36 bits of integer, 28 bits of fraction.</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">SFixed32_32</font></td>
<td>signed</td>
<td>64</td>
<td>32 bits of integer, 32 bits of fraction.</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">UFixed32_32</font></td>
<td>unsigned</td>
<td>64</td>
<td>32 bits of integer, 32 bits of fraction.</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">SFixed28_36</font></td>
<td>signed</td>
<td>64</td>
<td>28 bits of integer, 36 bits of fraction.</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">UFixed28_36</font></td>
<td>unsigned</td>
<td>64</td>
<td>28 bits of integer, 36 bits of fraction.</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">SFixed24_40</font></td>
<td>signed</td>
<td>64</td>
<td>24 bits of integer, 40 bits of fraction.</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">UFixed24_40</font></td>
<td>unsigned</td>
<td>64</td>
<td>24 bits of integer, 40 bits of fraction.</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">SFixed20_44</font></td>
<td>signed</td>
<td>64</td>
<td>20 bits of integer, 44 bits of fraction.</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">UFixed20_44</font></td>
<td>unsigned</td>
<td>64</td>
<td>20 bits of integer, 44 bits of fraction.</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">SFixed16_48</font></td>
<td>signed</td>
<td>64</td>
<td>16 bits of integer, 48 bits of fraction.</td>
</tr>
<tr>
<td><font face="Courier New, Courier, mono" size="-1">UFixed16_48</font></td>
<td>unsigned</td>
<td>64</td>
<td>16 bits of integer, 48 bits of fraction.</td>
</tr>
</table>
<h2>Example usage </h2>
<p>To a large degree, you can use fixed point types the same way you would use
floating point types. </p>
<p>Mixed integer math expressions (same as shown earlier above):</p>
<pre class="code-example">SFixed16_16 a(1), b(2), c(3);<br>float f(4.5f);<br>double d(3.2);<br>int i(6);
<br>a = b * f;<br>a = (c / d) + b + f;<br>a = c / d * (b % i) + f / c;<br>a = i * -c / (b++);<br>a = sin(a) + pow(b, d) * sqrt(a);<br>a = log(a) / log(f);</pre>
<p>printf:</p>
<pre class="code-example">SFixed24_8 f = 23.5f;<br><br>printf(&quot;%f&quot;, f.AsFloat());</pre>
<p>Logical expresions:</p>
<pre class="code-example">SFixed16_16 a = 20.4;
SFixed16_16 b = 130.6;
SFixed16_16 c = 223.3;
if((a &lt; b) || (b &gt;= c) || (a &lt; 23.5))
a *= 25;</pre>
<h2>Limitations </h2>
<p>The primary differences between our fixed point type and a hypothetical built-in
version are:</p>
<ul>
<li>EAFixedPoint doesn't implement cast operators. Instead, provides explicit
converters such as AsInt, AsFloat, etc. This is by design, as such casting
operators result in ambiguous conversions and would need built-in compiler
knowledge to resolve the situation.</li>
<li>Standard library functions such as sprintf have no support for such fixed
point types. However, most of the time it is sufficient to convert to floating
point and use the built-in floating point formatting functions.</li>
<li>There is no explicit support for mixing expressions between two different
fixed point types, such as SFixed16_16 with SFixed24_8. You can use these
together via conversion between built-in types. </li>
</ul>
<h2>Interface </h2>
<p>C interface:</p>
<pre class="code-example">typedef int32_t EAFixed16;
#define EAMAX_FIXED16 0x7fffffff
#define EAMIN_FIXED16 0x80000000
#define EAFixed16ToInt(a) ((int32_t)(a) >> 16)
#define EAIntToFixed16(a) ((EAFixed16)((a) << 16))
#define EAFixed16ToDouble(a) (((double)a) / 65536.0)
#define EADoubleToFixed16(a) ((EAFixed16)((a) * 65536.0))
#define EAFixed16ToFloat(a) (((float)a) / 65536.f)
#define EAFloatToFixed16(a) ((EAFixed16)((a) * 65536.f))
#define EAFixed16Negate(a) (-a)
EAFixed16 EAFixed16Mul (EAFixed16 a, EAFixed16 b);
EAFixed16 EAFixed16Div (EAFixed16 a, EAFixed16 b);
EAFixed16 EAFixed16DivSafe (EAFixed16 a, EAFixed16 b);
EAFixed16 EAFixed16MulDiv (EAFixed16 a, EAFixed16 b, EAFixed16 c);
EAFixed16 EAFixed16MulDivSafe (EAFixed16 a, EAFixed16 b, EAFixed16 c);
EAFixed16 EAFixed16Mod (EAFixed16 a, EAFixed16 b);
EAFixed16 EAFixed16ModSafe (EAFixed16 a, EAFixed16 b);
EAFixed16 EAFixed16Abs (EAFixed16 a);
</pre>
<p>C++ interface, by example of SFixed16_16. Note that nearly all the functions
below are implemented as simple inlines:</p>
<pre class="code-example">struct SFixed16_16
{
SFixed16_16();
SFixed16_16(const SFixed16_16&amp; value);
SFixed16_16(const int&amp; value);
SFixed16_16(const unsigned int&amp; value);
SFixed16_16(const long&amp; value);
SFixed16_16(const unsigned long&amp; value);
SFixed16_16(const float&amp; value);
SFixed16_16(const double&amp; value);
void FromFixed(const int&amp; value);
int32_t AsFixed();
int AsInt() const;
unsigned int AsUnsignedInt() const;
long AsLong() const;
unsigned long AsUnsignedLong()const;
float AsFloat() const;
double AsDouble() const;
SFixed16_16&amp; operator=(const SFixed16_16&amp; value);
SFixed16_16&amp; operator=(const int&amp; value);
SFixed16_16&amp; operator=(const unsigned int&amp; value);
SFixed16_16&amp; operator=(const long&amp; value);
SFixed16_16&amp; operator=(const unsigned long&amp; value);
SFixed16_16&amp; operator=(const float&amp; value);
SFixed16_16&amp; operator=(const double&amp; value);
bool operator&lt; (const SFixed16_16&amp; value) const;
bool operator&gt; (const SFixed16_16&amp; value) const;
bool operator&gt;=(const SFixed16_16&amp; value) const;
bool operator&lt;=(const SFixed16_16&amp; value) const;
bool operator==(const SFixed16_16&amp; value) const;
bool operator!=(const SFixed16_16&amp; value) const;
bool operator&lt; (const int&amp; value) const;
bool operator&gt; (const int&amp; value) const;
bool operator&gt;=(const int&amp; value) const;
bool operator&lt;=(const int&amp; value) const;
bool operator==(const int&amp; value) const;
bool operator!=(const int&amp; value) const;
bool operator&lt; (const unsigned int&amp; value) const;
bool operator&gt; (const unsigned int&amp; value) const;
bool operator&gt;=(const unsigned int&amp; value) const;
bool operator&lt;=(const unsigned int&amp; value) const;
bool operator==(const unsigned int&amp; value) const;
bool operator!=(const unsigned int&amp; value) const;
bool operator&lt; (const long&amp; value) const;
bool operator&gt; (const long&amp; value) const;
bool operator&gt;=(const long&amp; value) const;
bool operator&lt;=(const long&amp; value) const;
bool operator==(const long&amp; value) const;
bool operator!=(const long&amp; value) const;
bool operator&lt; (const unsigned long&amp; value) const;
bool operator&gt; (const unsigned long&amp; value) const;
bool operator&gt;=(const unsigned long&amp; value) const;
bool operator&lt;=(const unsigned long&amp; value) const;
bool operator==(const unsigned long&amp; value) const;
bool operator!=(const unsigned long&amp; value) const;
bool operator&lt; (const float&amp; value) const;
bool operator&gt; (const float&amp; value) const;
bool operator&gt;=(const float&amp; value) const;
bool operator&lt;=(const float&amp; value) const;
bool operator==(const float&amp; value) const;
bool operator!=(const float&amp; value) const;
bool operator&lt; (const double&amp; value) const;
bool operator&gt; (const double&amp; value) const;
bool operator&gt;=(const double&amp; value) const;
bool operator&lt;=(const double&amp; value) const;
bool operator==(const double&amp; value) const;
bool operator!=(const double&amp; value) const;
bool operator! () const;
SFixed16_16 operator~() const;
SFixed16_16 operator-() const;
SFixed16_16 operator+() const;
SFixed16_16&amp; operator+=(const SFixed16_16&amp; value);
SFixed16_16&amp; operator+=(const int&amp; value);
SFixed16_16&amp; operator+=(const unsigned int&amp; value);
SFixed16_16&amp; operator+=(const long &amp; value);
SFixed16_16&amp; operator+=(const unsigned long&amp; value);
SFixed16_16&amp; operator+=(const float&amp; value);
SFixed16_16&amp; operator+=(const double&amp; value);
SFixed16_16&amp; operator-=(const SFixed16_16&amp; value);
SFixed16_16&amp; operator-=(const int&amp; value);
SFixed16_16&amp; operator-=(const unsigned int&amp; value);
SFixed16_16&amp; operator-=(const long&amp; value);
SFixed16_16&amp; operator-=(const unsigned long&amp; value);
SFixed16_16&amp; operator-=(const float&amp; value);
SFixed16_16&amp; operator-=(const double&amp; value);
SFixed16_16&amp; operator*=(const SFixed16_16&amp; value);
SFixed16_16&amp; operator*=(const int&amp; value)
SFixed16_16&amp; operator*=(const unsigned int&amp; value)
SFixed16_16&amp; operator*=(const long&amp; value)
SFixed16_16&amp; operator*=(const unsigned long&amp; value);
SFixed16_16&amp; operator*=(const float&amp; value);
SFixed16_16&amp; operator*=(const double&amp; value);
SFixed16_16&amp; operator/=(const SFixed16_16&amp; value);
SFixed16_16&amp; operator/=(const int&amp; value);
SFixed16_16&amp; operator/=(const unsigned int&amp; value);
SFixed16_16&amp; operator/=(const long&amp; value);
SFixed16_16&amp; operator/=(const unsigned long&amp; value);
SFixed16_16&amp; operator/=(const float&amp; value);
SFixed16_16&amp; operator/=(const double&amp; value);
SFixed16_16&amp; operator%=(const SFixed16_16&amp; value);
SFixed16_16&amp; operator%=(const int&amp; value);
SFixed16_16&amp; operator%=(const unsigned int&amp; value);
SFixed16_16&amp; operator%=(const long&amp; value);
SFixed16_16&amp; operator%=(const unsigned long&amp; value);
SFixed16_16&amp; operator%=(const float&amp; value);
SFixed16_16&amp; operator%=(const double&amp; value);
SFixed16_16&amp; operator|=(const SFixed16_16&amp; value);
SFixed16_16&amp; operator|=(const int&amp; value);
SFixed16_16&amp; operator&amp;=(const SFixed16_16&amp; value);
SFixed16_16&amp; operator&amp;=(const int&amp; value);
SFixed16_16&amp; operator^=(const SFixed16_16&amp; value);
SFixed16_16&amp; operator^=(const int&amp; value);
SFixed16_16 operator&lt;&lt;(int numBits) const;
SFixed16_16 operator&gt;&gt;(int numBits) const;
SFixed16_16&amp; operator&lt;&lt;=(int numBits);
SFixed16_16&amp; operator&gt;&gt;=(int numBits);
SFixed16_16&amp; operator++();
SFixed16_16&amp; operator--();
SFixed16_16 operator++(int);
SFixed16_16 operator--(int);
SFixed16_16 Abs();
SFixed16_16 DivSafe(const SFixed16_16&amp; denominator);
SFixed16_16&amp; DivSafeAssign(const SFixed16_16&amp; denominator);
}<font color="#000099">;</font>
</pre>
<hr>
<p><br>
<br>
<br>
<span style="font-family: monospace;">&nbsp;&nbsp; </span><br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
</p>
</body></html>
+157
View File
@@ -0,0 +1,157 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<title>EAGlobal</title>
<link type="text/css" rel="stylesheet" href="UTFDoc.css">
<meta name="author" content="Paul Pedriana">
</head>
<body bgcolor="#FFFFFF">
<h1>EAGlobal</h1>
<h2>Introduction</h2>
<p>EAGlobal provides the GlobalPtr class. GlobalPtr acts as a reference to a pointer which is global throughout the process (includes the application and any loaded DLLs). The object pointed to must define a unique 32-bit kGlobalID if one is not given. The GlobalPtr class works in a way similar to a smart pointer, but note that it is not the same as your typical auto_ptr or anything else provided by C++ library vendors. The pointer is set to NULL on creation.<br>
<br>
Global pointers may be used from multiple threads once initialized to point to an object, but are _not_ thread-safe when being set. If you have a situation where two threads may attempt to set a global pointer at the same time, you should use OS globals (See EAOSGlobal.h) instead to serialize the creators on the OS global lock and prevent race conditions.<br>
<br>
A GlobalPtr is not the same thing as simply declaring a pointer at
a globally accessible scope, especially on platforms with dynamic libraries such as Windows with its DLLs. A GlobalPtr allows multiple pieces of code to declare independent pointers to an object, even if the pieced of code are in independent DLLs.<br>
<br>
The pointer assigned to a GlobalPointer need not be a pointer allocated
dynamically on the heap. It can just as well be the address of some static or local variable.</p>
<h2>Example usage </h2>
<p>Here we provide some basic example usage.</p>
<pre class="code-example">GlobalPtr&lt;int, 0x11111111&gt; pInteger;
GlobalPtr&lt;int, 0x11111111&gt; pInteger2;
assert(pInteger == NULL);
pInteger = new int[2];
pInteger[0] = 10;
pInteger[1] = 20;
assert(pInteger2 == pInteger);
assert(pInteger2[0] == pInteger[0]);
delete[] pInteger;
pInteger = NULL;
assert(pInteger2 == NULL);
</pre>
<h2>Interface</h2>
<p>The GlobalPtr class works like a smart pointer, but note that it is not the same as your typical auto_ptr or anything else provided by C++ library vendors. </p>
<pre class="code-example">template&lt;class t, uint32_t kGlobalId = T::kGlobalId&gt;
class GlobalPtr
{
public:
<span class="code-example-comment"> /// this_type
/// This is an alias for this class.
</span> typedef GlobalPtr&lt;T, kGlobalId&gt; this_type;
<span class="code-example-comment"> /// GlobalPtr
///
/// Default constructor. Sets member pointer to whatever the
/// shared version is. If this is the first usage of the shared
/// version, the pointer will be set to NULL.
///
/// Example usage:
/// GlobalPtr&lt;SomeClass, 0x12345678&gt; pSomeClass;
///
</span> GlobalPtr();
<span class="code-example-comment"> /// GlobalPtr (copy constructor)
///
/// Default constructor. Sets member pointer to whatever the
/// shared version is. If this is the first usage of the shared
/// version, the pointer will be set to NULL.
///
/// Example usage:
/// GlobalPtr&lt;SomeClass, 0x12345678&gt; pSomeClass1;
/// pSomeClass1 = new pSomeClass;
/// GlobalPtr&lt;SomeClass, 0x12345678&gt; pSomeClass2(pSomeClass1);
/// pSomeClass2-&gt;DoSomething();
///
</span> explicit GlobalPtr(const this_type& globalPtr);
<span class="code-example-comment"> /// operator =
///
/// Example usage:
/// GlobalPtr&lt;SomeClass, 0x12345678&gt; pSomeClass1;
/// pSomeClass1 = new pSomeClass;
/// GlobalPtr&lt;SomeClass, 0x12345678&gt; pSomeClass2(pSomeClass1);
/// pSomeClass2->DoSomething();
///
</span> this_type& operator=(const this_type& /*globalPtr*/);
<span class="code-example-comment"> /// operator =
///
/// Example usage:
/// GlobalPtr&lt;SomeClass, 0x12345678&gt; pSomeClass1;
/// pSomeClass1 = new pSomeClass;
/// delete pSomeClass1;
/// pSomeClass1 = new pSomeClass;
///
</span> this_type& operator=(T* p);
<span class="code-example-comment"> /// operator T*
///
/// Example usage:
/// GlobalPtrlt;SomeClass, 0x12345678&gt; pSomeClass;
/// FunctionWhichUsesSomeClassPtr(pSomeClass);
///
</span> operator T*() const;
<span class="code-example-comment"> /// operator T*
///
/// Example usage:
/// GlobalPtr&lt;SomeClass, 0x12345678&gt; pSomeClass;
/// CallFunctionWhichUsesSomeClassPtr(pSomeClass);
///
</span> T& operator*() const;
<span class="code-example-comment"> /// operator -&gt;
///
/// Example usage:
/// GlobalPtr&lt;SomeClass, 0x12345678&gt; pSomeClass;
/// pSomeClass-&gt;DoSomething();
///
</span> T* operator-&gt;() const;
<span class="code-example-comment"> /// operator !
///
/// Example usage:
/// GlobalPtr&lt;SomeClass, 0x12345678&gt; pSomeClass;
/// if(!pSomeClass)
/// pSomeClass = new SomeClass;
///
</span> bool operator!() const;
<span class="code-example-comment"> /// get
///
/// Returns the owned pointer.
///
/// Example usage:
/// GlobalPtr&lt;SomeClass, 0x12345678&gt; pSomeClass = new SomeClass;
/// SomeClass* pSC = pSomeClass.get();
/// pSC->DoSomething();
///
</span> T* get() const;
};</pre>
<p></p>
<hr>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p> </p>
</body></html>
+65
View File
@@ -0,0 +1,65 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<title>EAHash</title>
<link type="text/css" rel="stylesheet" href="UTFDoc.css">
<meta name="author" content="Paul Pedriana">
</head>
<body bgcolor="#FFFFFF">
<h1>EAHash</h1>
<h2>Introduction</h2>
<p>EAHash is a family of hashing functions. There are string hashes, binary hashes, cryptographic hashes, checksums, and CRCs; each has its applications. If you are looking for hash tables, they are present in the EASTL library, which provides a suite of hash table containers.</p>
<p>Hash functions are functions which take input data and produce a hash value, which is usually an integer or some short fixed-size data. This is useful for implementing hash-tables, cryptographic security, and error checking. A good hash function produces a unique hash value for the large majority of unique input. A cryptographic hash goes further and has a level of mathematical security built into it so that it is difficult or impossible to guess the original input from a given hash value output. You can read more about hash functions at Wikipedia at <a href="http://en.wikipedia.org/wiki/Hash_function">http://en.wikipedia.org/wiki/Hash_function</a>.</p>
<p>EAStdC provides the following hash submodules:</p>
<ul><li>EAHashString (string hashing) </li>
<li>EAHashCRC (cyclical redundancy check)</li>
</ul>
<p>EAHash provides these hashes in forms that read from blocks in memory. </p>
<h2>EAHashString</h2>
<p>String hashes are probably the most common hashes used in game development. There is a particular interest in having string hashes that are fast but reasonably collision-free in practice. Cryptographical security is not of interest to string hashes. However, being able to do a case-insensitive hash often is. </p>
<p>String hashes are different from binary hashes in that they hash characters and not bytes. Thus, the hash for the 8 bit string &quot;hello&quot; will be the same as the hash for a 16 bit char string L&quot;hello&quot; even though the latter uses twice as many bytes and would hash to a different value via a binary hash function. String hashes are also different in that they sometimes have the option to act with case insensitivity. In such cases the hash for &quot;Hello&quot; is the same as for &quot;hello&quot;. </p>
<p>The primary string hash provided by EAHashString is the FNV1 hash, though the DJB2 hash is also provided. The FNV1 hash appears to be the best string hash for most users' needs, as it is very fast and yet generates surprisingly few collisions with typical text input. </p>
<p>The FNV1 hash functions provided by EAHashString are:</p>
<pre class="code-example">uint32_t FNV1 (const void* pData, size_t nLength, uint32_t nInitialValue = kFNV1InitialValue);<br>uint32_t FNV1_String8 (const char8_t* pData, uint32_t nInitialValue = kFNV1InitialValue, CharCase charCase = kCharCaseAny);<br>uint32_t FNV1_String16(const char16_t* pData, uint32_t nInitialValue = kFNV1InitialValue, CharCase charCase = kCharCaseAny);</pre>
<p>Example usage: </p>
<pre class="code-example">const char16_t fileName[IO::kMaxFileNameLength];
const uint32_t fileNameHash = FNV1_string16(filePath, kFNV1InitialValue, kCharCaseLower);
printf(&quot;Case-insensitive hash for file %ls is 0x%08x.\n&quot;, filePath, fileNameHash);</pre>
<h2>EAHashCRC</h2>
<p>A CRCs (cyclical redundancy check) is a form of hash which is good at detecting uniqueness of input yet is fairly simple to implement. CRCs are most often used to detect errors during data transmission in a non-security-sensitive environment. If a recieved file has a different checksum than the original file, there was a transmission error. A cryptographic hash could also be used to do what a CRC hash does, but it would have more overhead, particularly when implemented in hardware. </p>
<p>There are many standards and variations of CRC algorithms, and trying to understand them can be a tedious frustrating experience. EAHashCRC provides a single CRC implementation for each of various bit sizes and doesn't try to cater to the myriad of variations that exist. Unless you need a CRC function which interacts with some specific third party CRC convention, the version in EAHashCRC is probably fine. You can read more about CRCs on Wikipedia at <a href="http://en.wikipedia.org/wiki/Cyclic_redundancy_check">http://en.wikipedia.org/wiki/Cyclic_redundancy_check</a>.</p>
<p>The CRC functions have a 'bFinalize' parameter, which enables the inversion of the bits upon completion. This is a common practice in standardized CRC calculations. When doing iterative CRC calculations, you need to make sure you set bFinalize to false for all but the last call. See the example code below.</p>
<p>EAHashCRC provides the following block functions: </p>
<pre class="code-example">uint16_t CRC16(const void* pData, size_t nLength, uint16_t nInitialValue = kCRC16InitialValue, bool bFinalize = true);
uint32_t CRC24(const void* pData, size_t nLength, uint32_t nInitialValue = kCRC24InitialValue, bool bFinalize = true);
uint32_t CRC32(const void* pData, size_t nLength, uint32_t nInitialValue = kCRC32InitialValue, bool bFinalize = true);
uint64_t CRC64(const void* pData, size_t nLength, uint64_t nInitialValue = kCRC64InitialValue, bool bFinalize = true);
uint32_t CRC32Reverse(const void* pData, size_t nLength, uint32_t nInitialValue = kCRC32InitialValue, bool bFinalize = true);</pre>
<p>Example basic usage:</p>
<pre class="code-example">char* fileData;
size_t fileLength;
ReadFile(pData, fileLength);
uint16_t crc = CRC16(fileData, fileLength);</pre>
<p>Example usage of incremental CRC calculation, which is useful when you don't have the data in a single block:</p>
<pre class="code-example">char pDataArray[1000];<br>uint64_t crc = kCRC64InitialValue;<br><br>for(int i = 0; i &lt; 10; i++)<span class="code-example-comment"> // Calculate the CRC for the data array incrementally.</span><br> crc = EA::Hash::CRC64(pDataArray[i * 100], 100, crc, i == 9);<br>
</pre>
<hr>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
</body></html>
+232
View File
@@ -0,0 +1,232 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<Title>EAMathHelp</title>
<link type="text/css" rel="stylesheet" href="UTFDoc.css">
<meta name="author" content="Paul Pedriana">
</head>
<body bgcolor="#FFFFFF">
<h1>EAMathHelp</h1>
<h2>Introduction</h2>
<p>EAMathHelp provides fast floating point math primitives. It is not a vector/matrix math library such as those in use around Electronic Arts, but rather is a base
for doing floating point characterizations and for doing fast floating point conversions. The former often serve to help implement the latter.</p>
<p>The constants listed below may look odd if you aren't familiar with the standardized IEEE floating point format. A description of this format is outside the scope
of this document, but you can find plenty of documentation about it by looking it up on the Internet. Suffice it to say the floating point numbers are essentially
bitfields that specify a sign, an integer value (mantissa), and an exponent to raise the integer value by.</p>
<h2>Constants</h2>
<pre class="code-example"><span class="code-example-comment">// 32 bit float bits
</span>const uint32_t kFloat32SignMask = UINT32_C(0x80000000);
const uint32_t kFloat32ExponentMask = UINT32_C(0x7F800000);
const uint32_t kFloat32MantissaMask = UINT32_C(0x007FFFFF);
const uint32_t kFloat32SignAndExponentMask = UINT32_C(0xFF800000);
const uint32_t kFloat32SignAndMantissaMask = UINT32_C(0x807FFFFF);
const uint32_t kFloat32ExponentAndMantissaMask = UINT32_C(0x7FFFFFFF);
const uint32_t kFloat32PositiveInfinityBits = UINT32_C(0x7F800000);
const unsigned kFloat32SignBits = 1;
const unsigned kFloat32ExponentBits = 8;
const unsigned kFloat32MantissaBits = 23;
const unsigned kFloat32BiasValue = 127;
<span class="code-example-comment">// 64 bit float bits
</span>const uint64_t kFloat64SignMask = UINT64_C(0x8000000000000000);
const uint64_t kFloat64ExponentMask = UINT64_C(0x7FF0000000000000);
const uint64_t kFloat64MantissaMask = UINT64_C(0x000FFFFFFFFFFFFF);
const uint64_t kFloat64SignAndExponentMask = UINT64_C(0xFFF0000000000000);
const uint64_t kFloat64SignAndMantissaMask = UINT64_C(0x800FFFFFFFFFFFFF);
const uint64_t kFloat64ExponentAndMantissaMask = UINT64_C(0x7FFFFFFFFFFFFFFF);
const uint64_t kFloat64PositiveInfinityBits = UINT64_C(0x7FF0000000000000);
const unsigned kFloat64SignBits = 1;
const unsigned kFloat64ExponentBits = 11;
const unsigned kFloat64MantissaBits = 52;
const unsigned kFloat64BiasValue = 1023;
const float32_t kFloat32Infinity = kFloat32PositiveInfinityBits;
const float64_t kFloat64Infinity = kFloat64PositiveInfinityBits;
<span class="code-example-comment">// bias to integer
</span>const float32_t kFToIBiasF32 = uint32_t(3) << 22;
const int32_t kFToIBiasS32 = 0x4B400000; <span class="code-example-comment">// Same as ((int32_t&) kFToIBiasF32), but known to optimizer at compile time.</span>
const float64_t kFToIBiasF64 = uint64_t(3) << 52;
<span class="code-example-comment">// bias to 8-bit fraction
</span>const float32_t kFToI8BiasF32 = uint32_t(3) << 14;
const int32_t kFToI8BiasS32 = 0x47400000; <span class="code-example-comment">// Same as ((int32_t&) kFToI8BiasF32), but known to optimizer at compile time.</span>
<span class="code-example-comment">// bias to 16-bit fraction
</span>const float32_t kFToI16BiasF32 = uint32_t(3) << 6;
const int32_t kFToI16BiasS32 = 0x43400000; <span class="code-example-comment">// Same as ((int32_t&) kFToI16BiasF32), but known to optimizer at compile time.</span>
</pre>
<h2>Functions</h2>
<p>Float conversion functions</p>
<pre class="code-example"><span class="code-example-comment">///////////////////////////////////////////////////////////////////////
// Full range conversion functions
//
// These are good for floats within the full range of a float. Remember
// that a single-precision float only has a 24-bit significand so
// most integers |x| > 2^24 cannot be represented exactly.
//
// The result of converting an out-of-range number, infinity, or NaN
// is undefined.
//
</span>inline uint32_t RoundToUint32(float fValue);
inline int32_t RoundToInt32(float fValue);
inline int32_t FloorToInt32(float fValue);
inline int32_t CeilToInt32(float fValue);
inline int32_t TruncateToInt32(float fValue);
<span class="code-example-comment">///////////////////////////////////////////////////////////////////////
// Partial range conversion functions.
//
// These are only good for |x| &lt;= 2^23. The result of converting an
// out-of-range number, infinity, or NaN is undefined.
//
</span>inline int32_t FastRoundToInt23(float fValue);
<span class="code-example-comment">///////////////////////////////////////////////////////////////////////
// Unit-to-byte functions.
//
// Converts real values in the range |x| &lt;= 1 to unsigned 8-bit values
// [0, 255]. The result of calling UnitFloatToUint8() with |x|>1 is
// undefined.
//
</span>inline uint8_t UnitFloatToUint8(float fValue);
inline uint8_t ClampUnitFloatToUint8(float fValue);
</pre>
<p>Float characterization functions</p>
<pre class="code-example"><span class="code-example-comment">///////////////////////////////////////////////////////////////////////
// IsInvalid
//
// Returns true if a value does not obey normal arithmetic rules;
// specifically, x != x. In the case of Visual C++ 2003, this is true
// for NaNs and indefinites, and not for normalized finite values,
// denormals, and infinities. Other compilers may return different
// results or even false for all values.
//
// IsInvalid() is useful as a fast assert check that floats are
// sane and won't poison computations as NaNs can with masked
// exceptions.
//
</span>inline bool IsInvalid(float32_t fValue);
inline bool IsInvalid(float64_t fValue);
<span class="code-example-comment">///////////////////////////////////////////////////////////////////////////////
// IsNormal
//
// Returns true if the value is a normalized finite number. That is, it is neither
// an infinite, nor a NaN (including indefinite NaN), nor a denormalized number.
// You generally want to write math operation checking code that asserts for
// IsNormal() as opposed to checking specifically for IsNaN, etc.
//
// Normal values are defined as any floating point value with an exponent in
// the range of [1, 254], as 0 is reserved for denormalized (underflow) values
// and 255 is reserved for infinite (overflow) and NaN values.
//
</span>inline bool IsNormal(float32_t fValue);
inline bool IsNormal(float64_t fValue);
<span class="code-example-comment">///////////////////////////////////////////////////////////////////////////////
// IsNAN
//
// A NaN is a special kind of number that is neither finite nor infinite.
// It is the result of doing things like the following:
// float x = 1 * NaN;
// float x = NaN + NaN;
// float x = 0 / 0;
// float x = 0 / infinite;
// float x = infinite - infinite
// float x = sqrt(-1);
// float x = cos(infinite);
// Under the VC++ debugger, x will be displayed as 1.#QNAN00 or 1.#IND00 and
// the bit representation of x will be 0x7fc00001 (in the case of 1 * NaN).
// The 'Q' in front of NAN stands for "quiet" and means that use of that value
// in expressions won't generate exceptions. A signaling NaN (SNAN) means that
// use of the value would generate exceptions.
//
// NaNs are frequently generated in physics simulations and similar mathematical
// situations when you are simulating an object moving or turning over time but
// the time or distance differential in the calculation is very small.
// Also, floating point roundoff error can generate NaNs if you do things
// like call acos(x) where you didn't take care to clamp x to &lt;= 1. You can
// also get a NaN when memory used to store a floating point value is written
// with random data.
//
// A curious property of NaNs is that all comparisons between NaNs return
// false except the expression: NaN != NaN. This is so even if the bit
// representation of the two compared NaNs are identical. Thus, with NaNs,
// the following holds:
// x == x is always false
// x < y is always false
// x > y is always false
//
// As a result, one simple way to test for a NaN without fiddling with bits is
// to simply test for x == x. If this returns false, then you have a NaN.
// Unfortunately, many C and C++ compilers don't obey this, so you are usually
// stuck fiddling with bits.
//
// With a NaN, all exponent bits are 1 and the mantissa is not zero.
// If the highest fraction bit is 1, the NAN is "quiet" -- it represents
// and indeterminant operation rather than an invalid one.
//</span>
inline bool IsNAN(float32_t fValue);
inline bool IsNAN(float64_t fValue);
<span class="code-example-comment">///////////////////////////////////////////////////////////////////////////////
// IsInfinite
//
// A value is infinity if the exponent bits are all 1 and all the bits of the
// mantissa (significand) are 0. The sign bit indicates positive or negative
// infinity. Thus, for Float32, 0x7f800000 is positive infinity and 0xff800000
// is negative infinity.
//
</span>inline bool IsInfinite(float32_t fValue);
inline bool IsInfinite(float64_t fValue);
<span class="code-example-comment">///////////////////////////////////////////////////////////////////////////////
// IsIndefinite
//
// An indefinite is a special kind of NaN that is used to signify that an
// operation between non-NaNs generated a NaN. Other than that, it really is
// simply another NaN.
//
</span>inline bool IsIndefinite(float32_t fValue);
inline bool IsIndefinite(float64_t fValue);
<span class="code-example-comment">///////////////////////////////////////////////////////////////////////////////
// IsDenormalized
//
// Much in the same way that infinite numbers represent an overflow,
// denormalized numbers represent an underflow. A denormalized number is
// indicated by an exponent with a value of zero. You get a denormalized
// number when you do operations such as this:
// float x = 1e-10 / 1e35;
// Under the VC++ debugger, x will be displayed as 1.4e-045#DEN and the
// bit representation of x will be 0x00000001. Unlike infinites and NaNs,
// you can still do math with denormalized numbers. However, the results
// of your math will likely have a lot of imprecision. You can also get a
// denormalized value when memory used to store a floating point value is
// written with random data.
//
</span>inline bool IsDenormalized(float32_t fValue);
inline bool IsDenormalized(float64_t fValue);</pre>
<hr>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
</body></html>
+144
View File
@@ -0,0 +1,144 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<title>EAMemory</title>
<link type="text/css" rel="stylesheet" href="UTFDoc.css">
<meta name="author" content="Paul Pedriana">
<style type="text/css">
<!--
.style1 {font-size: smaller}
-->
</style>
</head>
<body bgcolor="#FFFFFF">
<h1>EAMemory</h1>
<p>EAMemory provides functions related to copying and filling memory. </p>
<p>Note the presence of &quot;C&quot; functions below such as MemcpyC. These refer to memory functions that operate only on cacheable memory, but are faster than otherwise. Cacheable memory is standard system RAM used by applications and is the memory you work with 98% of the time. However, on some hardware systems (e.g. gaming console machines) there is uncacheable memory, such as memory that is mapped to video addresses. This memory is typically called write-through or write-combined memory and is useful for writing data in one direction from system RAM to video memory. The &quot;C&quot; functions do not work on this kind of memory and you can instead use the regular functions such as Memcpy for uncacheable memory. The C here has nothing to do with the C vs. C++ language.</p>
<table border="1">
<tr>
<td colspan="2" valign="top" scope="col"><h3>Memcpy</h3></td>
</tr>
<tr>
<td width="527" valign="top"><span class="style1">char8_t* Memcpy (void* pDest, const void* pSource, size_t n)</span></td>
<td rowspan="5" valign="top"><p>Copies nByteCount bytes from pSource to pDestination. The source and destination memory ranges must not overlap. Returns pDestination. There are no restrictions in the way of size, alignment, or memory type, though the source memory must be readable and the destination memory must be writable. </p>
<p>The MemcpyS function copies memory from source to destination without filling the cache with the memory. This is useful for when you want to write memory that will not be read by the processor used to write it, such as when the CPU writes to memory used by the GPU. </p>
<p>The Memcpy128 function is useful for higher performance memory copies when the requirements can be met. The address pointed to by pDestination must be aligned on a 128-byte boundary, and uint8Count must be a multiple of 128.</p></td>
</tr>
<tr>
<td valign="top"><span class="style1">char8_t* MemcpyC (void* pDest, const void* pSource, size_t n)</span></td>
</tr>
<tr>
<td valign="top"><span class="style1">char8_t* MemcpyS (void* pDest, const void* pSource, size_t n)</span></td>
</tr>
<tr>
<td valign="top"><span class="style1">char8_t* Memcpy128 (void* pDest, const void* pSource, size_t n)</span></td>
</tr>
<tr>
<td valign="top"><span class="style1">char8_t* Memcpy128C (void* pDest, const void* pSource, size_t n)</span></td>
</tr>
<tr>
<td colspan="2" valign="top"><h3>Memmove</h3></td>
</tr>
<tr>
<td valign="top"><span class="style1">char8_t* Memmove (void* pDest, const void* pSource, size_t n)</span></td>
<td rowspan="2" valign="top">Copies nByteCount bytes from pSource to pDestination. The source and destination memory ranges may overlap. Returns pDestination. There are no restrictions in the way of size, alignment, or memory type, though the source memory must be readable and the destination memory must be writable. </td>
</tr>
<tr>
<td valign="top"><span class="style1">char8_t* MemmoveC (void* pDest, const void* pSource, size_t n)</span></td>
</tr>
<tr>
<td colspan="2" valign="top"><h3>Memset</h3></td>
</tr>
<tr>
<td valign="top"><span class="style1">uint8_t* Memset8 (void* pDest, uint8_t c, size_t uint8Count)</span></td>
<td rowspan="10" valign="top"><p> The standard memset function replicates a given 8 bit value into a memory block. However, we might want to replicate a 16 bit, 32 bit, or 64 bit value into a block. That's what these functions do. The MemsetN function is a generic version which can copy unusual sizes such as 24 bits (e.g. RGB fills). The count values for each of these is the count of uint16_t, count of uint32_t, count of pointers, etc.<br>
<br>
Memset8 is the same as the memset function. We provide additional variations of memset which set uint16_t values, uint32_t value, etc. instead of uint8_t values like Memset8. MemsetN writes a generic type of any size. In each case pDestination must point to enough memory to hold full values. Thus pDestination for Memset32 must have a capacity for at least (uint32Count * sizeof(uint32_t)) bytes. The destination is required to be aligned to its type. Thus the destination of Memset32 must be 32 bit aligned. There are no restrictions about the type of memory pDestination refers to except that it be writable.</p>
</td>
</tr>
<tr>
<td valign="top"><span class="style1">uint8_t* Memset8C (void* pDest, uint8_t c, size_t uint8Count)</span></td>
</tr>
<tr>
<td valign="top"><span class="style1">uint8_t* Memset8_128 (void* pDest, uint8_t c, size_t uint8Count)</span></td>
</tr>
<tr>
<td valign="top"><span class="style1">uint8_t* Memset8_128C (void* pDest, uint8_t c, size_t uint8Count)</span></td>
</tr>
<tr>
<td valign="top"><span class="style1">uint16_t* Memset16 (void* pDest, uint16_t c, size_t uint16Count)</span></td>
</tr>
<tr>
<td valign="top"><span class="style1">uint32_t* Memset32 (void* pDest, uint32_t c, size_t uint32Count)</span></td>
</tr>
<tr>
<td valign="top"><span class="style1">uint64_t* Memset64 (void* pDest, uint64_t c, size_t uint64Count)</span></td>
</tr>
<tr>
<td valign="top"><span class="style1">void* MemsetN (void* pDest, const void* pSource, size_t sourceBytes, size_t nCount)</span></td>
</tr>
<tr>
<td valign="top"><span class="style1">void Memclear (void* pDest, size_t n)</span></td>
</tr>
<tr>
<td valign="top"><span class="style1">void MemclearC (void* pDest, size_t n)</span></td>
</tr>
<tr>
<td colspan="2" valign="top"><h3>Memfill</h3></td>
</tr>
<tr>
<td valign="top"><span class="style1">void Memfill16 (void* pDest, uint16_t c, size_t byteCount)</span></td>
<td rowspan="5" valign="top">Memfill is the same as memset except that the count parameter is a count of bytes and not (for example) a count of uint32_t values. Memfill supports byte counts that aren't an even multiple the value size. Thus a call to Memfill32(p, 0x00112233, 3) is valid and does what you would expect. MemFill8 is not defined because it is the same thing as Memset8. MemfillSpecific fills (and potentially repeats) any source pattern into any destination space. There are no restrictions about the type of memory pDest refers to except that it be writable.</td>
</tr>
<tr>
<td valign="top"><span class="style1">void Memfill24 (void* pDest, uint32_t c, size_t byteCount)</span></td>
</tr>
<tr>
<td valign="top"><span class="style1">void Memfill32 (void* pDest, uint32_t c, size_t byteCount)</span></td>
</tr>
<tr>
<td valign="top"><span class="style1">void Memfill64 (void* pDest, uint64_t c, size_t byteCount)</span></td>
</tr>
<tr>
<td valign="top"><span class="style1">void MemfillSpecific(void* pDest, const void* pSource, size_t destByteCount, size_t sourceByteCount)</span></td>
</tr>
<tr>
<td colspan="2" valign="top"><h3>Memcheck</h3></td>
</tr>
<tr>
<td valign="top"><span class="style1">uint8_t* Memcheck8 (void* pDest, uint8_t c, size_t byteCount)</span></td>
<td rowspan="4" valign="top">This family of functions is like Memfill except it verifies that the memory is filled as per the value and byte count. Returns a pointer to the first mis-matching byte if there's a mismatch. Returns NULL if there are no mismatches. There are no restrictions about the type of memory pDest refers to except that it be readable.</td>
</tr>
<tr>
<td valign="top"><span class="style1">uint16_t* Memcheck16 (void* pDest, uint16_t c, size_t byteCount)</span></td>
</tr>
<tr>
<td valign="top"><span class="style1">uint32_t* Memcheck32 (void* pDest, uint32_t c, size_t byteCount)</span></td>
</tr>
<tr>
<td valign="top"><span class="style1">uint64_t* Memcheck64 (void* pDest, uint64_t c, size_t byteCount)</span></td>
</tr>
<tr>
<td colspan="2" valign="top"><h3>Misc</h3></td>
</tr>
<tr>
<td valign="top"><span class="style1">const void* Memchr(const void* p, char8_t c, size_t n)</span></td>
<td valign="top">This is the same as memchr and wmemchr. Searches the first n characters (not necessarily bytes) of the memory block pointed to by pString for character c. Returns a pointer to the character or NULL if not found. There are no restrictions about the type of memory p refers to except that it be readable.</td>
</tr>
<tr>
<td valign="top"><span class="style1">int Memcmp(const void* p1, const void* p2, size_t n)</span></td>
<td valign="top">Same as memcmp and wmemcmp. Compares the first n bytes of two memory blocks pointed by p1 and p2. The comparison is a bytewise compare and thus for strings it is case-sensitive. For a case-insensitive string comparison, use the Stricmp function. Bytes are treated as uint8_t for comparison purposes. Returns 0 if the memory is equal, &lt; 0 if p1 &lt; p2, and &gt; 0 if p1 &gt; p2. There are no restrictions about the type of memory p1 and p2 refer to except that they be readable.</td>
</tr>
<tr>
<td valign="top"><span class="style1">void* EAAlloca(size_t n)</span></td>
<td valign="top"><p>EAAlloca is a portable declaration for the alloca function. </p>
<p>The alloca function allocates space in the stack frame of the caller, and returns a pointer to the allocated block. This temporary space is automatically freed when the function from which alloca is called returns.</p></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</body></html>
+85
View File
@@ -0,0 +1,85 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<title>EAOSGlobal</title>
<link type="text/css" rel="stylesheet" href="UTFDoc.css">
<meta name="author" content="Paul Pedriana">
</head>
<body bgcolor="#FFFFFF">
<h1>EAOSGlobal</h1>
<h2>Introduction</h2>
<p>OS globals are process-wide globals (singletons, actually) and are shared between an EXE and DLLs, though you can use them on platforms that don't support DLLs. The Windows OS does not directly support this concept of global object sharing, as the only way to accomplish this under Windows is to sequester the global object in its own DLL of which the EXE and all DLLs explicitly reference. OS Globals allow you to have the global object anywhere (including the EXE) and does so without requiring explicit linking. The OS global system works at the operating system level and has auto-discovery logic so that no pointers or init calls need to be made between modules for them to link their OS global systems together. The OS global system consists of EAOSGlobal and <a href="EAGlobal.html">EAGlobal</a>. The latter provides simpler functionality but has less overhead.</p>
<p>A primary use of OS globals is in the creation of application singletons such as the main heap, messaging servers, asset managers, etc. <br>
<br>
Note that the implementation behind OS globals (EAOSGlobal.cpp) may seem a bit convoluted; this is because it needs to be thread-safe, cross-module, and independent of application-level memory allocators. For objects for which order of initialization is clearer and you don't need to reference singletons across DLLs, EASingleton is probably a better choice, as it is simpler and has lower overhead. Indeed, another way of looking at OS globals is to view them as process-wide singletons. </p>
<p>The easiest way to use OS globals is via their auto pointers, which make OS globals just about trivial to use. We will cover the major components of EAOSGlobal below, starting with the auto pointers. </p>
<p><strong>Caveats</strong></p>
<p>OS globals have the potential for resulting in code that's duplicated within each DLL and thus increasing code memory usage. It might be useful to use an OS global to store a pointer to an interface rather than an instance of an interface, and have just a single entity within the application provide the implementation. With this approach you still get the benefit of users of the global not having to know ahead of time where the implementation is as you otherwise need to do with standard DLL linking via &quot;dllexport.&quot;</p>
<p>OS globals probably aren't needed in cases where you can simply use dllexport (and other platforms' equivalents).</p>
<h2>AutoOSGlobalPtr</h2>
<p> Holds a reference to an OS global of the specified type and Id. If the OS global does not exist, a new one is created in the shared heap. The Id parameter is an arbitrary guid and allows the user to have multiple OSGlobalPtrs of the same stored type T.<br>
<br>
OS global lookup is not very fast so the preferred usage of this class is to wrap it in an accessor. This also ensures that the OS global stays around while created.</p>
<p>Example usage: </p>
<pre class="code-example">AutoOSGlobalPtr&lt;Widget, 0x11111111&gt; gpWidget1A; <span class="code-example-comment">// Declare a global pointer.</span><br>AutoOSGlobalPtr&lt;Widget, 0x11111111&gt; gpWidget1B; <span class="code-example-comment">// Points to the same global Widget as gpWidget1A.</span><br>AutoOSGlobalPtr&lt;Widget, 0x22222222&gt; gpWidget2; <span class="code-example-comment">// Points to a different Widget, as it has the 0x22222222 id.</span><br><br>void Foo()
{<br> assert(gpWidget1A == gpWidget1B);<br> assert(gpWidget1A != gpWidget2);<br><br> gpWidget1A-&gt;DoSomething();<br> gpWidget2-&gt;DoSomething();<br>}</pre>
<h2>AutoStaticOSGlobalPtr</h2>
<p> Holds a reference to a OS global of the specified type and ID. If the OS global does not exist, a new one is created using static memory.<br>
The Id parameter is an arbitrary guid and allows the user to have multiple OSGlobalPtrs of the same stored type T.<br>
<br>
The advantage of this class is that it uses static memory, so it does not contribute to heap usage and it always succeeds in allocating the object. The disadvantage is that if multiple DLLs are involved each will have its own static space reserved for the OS global.</p>
<p>AutoStaticOSGlobalPtrs and AutoOSGlobalPtrs should not be mixed when referring to a OS global. You should reference an OSGlobal via either one or more AutoOSGlobalPtrs, one or more AutoStaticOSGlobalPtrs, but not both at the same time.</p>
<p>Example usage (note that it is virtually identical to the AutoOSGlobalPtr example): </p>
<pre class="code-example">AutoStaticOSGlobalPtr&lt;Widget, 0x11111111&gt; gpWidget1A; <span class="code-example-comment">// Declare a global pointer.</span><br>AutoStaticOSGlobalPtr&lt;Widget, 0x11111111&gt; gpWidget1B; <span class="code-example-comment">// Points to the same global Widget as gpWidget1A.</span><br>AutoStaticOSGlobalPtr&lt;Widget, 0x22222222&gt; gpWidget2; <span class="code-example-comment">// Points to a different Widget, as it has the 0x22222222 id.</span><br><br>void Foo()
{<br> assert(gpWidget1A == gpWidget1B);<br> assert(gpWidget1A != gpWidget2);<br><br> gpWidget1A-&gt;DoSomething();<br> gpWidget2-&gt;DoSomething();<br>}</pre>
<h2>Low level functionality </h2>
<p>The above auto pointer classes are really just wrappers around the low level OS global API. Most of the time you want to use the auto pointers. We provide a description of the lowel level API here for those who need to access OS globals in a custom way.</p>
<p>The low level system is comprised of the following four entities: </p>
<pre class="code-example">struct OSGlobalNode : public eastl::intrusive_list_node { };
typedef OSGlobalNode* (*OSGlobalFactoryPtr)();
OSGlobalNode* GetOSGlobal(uint32_t id, OSGlobalFactoryPtr pFactory);
bool ReleaseOSGlobal(OSGlobalNode* pOSGlobalNode);
</pre>
<p>Example usage:</p>
<pre class="code-example">struct Widget : public OSGlobalNode
{
<span class="code-example-comment">// User data here.</span>
};
Widget* WidgetFactory()
{
return new Widget;
}
int main(int, char**)
{
Widget* pWidget = GetOSGlobal(0x12345678, WidgetFactory);
pWidget-&gt;DoSomething();
if(ReleaseOSGlobal(pWidget))
delete pWidget;
return 0;
}</pre>
<p>The above example looks like a basic singleton pattern, and it is such a thing. The difference between this and your typical singleton system is that the OS global system solves the potentially tricky problems of cross-DLL access, thread safety, and memory allocation. </p>
<p>For additional example usage, see the source code to AutoOSGlobalPtr in EAOSGlobal.h.</p>
<hr>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p></p>
</body></html>
+374
View File
@@ -0,0 +1,374 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<title>EARandom</title>
<link type="text/css" rel="stylesheet" href="UTFDoc.css">
<meta name="author" content="Paul Pedriana">
</head>
<body bgcolor="#FFFFFF">
<h1>EARandom</h1>
<h2>Introduction</h2>
<p>EARandom provides pseudo-random number generation suitable for most kinds of
professional game development. Functionality is divided into two modules:</p>
<ul>
<li>Core random number generation (e.g. random integer, random float)</li>
<li>Variable distribution generation (e.g. Gaussian distribution, triangle distribution)</li>
</ul>
<p>EARandom provides two core generators which address a speed/randomness tradeoff:</p>
<ul>
<li> RandomLinearCongruential (very fast, also known as RandomFast, but still good randomness)</li>
<li>RandomMersenneTwister (very random, also known as RandomQuality)</li>
</ul>
<p>EARandom provides a number of distribution generators, each of which uses the
above core generators underneath:</p>
<ul>
<li>RandomBool</li>
<li>Random2, Random4, Random8, ... Random256</li>
<li>RandomInt32UniformRange</li>
<li>RandomDoubleUniformRange</li>
<li>RandomUint32WeightedChoice</li>
<li>RandomUint32Gaussian</li>
<li>RandomUint32Triangle</li>
</ul>
<p><i>Note: EARandom is not certified nor suitable for use in certified gambling
software. There are strict standards regarding such software which EARandom
does not try to comply with. Similarly, EARandom is not suitable for use in security-related entropy collection (at least not by itself). EARandom's goal is to provide good random number
generation with high efficiency.</i></p>
<h2>Don't use the C rand() function!</h2>
<p> The C library rand function does an OK job as a basic random number generator
for testing and hobby purposes. However, the rand function is generally not
suitable for professional game software. This is because the rand function:</p>
<ul>
<li>Generates only numbers between 0 and RAND_MAX, which is usually 32767.</li>
<li>Doesn't generate random numbers within a prescribed range. Using the % operator
to rectify this is slow (requires integer division) and produces a lopsided
distribution unless the divisor is evenly divisible into RAND_MAX.</li>
<li>Generates rather poor random numbers. In particular, they tend to have obvious
patterns in the low bits. In some cases this can result in users taking advantage
of the number generator at the expense of other players or your game franchise
itself.</li>
<li>Exists only as a single instance of a generator which is shared with the
entire application. There is no way to make another instance.</li>
<li>Is slow. Generating a random number via rand() was measured as 70% slower
than the EARandom generator on modern hardware.</li>
<li>Doesn't generate floating point numbers.</li>
</ul>
<h2>How random is EARandom?</h2>
<p>Both RandomLinearCongruential (i.e. RandomFast) and RandomMersenneTwister (RandomQuality) provide randomness that is likely good enough for most convential game uses. Don't be fooled by the &quot;linear congruential&quot; name; it's not the bad generator that you might think based on what you've read about old C rand implementations. </p>
<p>A good way to test randomness is with the DieHard randomness tests. See http://en.wikipedia.org/wiki/Diehard_tests for information about DieHard. We have a copy of the <a href="http://eaos.rws.ad.ea.com:8080/@md=d&cd=//EAOS/UTF/DL/UTFResearch/DieHard%20Random%20Number%20Tester/&c=2lr@//EAOS/UTF/DL/UTFResearch/DieHard%20Random%20Number%20Tester/bin/?ac=83">DieHard tester in EAOS</a> which is used to test EARandom and could test any other random number generator. EARandom produces DieHard scores which are pretty good. A number of home-grown random number generators have shown much worse results. </p>
<h2>Common misuses</h2>
<p>It is worth mentioning that it is surprisingly common for users of random number
generators (including EARandom) to come to the belief that the generator is
broken when in fact they are misusing the generator. Common misuses of generators
include:</p>
<ul>
<li>Seeding a generator with the same seed every time it's used.</li>
<li>Seeding two generators at the same time via the system clock and finding
that they produce idential values.</li>
<li>Using 'RandomUint32Uniform() % 5000' instead of 'RandomUint32Uniform(5000)'.</li>
<li>Inventing flawed distribution generators.</li>
<li>Misusing the results of a generator but assuming the generator is yielding
bad values.</li>
<li>Creating a random number generator for a single use right when it is needed.
This is usually bad because the first generated value is no more random than
the seed used to generate the number.</li>
</ul>
<h2>Example usage </h2>
<p>EARandom is fairly straightforward to use. Just avoid the above common mistakes
and things should work well.</p>
<p>Mixed integer math expressions.</p>
<pre class="code-example">EA::RandomFast rng(GetCPUTick()); <span class="code-example-comment">// Seed with a hypthetical CPU tick function.</span>
uint32_t n = rng.RandomUint32Uniform(); <span class="code-example-comment">// Generate value in the range of [0, 0xffffffff] (all bit patterns).</span>
uint32_t i = rng.RandomUint32Uniform(200); <span class="code-example-comment">// Generate value in the range of [0, 200).</span>
double d = rng.RandomDoubleUniform(); <span class="code-example-comment">// Generate value in the range of [0, 1).</span>
double f = rng.RandomDoubleUniform(37); <span class="code-example-comment">// Generate value in the range of [0, 37).</span></pre>
How to use EARandom with STL (including EASTL).
<pre class="code-example">#include &lt;algorithm&gt;
#include &lt;vector&gt;
std::vector v;
EA::RandomFast rng;
std::random_shuffle(v.begin(), v.end(), rng);</pre>
How to use basic random distributions. Note that these functions take a random number generator as an argument.
<pre class="code-example">EA::RandomQuality rng;
bool b = EA::RandomBool(rng);
int32_t n = EA::Random256(rng);
double d = EA::RandomDoubleGaussian(rng, 15.0, 30.0);</pre>
<p>How to use RandomUint32WeightedChoice. This function is useful for generating
a custom distribution.</p>
<pre class="code-example">EA::RandomQuality rng;
const float weights[10] = { 1, 2, 3, 4, 5, 5, 4, 3, 2, 1 }; // Create a triangle distribution
uint32_t i = EA::RandomUint32WeightedChoice(rng, 10, weights); </pre>
<h2>Interface</h2>
<h3>RandomLinearCongruential</h3>
<p>This algorithm generates good enough pseudorandom numbers for most simulationuses.
Its biggest weakness is that there are some patterns that occur in the lower
bits. However, it is still far better than the C rand function. </p>
<pre class="code-example">class RandomLinearCongruential
{
public:
typedef uint32_t result_type;
<span class="code-example-comment"> /// RandomLinearCongruential
/// Constructs the random number generator with a given initial state (seed).
/// If the seed is 0xffffffff (MAX_UINT32), then the seed is generated automatically
/// by a semi-random internal mechanism such as reading the system clock. Note that
/// seeding by this mechanism can yield unexpected poor results if you create multiple
/// instances of this class within a short period of time, as they will all get the
/// same seed due to the system clock having not advanced.
</span> RandomLinearCongruential(uint32_t nSeed = 0xffffffff);
<span class="code-example-comment"> /// RandomLinearCongruential
/// Copy constructor
</span> RandomLinearCongruential(const RandomLinearCongruential& randomLC);
<span class="code-example-comment"> /// operator =
</span> RandomLinearCongruential& operator=(const RandomLinearCongruential& randomLC);
<span class="code-example-comment"> /// GetSeed
/// Gets the state of the random number generator, which can be entirely
/// defined by a single uint32_t.
</span> uint32_t GetSeed() const;
<span class="code-example-comment"> /// SetSeed
/// Sets the current state of the random number generator, which can be
/// entirely defined by a single uint32_t.
</span> void SetSeed(uint32_t nSeed = 0xffffffff);
<span class="code-example-comment"> /// operator ()
/// Generates a random uint32 with an optional limit. Acts the same as the
/// RandomUint32Uniform(uint32_t nLimit) function. This function is useful for
/// some templated uses whereby you want the class to act as a function object.
/// If the input nLimit is 0, then the return value is from 0 to MAX_UINT32 inclusively.
</span> uint32_t operator()(uint32_t nLimit = 0);
<span class="code-example-comment"> /// RandomUint32Uniform
/// Return value is from 0 to MAX_UINT32 inclusively, with uniform probability.
/// This is the most basic random integer generator for this class; it has no
/// extra options but is also the fastest. Note that if you want a random
/// integer between 0 and some value, you should use RandomUint32Uniform(nLimit)
/// and not use RandomUint32Uniform() % nLimit. The former is both faster and
/// more random; using % to achieve a truly random distribution fails unless
/// nLimit is evenly divisible into MAX_UINT32.
</span> uint32_t RandomUint32Uniform();
<span class="code-example-comment"> /// RandomUint32Uniform (with limit)
/// Return value is from 0 to nLimit-1 inclusively, with uniform probability.
</span> uint32_t RandomUint32Uniform(uint32_t nLimit);
<span class="code-example-comment"> /// RandomDoubleUniform
/// Output is in range of [0, 1) with uniform distribution.
</span> double RandomDoubleUniform();
<span class="code-example-comment"> /// RandomDoubleUniform (with limit)
/// Output is in range of [0, limit) with uniform distribution.
</span> double RandomDoubleUniform(double limit);
};
</pre>
<h3>RandomTaus</h3>
<p> RandomTaus is slower than the other EARandom generators but has only 12 bytes of state data. RandomLinearCongruental has only 4 bytes of data but is not as random as RandomTaus. RandomMersenneTwister is more random than RandomTaus but has about 2500 bytes of state data. Thus RandomTaus is a tradeoff. This generator optimizes randomness and and to some degree size at the cost of speed.</p>
<pre class="code-example">class RandomTaus
{
public:
typedef uint32_t result_type;
RandomTaus(uint32_t nSeed = 0xffffffff);
RandomTaus(const uint32_t* pSeedArray); <span class="code-example-comment">// Array of 3 uint32_t values.</span>
RandomTaus(const RandomTaus&amp; randomT);
RandomTaus&amp; operator=(const RandomTaus&amp; randomT);
<span class="code-example-comment"> // Single uint32_t version, for compatibility.
// Use the seed array version for best behavior.
// Not guaranteed to return the uint32_t set by SetSeed(uint32_t).
</span> uint32_t GetSeed() const;
void SetSeed(uint32_t nSeed = 0xffffffff);
void GetSeed(uint32_t* pSeedArray) const; <span class="code-example-comment">// Array of 3 uint32_t values.</span>
void SetSeed(const uint32_t* pSeedArray); <span class="code-example-comment">// Array of 3 uint32_t values.</span>
<span class="code-example-comment"> /// Output is in range of [0, nLimit) with uniform distribution.
</span> uint32_t operator()(uint32_t nLimit = 0);
<span class="code-example-comment"> /// Output is in range of [0, UINT32_MAX] with uniform distribution.
</span> uint32_t RandomUint32Uniform();
<span class="code-example-comment"> /// Output is in range of [0, nLimit) with uniform distribution.
</span> uint32_t RandomUint32Uniform(uint32_t nLimit);
<span class="code-example-comment"> /// Output is in range of [0, 1) with uniform numeric (not bit) distribution.
</span> double RandomDoubleUniform();
<span class="code-example-comment"> /// Output is in range of [0, limit) with uniform numeric (not bit) distribution.
/// limit is a value &gt; 0.
</span> double RandomDoubleUniform(double limit);<br><span class="code-example-comment"></span>};</pre>
<h3>RandomMersenneTwister</h3>
<p>This algorithm implements a random number generator via the Mersenne Twister
algorithm. This algorithm is popular for its very high degree of randomness
(period of 2^19937-1 with 623-dimensional equidistribution) while achieving
good speed.</p>
<pre class="code-example">class RandomMersenneTwister
{
public:
typedef uint32_t result_type;
<span class="code-example-comment"> /// enum SeedArray
/// This enum is public because it allows the user to know how much
/// data or space to provide for the GetSeed and SetSeed functions.
</span> enum SeedArray { kSeedArrayCount = 624 };
RandomMersenneTwister(uint32_t nSeed = 0xffffffff);
RandomMersenneTwister(const uint32_t seedArray[], unsigned nSeedArraySize);
RandomMersenneTwister(const RandomMersenneTwister& randomMT);
RandomMersenneTwister& operator=(const RandomMersenneTwister& randomMT);
void GetSeed(uint32_t seedArray[], unsigned nSeedArraySize) const;
void SetSeed(const uint32_t seedArray[], unsigned nSeedArraySize);
void SetSeed(uint32_t nSeed = 0xffffffff);
uint32_t operator()(uint32_t nLimit = 0);
uint32_t RandomUint32Uniform();
uint32_t RandomUint32Uniform(uint32_t nLimit);
double RandomDoubleUniform();
double RandomDoubleUniform(double limit);
};</pre>
<h3>Random distributions</h3>
<p>Here is a list of the currently provided distribution functions.</p>
<pre class="code-example"><span class="code-example-comment">/// RandomBool
/// Returns true or false.
</span>template &lt;typename Random&gt;
bool RandomBool(Random& r);
<span class="code-example-comment">/// Random2
/// Returns a value between 0 and 1, inclusively.
</span>template &lt;typename Random&gt;
int32_t Random2(Random& r);
<span class="code-example-comment">/// Random4
/// Returns a value between 0 and 3, inclusively.
</span>template &lt;typename Random&gt;
int32_t Random4(Random& r);
<span class="code-example-comment">/// Random8
/// Returns a value between 0 and 7, inclusively.
</span>template &lt;typename Random&gt;
int32_t Random8(Random& r);
<span class="code-example-comment">/// Random16
/// Returns a value between 0 and 15, inclusively.
</span>template &lt;typename Random&gt;
int32_t Random16(Random& r);
<span class="code-example-comment">/// Random32
/// Returns a value between 0 and 31, inclusively.
</span>template &lt;typename Random&gt;
int32_t Random32(Random& r);
<span class="code-example-comment">/// Random64
/// Returns a value between 0 and 63, inclusively.
</span>template &lt;typename Random&gt;
int32_t Random64(Random& r);
<span class="code-example-comment">/// Random128
/// Returns a value between 0 and 127, inclusively.
</span>template &lt;typename Random&gt;
int32_t Random128(Random& r);
<span class="code-example-comment">/// Random256
/// Returns a value between 0 and 255, inclusively.
</span>template &lt;typename Random&gt;
int32_t Random256(Random& r);
<span class="code-example-comment">/// RandomPowerOfTwo
/// Returns a value between 0 and 2 ^ nPowerOfTwo - 1, inclusively.
/// This is a generalized form of the RandomN set of functions.
</span>template &lt;typename Random&gt;
int32_t RandomPowerOfTwo(Random& r, unsigned nPowerOfTwo);
<span class="code-example-comment">/// RandomInt32UniformRange
/// Return value is from nBegin to nEnd-1 inclusively, with uniform probability.
</span>template &lt;typename Random&gt;
int32_t RandomInt32UniformRange(Random& r, int32_t nBegin, int32_t nEnd);
<span class="code-example-comment">/// RandomDoubleUniformRange
/// Return value is in range of [nBegin, nEnd) with uniform probability.
</span>template <class Random><class Random>&lt;typename Random&gt;
double RandomDoubleUniformRange(Random& r, double begin, double end);
<span class="code-example-comment">/// RandomUint32WeightedChoice
/// Return value is from 0 to nLimit-1 inclusively, with probabilities proportional to weights.
/// The input array weights must be of length <nlimit>. These values are used to
/// determine the probability of each choice. That is, weight[i] is proportional
/// to the probability that this function will return i. Negative values are ignored.
/// This function is useful in generating a custom distribution.
</span>template &lt;typename Random&gt;
uint32_t RandomUint32WeightedChoice(Random& r, uint32_t nLimit, float weights[]);
<span class="code-example-comment">/// RandomUint32Gaussian
/// Return value is in the range [0, nLimit) with Gaussian (a.k.a 'normal') distribution.
</span>template &lt;typename Random&gt;
uint32_t RandomUint32Gaussian(Random& r, int32_t nBegin, int32_t nEnd);
<span class="code-example-comment">/// RandomDoubleGaussian
/// Return value is in the range [0, nLimit) with Gaussian (a.k.a 'normal') distribution.
</span>template &lt;typename Random&gt;
double RandomDoubleGaussian(Random& r, double nBegin, double nEnd);
<span class="code-example-comment">/// RandomUint32Triangle
/// Return value is in the range [0, nLimit) with triangular distribution.
</span>template &lt;typename Random&gt;
uint32_t RandomUint32Triangle(Random& r, int32_t nBegin, int32_t nEnd);
<span class="code-example-comment">/// RandomDoubleTriangle
/// Return value is in the range [0, nLimit) with triangular distribution.
</span>template &lt;typename Random&gt;
double RandomDoubleTriangle(Random& r, double nBegin, double nEnd);
</pre>
<h3>Random fills and shuffles</h3>
<p>How to fill a container or sequence with random uint32_t values:</p>
<pre class="code-example">#include &lt;eastl/algorithm.h&gt; <span class="code-example-comment"> // or #include &lt;algorithm&gt; to use std STL.</span>
EA::StdC::Random rand(someSeedValue); <span class="code-example-comment">// We can just use EA::StdC::Random directly because</span> <br>eastl::generate(myVector.begin(), myVector.end(), rand); <span class="code-example-comment">// it has an operator() that returns uint32_t.</span></pre>
<p>How to randomize (shuffle) an existing container or sequence of uint32_t values:</p>
<pre class="code-example">#include &lt;eastl/algorithm.h&gt; <span class="code-example-comment"> // or #include &lt;algorithm&gt; to use std STL.</span>
EA::StdC::Random rand(someSeedValue);
eastl::random_shuffle(myVector.begin(), myVector.end(), rand);</pre>
<p>How to fill a container or sequence with random double:</p>
<pre class="code-example">#include &lt;eastl/algorithm.h&gt; <span class="code-example-comment"> // or #include &lt;algorithm&gt; to use std STL.</span>
struct GenerateDouble
{ <br> EA::StdC::Random mRand; <span class="code-example-comment">// We need to make a tiny class that simply has</span> <br> <span class="code-example-comment">// an operator() member function that returns double.</span>
GenerateDouble(uint32_t seed) : mRand(seed){} <br>
double operator(){ mRand.RandomDoubleUniform(); }
};<br>
GenerateDouble randDouble(someSeedValue);<br>eastl::generate(myVector.begin(), myVector.end(), randDouble);</pre>
<hr>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p> </p>
</body></html>
+146
View File
@@ -0,0 +1,146 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type"
content="text/html; charset=ISO-8859-1">
<title>EAScanf</title>
<link type="text/css" rel="stylesheet"
href="UTFDoc.css">
<meta name="author" content="Paul Pedriana">
</head>
<body style="background-color: rgb(255, 255, 255);">
<h1>EAScanf</h1>
<h2>Introduction</h2>
<p>EAScanf provides a portable
version of the C scanf family of functions which improves on
the C family in the following ways:</p>
<ul>
<li>Behaves identically on all
platforms</li>
<li>Provides the full gamut of
scanf functions, including vsscanf</li>
<li>Is more efficient</li>
<li>Never allocates memory</li>
<li>Provides both 8 and 16 bit
versions for all platforms</li>
<li>Provides&nbsp;useful
extended functionality</li>
<li>Complies with the C99
standard (except for the %a format, as of this writing)</li>
<li>Is readable enough to be
traced/debugged by non-experts</li>
<li>Is savvy to UTF8 Unicode</li>
</ul>
<p>The primary disadvantages of
EAScanf are:</p>
<ul>
<li>It doesn't use
locale-specific formatting</li>
<li>It isn't part of the C/C++
standard library</li>
</ul>
<p>EAScanf doesn't attempt to
solve the locale formatting problem because users really are better off
using serious locale libraries for such things rather than using the
meager support provided by the C standard library. The EALocale library
attempts to provide such functionality.</p>
<p>EAScanf provides the
following functions in 8 and 16 bit versions:
</p>
<pre><span class="code-example">int Cscanf(ReadFunction8 pReadFunction8, void* pContext, const char8_t* pFormat, ...);
int Fscanf(FILE* pFile, const char8_t* pFormat, ...);
int Scanf(const char8_t* pFormat, ...);
int Sscanf(const char8_t* pTextBuffer, const char8_t* pFormat, ...);
int Cscanf(ReadFunction16 pReadFunction16, void* pContext, const char16_t* pFormat, ...);
int Fscanf(FILE* pFile, const char16_t* pFormat, ...);
int Scanf(const char16_t* pFormat, ...);
int Sscanf(const char16_t* pTextBuffer, const char16_t* pFormat, ...);
int Vcscanf(ReadFunction8 pReadFunction8, void* pContext, const char8_t* pFormat, va_list arguments);
int Vfscanf(FILE* pFile, const char8_t* pFormat, va_list arguments);
int Vscanf(const char8_t* pFormat, va_list arguments);
int Vsscanf(const char8_t* pTextBuffer, const char8_t* pFormat, va_list arguments);
int Vcscanf(ReadFunction16 pReadFunction16, void* pContext, const char16_t* pFormat, va_list arguments);
int Vfscanf(FILE* pFile, const char16_t* pFormat, va_list arguments);
int Vscanf(const char16_t* pFormat, va_list arguments);
int Vsscanf(const char16_t* pTextBuffer, const char16_t* pFormat, va_list arguments);</span></pre>
<blockquote> </blockquote>
<h2>Extended Functionality</h2>
<p> EAPrintf provides extended
format functionality not found in the C99 standard but which is useful
nevertheless:</p>
<table style="text-align: left; width: 100%;" border="1" cellpadding="2"
cellspacing="2">
<tbody>
<tr style="font-weight: bold;">
<td>Format</td>
<td>Description</td>
<td>Example</td>
<td>Example output</td>
</tr>
<tr style="font-weight: bold;">
<td><span style="font-weight: normal;">b</span></td>
<td style="font-weight: normal;">Binary
output field type (joins d, i, x, o, etc.).</td>
<td><span style="font-weight: normal;">sscanf(&quot;11111111&quot;, "%b", &amp;integer);</span></td>
<td><span style="font-weight: normal;">integer == 0xff </span></td>
</tr>
<tr>
<td>I8</td>
<td>8 bit integer field
modifier.</td>
<td><span style="font-weight: normal;">sscanf</span>(&quot;0xff&quot;, "%I8d"<span style="font-weight: normal;">, &amp;int8</span>);</td>
<td><span style="font-weight: normal;"><span style="font-weight: normal;">int8</span> == <span style="font-weight: normal;">0xff </span></span></td>
</tr>
<tr>
<td>I16</td>
<td>16 bit integer field
modifier.</td>
<td><span style="font-weight: normal;">sscanf</span>(&quot;0xffff&quot;, "%I16u"<span style="font-weight: normal;">, &amp;uint16</span>);</td>
<td><span style="font-weight: normal;"><span style="font-weight: normal;">uint16</span> == <span style="font-weight: normal;">0xffff</span></span></td>
</tr>
<tr>
<td>I32</td>
<td>32 bit integer field
modifier.</td>
<td><span style="font-weight: normal;">sscanf</span>(&quot;0xffffffff&quot;, "%I32d"<span style="font-weight: normal;">, &amp;int32</span>);</td>
<td><span style="font-weight: normal;"><span style="font-weight: normal;">int32</span> == <span style="font-weight: normal;">0xffff</span></span>ffff</td>
</tr>
<tr>
<td>I64</td>
<td>64 bit integer field
modifier.</td>
<td><span style="font-weight: normal;">sscanf</span>(&quot;0xffffffffffffffff&quot;, "%I64u"<span style="font-weight: normal;">, &amp;int64</span>);</td>
<td><span style="font-weight: normal;">int64</span> == -1 </td>
</tr>
<tr>
<td>I128</td>
<td>128 bit integer field
modifier.</td>
<td><span style="font-weight: normal;">sscanf</span>(&quot;0xffffffffffffffffffffffffffffffff&quot;, "%I128d"<span style="font-weight: normal;">, &amp;int128</span>);</td>
<td><span style="font-weight: normal;">int128</span> = -1</td>
</tr>
</tbody>
</table>
<h2>Example usage</h2>
<p>To do.<br>
</p>
<hr>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p> </p>
</body>
</html>
+298
View File
@@ -0,0 +1,298 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type"
content="text/html; charset=ISO-8859-1">
<title>EASprintf</title>
<link type="text/css" rel="stylesheet"
href="UTFDoc.css">
<meta name="author" content="Paul Pedriana">
</head>
<body style="background-color: rgb(255, 255, 255);">
<h1>EASprintf</h1>
<h2>Introduction</h2>
<p>EAStdC provides a portable
version of the C printf family of functions which improves on
the C family in the following ways:</p>
<ul>
<li>Behaves identically on all
platforms</li>
<li>Provides the full gamut of
printf functions, including vsnprintf</li>
<li>Is more efficient; executes 20-80% faster. </li>
<li>Never allocates memory</li>
<li>Provides both 8 and 16 bit
versions for all platforms</li>
<li>Provides&nbsp;useful
extended functionality</li>
<li>Complies with the C99
standard (except for the %a format, as of this writing)</li>
<li>Is readable enough to be
traced/debugged by non-experts</li>
<li>Is savvy to UTF8 Unicode</li>
</ul>
<p>The primary disadvantages of
EAStdC's printf are:</p>
<ul>
<li>It doesn't use
locale-specific formatting</li>
<li>It isn't part of the C/C++
standard library</li>
</ul>
<p>EAStdC doesn't attempt to
solve the locale formatting problem because users really are better off
using serious locale libraries for such things rather than using the
meager support provided by the C standard library. The EALocale library
attempts to provide such functionality.</p>
<p>EAStdC provides the
following functions in 8, 16, and 32 bit versions:
</p>
<pre><span class="code-example">int Cprintf(WriteFunction8 pWriteFunction, void* pContext, const char8_t* pFormat, ...);
int Fprintf(FILE* pFile, const char8_t* pFormat, ...);
int Printf(const char8_t* pFormat, ...);
int Sprintf(char8_t* pDestination, const char8_t* pFormat, ...);
int Snprintf(char8_t* pDestination, size_t n, const char8_t* pFormat, ...);
int Vcprintf(WriteFunction8 pWriteFunction8, void* pContext, const char8_t* pFormat, va_list arguments);
int Vfprintf(FILE* pFile, const char8_t* pFormat, va_list arguments);
int Vprintf(const char8_t* pFormat, va_list arguments);
int Vsprintf(char8_t* pDestination, const char8_t* pFormat, va_list arguments);
int Vsnprintf(char8_t* pDestination, size_t n, const char8_t* pFormat, va_list arguments);<br>int Vscprintf(const char8_t* EA_RESTRICT pFormat, va_list arguments);</span></pre>
<p>Also there are:</p>
<pre class="code-example">template &lt;typename String&gt;
int StringPrintf(String&amp; s, const typename String::value_type* EA_RESTRICT pFormat, ...);</pre>
<pre class="code-example">template &lt;typename String&gt;
int StringVcprintf(String&amp; s, const typename String::value_type* EA_RESTRICT pFormat, va_list arguments);</pre>
<blockquote></blockquote>
<h2>Snprintf uses C99 behavior</h2>
<p> The EASprintf 'n' functions (Snprintf and Vsnprintf) follow the C99 standard
for return value, which is different from some C standard library implementations
such as VC++. These functions return the number of characters that would have
been written had n been sufficiently large, not counting the terminating null
character, or a negative value if an encoding error occurred. Thus, the null-terminated
output has been completely written if and only if the returned value is nonnegative
and less than n. Another way of saying it is that the return value equal to
the strlen of the intended output. See the examples below.</p>
<h2>Watch out for common mistakes and security problems</h2>
<p> The sprintf family of functions are very convenient but offer numerous opportunities
for incorrect usage and security problems. Here is a list of some of the most
common issues.</p>
<ul>
<li>Don't use sprintf unless you are absolutely certain the result will fit
into the output buffer. Instead use snprintf.</li>
<li>When printing a string, always use <font face="Courier New, Courier, mono" size="-1">printf(&quot;%s&quot;,
pStr)</font> and never <font face="Courier New, Courier, mono" size="-1">printf(pStr)</font>,
as the latter may have formatting characters in it.</li>
<li>Watch out for platform differences between format types. For example, %u
means unsigned int, and you can't use a size_t argument with it on 64 bit
platforms. Instead, explicitly cast your arguments to the expected type or
use the EASprintf extended format types (see below).</li>
<li>Similarly, watch out when passing int8_t and int16_t arguments to EAPrintf
(and regular printf), as the compiler will promote them to int and they might
not print as you expected, depending on your output format.</li>
<li>Watch out for EASprintf's C99 behaviour. C99 behaviour is standard C and
is superior to previous C library behaviour, but the previous behaviour exists
in the C library today with compilers such as VC++. This behaviour affects
the return value of Snprintf/Vsnprintf, and affects the way some format specifiers
are rendered.</li>
</ul>
<h2>Extended Functionality</h2>
<p> Printf provides extended
format functionality not found in the C99 standard but which is useful
nevertheless:</p>
<table style="text-align: left; width: 100%;" border="1" cellpadding="2"
cellspacing="2">
<tbody>
<tr style="font-weight: bold;">
<td>Format/modifier</td>
<td>Description</td>
<td>Example</td>
<td>Example output</td>
</tr>
<tr style="font-weight: bold;">
<td><span style="font-weight: normal;">b</span></td>
<td style="font-weight: normal;">Binary
output field type (joins d, i, x, o, etc.).</td>
<td><span class="code-example-span">printf("0b%b", 255);<br>
printf<span style="font-weight: normal;">("%<span style="font-weight: normal;"><span style="font-weight: normal;">#</span></span>b", 255);</span></span> <span class="code-example-span"><br>
<span style="font-weight: normal;">printf<span style="font-weight: normal;">("%<span style="font-weight: normal;"><span style="font-weight: normal;">#</span></span>B", 255);</span> </span></span> </td>
<td><span class="code-example-span">0b11111111<br>
<span style="font-weight: normal;">0b11111111</span></span> <span class="code-example-span"><br>
<span style="font-weight: normal;"><span style="font-weight: normal;">0B11111111</span> </span></span></td>
</tr>
<tr>
<td>I8</td>
<td>8 bit integer field
modifier.</td>
<td class="code-example-span">printf("%I8d", 0xff);</td>
<td class="code-example-span">-1</td>
</tr>
<tr>
<td>I16</td>
<td>16 bit integer field
modifier.</td>
<td class="code-example-span">printf("%I16u", 0xffff);</td>
<td class="code-example-span">65535</td>
</tr>
<tr>
<td>I32</td>
<td>32 bit integer field
modifier.</td>
<td class="code-example-span">printf("%I32d",
0xffffffff);</td>
<td class="code-example-span">-1</td>
</tr>
<tr>
<td>I64</td>
<td>64 bit integer field
modifier.</td>
<td class="code-example-span">printf("%I64u",
0xffffffffffffffff);</td>
<td class="code-example-span">18446744073709551615</td>
</tr>
<tr>
<td>I128</td>
<td>128 bit integer field
modifier.</td>
<td class="code-example-span">printf("%I128d",
0xffffffffffffffffffffffffffffffff);</td>
<td class="code-example-span">-1</td>
</tr>
<tr>
<td>'</td>
<td>Display a thousands separator.</td>
<td class="code-example-span">printf("%'I16u", 0xffff);</td>
<td class="code-example-span">65,535</td>
</tr>
</tbody>
</table>
<h2>SprintfOrdered</h2>
<p>EAStdC also provides an ordered sprintf</p>
<p>Ordered printf is like printf except it works on &quot;ordered&quot; printf specifiers. This means that instead of using &quot;%4d %f&quot; we give an order to the arguments via an index and colon, as with &quot;%1:4d %2:f&quot;. The point, however, is that you can reorder the indexes, as with &quot;%2:f %1:4d&quot;. This is particularly useful for formatted string localization, as different locales use subjects and verbs in different orders.<br>
<br>
User indexes can start at either 0 or 1. Oprintf detects which is in use as it goes. So the following have identical effect:</p>
<pre class="code-example">OPrintf(&quot;%1:s&quot; %0:f&quot;, 3.0, &quot;hello&quot;);
OPrintf(&quot;%2:s&quot; %1:f&quot;, 3.0, &quot;hello&quot;);</pre>
<p> // User indexes must be contiguous and the behaviour of Oprintf is undefined<br>
// if the ordering is non-contiguous. There are debug checks to validate <br>
// contiguity, so debug tests should catch mistakes. The following is an <br>
// example of non-contiguous ordering, as it is missing a &quot;3:&quot; format:<br>
// OPrintf(&quot;%1:d&quot; %0:d %3:d&quot;, 17, 18, 19, 20);<br>
</p>
<p>Example usage:</p>
<pre><span class="code-example">char16_t buffer[80];</span></pre>
<p>// The module provides ordered versions of the printf family of functions:<br>
// int OCprintf(WriteFunction pFunction, void* pContext, const char_t* pFormat, ...);<br>
// int OFprintf(FILE* pFile, const char_t* pFormat, ...);<br>
// int OPrintf(cconst char_t* pFormat, ...);<br>
// int OSprintf(char_t* pDestination, const char_t* pFormat, ...);<br>
// int OSnprintf(char_t* pDestination, size_t n, const char_t* pFormat, ...);<br>
//<br>
// int OVcprintf(WriteFunction pFunction, void* pContext, const char_t* pFormat, va_list arguments);<br>
// int OVfprintf(FILE* pFile, const char_t* pFormat, va_list arguments);<br>
// int OVprintf(const char_t* pFormat, va_list arguments);<br>
// int OVsprintf(char_t* pDestination, const char_t* pFormat, va_list arguments);<br>
// int OVsnprintf(char_t* pDestination, size_t n, const char_t* pFormat, va_list arguments);<br>
// int OVscprintf(const char* pFormat, va_list arguments);<br>
//<br>
// Ordered printf is like printf except it works on &quot;ordered&quot; printf specifiers.<br>
// This means that instead of using &quot;%4d %f&quot; we give an order to the arguments via <br>
// an index and colon, as with &quot;%1:4d %2:f&quot;. The point, however, is that you can <br>
// reorder the indexes, as with &quot;%2:f %1:4d&quot;. This is particularly useful for <br>
// formatted string localization, as different locales use subjects and verbs<br>
// in different orders.<br>
//<br>
// User indexes can start at either 0 or 1. Oprintf detects which is in use as <br>
// it goes. So the following have identical effect:<br>
// OPrintf(&quot;%1:s&quot; %0:f&quot;, 3.0, &quot;hello&quot;);<br>
// OPrintf(&quot;%2:s&quot; %1:f&quot;, 3.0, &quot;hello&quot;);<br>
//<br>
// User indexes must be contiguous and the behaviour of Oprintf is undefined<br>
// if the ordering is non-contiguous. There are debug checks to validate <br>
// contiguity, so debug tests should catch mistakes. The following is an <br>
// example of non-contiguous ordering, as it is missing a &quot;3:&quot; format:<br>
// OPrintf(&quot;%1:d&quot; %0:d %3:d&quot;, 17, 18, 19, 20);<br>
/////////////////////////////////////////////////////////////////////////////<br>
</p>
<h2>Example usage</h2>
<p>All examples presume the #include of EASprintf.h.</p>
<p>Snprintf usage:</p>
<pre><span class="code-example">char16_t buffer[80];
int nStrlen = Snprintf16(buffer, 80, &quot;Columbus arrived in %d.&quot;, 1492);
if((unsigned)nStrlen &lt; 80) // Cast to unsigned in order to make any negative values be positive and &gt; 80.
puts(&quot;success&quot;);</span></pre>
<p>How to write a function that takes variable arguments (e.g. ...) and passes
them to EASprintf:</p>
<pre><span class="code-example">#include &lt;stdarg.h&gt;
void CustomFormattedOutput(const char* pFormat, ...)
{
va_list arguments;
va_start(arguments, pFormat);
Vprintf8(pFormat, arguments);
va_end(arguments);
}</span></pre>
<p>How to write a function that does custom formatted output to a buffer that
is resized as needed for it. This is useful for the implementation of fail-safe
utility functions and for debug tracing systems, among other things.</p>
<pre><span class="code-example">#include &lt;stdarg.h&gt;
#include &lt;string&gt;
<span class="code-example-comment">// This is a generic function for doing a sprintf into a C++ std::string object.
// If the string object lacks enough space for the output, then the string will
// be resized to exactly fit the output.
</span>size_t StringSprintf(std::string&amp; s, const char* pFormat, ...)
{
va_list arguments;
va_start(arguments, pFormat);
if(s.size() &lt; s.capacity())
s.resize(s.capacity());
const int nStrlen = Vsnprintf8(const_cast&lt;char*&gt;(s.data()), s.capacity() + 1, pFormat, arguments);
va_end(arguments);
if(nStrlen &gt; (int)s.size())
{
s.resize(nStrlen);
Vsnprintf8(const_cast&lt;char*&gt;(s.data()), s.capacity() + 1, pFormat, arguments);
return (size_t)nStrlen;
}</span></pre>
<p>Write to the C stderr stream:</p>
<pre><span class="code-example">#include &lt;stdio.h&gt;
Fprintf8(stderr, &quot;Columbus arrived in %d.&quot;, 1492);</span></pre>
<p>Vsscanf usage. A complete discussion of the ins and outs of vsscanf are currently
beyond the scope of this document. The scanf found in EAPrintf acts the same
as with the C++ standard, so you can read about that elsewhere for the time
being.</p>
<pre><span class="code-example">char16_t buffer[64] = EAText16(&quot;Columbus arrived in 1492&quot;);
int year;
Vsscanf16(buffer, &quot;Columbus arrived in %d.&quot;, &amp;year);</span></pre>
<h2>Interface</h2>
<p>Printf family</p>
<pre><span class="code-example">int Fprintf8(FILE* pFile, const char8_t* pFormat, ...);<br>int Printf8(const char8_t* pFormat, ...);<br>int Sprintf8(char8_t* pDestination, const char8_t* pFormat, ...);<br>int Snprintf8(char8_t* pDestination, size_t n, const char8_t* pFormat, ...);<br><br>int Fprintf16(FILE* pFile, const char16_t* pFormat, ...);<br>int Printf16(const char16_t* pFormat, ...);<br>int Sprintf16(char16_t* pDestination, const char16_t* pFormat, ...);<br>int Snprintf16(char16_t* pDestination, size_t n, const char16_t* pFormat, ...);<br></span></pre>
<p>Vprintf family</p>
<pre><span class="code-example"><span class="code-example-comment">/// Note that vsnprintf was not added to the C standard until C99.<br>/// Here we follow the C99 standard and have the return value of vsnprintf <br>/// return the number of required characters to complete the formatted string.<br>/// This is more useful than the way some libraries implement vsnprintf by <br>/// returning -1 if there isn't enough space. The return value is -1 if there <br>/// was an "encoding error" or the implementation was unable to return a <br>/// value &gt; n upon lack of sufficient space as per the C99 standard.<br>///<br>/// Specification:<br>/// The vsnprintf function is equivalent to snprintf, with the variable <br>/// argument list replaced by arguments, which shall have been initialized <br>/// by the va_start macro (and possibly subsequent va_arg calls). <br>/// The vsnprintf function does not invoke the va_end macro. If copying <br>/// takes place between objects that overlap, the behavior is undefined.<br>///<br>/// The vsnprintf function returns the number of characters that would <br>/// have been written had n been sufficiently large, not counting the <br>/// terminating null character, or a neg ative value if an encoding error <br>/// occurred. Thus, the null-terminated output has been completely written <br>/// if and only if the returned value is nonnegative and less than n.<br>///<br></span>int Vfprintf8(FILE* pFile, const char8_t* pFormat, va_list arguments);<br>int Vprintf8(const char8_t* pFormat, va_list arguments);<br>int Vsprintf8(char8_t* pDestination, const char8_t* pFormat, va_list arguments);<br>int Vsnprintf8(char8_t* pDestination, size_t n, const char8_t* pFormat, va_list arguments);<br><br>int Vfprintf16(FILE* pFile, const char16_t* pFormat, va_list arguments);<br>int Vprintf16(const char16_t* pFormat, va_list arguments);<br>int Vsprintf16(char16_t* pDestination, const char16_t* pFormat, va_list arguments);<br>int Vsnprintf16(char16_t* pDestination, size_t n, const char16_t* pFormat, va_list arguments);<br></span><br>
</pre>
<hr>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p> </p>
</body>
</html>
Binary file not shown.
+81
View File
@@ -0,0 +1,81 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<Title>EAStdC</title>
<link type="text/css" rel="stylesheet" href="UTFDoc.css">
<meta name="author" content="Paul Pedriana">
</head>
<body bgcolor="#FFFFFF">
<h1>EAStdC</h1>
<p>EAStdC is a package which implements a number of basic library facilities that are similar to those in the standard C library. This does not mean that its functionality is identical to the C standard library. It is an evolution and convergence of the rwstdc and UTFFoundation packages. </p>
<p>The fundamental design characteristics of EAStdC are:</p>
<ul>
<li>The package has minimal dependencies: EABase and EAAssert.</li>
<li>It consists of simple standalone functions and classes.</li>
<li>Memory is not allocated by any of the functions or classes, excepts possibly under pathological conditions.</li>
<li>There is no thread-safety. All thread safety must be coordinated at a higher level by the user. </li>
<li>It does not implement localization functionality. Localization functionality is left to specialized libraries for that purpose.</li>
<li>With few exceptions, both char8_t and char16_t string functionality are supported equivalently.</li>
</ul>
<h3> Should you use EAStdC functions that overlap with Standard C library functions?</h3>
<p>A primary purpose of EAStdC is to provide a portable implementation of basic utility functions, many of which correspond the standard C library functions. Specifically: </p>
<ul>
<li> Provide a standardizes portable header file to #include. </li>
<ul>
<li> e.g. C libraries don&rsquo;t use the same name for headers, such as malloc.h, sys/types.h, memory.h, etc. </li>
</ul>
<li> Provide standardized function names. </li>
<ul>
<li> e.g. EAStdC has Vsnprintf, as opposed to VC++ having _vsnprintf but GCC having vsnprintf. </li>
</ul>
<li> Provide standardized function implementations. </li>
<ul>
<li> e.g. Sprintf/Scanf work the same in EAStdC, unlike most C libraries. </li>
</ul>
<li> Provide faster versions. </li>
<ul>
<li> e.g. Faster strlen, memcpy, special fast memcpy versions. EAStdC sprintf is much faster than stdc. </li>
</ul>
<li> Provide versions that don&rsquo;t exist in compiler-provided libraries. </li>
<ul>
<li> e.g. EAStdC has vsnprintf, whereas some C libraries don&rsquo;t. </li>
</ul>
<li> Lower memory requirements. </li>
<ul>
<li> Some stdc functions tend to bring in a lot of object code, often because of their locale requirements. </li>
</ul>
<li> Provides consistent standardized encoding. </li>
<ul>
<li> EAStdC uses UTF8 for char8_t and UCS2 for char16_t, whereas C libraries aren&rsquo;t consistent. wchar_t could be 8, 16, or 32 bit (we&rsquo;ve seen each of these). </li>
</ul>
<li> Provide auxiliary or &ldquo;better&rdquo; versions of functions. </li>
<ul>
<li> e.g. EAStdC&rsquo;s Random, DateTime. </li>
</ul>
<li> EAStdC has additional functionality that doesn&rsquo;t directly match something from the Standard C library. </li>
<ul>
<li> e.g. Stopwatch, Hash, FixedPoint. </li>
</ul>
</ul>
<p> Primary downsides to EAStdC: </p>
<ul>
<li> It doesn&rsquo;t have localization support. You can&rsquo;t call setlocale() with it and have it change how it interprets &ldquo;.&rdquo; And &ldquo;,&rdquo; in numbers. You need to use the EALocale or EAText package for that, though EALocale and EAText do a better job than stdc does. </li>
<li> EAStdC might have bugs that haven&rsquo;t been eradicated, while most stdc implementations are pretty good. </li>
<li> Stdc has better documentation, though the EAStdC functions that are stdc equivalents usually have the same specification. </li>
</ul>
<p> In the case of overlap between stdc and EAStdC, I think the policy of what to use depends on your team conventions and your project requirements. Some notes: </p>
<ul>
<li> If you want to guarantee portability then you&rsquo;re better off using EAStdC. </li>
<li> Some functions (e.g. strlen and memcpy) are basic enough that the stdc versions are usually fine. </li>
<ul>
<li> Except EAStdC&rsquo;s Strlen is faster than most stdc versions, and a surprising number of memcpy implementations for uncommon platforms are slow. </li>
</ul>
<li> If you think your code will need to build outside our codebase then maybe you should try to stick with stdc. </li>
</ul>
<hr>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
</body>
</html>
+289
View File
@@ -0,0 +1,289 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<title>EARandom</title>
<link type="text/css" rel="stylesheet" href="UTFDoc.css">
<meta name="author" content="Paul Pedriana">
</head>
<body bgcolor="#FFFFFF">
<h1>EAStopwatch</h1>
<h2>Introduction</h2>
<p>EAStopwatch provides timing facilities for use in game development. It provides
two C++ classes:</p>
<blockquote>
<table width="100%" border="1">
<tr>
<td>Stopwatch</td>
<td>A general-purpose timer</td>
</tr>
<tr>
<td>LimitStopwatch</td>
<td>A special-purpose countdown-style timer</td>
</tr>
</table>
</blockquote>
<p>Stopwatch acts much like and classic hand-held stopwatch or like the stopwatch
found on sports watches. It has additional flexibility, such as the ability
to set an elapsed time to any value.</p>
<p>LimitStopwatch is a stopwatch which simply tells you if a given amount of time
has passed. You can accomplish this same functionality by polling a Stopwatch,
but LimitStopwatch is more efficient.</p>
<h2>Important things to remember</h2>
<ul>
<li> You won't get very accurate timings if you use a millisecond stopwatch
repeatedly to time tiny sections of code that take only nanoseconds.</li>
<li>You can start and stop a stopwatch repeatedly and it will do the right thing,
which is sum up the times during which it was running.</li>
<li>Timing CPU cycles (clock ticks) accurately can be hard if you are trying
to time very small pieces of code. Pipeline stalls and memory stalls can result
in highly variable results.</li>
<li>A running stopwatch consumes no resources (CPU cycles nor memory) during
its existence nor while it is running.</li>
<li>You don't have to stop a stopwatch that is running; it doesn't take up CPU
time to be running. It is not an error to not stop a stopwatch.</li>
<li>There is a distinction between stopwatch cycles and CPU-based cycles. While
it may be the case that the stopwatch uses a CPU cycle counter as its basis,
this also may not be the case. In fact, using a CPU cycles counter as the
basis for a stopwatch is often a dangerous thing to do because processors
these days will sometimes switch frequencies on the fly. </li>
<li>You don't have to worry about multi-processor issues unless you are running
on a desktop platform such as Windows. In the case of such platforms, you
only need to worry about such issues if you happen to define EA_STOPWATCH_FORCE_CPU_CYCLE_USAGE = 1.</li>
<li>You can call safely GetElapsedTime while the stopwatch is running; it will
simply return the currently elapsed time.</li>
<li>The construction and destruction instances of Stopwatch is fast; don't worry
about it. Similarly, a Stopwatch instance is small in size.</li>
</ul>
<h2>Example usage </h2>
<p>EAStopwatch is very easy to use, though curiously its simplicity actually confuses
some users familiar with more cumbersome alternatives.</p>
<p>Basic usage:</p>
<pre class="code-example">Stopwatch stopwatch(Stopwatch::kUnitsMilliseconds);
stopwatch.Start();
DoSomethingThatYouWantToMeasure();
printf("Time to do something: %u.\n", stopwatch.GetElapsedTime());</pre>
Example of stopwatch reuse (via Restart):
<pre class="code-example">Stopwatch stopwatch(Stopwatch::kUnitsCycles, true); // Note that 'true' tells the timer to auto-start here.
DoSomethingSmall();
printf("Time to do something small: %u.\n", stopwatch.GetElapsedTime());
stopwatch.Restart();
DoSomethingElseSmall();
printf("Time to do something else small: %d.\n", stopwatch.GetElapsedTime());</pre>
Example of SetElapsedTime usage.
<pre class="code-example">Stopwatch stopwatch(Stopwatch::kUnitsMilliseconds);
stopwatch.SetElapsedTime(100); // Give the stopwatch a &quot;100 ms head start.&quot;
stopwatch.Start();
printf("This should print out 100 (or maybe 101): %u.\n", stopwatch.GetElapsedTime());</pre>
<p>Example of LimitStopwatch usage:</p>
<pre class="code-example">LimitStopwatch limitStopwatch(Stopwatch::kUnitsMilliseconds, 1000, true);
while(!limitStopwatch.IsTimeUp())
printf("waiting\n"); </pre>
<h2>Don't do this!</h2>
<p> It seems that quite often people unfamiliar with a C++ stopwatch tend to revert
away from using the stopwatch as it was designed and try to do timings manually,
like shown below. The code below is more complicated than it needs to be and
is less precise than it can be, as the high internal resolution of the stopwatch
is lost when using it like this. </p>
<pre class="code-example"><font color="#CC0000">Stopwatch stopwatch(Stopwatch::kUnitsMilliseconds);
stopwatch.Start();
uint64_t timeStart = stopwatch.GetElapsedTime();
DoSomething();
uint64_t timeElapsed = stopwatch.GetElapsedTime() - time;</font>
</pre>
<h2>Interface </h2>
<p>Stopwatch</p>
<pre class="code-example">class Stopwatch
{
public:
<span class="code-example-comment"> /// Units
/// Defines common timing units plus a user-definable set of units.
</span> enum Units
{
kUnitsCycles = 0, <font color="#999999">/// Stopwatch clock ticks. </font>
kUnitsCPUCycles = 1, <font color="#999999">/// CPU clock ticks (or similar equivalent for the platform).</font>
kUnitsNanoseconds = 2, <font color="#999999">/// Count in nanoseconds.</font>
kUnitsMicroseconds = 3, <font color="#999999">/// Count in microseconds.</font>
kUnitsMilliseconds = 4, <font color="#999999">/// Count in milliseconds.</font>
kUnitsSeconds = 5, <font color="#999999">/// Count in seconds.</font>
kUnitsMinutes = 6, <font color="#999999">/// Count in minutes.</font>
kUnitsUserDefined = 1000 <font color="#999999">/// User defined units (animation frames, video vertical retrace, etc.).</font>
};
public:
<span class="code-example-comment"> /// Stopwatch
/// Constructor for Stopwatch, allows user to specify units.
/// If units are kUnitsUserDefined, you'll need to either subclass
/// Stopwatch and implement GetUserDefinedStopwatchCycle or call
/// SetUserDefinedUnitsToStopwatchCyclesRatio in order to allow it
/// to know how to convert units.
</span> explicit Stopwatch(int nUnits = kUnitsCycles, bool bStartImmediately = false);
<span class="code-example-comment"> /// Stopwatch
/// Copy constructor.
</span> Stopwatch(const Stopwatch& stopwatch);
<span class="code-example-comment"> /// ~Stopwatch
/// Destructor.
</span> ~Stopwatch();
<span class="code-example-comment"> /// operator=
/// Assignment operator.
</span> Stopwatch& operator=(const Stopwatch& stopwatch);
<span class="code-example-comment"> /// GetUnits
/// Gets the current units. Returns one of enum Units or kUnitsUserDefined+.
</span> int GetUnits() const;
<span class="code-example-comment"> /// SetUnits
/// Sets the current units. One of enum Units or kUnitsUserDefined+.
</span> void SetUnits(int nUnits);
<span class="code-example-comment"> /// Start
/// Starts the stopwatch. Continues where it was last stopped.
/// Does nothing if the stopwatch is already started.
</span> void Start();
<span class="code-example-comment"> /// Stop
/// Stops the stopwatch it it was running and retaines the elasped time.
</span> void Stop();
<span class="code-example-comment"> /// Reset
/// Stops the stopwatch if it was running and clears the elapsed time.
</span> void Reset();
<span class="code-example-comment"> /// Restart
/// Clears the elapsed time and starts the stopwatch if it was not
/// already running. Has the same effect as Reset(), Start().
</span> void Restart();
<span class="code-example-comment"> /// IsRunning
/// Returns true if the stopwatch is running.
</span> bool IsRunning() const;
<span class="code-example-comment"> /// GetElapsedTime
/// Gets the elapsed time, which properly takes into account any
/// intervening stops and starts. Works properly whether the stopwatch
/// is running or not.
</span> uint64_t GetElapsedTime() const;
<span class="code-example-comment"> /// SetElapsedTime
/// Allows you to set the elapsed time. Erases whatever is current.
/// Works properly whether the stopwatch is running or not.
</span> void SetElapsedTime(uint64_t nElapsedTime);
<span class="code-example-comment"> /// GetElapsedTimeFloat
/// Float version, which is useful for counting fractions of
/// seconds or possibly milliseconds.
</span> float GetElapsedTimeFloat() const;
<span class="code-example-comment"> /// SetElapsedTimeFloat
/// Allows you to set the elapsed time. Erases whatever is current.
/// Works properly whether the stopwatch is running or not.
</span> void SetElapsedTimeFloat(float fElapsedTime);
<span class="code-example-comment"> /// SetCyclesPerUnit
/// Allows the user to manually override the frequency of the
/// timer.
</span> void SetCyclesPerUnit(float fCyclesPerUnit);
<span class="code-example-comment"> /// GetCyclesPerUnit
/// Returns the value number of cycles per unit. If the user
/// set a manual value via SetCyclesPerUnit, this function returns
/// that value.
</span> float GetCyclesPerUnit() const;
<span class="code-example-comment"> /// GetStopwatchCycle
/// Gets the current stopwatch cycle on the current machine.
/// Note that a stopwatch cyle may or may not be the same thing
/// as a CPU cycle. We provide the distinction between stopwatch
/// cycles and CPU cycles in order to accomodate platforms (e.g.
/// desktop platforms) in which CPU cycle counting is unreliable.
</span> static uint64_t GetStopwatchCycle();
<span class="code-example-comment"> /// GetStopwatchFrequency
/// Note that the stopwatch freqency may or may not be the same thing
/// as the CPU freqency. We provide the distinction between stopwatch
/// cycles and CPU cycles in order to accomodate platforms (e.g.
/// desktop platforms) in which CPU cycle counting is unreliable.
</span> static uint64_t GetStopwatchFrequency();
<span class="code-example-comment"> /// GetUnitsPerStopwatchCycle
/// Returns the number of stopwatch cycles per the given unit.
/// If the unit is seconds, the return value would be the frequency of
/// the stopwatch timer and thus be the same value as returned by
/// GetStopwatchFrequency().
</span> static float GetUnitsPerStopwatchCycle(Units units);
<span class="code-example-comment"> /// GetCPUCycle
/// Gets the current CPU-based timer cycle on the current processor
/// (if in a multiprocessor system). Note that this doesn't necessarily
/// get the actual machine CPU clock cycle; rather it returns the
/// CPU-based timer cycle. One some platforms the CPU-based timer is
/// a 1:1 relation to the CPU clock, while on others it is some multiple
/// of it.
</span> static uint64_t GetCPUCycle();
<span class="code-example-comment"> /// GetCPUFrequency
/// Gets the frequency of the CPU-based timer. Note that this doesn't
/// necessarily get the actual machine CPU clock frequency; rather it returns
/// the CPU-based timer frequency. One some platforms the CPU-based timer is
/// a 1:1 relation to the CPU clock, while on others it is some multiple of it.
</span> static uint64_t GetCPUFrequency();
<span class="code-example-comment"> /// GetUnitsPerCPUCycle
/// Returns the number of CPU cycles per the given unit.
/// If the unit is seconds, the return value would be the frequency
/// of the CPU-based timer.
</span> static float GetUnitsPerCPUCycle(Units units);
};
</pre>
<p>LimitStopwatch</p>
<pre class="code-example">class LimitStopwatch : public Stopwatch
{
public:
<span class="code-example-comment"> /// LimitStopwatch
/// Constructor
</span> LimitStopwatch(int nUnits = kUnitsCycles, uint32_t nLimit = 0, bool bStartImmediately = false);
<span class="code-example-comment"> /// SetTimeLimit
/// Sets the time limit and lets you start the stopwatch at the same time.
</span> void SetTimeLimit(uint32_t nLimit, bool bStartImmediately = false);
<span class="code-example-comment"> /// IsTimeUp
/// Returns true if the limit has been reached. Highly efficient.
</span> bool IsTimeUp();
<span class="code-example-comment"> /// GetTimeRemaining
/// More expensive than IsTimeUp, as it returns a value.
</span> int64_t GetTimeRemaining();
<span class="code-example-comment"> /// GetTimeRemainingFloat
/// More expensive than IsTimeUp, as it returns a value.
</span> float GetTimeRemainingFloat();
};</pre>
<hr>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p> </p>
</body></html>
+298
View File
@@ -0,0 +1,298 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<Title>EAString</title>
<link type="text/css" rel="stylesheet" href="UTFDoc.css">
<meta name="author" content="Paul Pedriana">
</head>
<body bgcolor="#FFFFFF">
<h1>EAString</h1>
<h2>Introduction</h2>
<p>EAString implements an extensive suite of C string functionality from &lt;string.h&gt; in a portable way. Much of this functionality is the same as what
is present in the C standard and in common (but non-portable) extensions to the C standard. EAString presents a consistent portable interface to its functionality
in both 8 bit and 16 bit string form.</p>
<p>The C language provides various functions which work with non-portable data types, such as long. EAString defines all significant data types in terms of portable
types such as int32_t and int64_t. Additionally, the EAString versions of functions are usually faster than the C runtime library versions, usually because the EAString versions minimize cache misses
and branching, whereas typical C runtime libraries optimize for the smallest memory footprint with little or no regard to other performance characteristics. Also, the EAString functions do not implement locale-specific functionality and thus save time and space as a result. Other packages within EA implement localization functionality in a way that is better suited to high performance game development.</p>
<p>C-style printf functionality is separate from EAString and is found in <a href="EASprintf.html">EASprintf</a>. Memcpy functionality (which comes from the &lt;string.h&gt;
header file) is present in <a href="EAMemory.html">EAMemory</a>. </p>
<h2>Extension functions</h2>
<p> EAString provides extended functionality that isn't found in conventional C libraries, but it useful nevertheless.</p>
<table width="100%" border="1" cellpadding="3">
<tr>
<td><b>Function</b></td>
<td><b>Description</b></td>
<td><b>Signature</b></td>
</tr>
<tr>
<td>Strlcat</td>
<td>Safe variation of strncat</td>
<td><font size="-1">char_t* Strlcat(char_t* pDestination, const char_t* pSource, size_t n); </font></td>
</tr>
<tr>
<td>Strlcpy</td>
<td>Safe variation of strcpy</td>
<td><p><font size="-1">char_t* Strlcpy(char_t* pDestination, const char_t* pSource, size_t n); <br>
int Strlcpy(char16_t* pDestination, const char8_t* pSource, size_t nDestCapacity, size_t nSourceLength = (size_t)~0);<br>
int Strlcpy(char32_t* pDestination, const char8_t* pSource, size_t nDestCapacity, size_t nSourceLength = (size_t)~0);<br>
int Strlcpy(char8_t* pDestination, const char16_t* pSource, size_t nDestCapacity, size_t nSourceLength = (size_t)~0);<br>
int Strlcpy(char32_t* pDestination, const char16_t* pSource, size_t nDestCapacity, size_t nSourceLength = (size_t)~0);<br>
int Strlcpy(char8_t* pDestination, const char32_t* pSource, size_t nDestCapacity, size_t nSourceLength = (size_t)~0);<br>
int Strlcpy(char16_t* pDestination, const char32_t* pSource, size_t nDestCapacity, size_t nSourceLength = (size_t)~0); <br>
int Strlcpy(char8_t* pDestination, const wchar_t* pSource, size_t nDestCapacity, size_t nSourceLength = (size_t)~0);<br>
int Strlcpy(char16_t* pDestination, const wchar_t* pSource, size_t nDestCapacity, size_t nSourceLength = (size_t)~0); <br>
int Strlcpy(char32_t* pDestination, const wchar_t* pSource, size_t nDestCapacity, size_t nSourceLength = (size_t)~0);<br>
int Strlcpy(wchar_t* pDestination, const char8_t* pSource, size_t nDestCapacity, size_t nSourceLength = (size_t)~0);<br>
int Strlcpy(wchar_t* pDestination, const char16_t* pSource, size_t nDestCapacity, size_t nSourceLength = (size_t)~0); <br>
int Strlcpy(wchar_t* pDestination, const char32_t* pSource, size_t nDestCapacity, size_t nSourceLength = (size_t)~0);<br>
bool Strlcpy(char16_t* pDestination, const char8_t* pSource, size_t nDestCapacity, size_t nSourceLength, size_t&amp; nDestUsed, size_t&amp; nSourceUsed);<br>
bool Strlcpy(char32_t* pDestination, const char8_t* pSource, size_t nDestCapacity, size_t nSourceLength, size_t&amp; nDestUsed, size_t&amp; nSourceUsed);<br>
bool Strlcpy(char8_t* pDestination, const char16_t* pSource, size_t nDestCapacity, size_t nSourceLength, size_t&amp; nDestUsed, size_t&amp; nSourceUsed);<br>
bool Strlcpy(char32_t* pDestination, const char16_t* pSource, size_t nDestCapacity, size_t nSourceLength, size_t&amp; nDestUsed, size_t&amp; nSourceUsed);<br>
bool Strlcpy(char8_t* pDestination, const char32_t* pSource, size_t nDestCapacity, size_t nSourceLength, size_t&amp; nDestUsed, size_t&amp; nSourceUsed);<br>
bool Strlcpy(char16_t* pDestination, const char32_t* pSource, size_t nDestCapacity, size_t nSourceLength, size_t&amp; nDestUsed, size_t&amp; nSourceUsed);<br>
bool Strlcpy(char8_t* pDestination, const wchar_t* pSource, size_t nDestCapacity, size_t nSourceLength, size_t&amp; nDestUsed, size_t&amp; nSourceUsed);<br>
bool Strlcpy(char16_t* pDestination, const wchar_t* pSource, size_t nDestCapacity, size_t nSourceLength, size_t&amp; nDestUsed, size_t&amp; nSourceUsed);<br>
bool Strlcpy(char32_t* pDestination, const wchar_t* pSource, size_t nDestCapacity, size_t nSourceLength, size_t&amp; nDestUsed, size_t&amp; nSourceUsed);<br>
bool Strlcpy(wchar_t* pDestination, const char8_t* pSource, size_t nDestCapacity, size_t nSourceLength, size_t&amp; nDestUsed, size_t&amp; nSourceUsed);<br>
bool Strlcpy(wchar_t* pDestination, const char16_t* pSource, size_t nDestCapacity, size_t nSourceLength, size_t&amp; nDestUsed, size_t&amp; nSourceUsed);<br>
bool Strlcpy(wchar_t* pDestination, const char32_t* pSource, size_t nDestCapacity, size_t nSourceLength, size_t&amp; nDestUsed, size_t&amp; nSourceUsed);
</font></p>
</td>
</tr>
<tr>
<td>Stristr</td>
<td>Case insensitive version of strstr (find string within string)</td>
<td><font size="-1">char_t* Stristr(const char_t* pString, const char_t* pSubString);</font></td>
</tr>
<tr>
<td>FtoaEnglish</td>
<td>
<p>Float to ascii; always use English numeric format, regardless of the current locale.</p>
</td>
<td><font size="-1">char_t* FtoaEnglish(double dValue, char_t* pResult, int nInputLength, int nPrecision, bool bExponentEnabled); </font></td>
</tr>
<tr>
<td>AtofEnglish</td>
<td>Ascii to float; always use English numeric format, regardless of the current locale.</td>
<td><font size="-1">double AtofEnglish(const char_t* pString); </font></td>
</tr>
<tr>
<td> StrtodEnglish</td>
<td>Same as strtod, but always use English numeric format, regardless of the current locale.</td>
<td><font size="-1">double StrtodEnglish(const char_t* pString, char_t** ppStringEnd);</font></td>
</tr>
<tr>
<td>Memset16</td>
<td>Sets 16 bit values in memory (as opposed to memset's 8 bit values)</td>
<td><font size="-1">uint16_t* Memset16(void* pDestination, uint16_t c, size_t count); </font></td>
</tr>
<tr>
<td>Memset32</td>
<td>Sets 32 bit values in memory (as opposed to memset's 8 bit values)</td>
<td><font size="-1"> uint32_t* Memset32(void* pDestination, uint32_t c, size_t count);</font></td>
</tr>
<tr>
<td>Memset64</td>
<td>Sets 64 bit values in memory (as opposed to memset's 8 bit values)</td>
<td><font size="-1">uint64_t* Memset64(void* pDestination, uint64_t c, size_t count);</font></td>
</tr>
<tr>
<td>MemsetN</td>
<td>Sets arbitrarily sized values in memory.</td>
<td><font size="-1">void* MemsetN (void* pDestination, const void* pSource, size_t sourceBytes, size_t count); </font></td>
</tr>
<tr>
<td>EcvtBuf</td>
<td>Base function for converting a float to a %e string.</td>
<td>
<p><font size="-1">char_t* EcvtBuf(double dValue, int nDigitCount, int* decimalPos, int* sign, char_t* buffer); </font></p>
</td>
</tr>
<tr>
<td>FcvtBuf</td>
<td>Base function for converting a float to a %f string.</td>
<td><font size="-1">char_t* FcvtBuf(double dValue, int nDigitCountAfterDecimal, int* decimalPos, int* sign, char_t* buffer); </font></td>
</tr>
</table>
<h2>Example usage </h2>
<p>We provide a random smattering of example code here.</p>
<pre class="code-example">char16_t buffer[32] = L"hello ";
Strcat(buffer, L"world");
</pre>
<p>Strlcpy, Strlcat:</p>
<pre class="code-example">char8_t buffer[32];
Strlcpy(buffer, "Hello ", sizeof(buffer));<br>Strlcat(buffer, "world", sizeof(buffer));
</pre>
<p>Strlcpy, used to translate UTF8 to UTF16: </p>
<pre class="code-example">char8_t buffer8[64];
char16_t buffer16[64];
int length16 = Strlcpy(buffer16, buffer8, 64);</pre>
<p>U64toa:</p>
<pre class="code-example">char buffer[32];
U64toa(UINT64_C(12345678901234567890), buffer, 16);
</pre>
<p>AtoI32:</p>
<pre class="code-example">int32_t x = AtoI32(&quot;1234567890&quot;);
</pre>
<p>Strtod:</p>
<pre class="code-example">const char16_t* pString = L"12345.678 123.456 1.23456";
while(*pString)
{
double value = Strtod(pString, &pString);
printf("Field = %f\n, value);
}
</pre>
<h2>Interface</h2>
<p>In each of the functions below, there is an char8_t and char16_t version. So for Strcat there are the following:</p>
<blockquote>
<p><span class="code-example-span">char8_t* &nbsp;Strcat(char8_t* &nbsp;pDestination, const char8_t* &nbsp;pSource)<br>
</span><span class="code-example-span">char16_t* Strcat(char16_t* pDestination, const char16_t* pSource)</span></p>
</blockquote>
<p>The list below may be out of date as you read this, so see EAString.h for a definitive list of supported functionality.</p>
<pre class="code-example">char_t* Strcat(char_t* pDestination, const char_t* pSource);
char_t* Strncat(char_t* pDestination, const char_t* pSource, size_t n);
char_t* Strlcat(char_t* pDestination, const char_t* pSource, size_t n);
char_t* Strcpy(char_t* pDestination, const char_t* pSource);
char_t* Strncpy(char_t* pDestination, const char_t* pSource, size_t n);
char_t* Strlcpy(char_t* pDestination, const char_t* pSource, size_t n);
int Strlcpy(char16_t* pDestination, const char8_t* pSource, size_t nDestCapacity, size_t nSourceLength = (size_t)~0);
int Strlcpy(char32_t* pDestination, const char8_t* pSource, size_t nDestCapacity, size_t nSourceLength = (size_t)~0);
int Strlcpy(char8_t* pDestination, const char16_t* pSource, size_t nDestCapacity, size_t nSourceLength = (size_t)~0);
int Strlcpy(char32_t* pDestination, const char16_t* pSource, size_t nDestCapacity, size_t nSourceLength = (size_t)~0);
int Strlcpy(char8_t* pDestination, const char32_t* pSource, size_t nDestCapacity, size_t nSourceLength = (size_t)~0);
int Strlcpy(char16_t* pDestination, const char32_t* pSource, size_t nDestCapacity, size_t nSourceLength = (size_t)~0);
int Strlcpy(char8_t* pDestination, const wchar_t* pSource, size_t nDestCapacity, size_t nSourceLength = (size_t)~0);
int Strlcpy(char16_t* pDestination, const wchar_t* pSource, size_t nDestCapacity, size_t nSourceLength = (size_t)~0);
int Strlcpy(char32_t* pDestination, const wchar_t* pSource, size_t nDestCapacity, size_t nSourceLength = (size_t)~0);
int Strlcpy(wchar_t* pDestination, const char8_t* pSource, size_t nDestCapacity, size_t nSourceLength = (size_t)~0);
int Strlcpy(wchar_t* pDestination, const char16_t* pSource, size_t nDestCapacity, size_t nSourceLength = (size_t)~0);
int Strlcpy(wchar_t* pDestination, const char32_t* pSource, size_t nDestCapacity, size_t nSourceLength = (size_t)~0);
bool Strlcpy(char16_t* pDestination, const char8_t* pSource, size_t nDestCapacity, size_t nSourceLength, size_t&amp; nDestUsed, size_t&amp; nSourceUsed);
bool Strlcpy(char32_t* pDestination, const char8_t* pSource, size_t nDestCapacity, size_t nSourceLength, size_t&amp; nDestUsed, size_t&amp; nSourceUsed);
bool Strlcpy(char8_t* pDestination, const char16_t* pSource, size_t nDestCapacity, size_t nSourceLength, size_t&amp; nDestUsed, size_t&amp; nSourceUsed);
bool Strlcpy(char32_t* pDestination, const char16_t* pSource, size_t nDestCapacity, size_t nSourceLength, size_t&amp; nDestUsed, size_t&amp; nSourceUsed);
bool Strlcpy(char8_t* pDestination, const char32_t* pSource, size_t nDestCapacity, size_t nSourceLength, size_t&amp; nDestUsed, size_t&amp; nSourceUsed);
bool Strlcpy(char16_t* pDestination, const char32_t* pSource, size_t nDestCapacity, size_t nSourceLength, size_t&amp; nDestUsed, size_t&amp; nSourceUsed);
bool Strlcpy(char8_t* pDestination, const wchar_t* pSource, size_t nDestCapacity, size_t nSourceLength, size_t&amp; nDestUsed, size_t&amp; nSourceUsed);
bool Strlcpy(char16_t* pDestination, const wchar_t* pSource, size_t nDestCapacity, size_t nSourceLength, size_t&amp; nDestUsed, size_t&amp; nSourceUsed);
bool Strlcpy(char32_t* pDestination, const wchar_t* pSource, size_t nDestCapacity, size_t nSourceLength, size_t&amp; nDestUsed, size_t&amp; nSourceUsed);
bool Strlcpy(wchar_t* pDestination, const char8_t* pSource, size_t nDestCapacity, size_t nSourceLength, size_t&amp; nDestUsed, size_t&amp; nSourceUsed);
bool Strlcpy(wchar_t* pDestination, const char16_t* pSource, size_t nDestCapacity, size_t nSourceLength, size_t&amp; nDestUsed, size_t&amp; nSourceUsed);
bool Strlcpy(wchar_t* pDestination, const char32_t* pSource, size_t nDestCapacity, size_t nSourceLength, size_t&amp; nDestUsed, size_t&amp; nSourceUsed);
size_t Strlen(const char_t* pString);
size_t Strxfrm(char_t* pDest, const char_t* pSource, size_t n);
char_t* Strdup(const char_t* pString);
char_t* Strlwr(char_t* pString);
char_t* Strupr(char_t* pString);
char_t* Strchr(const char_t* pString, char_t c);
size_t Strcspn(const char_t* pString1, const char_t* pString2);
char_t* Strpbrk(const char_t* pString1, const char_t* pString2);
char_t* Strrchr(const char_t* pString, char_t c);
size_t Strspn(const char_t* pString, const char_t* pSubString);
char_t* Strstr(const char_t* pString, const char_t* pSubString);
char_t* Stristr(const char_t* pString, const char_t* pSubString);
char_t* Strtok(char_t* pString, const char_t* pTokens, char_t** pContext);
char_t* Strset(char_t* pString, char_t c);
char_t* Strnset(char_t* pString, char_t c, size_t n);
char_t* Strrev(char_t* pString);
int Strcmp(const char_t* pString1, const char_t* pString2);
int Strncmp(const char_t* pString1, const char_t* pString2, size_t n);
int Stricmp(const char_t* pString1, const char_t* pString2);
int Strnicmp(const char_t* pString1, const char_t* pString2, size_t n);
int Strcoll(const char_t* pString1, const char_t* pString2);
int Strncoll(const char_t* pString1, const char_t* pString2, size_t n);
int Stricoll(const char_t* pString1, const char_t* pString2);
int Strnicoll(const char_t* pString1, const char_t* pString1, size_t n);
char_t* EcvtBuf(double dValue, int nDigitCount, int* decimalPos, int* sign, char_t* buffer);
char_t* FcvtBuf(double dValue, int nDigitCountAfterDecimal, int* decimalPos, int* sign, char_t* buffer);
char_t* I32toa(int32_t nValue, char_t* pResult, int nBase);
char_t* U32toa(uint32_t nValue, char_t* pResult, int nBase);
char_t* I64toa(int64_t nValue, char_t* pBuffer, int nBase);
char_t* U64toa(uint64_t nValue, char_t* pBuffer, int nBase);
double Strtod(const char_t* pString, char_t** ppStringEnd);
double StrtodEnglish(const char_t* pString, char_t** ppStringEnd);
int64_t StrtoI64(const char_t* pString, char_t** ppStringEnd, int nBase);
uint64_t StrtoU64(const char_t* pString, char_t** ppStringEnd, int nBase);
int32_t StrtoI32(const char_t* pString, char_t** ppStringEnd, int nBase);
uint32_t StrtoU32(const char_t* pString, char_t** ppStringEnd, int nBase);
int32_t AtoI32(const char_t* pString);
uint32_t AtoU32(const char_t* pString);
int64_t AtoI64(const char_t* pString);
uint64_t AtoU64(const char_t* pString);
double Atof(const char_t* pString);
double AtofEnglish(const char_t* pString);
char_t* Ftoa(double dValue, char_t* pResult, int nInputLength, int nPrecision, bool bExponentEnabled);
char_t* FtoaEnglish(double dValue, char_t* pResult, int nInputLength, int nPrecision, bool bExponentEnabled);
</pre>
<h2>Encoded Strlcpy Issue </h2>
<p>The Strlcpy function <span class="code-example-comment"> size_t Strlcpy(char16_t* pDestination, const char8_t* pSource, size_t nDestCapacity, size_t nSourceLength)</span> converts UTF8 text (char8_t) to UCS2 (char16_t). It doesn't work if your pSource string isn't truly UTF8-encoded. Typically this would happen because the source string is using Windows code page 1252 or HTML's ISO 8859-1. All 8 bit strings in EAStdC are assumed to be UTF8 unless specifically documented otherwise. </p>
<p>Any 8 bit text that's not UTF8 has to be defined within the context of a code page; otherwise any chars above 127 have an arbitrary meaning, and may include multi-byte characters for some code pages. If you need to convert code page 1252 to UCS2, you need to implement a function which uses a table that maps the high byte values into their proper Unicode values. It's not so simple to just cast the byte value to char16_t, as some of the code page 1252 characters don't map directly to their numerical values in Unicode, though ISO 8859-1 characters to completely map to their equivalent Unicode values. </p>
<p>The following is an implementation of Strcpy and Strlcpy for ISO 8859-1 char8_t text which isn't currently part of EAStdC: </p>
<p class="code-example">char16_t* StrcpyISO8859_1(char16_t* pDestination, const char8_t* pSource)<br>
{<br>
&nbsp;&nbsp;&nbsp;&nbsp;char16_t* pDestSaved = pDestination;<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;while(*pSource)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*(pDestination++) = (uint8_t)*pSource++;<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;*pDestination = 0;<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;return pDestSaved;<br>
}</p>
<p> </p>
<p class="code-example">size_t StrlcpyISO8859_1(char16_t* pDestination, const char8_t* pSource, size_t nDestCapacity)<br>
{<br>
&nbsp;&nbsp;&nbsp;&nbsp;const char8_t* s = pSource;<br>
&nbsp;&nbsp;&nbsp;&nbsp;size_t n = nDestCapacity;<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;if(n &amp;&amp; --n)<br>
&nbsp;&nbsp;&nbsp;&nbsp;{<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do{<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((*pDestination++ = (uint8_t)*s++) == 0)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} while(--n);<br>
&nbsp;&nbsp;&nbsp;&nbsp;}<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;if(!n)<br>
&nbsp;&nbsp;&nbsp;&nbsp;{<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(nDestCapacity)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*pDestination = 0;<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(*s)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++s;<br>
&nbsp;&nbsp;&nbsp;&nbsp;}<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;return (s - pSource - 1);<br>
}</p>
<hr>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p> </p>
</body>
</html>
+724
View File
@@ -0,0 +1,724 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<Title>EATextUtil</title>
<link type="text/css" rel="stylesheet" href="UTFDoc.css">
<meta name="author" content="Paul Pedriana">
</head>
<body bgcolor="#FFFFFF">
<h1>EATextUtil</h1>
<h2>Introduction</h2>
<p>EATextUtil is a collection of string utilities that are of a higher-level nature than those found in the C runtime library or our <a href="EAString.html">EAString</a>
module. EASTL/string.h and EASTL/algorithm.h contain C++/STL variations of functions that are similar to the C runtime library functions, but which are generally
more powerful and flexible than the C functions while usually being more efficient. </p>
<p>All functions in EATextUtil are present in char8_t versions and char16_t versions, and assume UTF8 and UCS2 Unicode encoding respectively. Recall that these encodings
are backward-compatible with ASCII and so will work for most or all of the text that you give them. </p>
<p>Each of the functions comes in a version that doesn't allocate any memory but instead uses user-supplied memory in-place. In a few cases, there are String versions
that will allocate memory if they need to increase the size of the user-supplied string.</p>
<p>Here's a brief summary of the functions currently found in EATextUtil. We use char_t in the declarations below to refer to both char8_t and char16_t; there are
thus two versions of each function. </p>
<pre class="code-example">bool WildcardMatch(const char_t* pString, const char_t* pPattern, bool bCaseSensitive);
bool ParseDelimitedText(const char_t* pText, const char_t* pTextEnd, char_t cDelimiter,
const char_t*& pToken, const char_t*& pTokenEnd, const char_t** ppNewText);
const char_t* GetTextLine(const char_t* pText, const char_t* pTextEnd, const char_t** ppNewText);
bool SplitTokenDelimited(const char_t* pSource, size_t nSourceLength, char_t cDelimiter,
char_t* pToken, size_t nTokenLength, const char_t** ppNewSource = NULL);
bool SplitTokenSeparated(const char_t* pSource, size_t nSourceLength, char_t cDelimiter,
char_t* pToken, size_t nTokenLength, const char_t** ppNewSource = NULL);
void ConvertBinaryDataToASCIIArray(const void* pBinaryData, size_t nBinaryDataLength, char_t* pASCIIArray);
bool ConvertASCIIArrayToBinaryData(const char_t* pASCIIArray, size_t nASCIIArrayLength, void* pBinaryData);
int BoyerMooreSearch(const char8_t* pPattern, int nPatternLength, const char8_t* pSearchString, int nSearchStringLength,
int* pPatternBuffer1, int* pPatternBuffer2, int* pAlphabetBuffer, int nAlphabetBufferSize);
</pre>
<p>We will proceed to address each of the above functions.</p>
<h2>WildcardMatch</h2>
<pre class="code-example">bool WildcardMatch(const char16_t* pString, const char16_t* pPattern, bool bCaseSensitive);
bool WildcardMatch(const char8_t* pString, const char8_t* pPattern, bool bCaseSensitive);
</pre>
<p>These functions match source strings to wildcard patterns like those used in file specifications. '*' in the pattern means match zero or more consecutive source
characters. '?' in the pattern means match exactly one source character. Multiple * and ? characters may be used. Two consecutive * characters are treated as
if they were one. Here are some examples:</p>
<table width="500" border="1" hspace="32">
<tr>
<td><b>Source</b></td>
<td><b>Pattern</b></td>
<td><b>Result</b></td>
</tr>
<tr>
<td>abcde</td>
<td>*e</td>
<td>true</td>
</tr>
<tr>
<td>abcde</td>
<td>*f</td>
<td>false</td>
</tr>
<tr>
<td>abcde</td>
<td>???de</td>
<td>true</td>
</tr>
<tr>
<td>abcde</td>
<td>????g</td>
<td>false</td>
</tr>
<tr>
<td>abcde</td>
<td>*c??</td>
<td>true</td>
</tr>
<tr>
<td>abcde</td>
<td>*e??</td>
<td>false</td>
</tr>
<tr>
<td>abcde</td>
<td>*????</td>
<td>true</td>
</tr>
<tr>
<td>abcde</td>
<td>bcdef</td>
<td>false</td>
</tr>
<tr>
<td>abcde</td>
<td> *?????</td>
<td>true</td>
</tr>
</table>
<p>Example usage:</p>
<pre class="code-example">bool result = WildcardMatch(&quot;Hello world&quot;, &quot;hello*&quot;, false); <font color="#0033CC"> // result becomes true</font>
bool result = WildcardMatch(&quot;Hello world&quot;, &quot;hello?&quot;, false); <font color="#0033CC">// result becomes false</font>
bool result = WildcardMatch(&quot;Hello world&quot;, &quot;Hello??orld&quot;, true); <font color="#0033CC">// result becomes true</font>
bool result = WildcardMatch(&quot;Hello world&quot;, &quot;*Hello*world*&quot;, true); <font color="#0033CC">// result becomes true</font>
</pre>
<h2>ParseDelimitedText (iterative version)</h2>
<pre class="code-example">bool ParseDelimitedText(const char16_t* pText, const char16_t* pTextEnd, char16_t cDelimiter,
const char16_t*& pToken, const char16_t*& pTokenEnd, const char16_t** ppNewText);
bool ParseDelimitedText(const char8_t* pText, const char8_t* pTextEnd, char8_t cDelimiter,
const char8_t*& pToken, const char8_t*& pTokenEnd, const char8_t** ppNewText);
</pre>
<p>Given a line of text (e.g. like this:)</p>
<pre class="code-example">342.5, &quot;This is a string&quot;, test, &quot;This is a string, with a comma&quot;</pre>
<p>ParseDelimitedText parses it into separate fields (e.g. like this:)</p>
<pre class="code-example">342.5
This is a string
test
This is a string, with a comma </pre>
<p> ParseDelimitedText lets you dynamically specify the delimiter. The delimiter can be any char (e.g. space, tab, semicolon) except the quote char itself, which
is reserved for the purpose of grouping. See the source code comments for more details. However, in the case of text that is UTF8-encoded, you need to make sure
the delimiter char is a value that is less than 127, so as not to collide with UTF8 encoded chars.<br>
<br>
The input is a pointer to text and the text length. For ASCII, MBCS, and UTF8, this is the number of bytes or chars. For UTF16 (Unicode) it is the number of characters.
There are two bytes (two chars) per character in UTF16. The input nTextLength can be -1 (kLengthNull) to indicate that the string is null-terminated. </p>
<p>Example behaviour for string array version (which you can extrapolate to the iterative version):</p>
<table width="100%" border="1">
<tr>
<td><b>Input string</b></td>
<td><b>MaxResults</b></td>
<td><b>Delimiter</b></td>
<td><b>Return value</b></td>
<td>
<p><b>O</b><b>utput array size</b></p>
</td>
<td><b>Output array value</b></td>
</tr>
<tr>
<td>
<pre><font size="-1">""</font></pre>
</td>
<td><font size="-1">-1</font></td>
<td>
<pre><font size="-1">' '</font></pre>
</td>
<td><font size="-1">0</font></td>
<td><font size="-1">0</font></td>
<td>
<pre><font size="-1">""</font></pre>
</td>
</tr>
<tr>
<td>
<pre><font size="-1">"000 111"</font></pre>
</td>
<td><font size="-1">-1</font></td>
<td>
<pre><font size="-1">' '</font></pre>
</td>
<td><font size="-1">2</font></td>
<td><font size="-1">2</font></td>
<td>
<pre><font size="-1">"000" "111"</font></pre>
</td>
</tr>
<tr>
<td>
<pre><font size="-1">"000 111 222 333 444 \"555 555\" 666"</font></pre>
</td>
<td><font size="-1">-1</font></td>
<td>
<pre><font size="-1">' '</font></pre>
</td>
<td><font size="-1">7</font></td>
<td><font size="-1">7</font></td>
<td>
<pre><font size="-1">"000" "111" "222" "333" "444" "555 555" "666"</font></pre>
</td>
</tr>
<tr>
<td>
<pre><font size="-1">" 000 111 222 333 "</font></pre>
</td>
<td><font size="-1">-1</font></td>
<td>
<pre><font size="-1">' '</font></pre>
</td>
<td><font size="-1">4</font></td>
<td><font size="-1">4</font></td>
<td>
<pre><font size="-1">"000" "111" "222" "333"</font></pre>
</td>
</tr>
<tr>
<td>
<pre><font size="-1">" 000 111 222 333 "</font></pre>
</td>
<td><font size="-1">-1</font></td>
<td>
<pre><font size="-1">' '</font></pre>
</td>
<td><font size="-1">2</font></td>
<td><font size="-1">2</font></td>
<td>
<pre><font size="-1">"000" "111"</font></pre>
</td>
</tr>
<tr>
<td>
<pre><font size="-1">""</font></pre>
</td>
<td><font size="-1">-1</font></td>
<td>
<pre><font size="-1">','</font></pre>
</td>
<td><font size="-1">0</font></td>
<td><font size="-1">0</font></td>
<td>
<pre><font size="-1">""</font></pre>
</td>
</tr>
<tr>
<td>
<pre><font size="-1">"000,111"</font></pre>
</td>
<td><font size="-1">-1</font></td>
<td>
<pre><font size="-1">','</font></pre>
</td>
<td><font size="-1">2</font></td>
<td><font size="-1">2</font></td>
<td>
<pre><font size="-1">"000" "111"</font></pre>
</td>
</tr>
<tr>
<td>
<pre><font size="-1">"000, 111 , 222 333 ,444 \"555, 555 \" 666"</font></pre>
</td>
<td><font size="-1">-1</font></td>
<td>
<pre><font size="-1">','</font></pre>
</td>
<td><font size="-1">4</font></td>
<td><font size="-1">4</font></td>
<td>
<pre><font size="-1">"000" "111" "222 333" "444 \"555, 555 \" 666"</font></pre>
</td>
</tr>
<tr>
<td>
<pre><font size="-1">" ,, 000 ,111, 222, 333 , "</font></pre>
</td>
<td><font size="-1">-1</font></td>
<td>
<pre><font size="-1">','</font></pre>
</td>
<td><font size="-1">6</font></td>
<td><font size="-1">6</font></td>
<td>
<pre><font size="-1">"" "" "000" "111" "222" "333"</font></pre>
</td>
</tr>
<tr>
<td>
<pre><font size="-1">" ,, 000 ,111, 222, 333 , "</font></pre>
</td>
<td><font size="-1">2 </font></td>
<td>
<pre><font size="-1">','</font></pre>
</td>
<td><font size="-1">0</font></td>
<td><font size="-1">0</font></td>
<td>
<pre><font size="-1">"" ""</font></pre>
</td>
</tr>
</table>
<h2>Convert binary ASCII</h2>
<pre class="code-example">void ConvertBinaryDataToASCIIArray(const void* pBinaryData, size_t nBinaryDataLength, char16_t* pASCIIArray);
void ConvertBinaryDataToASCIIArray(const void* pBinaryData, size_t nBinaryDataLength, char8_t* pASCIIArray);
bool ConvertASCIIArrayToBinaryData(const char8_t* pASCIIArray, size_t nASCIIArrayLength, void* pBinaryData);
bool ConvertASCIIArrayToBinaryData(const char16_t* pASCIIArray, size_t nASCIIArrayLength, void* pBinaryData);
</pre>
<p> The first two functions convert an array of binary characters into an encoded ASCII format that can be later converted back to binary. You might want to do this
if you are trying to embed binary data into a text file (e.g. .ini file) and need a way to encode the binary data as text.</p>
<p> The second two functions take an ASCII string of text and converts it to binary data. This is the reverse of the ConvertBinaryDataToASCIIArray functions. If an
invalid hexidecimal character is encountered, it is replaced with a '0' character. These functions return true if the input was entirely valid hexadecimal data.</p>
<p>Example usage:</p>
<pre class="code-example">const uint8_t data[4] = { 0x12, 0x34, 0x56, 0x78 };
char8_t ascii[8];
ConvertBinaryDataToASCIIArray(data, 4 * sizeof(uint8_t), ascii); <font color="#0033CC">// ascii becomes "12345678"</font>
</pre>
<pre class="code-example">const char16_t ascii[8] = &quot;12345678&quot;;
uint8_t data[4];
ConvertASCIIArrayToBinaryData(ascii, 8, data); <font color="#0033CC">// data becomes { 0x12, 0x34, 0x56, 0x78 }</font>
</pre>
<h2>GetTextLine</h2>
<pre class="code-example">const char16_t* GetTextLine(const char16_t* pText, const char16_t* pTextEnd, const char16_t** ppNewText);
const char8_t* GetTextLine(const char8_t* pText, const char8_t* pTextEnd, const char8_t** ppNewText);
</pre>
<p>Given a block of text, this function reads a line of text and moves to the beginning of the next line. The return value is the end of the current line, previous
to the newline characters. If ppNewText is supplied, it holds the start of the new line, which will often be different from the return value, as the start of
the new line is after any newline characters. The length of the current line is pTextEnd - pText.</p>
<p>These functions are useful for reading lines of text from a text file via an iterative method, which is perhaps the most flexible way of doing this.</p>
<p>Example usage:</p>
<pre class="code-example">char buffer[256];<br>char* pLineNext(buffer);<br>char* pLine;<br><br>do{<br> pText = pLineNext;<br> const char* pLineEnd = GetTextLine(pLine, buffer + 256, &amp;pLineNext);<br> <span class="code-example-comment">// Use pLine - pLineEnd here</span><br>}while(pLineNext != (buffer + 256));</pre>
<h2>SplitTokenDelimited </h2>
<pre class="code-example">bool SplitTokenDelimited(const char16_t* pSource, size_t nSourceLength, char16_t cDelimiter,
char16_t* pToken, size_t nTokenLength, const char16_t** ppNewSource = NULL);
bool SplitTokenDelimited(const char8_t* pSource, size_t nSourceLength, char8_t cDelimiter,
char8_t* pToken, size_t nTokenLength, const char8_t** ppNewSource = NULL);
</pre>
<p> SplitTokenDelimited returns tokens that are delimited by a single character -- repetitions of that character will result in empty tokens returned. This is most
commonly useful when you want to parse a string of text delimited by commas or spaces. Returns true whenever it extracts a token. Note however that the extracted
token may be empty. Note that the return value will be true if the source has length and will be false if the source is empty. If the input pToken is non-null,
the text before the delimiter is copied to it. </p>
<p>Example behaviour (delimiter is a comma):</p>
<table width="500" border="1" hspace="32">
<tr>
<td><b>Source</b></td>
<td><b>Token</b></td>
<td><b>New source</b></td>
<td><b>Return value</b></td>
</tr>
<tr>
<td>
<pre>"a,b"</pre>
</td>
<td>
<pre>"a"</pre>
</td>
<td>
<pre>"b"</pre>
</td>
<td>
<pre>true</pre>
</td>
</tr>
<tr>
<td>
<pre>" a , b "</pre>
</td>
<td>
<pre>" a "</pre>
</td>
<td>
<pre>" b "</pre>
</td>
<td>
<pre>true</pre>
</td>
</tr>
<tr>
<td>
<pre>"ab,b"</pre>
</td>
<td>
<pre>"ab"</pre>
</td>
<td>
<pre>"b"</pre>
</td>
<td>
<pre>true</pre>
</td>
</tr>
<tr>
<td>
<pre>",a,b"</pre>
</td>
<td>
<pre>""</pre>
</td>
<td>
<pre>"a,b"</pre>
</td>
<td>
<pre>true</pre>
</td>
</tr>
<tr>
<td>
<pre>",b"</pre>
</td>
<td>
<pre>""</pre>
</td>
<td>
<pre>"b"</pre>
</td>
<td>
<pre>true</pre>
</td>
</tr>
<tr>
<td>
<pre>",,b"</pre>
</td>
<td>
<pre>""</pre>
</td>
<td>
<pre>",b"</pre>
</td>
<td>
<pre>true</pre>
</td>
</tr>
<tr>
<td>
<pre>",a,"</pre>
</td>
<td>
<pre>""</pre>
</td>
<td>
<pre>"a,"</pre>
</td>
<td>
<pre>true</pre>
</td>
</tr>
<tr>
<td>
<pre>"a,"</pre>
</td>
<td>
<pre>"a"</pre>
</td>
<td>
<pre>""</pre>
</td>
<td>
<pre>true</pre>
</td>
</tr>
<tr>
<td>
<pre>","</pre>
</td>
<td>
<pre>""</pre>
</td>
<td>
<pre>""</pre>
</td>
<td>
<pre>true</pre>
</td>
</tr>
<tr>
<td>
<pre>", "</pre>
</td>
<td>
<pre>""</pre>
</td>
<td>
<pre>&quot; &quot;</pre>
</td>
<td>
<pre>true</pre>
</td>
</tr>
<tr>
<td>
<pre>"a"</pre>
</td>
<td>
<pre>"a"</pre>
</td>
<td>
<pre>""</pre>
</td>
<td>
<pre>true</pre>
</td>
</tr>
<tr>
<td>
<pre>" "</pre>
</td>
<td>
<pre>&quot; &quot;</pre>
</td>
<td>
<pre>""</pre>
</td>
<td>
<pre>true</pre>
</td>
</tr>
<tr>
<td>
<pre>""</pre>
</td>
<td>
<pre>&quot;&quot;</pre>
</td>
<td>
<pre>""</pre>
</td>
<td>
<pre>false</pre>
</td>
</tr>
<tr>
<td>
<pre>NULL</pre>
</td>
<td>
<pre>&quot;&quot;</pre>
</td>
<td>
<pre>NULL</pre>
</td>
<td>
<pre>false</pre>
</td>
</tr>
</table>
<p>Example usage:</p>
<pre class="code-example">const char16_t* pString = L"a, b, c, d";
char16_t pToken[16];
while(SplitTokenDelimited(pString, kLengthNull, ',', pToken, 16, &pString))
printf("%s\n", pToken);
</pre>
<h2>SplitTokenSeparated </h2>
<pre class="code-example">bool SplitTokenSeparated(const char16_t* pSource, size_t nSourceLength, char16_t cDelimiter,
char16_t* pToken, size_t nTokenLength, const char16_t** ppNewSource = NULL);
bool SplitTokenSeparated(const char8_t* pSource, size_t nSourceLength, char8_t cDelimiter,
char8_t* pToken, size_t nTokenLength, const char8_t** ppNewSource = NULL);</pre>
<p>SplitTokenSeparated returns tokens that are separated by one or more instances of a character. Returns true whenever it extracts a token. </p>
<p>Example behaviour (delimiter is a space char):</p>
<table width="500" border="1" hspace="32">
<tr>
<td><b>Source</b></td>
<td><b>Token</b></td>
<td><b>New source</b></td>
<td><b>Return value</b></td>
</tr>
<tr>
<td>
<pre>"a"</pre>
</td>
<td>
<pre>"a"</pre>
</td>
<td>
<pre>""</pre>
</td>
<td>
<pre>true</pre>
</td>
</tr>
<tr>
<td>
<pre>"a b"</pre>
</td>
<td>
<pre>"a"</pre>
</td>
<td>
<pre>"b"</pre>
</td>
<td>
<pre>true</pre>
</td>
</tr>
<tr>
<td>
<pre>"a b"</pre>
</td>
<td>
<pre>"a"</pre>
</td>
<td>
<pre>"b"</pre>
</td>
<td>
<pre>true</pre>
</td>
</tr>
<tr>
<td>
<pre>" a b"</pre>
</td>
<td>
<pre>"a"</pre>
</td>
<td>
<pre>"b"</pre>
</td>
<td>
<pre>true</pre>
</td>
</tr>
<tr>
<td>
<pre>" a b "</pre>
</td>
<td>
<pre>"a"</pre>
</td>
<td>
<pre>"b "</pre>
</td>
<td>
<pre>true</pre>
</td>
</tr>
<tr>
<td>
<pre>" a "</pre>
</td>
<td>
<pre>"a"</pre>
</td>
<td>
<pre>""</pre>
</td>
<td>
<pre>true</pre>
</td>
</tr>
<tr>
<td>
<pre>" a "</pre>
</td>
<td>
<pre>"a"</pre>
</td>
<td>
<pre>""</pre>
</td>
<td>
<pre>true</pre>
</td>
</tr>
<tr>
<td>
<pre>""</pre>
</td>
<td>
<pre>&quot;&quot;</pre>
</td>
<td>
<pre>""</pre>
</td>
<td>
<pre>false</pre>
</td>
</tr>
<tr>
<td>
<pre>" "</pre>
</td>
<td>
<pre>&quot;&quot;</pre>
</td>
<td>
<pre>""</pre>
</td>
<td>
<pre>false</pre>
</td>
</tr>
<tr>
<td>
<pre>NULL</pre>
</td>
<td>
<pre>&quot;&quot;</pre>
</td>
<td>
<pre>NULL</pre>
</td>
<td>
<pre>false</pre>
</td>
</tr>
</table>
<h2>BoyerMooreSearch</h2>
<pre class="code-example"><span class="code-example-comment">/// BoyerMooreSearch
///
/// patternBuffer1 is a user-supplied buffer and must be at least as long as the search pattern.
/// patternBuffer2 is a user-supplied buffer and must be at least as long as the search pattern.
/// alphabetBuffer is a user-supplied buffer and must be at least as long as the highest character value
/// used in the searched string and search pattern.
///
</span>int BoyerMooreSearch(const char* pPattern, int nPatternLength, const char* pSearchString, int nSearchStringLength,
int* pPatternBuffer1, int* pPatternBuffer2, int* pAlphabetBuffer, int nAlphabetBufferSize)
</pre>
<p> Boyer-Moore is a very fast string search compared to most others, including those in the STL. However, you need to be searching a string of at least 100 chars
and have a search pattern of at least 3 characters for the speed to show, as Boyer-Moore has a startup precalculation that costs some cycles. This startup precalculation
is proportional to the size of your search pattern and the size of the alphabet in use. Thus, doing Boyer-Moore searches on the entire Unicode alphabet is going
to incur a fairly expensive precalculation cost.</p>
<hr>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p> </p>
</body></html>
+219
View File
@@ -0,0 +1,219 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<title>Int128_t</title>
<link type="text/css" rel="stylesheet" href="UTFDoc.css">
<meta name="author" content="Paul Pedriana">
</head>
<body bgcolor="#FFFFFF">
<h1>int128_t</h1>
<h2>Introduction</h2>
<p>The int128_t module implements the int128_t and uint128_t integer data types
via C++ classes. These types are largely identical in behavior to how a compiler's
built-in int128_t / uint128_t would be. These classes exist because compilers
don't provide true 128 bit data types. The most you'll typically see from a
compiler is int64_t / uint64_t. </p>
<p>128 bit integers are useful for things such as the following:</p>
<ul>
<li>Storing very large numbers or bitfields. This can be useful when attempting
to simulate city or world economies, for example.</li>
<li>Implementing 64 * 64 bit multiplication without losing data.</li>
<li>Implementing very precise fixed point mathematics.</li>
</ul>
<h2> Example usage </h2>
<p>For the most part, you can use int128_t the same way you would use int64_t.
</p>
<p>Mixed integer math expressions:</p>
<pre class="code-example">int a(17);
short b(26);
int128_t c(45);
int64_t d(77);
unsigned short e(25);
uint128_t x(13);
uint128_t y;
y = (((x + (a + b) * 37) / c) * x) % (d + e);</pre>
<p>Logical expressions:</p>
<pre class="code-example">uint128_t x;<br>uint128_t y(&quot;0x11111111000100001111111100000001&quot;, 16); // Assign a full 128 bit value of base 16 via a string.<br>uint128_t z(&quot;0x22222222000100002222222200000001&quot;, 16);
<br>x = (y ^ z) + (y &amp; z) + (y | z);</pre>
<blockquote></blockquote>
<p>Floating point:</p>
<pre class="code-example">uint128_t x = 143249.f;
x *= 32245.6f
<br>printf(&quot;%f&quot;, x.AsFloat());</pre>
<p>Mixture of int128_t and uint128_t:</p>
<pre class="code-example">int128_t x(-1000000000);<br>uint128_t y(120);
<br>x *= y; </pre>
<p>Converting int128_t to a string:</p>
<pre class="code-example">char buffer[64];
int128_t x = 10345;
s.Int128ToStr(buffer, NULL, 10); // Just like strtol().</pre>
<p>Set int128_t as a very large value from a string:</p>
<pre class="code-example">uint128_t x("141183460469231731687303715884105728");</pre>
<p>Set int128_t as a very large value from two 64 bit values:</p>
<pre class="code-example">uint128_t x(0x1122334455667788);
x &lt;&lt;= 64;
x |= 0x8877665544332211;</pre>
<h2>
Limitations</h2>
<p>The primary differences between our int128_t and a hypothetical built-in version
are:</p>
<ul>
<li>int128_t doesn't implement cast operators to lesser integer types. Instead,
provides explicit converters such as AsInt32, AsInt64, etc. This is by design,
as such casting operators result in ambiguous conversions and would need built-in
compiler knowledge to resolve the situation.</li>
<li>Standard library functions such as sprintf have no support for such 128
bit types. We partially rectify this by providing StrToInt128 and Int128ToStr
functions.</li>
<li>128 bit contant literals aren't supported by the compiler, so we implement
them via strings (and indirectly via shifting). You can assign an 8 through
64 bit integral constant to int128_t, but if you want to assign a full 128
bit constant to an int128_t, you'll need to use a string or use two 64 bit
constants, one for low and one for high.</li>
</ul>
<h2>Interface </h2>
<pre class="code-example">class int128_t
{
public:
int128_t();
int128_t(uint32_t nPart0, uint32_t nPart1, uint32_t nPart2, uint32_t nPart3);
int128_t(uint64_t nPart0, uint64_t nPart1);
int128_t(int8_t value);
int128_t(uint8_t value);
int128_t(int16_t value);
int128_t(uint16_t value);
int128_t(int32_t value);
int128_t(uint32_t value);
int128_t(int64_t value);
int128_t(uint64_t value);
int128_t(const int128_t& value);
int128_t(const float value);
int128_t(const double value);
int128_t(const char* pValue, int nBase = 10);
int128_t(const wchar_t* pValue, int nBase = 10);
// Assignment operator
int128_t& operator=(const int128_t_base& value);
// Unary arithmetic/logic operators
int128_t operator-() const;
int128_t& operator++();
int128_t& operator--();
int128_t operator++(int);
int128_t operator--(int);
int128_t operator~() const;
int128_t operator+() const;
// Math operators
friend int128_t operator+(const int128_t& value1, const int128_t& value2);
friend int128_t operator-(const int128_t& value1, const int128_t& value2);
friend int128_t operator*(const int128_t& value1, const int128_t& value2);
friend int128_t operator/(const int128_t& value1, const int128_t& value2);
friend int128_t operator%(const int128_t& value1, const int128_t& value2);
int128_t& operator+=(const int128_t& value);
int128_t& operator-=(const int128_t& value);
int128_t& operator*=(const int128_t& value);
int128_t& operator/=(const int128_t& value);
int128_t& operator%=(const int128_t& value);
// Shift operators
int128_t operator>> (int nShift) const;
int128_t operator<< (int nShift) const;
int128_t& operator>>=(int nShift);
int128_t& operator<<=(int nShift);
// Logical operators
friend int128_t operator^(const int128_t& value1, const int128_t& value2);
friend int128_t operator|(const int128_t& value1, const int128_t& value2);
friend int128_t operator&(const int128_t& value1, const int128_t& value2);
int128_t& operator^= (const int128_t& value);
int128_t& operator|= (const int128_t& value);
int128_t& operator&= (const int128_t& value);
// Equality operators
friend int compare (const int128_t& value1, const int128_t& value2);
friend bool operator==(const int128_t& value1, const int128_t& value2);
friend bool operator!=(const int128_t& value1, const int128_t& value2);
friend bool operator> (const int128_t& value1, const int128_t& value2);
friend bool operator>=(const int128_t& value1, const int128_t& value2);
friend bool operator< (const int128_t& value1, const int128_t& value2);
friend bool operator<=(const int128_t& value1, const int128_t& value2);
// Operators to convert back to basic types
int8_t AsInt8() const;
int16_t AsInt16() const;
int32_t AsInt32() const;
int64_t AsInt64() const;
float AsFloat() const;
double AsDouble() const;
// Misc. Functions
void Negate();
bool IsNegative() const;
bool IsPositive() const;
void Modulus(const int128_t& divisor, int128_t& quotient, int128_t& remainder) const;
// String conversion functions
int128_t StrToInt128(const char* pValue, char** ppEnd, int base) const;
int128_t StrToInt128(const wchar_t* pValue, wchar_t** ppEnd, int base) const;
void Int128ToStr(char* pValue, char** ppEnd, int base) const;
void Int128ToStr(wchar_t* pValue, wchar_t** ppEnd, int base) const;
}; <span class="code-example-comment">// class int128_t</span>
class uint128_t<br>{<br>public:<br> uint128_t();<br> uint128_t(uint32_t nPart0, uint32_t nPart1, uint32_t nPart2, uint32_t nPart3);<br> uint128_t(uint64_t nPart0, uint64_t nPart1);
uint128_t(int8_t value);
uint128_t(uint8_t value);
uint128_t(int16_t value);<br> uint128_t(uint16_t value);
<br> uint128_t(int32_t value);<br> uint128_t(uint32_t value);
<br> uint128_t(int64_t value);<br> uint128_t(uint64_t value);
<br> uint128_t(const int128_t&amp; value);<br> uint128_t(const uint128_t&amp; value);
<br> uint128_t(const float value);<br> uint128_t(const double value);
<br> uint128_t(const char* pValue, int nBase = 10);<br> uint128_t(const wchar_t* pValue, int nBase = 10);
<br> // Assignment operator<br> uint128_t&amp; operator=(const int128_t_base&amp; value);
<br> // Unary arithmetic/logic operators<br> uint128_t operator-() const;<br> uint128_t&amp; operator++();<br> uint128_t&amp; operator--();<br> uint128_t operator++(int);<br> uint128_t operator--(int);<br> uint128_t operator~() const;<br> uint128_t operator+() const;
<br> // Math operators<br> friend uint128_t operator+(const uint128_t&amp; value1, const uint128_t&amp; value2);<br> friend uint128_t operator-(const uint128_t&amp; value1, const uint128_t&amp; value2);<br> friend uint128_t operator*(const uint128_t&amp; value1, const uint128_t&amp; value2);<br> friend uint128_t operator/(const uint128_t&amp; value1, const uint128_t&amp; value2);<br> friend uint128_t operator%(const uint128_t&amp; value1, const uint128_t&amp; value2);
<br> uint128_t&amp; operator+=(const uint128_t&amp; value);<br> uint128_t&amp; operator-=(const uint128_t&amp; value);<br> uint128_t&amp; operator*=(const uint128_t&amp; value);<br> uint128_t&amp; operator/=(const uint128_t&amp; value);<br> uint128_t&amp; operator%=(const uint128_t&amp; value);
<br> // Shift operators<br> uint128_t operator&gt;&gt; (int nShift) const;<br> uint128_t operator&lt;&lt; (int nShift) const;<br> uint128_t&amp; operator&gt;&gt;=(int nShift);<br> uint128_t&amp; operator&lt;&lt;=(int nShift);
<br> // Logical operators<br> friend uint128_t operator^(const uint128_t&amp; value1, const uint128_t&amp; value2);<br> friend uint128_t operator|(const uint128_t&amp; value1, const uint128_t&amp; value2);<br> friend uint128_t operator&amp;(const uint128_t&amp; value1, const uint128_t&amp; value2);<br> uint128_t&amp; operator^= (const uint128_t&amp; value);<br> uint128_t&amp; operator|= (const uint128_t&amp; value);<br> uint128_t&amp; operator&amp;= (const uint128_t&amp; value);
<br> // Equality operators<br> friend int compare (const uint128_t&amp; value1, const uint128_t&amp; value2);<br> friend bool operator==(const uint128_t&amp; value1, const uint128_t&amp; value2);<br> friend bool operator!=(const uint128_t&amp; value1, const uint128_t&amp; value2);<br> friend bool operator&gt; (const uint128_t&amp; value1, const uint128_t&amp; value2);<br> friend bool operator&gt;=(const uint128_t&amp; value1, const uint128_t&amp; value2);<br> friend bool operator&lt; (const uint128_t&amp; value1, const uint128_t&amp; value2);<br> friend bool operator&lt;=(const uint128_t&amp; value1, const uint128_t&amp; value2);
<br> // Operators to convert back to basic types<br> int8_t AsInt8() const;<br> int16_t AsInt16() const;<br> int32_t AsInt32() const;<br> int64_t AsInt64() const;<br> float AsFloat() const;<br> double AsDouble() const;
<br> // Misc. Functions<br> void Negate();<br> bool IsNegative() const;<br> bool IsPositive() const;<br> void Modulus(const uint128_t&amp; divisor, uint128_t&amp; quotient, uint128_t&amp; remainder) const;
<br> // String conversion functions<br> uint128_t StrToInt128(const char* pValue, char** ppEnd, int base) const;<br> uint128_t StrToInt128(const wchar_t* pValue, wchar_t** ppEnd, int base) const;<br> void Int128ToStr(char* pValue, char** ppEnd, int base) const;<br> void Int128ToStr(wchar_t* pValue, wchar_t** ppEnd, int base) const;
<br>}; <span class="code-example-comment">// class uint128_t</span>
</pre>
<p></p>
<hr>
<p><br>
<br>
<br>
<span style="font-family: monospace;">&nbsp;&nbsp; </span><br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
</p>
</body></html>
+83
View File
@@ -0,0 +1,83 @@
body
{
font-family: Palatino Linotype, Book Antiqua, Times New Roman;
font-size: 11pt;
}
h1
{
font-family: Verdana;
display: block;
background-color: #FFF0B0;
border: solid 2px black;
font-size: 16pt;
font-weight: bold;
padding: 6px;
}
h2
{
font-size: 14pt;
font-family: Verdana;
border-bottom: 2px solid black;
}
h3
{
font-family: Verdana;
font-size: 13pt;
font-weight: bold;
}
.code-example
{
display: block;
background-color: #e0e0f0;
margin-left: 3em;
margin-right: 3em;
margin-top: 1em;
margin-bottom: 1em;
padding: 8px;
border: solid 2px #a0a0d0;
font-family: monospace;
font-size: 10pt;
white-space: pre;
}
.code-example-span
{
font-family: monospace;
font-size: 10pt;
white-space: pre;
}
.code-example-comment
{
background-color: #e0e0f0;
padding: 0px 0px;
font-family: monospace;
font-size: 10pt;
white-space: pre;
color: #999999;
margin: auto auto;
}
.faq-question
{
background-color: #D0E0D0;
font-size: 12pt;
font-weight: bold;
margin-bottom: 0.5em;
margin-top: 0em;
padding-left:8px;
padding-right:8px;
padding-top:2px;
padding-bottom:2px
}
.faq-answer
{
display: block;
margin: 4pt 1em 0.5em 1em;
}