OS portion of the triplet (the default), then nothing needs to be changed.
</p><p>The first file to create in this directory, should be called
<code class="code">os_defines.h</code>. This file contains basic macro definitions
-that are required to allow the C++ library to work with your C library.
+that are required to allow the C++ library to work with your C library.
</p><p>Several libstdc++ source files unconditionally define the macro
<code class="code">_POSIX_SOURCE</code>. On many systems, defining this macro causes
large portions of the C library header files to be eliminated
it must be 0 while bootstrapping the compiler/rebuilding the library.
</p><p>Finally, you should bracket the entire file in an include-guard, like
this:
- </p><pre class="programlisting">
+ </p><pre class="programlisting">
#ifndef _GLIBCXX_OS_DEFINES
#define _GLIBCXX_OS_DEFINES
file gives the type of the integer, and the values of the various bit
masks. You will have to peer at your own <code class="code"><ctype.h></code> to figure out
how to define the values required by this file.
- </p><p>The <code class="code">ctype_base.h</code> header file does not need include guards.
+ </p><p>The <code class="code">ctype_base.h</code> header file does not need include guards.
It should contain a single <code class="code">struct</code> definition called
<code class="code">ctype_base</code>. This <code class="code">struct</code> should contain two type
declarations, and one enumeration declaration, like this example, taken
{
typedef unsigned int mask;
typedef int* __to_type;
-
+
enum
{
- space = _ISspace,
- print = _ISprint,
- cntrl = _IScntrl,
- upper = _ISupper,
- lower = _ISlower,
- alpha = _ISalpha,
- digit = _ISdigit,
- punct = _ISpunct,
- xdigit = _ISxdigit,
- alnum = _ISalnum,
- graph = _ISgraph
+ space = _ISspace,
+ print = _ISprint,
+ cntrl = _IScntrl,
+ upper = _ISupper,
+ lower = _ISlower,
+ alpha = _ISalpha,
+ digit = _ISdigit,
+ punct = _ISpunct,
+ xdigit = _ISxdigit,
+ alnum = _ISalnum,
+ graph = _ISgraph
};
};
</pre><p>The <code class="code">mask</code> type is the type of the elements in the table. If your
constructor. Here is the IRIX example:
</p><pre class="programlisting">
ctype<char>::ctype(const mask* __table = 0, bool __del = false,
- size_t __refs = 0)
+ size_t __refs = 0)
: _Ctype_nois<char>(__refs), _M_del(__table != 0 && __del),
- _M_toupper(NULL),
- _M_tolower(NULL),
- _M_ctable(NULL),
- _M_table(!__table
- ? (const mask*) (__libc_attr._ctype_tbl->_class + 1)
- : __table)
+ _M_toupper(NULL),
+ _M_tolower(NULL),
+ _M_ctable(NULL),
+ _M_table(!__table
+ ? (const mask*) (__libc_attr._ctype_tbl->_class + 1)
+ : __table)
{ }
</pre><p>There are two parts of this that you might choose to alter. The first,
and most important, is the line involving <code class="code">__libc_attr</code>. That is
char
ctype<char>::do_toupper(char __c) const
{ return _toupper(__c); }
-
+
char
ctype<char>::do_tolower(char __c) const
{ return _tolower(__c); }
ctype<char>::do_toupper(char* __low, const char* __high) const
{
while (__low < __high)
- {
- *__low = do_toupper(*__low);
- ++__low;
- }
+ {
+ *__low = do_toupper(*__low);
+ ++__low;
+ }
return __high;
}
-
+
const char*
ctype<char>::do_tolower(char* __low, const char* __high) const
{
while (__low < __high)
- {
- *__low = do_tolower(*__low);
- ++__low;
- }
+ {
+ *__low = do_tolower(*__low);
+ ++__low;
+ }
return __high;
}
</pre><p>You must also provide the <code class="code">ctype_inline.h</code> file, which
ctype<char>::
is(mask __m, char __c) const throw()
{ return (_M_table)[(unsigned char)(__c)] & __m; }
-</pre><p>The <code class="code">_M_table</code> is the table passed in above, in the constructor.
+</pre><p>The <code class="code">_M_table</code> is the table passed in above, in the constructor.
This is the table that contains the bitmasks for each character. The
implementation here should work on all systems.
</p><p>The next function is:
is(const char* __low, const char* __high, mask* __vec) const throw()
{
while (__low < __high)
- *__vec++ = (_M_table)[(unsigned char)(*__low++)];
+ *__vec++ = (_M_table)[(unsigned char)(*__low++)];
return __high;
}
</pre><p>This function is similar; it copies the masks for all the characters
scan_is(mask __m, const char* __low, const char* __high) const throw()
{
while (__low < __high && !this->is(__m, *__low))
- ++__low;
+ ++__low;
return __low;
}
-
+
const char*
ctype<char>::
scan_not(mask __m, const char* __low, const char* __high) const throw()
{
while (__low < __high && this->is(__m, *__low))
- ++__low;
+ ++__low;
return __low;
}
</pre></div><div class="sect2" title="Thread Safety"><div class="titlepage"><div><div><h3 class="title"><a id="internals.thread_safety"></a>Thread Safety</h3></div></div></div><p>The C++ library string functionality requires a couple of atomic
</p><p>The type is <code class="code">_Atomic_word</code>. Here is the version used on IRIX:
</p><pre class="programlisting">
typedef long _Atomic_word;
-</pre><p>This type must be a signed integral type supporting atomic operations.
+</pre><p>This type must be a signed integral type supporting atomic operations.
If you're using the OS approach, use the same type used by your system's
primitives. Otherwise, use the type for which your CPU provides atomic
primitives.
*__mem += __val;
return __result;
}
-
+
static inline void
__attribute__ ((__unused__))
__atomic_add (_Atomic_word* __mem, int __val)
*__mem += __val;
}
</pre></div><div class="sect2" title="Numeric Limits"><div class="titlepage"><div><div><h3 class="title"><a id="internals.numeric_limits"></a>Numeric Limits</h3></div></div></div><p>The C++ library requires information about the fundamental data types,
-such as the minimum and maximum representable values of each type.
+such as the minimum and maximum representable values of each type.
You can define each of these values individually, but it is usually
easiest just to indicate how many bits are used in each of the data
types and let the library do the rest. For information about the
macros to define, see the top of <code class="code">include/bits/std_limits.h</code>.
-</p><p>If you need to define any macros, you can do so in <code class="code">os_defines.h</code>.
+</p><p>If you need to define any macros, you can do so in <code class="code">os_defines.h</code>.
However, if all operating systems for your CPU are likely to use the
same values, you can provide a CPU-specific file instead so that you
-do not have to provide the same definitions for each operating system.
+do not have to provide the same definitions for each operating system.
To take that approach, create a new file called <code class="code">cpu_limits.h</code> in
your CPU configuration directory (see <a class="link" href="internals.html#internals.cpu" title="CPU">CPU</a>).
- </p></div><div class="sect2" title="Libtool"><div class="titlepage"><div><div><h3 class="title"><a id="internals.libtool"></a>Libtool</h3></div></div></div><p>The C++ library is compiled, archived and linked with libtool.
+ </p></div><div class="sect2" title="Libtool"><div class="titlepage"><div><div><h3 class="title"><a id="internals.libtool"></a>Libtool</h3></div></div></div><p>The C++ library is compiled, archived and linked with libtool.
Explaining the full workings of libtool is beyond the scope of this
document, but there are a few, particular bits that are necessary for
porting.