blob: b2fc95bcf8842df4843dce1701c7ba415577903c [file] [log] [blame]
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright
ownership. The ASF licenses this file to you under the Apache
License, Version 2.0 (the License); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
Copyright 1999-2007 Rogue Wave Software, Inc.
-->
<HTML>
<HEAD>
<TITLE>Defining Traits and Facets for User-Defined Types</TITLE>
<LINK REL=StyleSheet HREF="../rw.css" TYPE="text/css" TITLE="Apache stdcxx Stylesheet"></HEAD>
<BODY BGCOLOR=#FFFFFF>
<A HREF="41-1.html"><IMG SRC="images/bprev.gif" WIDTH=20 HEIGHT=21 ALT="Previous file" BORDER=O></A><A HREF="noframes.html"><IMG SRC="images/btop.gif" WIDTH=56 HEIGHT=21 ALT="Top of Document" BORDER=O></A><A HREF="booktoc.html"><IMG SRC="images/btoc.gif" WIDTH=56 HEIGHT=21 ALT="Contents" BORDER=O></A><A HREF="tindex.html"><IMG SRC="images/bindex.gif" WIDTH=56 HEIGHT=21 ALT="Index page" BORDER=O></A><A HREF="41-3.html"><IMG SRC="images/bnext.gif" WIDTH=25 HEIGHT=21 ALT="Next file" BORDER=O></A><DIV CLASS="DOCUMENTNAME"><B>Apache C++ Standard Library User's Guide</B></DIV>
<H2>41.2 Defining Traits and Facets for User-Defined Types</H2>
<A NAME="idx967"><!></A>
<P>A user-defined type requires its own traits class, its own code conversion facet, and its own character classification facet. The traits class defines a conversion <SAMP>state_type</SAMP> and also defines operations such as copying arrays of the type and comparing arrays. The code conversion facet provides conversion to and from simple <SAMP>char</SAMP>s. The <SAMP>ctype</SAMP> facet provides character classification and manipulation routines, including the method for converting the new type to and from simple <SAMP>char</SAMP>s.</P>
<A NAME="idx968"><!></A>
<P>The following code shows a traits class declaration for <SAMP>Echar</SAMP>:</P>
<UL><PRE>
struct Etraits
{
typedef Echar char_type;
typedef long int_type;
typedef std::streamoff off_type;
typedef std::mbstate_t state_type;
typedef std::fpos&lt;state_type&gt; pos_type;
static void assign (char_type&amp; c1, const char_type&amp; c2);
static bool eq(const char_type&amp; c1,const char_type&amp; c2);
static bool lt (const char_type&amp; c1, const char_type&amp; c2);
static int compare (const char_type* s1, const char_type* s2,
std::size_t n);
static std::size_t length(const char_type *s);
static const char_type*
find (const char_type* s, int n, const char_type&amp; a);
static char_type* move (char_type* s1, const char_type* s2,
std::size_t n);
static char_type* copy(char_type *dst,const char_type *src,
std::size_t n);
static char_type* assign (char_type* s, std::size_t n,
const char_type&amp; a);
static int_type not_eof(const int_type&amp; c);
static char_type to_char_type(const int_type&amp; c);
static int_type to_int_type(const char_type&amp; c);
static bool eq_int_type(const int_type&amp; c1,const int_type&amp; c2);
static state_type get_state(pos_type pos);
static int_type eof();
};
</PRE></UL>
<P>See the <A HREF="../stdlibref/noframes.html"><I>Apache C++ Standard Library Reference Guide</I></A> section on <A HREF="../stdlibref/char-traits.html">char_traits</A> for a complete description of the member functions in a traits class.</P>
<P>To create a new code conversion facet, you must inherit from the <SAMP>std::codecvt</SAMP> template and then override some or all the protected virtual functions. Iostreams calls the protected functions through the public interface defined for <SAMP>std::codecvt</SAMP>. You must also provide a constructor taking a single <SAMP>std::size_t</SAMP> argument, and initialize <SAMP>codecvt</SAMP> with that argument.</P>
<A NAME="idx969"><!></A>
<P>A code conversion facet for <SAMP>Echar</SAMP> has a declaration that looks like this:</P>
<UL><PRE>
class Ecodecvt : public std::codecvt&lt;Echar,char,Estate&gt;
{
public:
explicit Ecodecvt (std::size_t refs = 0)
: std::codecvt&lt;Echar,char,Estate&gt;(refs) { }
protected:
virtual result do_out(Estate&amp; state, const Echar* from,
const Echar* from_end,
const Echar*&amp; from_next,
char* to, char* to_limit,
char*&amp; to_next) const;
virtual result do_in(Estate&amp; state,
const char* from,
const char* from_end,
const char*&amp; from_next,
Echar* to, Echar* to_limit,
Echar*&amp; to_next) const;
virtual result do_unshift(Estate&amp; state,
char* to, char* to_limit,
char*&amp; to_next) const;
virtual int do_encoding() const throw();
virtual bool do_always_noconv() const throw();
virtual int do_length(Estate&amp; state, const char* from,
const char* end, size_t maxm) const;
virtual int do_max_length() const throw();
};
</PRE></UL>
<P>See <A HREF="40.html">Chapter&nbsp;40</A> on defining a code conversion facet for more details. Also see the <A HREF="../stdlibref/noframes.html"><I>Apache C++ Standard Library Reference Guide</I></A> section on <A HREF="../stdlibref/codecvt.html">codecvt</A> for a complete description of member functions.</P>
<P>To create a character classification facet, you must inherit from the <SAMP>std::ctype</SAMP> template and provide implementations for all protected virtual functions. You must also provide a constructor taking a single <SAMP>std::size_t</SAMP> argument, and initialize <SAMP>std::ctype</SAMP> with that argument.</P>
<P>Note that the <SAMP>widen()</SAMP> functions define conversions from simple <SAMP>char</SAMP>s to the user-defined character type, and the narrow function provides conversions from the user-defined type to simple <SAMP>char</SAMP>s.</P>
<A NAME="idx970"><!></A>
<P>A character classification facet for <SAMP>Echar</SAMP> has a declaration that looks like this:</P>
<UL><PRE>
class Ectype : public std::ctype&lt;Echar&gt;
{
public:
typedef Echar char_type;
explicit Ectype (std::size_t refs = 0) :
std::ctype&lt;Echar&gt;(refs) { } // must pass refs onto
// the ctype constructor
protected:
virtual bool do_is(mask m, Echar c) const;
virtual const Echar* do_is(
const Echar* low,
const Echar* high,
mask* vec) const;
virtual const Echar* do_scan_is(
mask m, const Echar* low,
const Echar* high) const;
virtual const Echar* do_scan_not(
mask m, const Echar* low,
const Echar* high) const;
virtual Echar do_toupper(Echar e) const;
virtual const Echar* do_toupper(Echar* low,
const Echar* high) const;
virtual Echar do_tolower(Echar) const;
virtual const Echar* do_tolower(Echar* low,
const Echar* high) const;
virtual Echar do_widen(char) const;
virtual const char* do_widen(const char* lo,
const char* hi,
Echar* dest) const;
virtual char do_narrow(Echar, char dfault) const;
virtual const Echar* do_narrow(const Echar* lo,
const Echar* hi,char dfault,
char* dest) const;
};
</PRE></UL>
<BR>
<HR>
<A HREF="41-1.html"><IMG SRC="images/bprev.gif" WIDTH=20 HEIGHT=21 ALT="Previous file" BORDER=O></A><A HREF="noframes.html"><IMG SRC="images/btop.gif" WIDTH=56 HEIGHT=21 ALT="Top of Document" BORDER=O></A><A HREF="booktoc.html"><IMG SRC="images/btoc.gif" WIDTH=56 HEIGHT=21 ALT="Contents" BORDER=O></A><A HREF="tindex.html"><IMG SRC="images/bindex.gif" WIDTH=56 HEIGHT=21 ALT="Index page" BORDER=O></A><A HREF="41-3.html"><IMG SRC="images/bnext.gif" WIDTH=20 HEIGHT=21 ALT="Next file" BORDER=O></A>
<!-- Google Analytics tracking code -->
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-1775151-1";
urchinTracker();
</script>
<!-- end of Google Analytics tracking code -->
</BODY>
</HTML>