<!--
    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>
