blob: fe4d10d5b906b658fce41f973e32afdf8a811c3d [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>Modifying a Standard Facet's Behavior</TITLE>
<LINK REL=StyleSheet HREF="../rw.css" TYPE="text/css" TITLE="Apache stdcxx Stylesheet"></HEAD>
<BODY BGCOLOR=#FFFFFF>
<A HREF="25-4.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="25-6.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>25.5 Modifying a Standard Facet's Behavior</H2>
<A NAME="idx577"><!></A>
<P>At times you may need to replace a facet object in a locale by another kind of facet object. In the following example, let us derive from one of the standard facet classes, <B><I><A HREF="../stdlibref/numpunct.html">numpunct</A></I></B>, and create a locale object in which the standard <SAMP>std::numpunct</SAMP> facet object is replaced by an instance of our new, derived facet class. </P>
<P>Here is the problem we want to solve. When you print Boolean values, you can choose between the numeric representation of the values <SAMP>"true"</SAMP> and <SAMP>"false"</SAMP>, or their alphanumeric representation. </P>
<UL><PRE>
int main(int argc, char** argv)
{
bool any_arguments = (argc &gt; 1); //1
std::cout.setf(ios_base::boolalpha); //2
std::cout &lt;&lt; any_arguments &lt;&lt; '\n'; //3
// ...
}
</PRE></UL>
<TABLE CELLPADDING="3">
<TR VALIGN="top"><TD><SAMP>//1</SAMP></TD><TD>A variable of type <SAMP>bool</SAMP> is defined. Its initial value is the boolean value of the logical expression <SAMP>(argc &gt; 1)</SAMP>, so the variable <SAMP>any_arguments</SAMP> contains the information, whether the program was called with or without arguments.
<TR VALIGN="top"><TD><SAMP>//2</SAMP></TD><TD>The format flag <SAMP>std::ios_base::boolalpha</SAMP> is set in the predefined output stream <SAMP>cout</SAMP>. The effect is that the string representation of boolean values is printed, instead of their numerical representation <SAMP>0</SAMP> or <SAMP>1</SAMP>, which is the default representation.
<TR VALIGN="top"><TD><SAMP>//3</SAMP></TD><TD>Here either the string <SAMP>"true"</SAMP> or the string <SAMP>"false"</SAMP> are printed.
</TABLE>
<P>Of course, the string representation depends on the language. Hence, the alphanumeric representation of boolean values is provided by a locale. It is the <SAMP>std::numpunct</SAMP> facet of a locale that describes the cultural conventions for numerical formatting. It contains services that return the string representations of the boolean values <SAMP>true</SAMP> and <SAMP>false</SAMP>.</P>
<A NAME="idx578"><!></A>
<P>This is the interface of facet <B><I><A HREF="../stdlibref/numpunct.html">numpunct</A></I></B>:</P>
<UL><PRE>
namespace std{
template &lt;class charT&gt;
class numpunct : public locale::facet {
public:
typedef charT char_type;
typedef basic_string&lt;charT&gt; string_type;
explicit numpunct(size_t refs = 0);
char_type decimal_point() const;
char_type thousands_sep() const;
string grouping() const;
string_type <I>truename</I>() const;
string_type <I>falsename</I>() const;
static locale::id id;
// ...
};
}
</PRE></UL>
<A NAME="idx579"><!></A>
<P>Now let us replace this facet. To make it more exciting, let's use not only a different language, but also different words for <SAMP>true</SAMP> and <SAMP>false</SAMP>, such as <SAMP>Yes!</SAMP> and <SAMP>No!</SAMP>. For just using another language, we would not need a new facet; we would simply use the right native locale, and it would contain the right facet.</P>
<UL><PRE>
template &lt;class charT&gt; //1
class change_bool_names
: public std::numpunct_byname&lt;charT&gt; //2
{
public:
typedef std::basic_string&lt;charT&gt; string_type;
explicit change_bool_names (const char* name, //3
const charT* t,
const charT* f, size_t refs=0)
: std::numpunct_byname&lt;charT&gt; (name,refs),
true_string(t), false_string(f) { }
protected:
virtual string_type do_truename() const { //4
return true_string;
}
virtual string_type do_falsename() const {
return false_string;
}
private:
string_type true_string, false_string;
};
</PRE></UL>
<TABLE CELLPADDING="3">
<TR VALIGN="top"><TD><SAMP>//1</SAMP></TD><TD>The new facet is a class template that takes the character type as a template parameter.
<TR VALIGN="top"><TD><SAMP>//2</SAMP></TD><TD>The new facet is derived from the <SAMP>std::numpunct_byname&lt;charT&gt;</SAMP> facet.
<BR><BR>The byname facets read the respective locale information from the external representation of a C locale. The name provided to construct a byname<I> </I>facet is the name of a locale, as you would use it in a call to <SAMP>setlocale()</SAMP>.
<TR VALIGN="top"><TD><SAMP>//3</SAMP></TD><TD>A constructor is provided that takes a locale name and the new values we want to display for the alpha versions of <SAMP>true</SAMP> and <SAMP>false</SAMP>. The fourth parameter, <SAMP>refs</SAMP>, controls the facet's lifetime, as described in an earlier section.
<TR VALIGN="top"><TD><SAMP>//4</SAMP></TD><TD>The virtual member functions <SAMP>do_truename()</SAMP> and <SAMP>do_falsename()</SAMP> are reimplemented. They are called by the public member functions <SAMP>truename()</SAMP> and <SAMP>falsename()</SAMP>. See the <A HREF="../stdlibref/noframes.html"><I>Apache C++ Standard Library Reference Guide</I></A> for further details.
</TABLE>
<P>Now let's create a German locale in which the <SAMP>std::numpunct&lt;char&gt;</SAMP> facet has been replaced by an object of our new derived facet type, as shown in <A HREF="25-5.html#Figure&nbsp;11">Figure&nbsp;11</A>:</P>
<A NAME="idx580"><!></A>
<H4><A NAME="Figure&nbsp;11">Figure&nbsp;11: Replacing the std::numpunct&lt;char&gt; facet object</A></H4>
<P><IMG SRC="images/locfig12.gif" WIDTH=476 HEIGHT=311></P>
<A NAME="idx581"><!></A>
<P>The code looks like this:</P>
<UL><PRE>
void main(int argc, char** argv)
{
std::locale loc(std::locale("de_DE"), //1
new change_bool_names&lt;char&gt;("de_DE","Ja.","Nein.")); //2
std::cout.imbue(loc); //3
std::cout &lt;&lt; "Argumente vorhanden? " //Any arguments?
&lt;&lt; std::boolalpha &lt;&lt; (argc &gt; 1) &lt;&lt; std::endl; //4
}
</PRE></UL>
<TABLE CELLPADDING="3">
<TR VALIGN="top"><TD><SAMP>//1</SAMP></TD><TD>A locale object is constructed with an instance of the new facet class. The locale object has all facet objects from a German locale object, except that the new facet object <SAMP>change_bool_names</SAMP> substitutes for the <SAMP>std::numpunct</SAMP> facet object<SAMP>.</SAMP>
<TR VALIGN="top"><TD><SAMP>//2</SAMP></TD><TD>The new facet object takes all information from a German <SAMP>numpunct</SAMP> facet object, and replaces the default native names for <SAMP>true</SAMP> and <SAMP>false</SAMP> with the provided strings <SAMP>"Ja."</SAMP> ("Yes.") and <SAMP>"Nein."</SAMP> ("No.").
<TR VALIGN="top"><TD><SAMP>//3</SAMP></TD><TD>The standard output stream <SAMP>std::cout</SAMP> is imbued with the newly created locale.
<TR VALIGN="top"><TD><SAMP>//4</SAMP></TD><TD>The expression <SAMP>(argc &gt; 1)</SAMP> yields a boolean value, which indicates whether the program was called with arguments. This boolean value's alphanumeric representation is printed to the standard output stream. The output might be:
<BR><BR><SAMP>Argument vorhanden? Ja.</SAMP>
</TABLE>
<BR>
<HR>
<A HREF="25-4.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="25-6.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>