blob: b307db66520e3366fca378842c052b5ed19b4fa8 [file] [log] [blame]
/***************************************************************************
*
* 22.locale.synopsis.cpp - test exercising synopsis of header <locale>
*
* $Id$
*
***************************************************************************
*
* 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 1994-2008 Rogue Wave Software, Inc.
*
**************************************************************************/
#include <rw/_defs.h>
// disable implicit inclusion to work around a limitation in
// IBM VAC++ 5.0.2.0 (PR #26959)
#if defined __IBMCPP__ && !defined _RWSTD_NO_IMPLICIT_INCLUSION
# define _RWSTD_NO_IMPLICIT_INCLUSION
#endif
// make protected members accessible if possible
#if defined _RWSTD_NO_EXPORT && !defined _MSC_VER
# define protected public
#endif
#include <iterator>
#include <locale>
#include <rw_driver.h>
static void
test_lc_defs ()
{
rw_info (0, __FILE__, __LINE__, "checking LC_XXX constants");
// check that <locale> doesn't introduce any LC_XXX constants
// (not required, but it's good practice to keep headers clean)
static const char* const lc_defs[] =
{
#ifdef LC_ALL
"LC_ALL",
#endif // LC_ALL
#ifdef LC_COLLATE
"LC_COLLATE",
#endif // LC_COLLATE
#ifdef LC_CTYPE
"LC_CTYPE",
#endif // LC_CTYPE
#ifdef LC_MONETARY
"LC_MONETARY",
#endif // LC_MONETARY
#ifdef LC_NUMERIC
"LC_NUMERIC",
#endif // LC_NUMERIC
#ifdef LC_TIME
"LC_TIME",
#endif // LC_TIME
#ifdef LC_MESSAGES
"LC_MESSAGES",
#endif // LC_MESSAGES
0
};
for (unsigned i = 0; i != sizeof lc_defs / sizeof *lc_defs; ++i) {
rw_assert (!lc_defs [i], __FILE__, __LINE__,
"<locale> unexpectedly #defines %s", lc_defs [i]);
}
}
static void
test_isxxx ()
{
rw_info (0, __FILE__, __LINE__, "checking isxxx() macros");
// check that <locale> doesn't introduce any isxxx() macros
static const char* const isxxx[] =
{
#ifdef isspace
"isspace",
#endif // isspace
#ifdef isprint
"isprint",
#endif // isprint
#ifdef iscntrl
"iscntrl",
#endif // iscntrl
#ifdef isupper
"isupper",
#endif // isupper
#ifdef islower
"islower",
#endif // islower
#ifdef isalpha
"isalpha",
#endif // isalpha
#ifdef isdigit
"isdigit",
#endif // isdigit
#ifdef ispunct
"ispunct",
#endif // ispunct
#ifdef isxdigit
"isxdigit",
#endif // isxdigit
#ifdef isalnum
"isalnum",
#endif // isalnum
#ifdef isgraph
"isgraph",
#endif // isgraph
#ifdef toupper
"toupper",
#endif // toupper
#ifdef tolower
"tolower",
#endif // tolower
0
};
for (unsigned i = 0; i != sizeof isxxx / sizeof *isxxx; ++i) {
rw_assert (!isxxx [i], __FILE__, __LINE__,
"<locale> unexpectedly #defines %s", isxxx [i]);
}
}
/***************************************************************************/
#include <clocale> // for LC_XXX macros
#include <cwchar> // for mbstate_t
#if !defined LC_MESSAGES && defined _RWSTD_LC_MESSAGES
# define LC_MESSAGES _RWSTD_LC_MESSAGES
#endif // !LC_MESSAGES && _RWSTD_LC_MESSAGES
// exercise the signature of a nonmember (or static member) function
#define FUN(result, name, arg_list) do { \
/* make name unique to prevent bogus gcc -Wshadow warnings */ \
result (*_RWSTD_PASTE (pf, __LINE__)) arg_list = &name; \
_RWSTD_UNUSED (_RWSTD_PASTE (pf, __LINE__)); \
} while (0)
/***************************************************************************/
// exercise the signatures of std::{has,use}_facet<>()
template <class charT>
static void
test_have_use_facet ()
{
rw_info (0, __FILE__, __LINE__,
"std::has_facet<Facet>(std::locale&) synopsis");
rw_info (0, __FILE__, __LINE__,
"std::use_facet<Facet>(std::locale&) synopsis");
#if !defined __HP_aCC || __HP_aCC > 33100
// working around an HP aCC bug (see PR #23312)
# if !(defined __GNUG__ || __GNUG__ > 2 || __GNUC_MINOR__ > 96) \
&& !(defined _MSC_VER || _MSC_VER >= 0x1300)
// working around a gcc 2.9{5,6} ICE
// working around an MSVC 6.0 bug (PR #26307)
FUN (const std::ctype<charT>&,
std::use_facet<std::ctype<charT> >, (const std::locale&));
FUN (bool, std::has_facet<std::ctype<charT> >, (const std::locale&));
# endif // gcc > 2.96 && MSVC > 6.0
#endif // __HP_aCC > 33000
}
/***************************************************************************/
// exercise the signatures of the convenience locale interfaces
template <class charT>
static void
test_convenience_funs ()
{
rw_info (0, __FILE__, __LINE__,
"std::isxxx(std::locale&) convenience functions synopsis");
FUN (bool, std::isspace, (charT, const std::locale&));
FUN (bool, std::isprint, (charT, const std::locale&));
FUN (bool, std::iscntrl, (charT, const std::locale&));
FUN (bool, std::isupper, (charT, const std::locale&));
FUN (bool, std::islower, (charT, const std::locale&));
FUN (bool, std::isalpha, (charT, const std::locale&));
FUN (bool, std::isdigit, (charT, const std::locale&));
FUN (bool, std::ispunct, (charT, const std::locale&));
FUN (bool, std::isxdigit, (charT, const std::locale&));
FUN (bool, std::isalnum, (charT, const std::locale&));
FUN (bool, std::isgraph, (charT, const std::locale&));
FUN (charT, std::toupper, (charT, const std::locale&));
FUN (charT, std::tolower, (charT, const std::locale&));
}
_RWSTD_NAMESPACE (std) {
#if !defined _MSC_VER
// verify that specializations are present in the lib
_RWSTD_SPECIALIZED_CLASS class ctype<char>;
_RWSTD_SPECIALIZED_CLASS class ctype_byname<char>;
# ifndef _RWSTD_NO_WCHAR_T
_RWSTD_SPECIALIZED_CLASS class ctype<wchar_t>;
_RWSTD_SPECIALIZED_CLASS class ctype_byname<wchar_t>;
# endif // _RWSTD_NO_WCHAR_T
#endif // _MSC_VER
} // namespace std
/***************************************************************************/
// test for the presence of the required facet templates
// and their specializations (as required by Table 52)
template <class charT>
static void
test_facets ()
{
// introduce a typedef to work around a SunPro 5.3 bug (see PR #25967)
typedef charT char_type;
const std::locale::facet *pfac;
_RWSTD_UNUSED (pfac);
{
// collate category
const std::collate<char_type> *col = 0;
const std::collate_byname<char_type> *col_byname = 0;
// verify that facet publicly derives from locale::facet
pfac = col;
col = col_byname;
}
{
// ctype category
// force a link failure if required specializations aren't
// provided (e.g., if only the primary template is defined)
const std::ctype<char_type> *ctp = 0;
const std::ctype_byname<char_type> *ctp_byname = 0;
// verify that facet publicly derives from locale::facet
const std::ctype_base *ctpbase = ctp;
pfac = ctp;
ctp = ctp_byname;
_RWSTD_UNUSED (ctpbase);
}
{
const std::codecvt<char_type, char, std::mbstate_t> *cvt = 0;
const std::codecvt_byname<char_type, char, std::mbstate_t>
*cvt_byname = 0;
// verify that facet publicly derives from locale::facet
pfac = cvt;
const std::codecvt_base *pcvtbase = cvt;
_RWSTD_UNUSED (pcvtbase);
cvt = cvt_byname;
}
typedef std::char_traits<char_type> CTr;
typedef std::istreambuf_iterator<char_type, CTr > IIt;
typedef std::ostreambuf_iterator<char_type, CTr > OIt;
{
// monetary category
const std::moneypunct<char_type, false> *mpun = 0;
const std::moneypunct<char_type, true> *mpun_intl = 0;
const std::moneypunct_byname<char_type, false> *mpun_byname = 0;
const std::moneypunct_byname<char_type, true> *mpun_intl_byname = 0;
const std::money_get<char_type, IIt> *mget = 0;
const std::money_put<char_type, OIt> *mput = 0;
// verify that facets publicly derive from locale::facet
pfac = mpun;
pfac = mpun_intl;
pfac = mget;
pfac = mput;
mpun = mpun_byname;
mpun_intl = mpun_intl_byname;
// verify that punct facets publicly derive from money_base
const std::money_base *pmbase = mpun;
pmbase = mpun_intl;
_RWSTD_UNUSED (pmbase);
#ifndef _RWSTD_NO_DEFAULT_TEMPLATE_ARGS
const std::moneypunct<char_type> *pmpun_noarg = mpun;
_RWSTD_UNUSED (pmpun_noarg);
// verify default template arguments
const std::money_get<char_type> *pmget = mget;
const std::money_put<char_type> *pmput = mput;
_RWSTD_UNUSED (pmget);
_RWSTD_UNUSED (pmput);
#endif // _RWSTD_NO_DEFAULT_TEMPLATE_ARGS
}
{
// numeric category
const std::num_get<char_type, IIt> *nget = 0;
const std::num_put<char_type, OIt> *nput = 0;
// verify that facets publicly derive from locale::facet
pfac = nget;
pfac = nput;
#ifndef _RWSTD_NO_DEFAULT_TEMPLATE_ARGS
// verify default template arguments
const std::num_get<char_type> *pnget = nget;
const std::num_put<char_type> *pnput = nput;
_RWSTD_UNUSED (pnget);
_RWSTD_UNUSED (pnput);
#endif // _RWSTD_NO_DEFAULT_TEMPLATE_ARGS
}
{
// time category
const std::time_get<char_type, IIt> *tget = 0;
const std::time_put<char_type, OIt> *tput = 0;
// verify that facets publicly derive from locale::facet
pfac = tget;
pfac = tput;
#ifndef _RWSTD_NO_DEFAULT_TEMPLATE_ARGS
// verify default template arguments
const std::time_get<char_type> *ptget = tget;
const std::time_put<char_type> *ptput = tput;
_RWSTD_UNUSED (ptget);
_RWSTD_UNUSED (ptput);
#endif // _RWSTD_NO_DEFAULT_TEMPLATE_ARGS
}
{
// messages category
const std::messages<char_type> *msgs = 0;
const std::messages_byname<char_type> *msgs_byname = 0;
// verify that facets publicly derive from locale::facet
pfac = msgs;
const std::messages_base *pmsgbase = msgs;
const std::messages<char_type> *pmsgs = msgs_byname;
_RWSTD_UNUSED (pmsgbase);
_RWSTD_UNUSED (pmsgs);
}
}
/***************************************************************************/
// helper to verify that locale and facet ctors are explicit
// not defined since they must not be referenced if test is successful
void is_explicit (const std::locale&);
void is_explicit (const std::locale::facet&);
void is_explicit (const std::collate<char>&);
void is_explicit (const std::ctype<char>&);
# ifndef _RWSTD_NO_WCHAR_T
void is_explicit (const std::collate<wchar_t>&);
void is_explicit (const std::ctype<wchar_t>&);
# endif // _RWSTD_NO_WCHAR_T
struct has_implicit_ctor
{
// NOT explicit
// for locale::facet::facet (size_t = 0) and derived facet ctors
has_implicit_ctor (std::size_t) { /* empty */ }
// for ctype<char>::ctype (const mask*, bool = false, size_t = 0)
has_implicit_ctor (const std::ctype_base::mask*) { /* empty */ }
// for locale::locale (const char*, size_t = 0)
has_implicit_ctor (const char*) { /* empty */ }
};
// calls to the overloaded is_explicit() resolve to the function below
void is_explicit (const has_implicit_ctor&) { /* empty */ }
/***************************************************************************/
// local to test_locale
static bool dtor_called = false;
struct Facet: std::locale::facet
{
typedef std::locale::facet Base;
// default argument provided to work around a library limitation
// that requires all facets to have default ctors
Facet (std::size_t refs = 0): Base (refs) { /* empty */ }
~Facet () {
dtor_called = true;
}
static std::locale::id id;
};
std::locale::id Facet::id;
// using a global in favor of a static local
// to work around an MSVC 6.0 bug (see PR #26305)
static bool is_dtor_virtual;
template <class charT>
struct StringTypes
{
typedef std::char_traits<charT> traits_type;
typedef std::allocator<charT> Allocator;
typedef std::basic_string<charT, traits_type, Allocator> string_type;
};
// test class locale definition
static void
test_locale ()
{
rw_info (0, __FILE__, __LINE__, "class std::locale synopsis");
// 21.1.1.1.1
const std::locale::category *pcat = (int*)0;
#ifndef _RWSTD_NO_STATIC_CONST_MEMBER_INIT
// verify that category constants are defined
pcat = &std::locale::none;
pcat = &std::locale::collate;
pcat = &std::locale::ctype;
pcat = &std::locale::monetary;
pcat = &std::locale::numeric;
pcat = &std::locale::time;
pcat = &std::locale::messages;
pcat = &std::locale::all;
#endif // _RWSTD_NO_STATIC_CONST_MEMBER_INIT
// verify that category constants are constant integral expressions
switch (*pcat) {
case std::locale::none:
case std::locale::collate:
case std::locale::ctype:
case std::locale::monetary:
case std::locale::numeric:
case std::locale::time:
case std::locale::messages:
case std::locale::all:
break;
}
static const int c_cats [] = {
LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME
#ifdef LC_MESSAGES
, LC_MESSAGES
#endif // LC_MESSAGES
};
static const std::locale::category cats[] = {
std::locale::none, std::locale::collate, std::locale::ctype,
std::locale::monetary, std::locale::numeric, std::locale::time,
std::locale::messages, std::locale::all
};
for (pcat = cats; pcat != cats + sizeof cats / sizeof *cats - 1; ++pcat) {
bool success = true;
for (unsigned i = pcat - cats + 1; i < sizeof cats / sizeof *cats; ++i)
if ( *pcat != std::locale::all
&& cats [i] != std::locale::all
&& (*pcat & cats [i]))
rw_assert (success = false, __FILE__, __LINE__,
"(%{Lc} & %{Lc}) != 0", *pcat, cats [i]);
for (unsigned j = 0; j != sizeof c_cats / sizeof *c_cats; ++j) {
// locale::category values must not conflict with LC_XXX constants
if (*pcat & c_cats [j])
rw_assert (success = false, __FILE__, __LINE__,
"(%{Lc} & %{Lc}) != 0", *pcat, c_cats [j]);
if (*pcat == c_cats [j])
rw_assert (success = false, __FILE__, __LINE__,
"%{Lc} != %{Lc}", *pcat, c_cats [j]);
}
rw_assert (success, __FILE__, __LINE__, "%{Lc}", *pcat);
}
// 21.1.1.1.1, p1
const int all = std::locale::collate
| std::locale::ctype
| std::locale::monetary
| std::locale::numeric
| std::locale::time
| std::locale::messages;
rw_assert (std::locale::all == all, __FILE__, __LINE__,
"std::locale::all == %#x, got %#x", all, std::locale::all);
// 22.1.1.1.2
// verify that locale::facet::facet (size_t) is explicit
is_explicit (std::size_t ());
{
// verify that ctor takes a default argument
struct Facet: std::locale::facet {
typedef std::locale::facet Base;
Facet (): Base () { /* empty */ }
Facet (std::size_t ref): Base (ref) {/* empty */ }
~Facet () {
is_dtor_virtual = true;
}
};
// delete a derived object using a pointer to the base
delete (std::locale::facet*)new Facet ();
rw_assert (is_dtor_virtual, __FILE__, __LINE__,
"locale::facet::~facet() not virtual");
}
// 22.1.1.1.3 - dfeault ctor and dtor are public
std::locale::id id;
_RWSTD_UNUSED (id);
// 22.1.1.2, p1
const std::locale l;
// 22.1.1.2, p3
std::locale l2 (l);
// 22.1.1.2, p6
(void)std::locale ("");
// verify that locale::locale (const char*) is explicit
is_explicit ((const char*)"");
// 22.1.1.2, p9
(void)std::locale (l, "", std::locale::all);
Facet *pf = new Facet (1 /* ref count */);
{
// 22.1.1.2, p12
// enclose unnamed temporary in its own scope to work around
// a SunPro 5.4 bug which amkes it calls the dtor too late
// see PR #27543
(void)std::locale (l, pf);
}
// exercise 22.1.1.1.2, p2, refs == 1
rw_assert (!dtor_called, __FILE__, __LINE__,
"facet dtor called for ref count of 1");
if (!dtor_called)
delete pf;
dtor_called = false;
// exercise 22.1.1.1.2, p2, refs == 0
pf = new Facet (0 /* ref count */);
{
// create an unnamed temporary object and force it to go out of
// scope (in case the compiler, such as SunPro 5.4, fails to
// detsroy it at the end of the expression) so that it is forced
// to destroy the user-defined facet
(void)std::locale (l, pf);
}
rw_assert (dtor_called, __FILE__, __LINE__,
"UD facet dtor not called for ref count of 0");
if (!dtor_called)
delete pf;
pf = 0;
// 22.1.1.2, p14
(void)std::locale (l, l, std::locale::all);
// verify that a member function is accessible and has the appropriate
// signature, including return type and exception specification
#define MEMFUN(result, name, arg_list) \
do { \
/* jumping thru hoops to avoid bogus gcc -Wshadow warnings */ \
result (std::locale::* _RWSTD_PASTE (pf, __LINE__)) \
arg_list = &std::locale::name; \
_RWSTD_UNUSED (_RWSTD_PASTE (pf, __LINE__)); \
} while (0)
#if !defined __HP_aCC || __HP_aCC > 33100
// working around an HP aCC bug (see PR #23312)
// 22.1.1.2, p4
MEMFUN (const std::locale&, operator=,(const std::locale&) _PTR_THROWS(()));
#endif // __HP_aCC > 33000
#if !defined __HP_aCC || __HP_aCC > 33100
// working around an HP aCC bug (see PR #23312)
// 22.1.1.3, p1
MEMFUN (std::locale, combine<Facet>, (const std::locale&) const);
#endif // __HP_aCC > 33000
// 22.1.1.3, p5
MEMFUN (std::string, name, () const);
// 22.1.1.4, p1
MEMFUN (bool, operator==, (const std::locale&) const);
// 22.1.1.4, p2
MEMFUN (bool, operator!=, (const std::locale&) const);
// 22.1.1.4, p3
MEMFUN (bool, operator(), (const std::string&, const std::string&) const);
#ifndef _RWSTD_NO_WCHAR_T
MEMFUN (bool, operator(), (const std::wstring&, const std::wstring&)const);
#endif // _RWSTD_NO_WCHAR_T
// exercise a specialization other than on the default char types
typedef StringTypes<int>::string_type IntString;
MEMFUN (bool, operator(), (const IntString&, const IntString&) const);
// 22.1.1.5
FUN (std::locale, std::locale::global, (const std::locale&));
FUN (const std::locale&, std::locale::classic, ());
}
/***************************************************************************/
// test class template ctype definition
template <class charT>
struct CtypeDerived: std::ctype<charT>
{
typedef std::ctype<charT> CtypeT;
typedef std::ctype_base::mask M;
typedef const charT* PtrT;
// verify that a member function is accessible and has the appropriate
// signature, including return type and exception specification
#undef MEMFUN
#define MEMFUN(result, name, arg_list) \
do { \
result (CtypeT::* pf) arg_list = &CtypeT::name; \
_RWSTD_UNUSED (pf); \
} while (0)
static void test_protected_members () {
// protected members (see `#define protected public' above)
MEMFUN (bool, do_is, (M, charT) const);
MEMFUN (PtrT, do_is, (PtrT, PtrT, M*) const);
// lwg issue 124
MEMFUN (PtrT, do_scan_is, (M, PtrT, PtrT) const);
MEMFUN (PtrT, do_scan_not, (M, PtrT, PtrT) const);
MEMFUN (charT, do_toupper, (charT) const);
MEMFUN (PtrT, do_toupper, (charT*, PtrT) const);
MEMFUN (charT, do_tolower, (charT) const);
MEMFUN (PtrT, do_tolower, (charT*, PtrT) const);
MEMFUN (charT, do_widen, (char) const);
MEMFUN (const char*,
do_widen, (const char*, const char*, charT*) const);
MEMFUN (char, do_narrow, (charT, char) const);
MEMFUN (PtrT, do_narrow,
(PtrT, PtrT, char, char*) const);
}
};
// exercise the primary template
template <class charT>
/*static*/ void
test_ctype_specialization ()
{
CtypeDerived<charT>::test_protected_members ();
}
struct CtypeCharDerived: std::ctype<char>
{
typedef std::ctype<char> CtypeT;
typedef std::ctype_base::mask Mask;
// verify that all required ctors (or one with default args) exist
CtypeCharDerived (): CtypeT () { /* empty */ }
CtypeCharDerived (const Mask *tbl): CtypeT (tbl) { /* empty */ }
CtypeCharDerived (const Mask *tbl, bool del): CtypeT (tbl, del) { /* empty */ }
CtypeCharDerived (const Mask *tbl, bool del, std::size_t ref)
: CtypeT (tbl, del, ref) { /* empty */ }
static void test_protected_members () {
#ifndef _RWSTD_NO_STATIC_CONST_MEMBER_INIT
// verify that table_size is properly defined
const std::size_t *psz = &std::ctype<char>::table_size;
#else
const std::size_t dummy = std::ctype<char>::table_size;
const std::size_t *psz = &dummy;
#endif // _RWSTD_NO_STATIC_CONST_MEMBER_INIT
// verify that table_size is an integral constant expression
switch (*psz) {
case std::ctype<char>::table_size: break;
}
MEMFUN (char, do_toupper, (char) const);
MEMFUN (const char*, do_toupper, (char*, const char*) const);
MEMFUN (char, do_tolower, (char) const);
MEMFUN (const char*, do_tolower, (char*, const char*) const);
MEMFUN (char, do_widen, (char) const);
MEMFUN (const char*, do_widen,
(const char*, const char*, char*) const);
MEMFUN (char, do_narrow, (char, char) const);
MEMFUN (const char*, do_narrow,
(const char*, const char*, char, char*) const);
// 22.2.1.3.2, p12
MEMFUN (const std::ctype_base::mask*,
table, () const _PTR_THROWS (()));
// 22.2.1.3.3
FUN (const std::ctype_base::mask*,
CtypeT::classic_table, () _PTR_THROWS (()));
}
};
// exercise the char specialization
_RWSTD_SPECIALIZED_FUNCTION
/*static*/ void
test_ctype_specialization<char> ()
{
// prevent multiple assertions
static int called /* = false */;
if (called++)
return;
// 22.2.1.3.2, p3 - verify that ctor is explicit
is_explicit ((const std::ctype_base::mask*)0);
CtypeCharDerived::test_protected_members ();
}
// skip POSIX-dependent behavior
static int opt_enable_posix = 0; // --enable-posix
template <class charT>
static void
test_ctype (const char* cname)
{
rw_info (0, __FILE__, __LINE__,
"std::ctype<%s> synopsis", cname);
std::ctype_base::mask m = std::ctype_base::space;
_RWSTD_UNUSED (m);
const std::ctype_base::mask *pm = 0;
_RWSTD_UNUSED (pm);
// verify that mask constants are constant integral expressions
// whose address can be taken
switch (m) {
#ifndef _RWSTD_NO_STATIC_CONST_MEMBER_INIT
// see lwg issue 339
# define ADDR(name) pm = &std::ctype_base::name
#else
# define ADDR(ignore) (void)0
#endif
#if !defined __IBMCPP__ || __IBMCPP__ > 800
// working around an IBM VAC++ bug #559
case std::ctype_base::mask (): break;
#endif // !VAC+ || VAC++ > 7.0
case std::ctype_base::space: ADDR (space); break;
case std::ctype_base::print: ADDR (print); break;
case std::ctype_base::cntrl: ADDR (cntrl); break;
case std::ctype_base::upper: ADDR (upper); break;
case std::ctype_base::lower: ADDR (lower); break;
case std::ctype_base::alpha: ADDR (alpha); break;
case std::ctype_base::digit: ADDR (digit); break;
case std::ctype_base::punct: ADDR (punct); break;
case std::ctype_base::xdigit: ADDR (xdigit); break;
case std::ctype_base::alnum: ADDR (alnum); break;
case std::ctype_base::graph: ADDR (graph); break;
default: break;
}
// prevent unnecessary assertions
if (sizeof (charT) == sizeof (char)) {
rw_assert (std::ctype_base::alnum ==
(std::ctype_base::alpha | std::ctype_base::digit),
__FILE__, __LINE__,
"std::ctype_base::alnum = %#x, expected %#x",
std::ctype_base::alnum,
std::ctype_base::alpha | std::ctype_base::digit);
if (opt_enable_posix) {
// POSIX allows graph characters that aren't alnum or punct
// 22.2.1 says the numeric values are for exposition only
// which presumably applies to all the constants
rw_assert (std::ctype_base::graph
== (std::ctype_base::alnum | std::ctype_base::punct),
__FILE__, __LINE__,
"std::ctype_base::graph = %#x, expected %#x",
std::ctype_base::graph,
std::ctype_base::alnum | std::ctype_base::punct);
}
}
typedef std::ctype<charT> CtypeT;
typedef typename CtypeT::mask Mask;
charT *pc = (typename CtypeT::char_type*)0;
_RWSTD_UNUSED (pc);
typedef const charT* PtrT;
MEMFUN (bool, is, (Mask, charT) const);
MEMFUN (PtrT, is, (PtrT, PtrT, Mask*) const);
MEMFUN (PtrT, scan_is, (Mask, PtrT, PtrT) const);
MEMFUN (PtrT, scan_not, (Mask, PtrT, PtrT) const);
MEMFUN (charT, toupper, (charT) const);
MEMFUN (PtrT, toupper, (charT*, PtrT) const);
MEMFUN (charT, tolower, (charT) const);
MEMFUN (PtrT, tolower, (charT*, PtrT) const);
MEMFUN (charT, widen, (char) const);
MEMFUN (const char*, widen, (const char*, const char*, charT*) const);
MEMFUN (char, narrow, (charT, char) const);
MEMFUN (PtrT, narrow,
(PtrT, PtrT, char, char*) const);
std::locale::id *pid = &CtypeT::id;
_RWSTD_UNUSED (pid);
// exercise virtuals and other parts that differ between
// the primary template and the char specialization
test_ctype_specialization<charT> ();
}
/***************************************************************************/
template <class charT>
struct CodecvtDerived: std::codecvt<charT, char, std::mbstate_t>
{
typedef std::codecvt<charT, char, std::mbstate_t> Codecvt;
typedef std::codecvt_base::result Result;
typedef typename Codecvt::intern_type InternT;
typedef typename Codecvt::extern_type ExternT;
typedef typename Codecvt::state_type StateT;
// verify that a member function is accessible and has the appropriate
// signature, including return type and exception specification
#undef MEMFUN
#define MEMFUN(result, name, arg_list) \
do { \
result (Codecvt::*pf) arg_list = &Codecvt::name; \
_RWSTD_UNUSED (pf); \
} while (0)
void test_protected_members () {
// protected virtuals
MEMFUN (Result, do_out,
(StateT&, const InternT*, const InternT*, const InternT*&,
ExternT*, ExternT*, ExternT*&) const);
MEMFUN (Result, do_unshift,
(StateT&, ExternT*, ExternT*, ExternT*&) const);
MEMFUN (Result, do_in,
(StateT&, const ExternT*, const ExternT*, const ExternT*&,
InternT*, InternT*, InternT*&) const);
MEMFUN (int, do_encoding, () const _PTR_THROWS (()));
MEMFUN (bool, do_always_noconv, () const _PTR_THROWS (()));
// lwg issue 75 changes first argument from const StateT& to State&
MEMFUN (int, do_length,
(StateT&, const ExternT*, const ExternT*,
std::size_t) const);
MEMFUN (int, do_max_length, () const _PTR_THROWS (()));
}
};
template <class charT>
static void
test_codecvt (const char* cname)
{
rw_info (0, __FILE__, __LINE__,
"std::codecvt<%s, char, std::mbstate_t> synopsis", cname);
// verify base class
std::codecvt_base b;
std::codecvt_base::result r = b.ok;
// prevent a bogus MSVC warning 4101 (see PR #24178)
_RWSTD_UNUSED (b);
// verify that result is a constant integral expression
switch (r) {
case std::codecvt_base::ok:
case std::codecvt_base::partial:
case std::codecvt_base::error:
case std::codecvt_base::noconv:
break;
}
typedef std::codecvt<charT, char, std::mbstate_t> Codecvt;
// verify that nested types exist
typedef typename Codecvt::intern_type InternT;
typedef typename Codecvt::extern_type ExternT;
typedef typename Codecvt::state_type StateT;
// verify nested types
const InternT *pint = (const charT*)0;
const ExternT *pext = (const char*)0;
const StateT *pst = (const std::mbstate_t*)0;
_RWSTD_UNUSED (pint);
_RWSTD_UNUSED (pext);
_RWSTD_UNUSED (pst);
typedef std::codecvt_base::result Result;
// public non-virtuals
MEMFUN (Result, out,
(StateT&, const InternT*, const InternT*, const InternT*&,
ExternT*, ExternT*, ExternT*&) const);
MEMFUN (Result, unshift, (StateT&, ExternT*, ExternT*, ExternT*&) const);
MEMFUN (Result, in,
(StateT&, const ExternT*, const ExternT*, const ExternT*&,
InternT*, InternT*, InternT*&) const);
MEMFUN (int, encoding, () const _PTR_THROWS (()));
MEMFUN (bool, always_noconv, () const _PTR_THROWS (()));
// lwg issue 75 changes the first argument from const StateT& to State&
MEMFUN (int, length,
(StateT&, const ExternT*, const ExternT*, std::size_t) const);
MEMFUN (int, max_length, () const _PTR_THROWS (()));
std::locale::id *pid = &Codecvt::id;
_RWSTD_UNUSED (pid);
CodecvtDerived<charT>().test_protected_members ();
}
/***************************************************************************/
// user-defined character type; used to exercise requirements in Table 52
// i.e., specializations of facets on types other than char and wchar_t
#define UDC int
// numeric category
namespace std {
// provide an explicit specialization of numpunct on UDC necessary
// in order to exercise num_get<UDC> and num_put<UDC>
_RWSTD_SPECIALIZED_CLASS
struct numpunct<UDC>: locale::facet
{
typedef UDC char_type;
typedef StringTypes<char_type>::string_type string_type;
// working around an MSVC 6.0 bug
typedef locale::facet Base;
explicit numpunct (size_t refs = 0)
: Base (refs) { /* empty */ }
static locale::id id;
char_type decimal_point () const { return char_type (); }
char_type thousands_sep () const { return char_type (); }
string grouping () const { return ""; }
string_type falsename () const { return string_type (); }
string_type truename () const { return string_type (); }
};
locale::id numpunct<UDC>::id;
} // namespace std
template <class charT>
struct NumPunctDerived: std::numpunct<charT>
{
typedef std::numpunct<charT> NumPunct;
typedef typename StringTypes<charT>::string_type StringT;
// verify that a member function is accessible and has the appropriate
// signature, including return type and exception specification
#undef MEMFUN
#define MEMFUN(result, name, arg_list) \
do { \
result (NumPunct::*pf) arg_list = &NumPunct::name; \
_RWSTD_UNUSED (pf); \
} while (0)
static void test_protected_members () {
// protected virtuals
MEMFUN (charT, do_decimal_point, () const);
MEMFUN (charT, do_thousands_sep, () const);
MEMFUN (std::string, do_grouping, () const);
MEMFUN (StringT, do_truename, () const);
MEMFUN (StringT, do_falsename, () const);
}
};
template <class charT>
static void
test_numpunct (const char* cname)
{
rw_info (0, __FILE__, __LINE__,
"std::numpunct<%s> synopsis", cname);
typedef std::numpunct<charT> NumPunct;
typedef typename StringTypes<charT>::string_type StringT;
// verify nested types
typename NumPunct::char_type *pc = (charT*)0;
typename NumPunct::string_type *pstr = (StringT*)0;
_RWSTD_UNUSED (pc);
_RWSTD_UNUSED (pstr);
// public interface
MEMFUN (charT, decimal_point, () const);
MEMFUN (charT, thousands_sep, () const);
MEMFUN (std::string, grouping, () const);
MEMFUN (StringT, truename, () const);
MEMFUN (StringT, falsename, () const);
// verify that id is defined and non-const
std::locale::id *pid = &NumPunct::id;
_RWSTD_UNUSED (pid);
NumPunctDerived<charT>::test_protected_members ();
}
typedef std::ios_base IosBase;
typedef std::ios_base::iostate IoState;
template <class charT, class IterT>
struct NumGetDerived: std::num_get<charT, IterT>
{
typedef std::num_get<charT, IterT> NumGet;
// verify that a member function is accessible and has the appropriate
// signature, including return type and exception specification
#undef MEMFUN
#define MEMFUN(result, name, arg_list) \
do { \
result (NumGet::*pf) arg_list = &NumGet::name; \
_RWSTD_UNUSED (pf); \
} while (0)
static void test_protected_members () {
// protected virtuals
MEMFUN (IterT, do_get,
(IterT, IterT, IosBase&, IoState&, bool&) const);
MEMFUN (IterT, do_get,
(IterT, IterT, IosBase& ,IoState&, long&) const);
MEMFUN (IterT, do_get,
(IterT, IterT, IosBase&, IoState&, unsigned short&) const);
MEMFUN (IterT, do_get,
(IterT, IterT, IosBase&, IoState&, unsigned&) const);
MEMFUN (IterT, do_get,
(IterT, IterT, IosBase&, IoState&, unsigned long&) const);
#ifdef _RWSTD_LONG_LONG
// extensions disabled in strict ANSI mode
MEMFUN (IterT, do_get,
(IterT, IterT, IosBase&, IoState&, _RWSTD_LONG_LONG&) const);
MEMFUN (IterT, do_get,
(IterT, IterT, IosBase&, IoState&,
unsigned _RWSTD_LONG_LONG&) const);
#endif // _RWSTD_LONG_LONG
MEMFUN (IterT, do_get,
(IterT, IterT, IosBase&, IoState&, float&) const);
MEMFUN (IterT, do_get,
(IterT, IterT, IosBase&, IoState&, double&) const);
MEMFUN (IterT, do_get,
(IterT, IterT, IosBase&, IoState&, long double&) const);
MEMFUN (IterT, do_get,
(IterT, IterT, IosBase&, IoState&, void*&) const);
}
};
template <class charT, class IterT>
static void
test_num_get (const char* cname, const char* iname)
{
rw_info (0, __FILE__, __LINE__,
"std::num_get<%s, %s > synopsis", cname, iname);
typedef std::num_get<charT, IterT> NumGet;
// verify nested types
typename NumGet::char_type *pc = (charT*)0;
typename NumGet::iter_type *pi = (IterT*)0;
_RWSTD_UNUSED (pc);
_RWSTD_UNUSED (pi);
// public interface
MEMFUN (IterT, get, (IterT, IterT, IosBase&, IoState&, bool&) const);
MEMFUN (IterT, get, (IterT, IterT, IosBase&, IoState&, long&) const);
MEMFUN (IterT, get,
(IterT, IterT, IosBase&, IoState&, unsigned short&) const);
MEMFUN (IterT, get,
(IterT, IterT, IosBase&, IoState&, unsigned&) const);
MEMFUN (IterT, get,
(IterT, IterT, IosBase&, IoState&, unsigned long&) const);
#ifdef _RWSTD_LONG_LONG
// extensions disabled in strict ANSI mode
MEMFUN (IterT, get,
(IterT, IterT, IosBase&, IoState&, _RWSTD_LONG_LONG&) const);
MEMFUN (IterT, get,
(IterT, IterT, IosBase&, IoState&,
unsigned _RWSTD_LONG_LONG&) const);
#endif // _RWSTD_LONG_LONG
MEMFUN (IterT, get,
(IterT, IterT, IosBase&, IoState&, float&) const);
MEMFUN (IterT, get,
(IterT, IterT, IosBase&, IoState&, double&) const);
MEMFUN (IterT, get,
(IterT, IterT, IosBase&, IoState&, long double&) const);
MEMFUN (IterT, get,
(IterT, IterT, IosBase&, IoState&, void*&) const);
std::locale::id *pid = &NumGet::id;
_RWSTD_UNUSED (pid);
NumGetDerived<charT, IterT>::test_protected_members ();
}
template <class charT, class IterT>
struct NumPutDerived: std::num_put<charT, IterT>
{
typedef std::num_put<charT, IterT> NumPut;
// verify that a member function is accessible and has the appropriate
// signature, including return type and exception specification
#undef MEMFUN
#define MEMFUN(result, name, arg_list) \
do { \
result (NumPut::*pf) arg_list = &NumPut::name; \
_RWSTD_UNUSED (pf); \
} while (0)
static void test_protected_members () {
// protected virtuals
MEMFUN (IterT, do_put, (IterT, IosBase&, charT, bool) const);
MEMFUN (IterT, do_put, (IterT, IosBase&, charT, long) const);
// no overloads for unsigned short or unsigned int
MEMFUN (IterT, do_put, (IterT, IosBase&, charT, unsigned long) const);
#ifdef _RWSTD_LONG_LONG
// extensions disabled when _RWSTD_NO_LONG_LONG is #defined
MEMFUN (IterT, do_put,
(IterT, IosBase&, charT, _RWSTD_LONG_LONG) const);
MEMFUN (IterT, do_put,
(IterT, IosBase&, charT, unsigned _RWSTD_LONG_LONG) const);
#endif // _RWSTD_LONG_LONG
// no float overload
MEMFUN (IterT, do_put, (IterT, IosBase&, charT, double) const);
MEMFUN (IterT, do_put, (IterT, IosBase&, charT, long double) const);
MEMFUN (IterT, do_put, (IterT, IosBase&, charT, const void*) const);
}
};
template <class charT, class IterT>
static void
test_num_put (const char* cname, const char* iname)
{
rw_info (0, __FILE__, __LINE__,
"std::num_put<%s, %s > synopsis", cname, iname);
typedef std::num_put<charT, IterT> NumPut;
// verify nested types
typename NumPut::char_type *pc = (charT*)0;
typename NumPut::iter_type *pi = (IterT*)0;
_RWSTD_UNUSED (pc);
_RWSTD_UNUSED (pi);
// public interface
MEMFUN (IterT, put, (IterT, IosBase&, charT, bool) const);
MEMFUN (IterT, put, (IterT, IosBase&, charT, long) const);
MEMFUN (IterT, put, (IterT, IosBase&, charT, unsigned long) const);
#ifdef _RWSTD_LONG_LONG
// extensions disabled in strict ANSI mode
MEMFUN (IterT, put,
(IterT, IosBase&, charT, _RWSTD_LONG_LONG) const);
MEMFUN (IterT, put,
(IterT, IosBase&, charT, unsigned _RWSTD_LONG_LONG) const);
#endif // _RWSTD_LONG_LONG
MEMFUN (IterT, put, (IterT, IosBase&, charT, double) const);
MEMFUN (IterT, put, (IterT, IosBase&, charT, long double) const);
MEMFUN (IterT, put, (IterT, IosBase&, charT, const void*) const);
std::locale::id *pid = &NumPut::id;
_RWSTD_UNUSED (pid);
NumPutDerived<charT, IterT>::test_protected_members ();
}
/***************************************************************************/
// collate category
template <class charT>
struct CollateDerived: std::collate<charT>
{
typedef const charT* PtrT;
typedef std::collate<charT> Collate;
typedef typename StringTypes<charT>::string_type StringT;
// verify that a member function is accessible and has the appropriate
// signature, including return type and exception specification
#undef MEMFUN
#define MEMFUN(result, name, arg_list) \
do { \
result (Collate::* pf) arg_list = &Collate::name; \
_RWSTD_UNUSED (pf); \
} while (0)
static void test_protected_members () {
MEMFUN (int, compare, (PtrT, PtrT, PtrT, PtrT) const);
MEMFUN (StringT, transform, (PtrT, PtrT) const);
MEMFUN (long, hash, (PtrT, PtrT) const);
std::locale::id *pid = &Collate::id;
_RWSTD_UNUSED (pid);
// protected virtuals (see `#define protected public' above)
MEMFUN (int, do_compare, (PtrT, PtrT, PtrT, PtrT) const);
MEMFUN (StringT, do_transform, (PtrT, PtrT) const);
MEMFUN (long, do_hash, (PtrT, PtrT) const);
}
};
template <class charT>
static void
test_collate (const char* cname)
{
rw_info (0, __FILE__, __LINE__,
"std::collate<%s> synopsis", cname);
typedef std::collate<charT> Collate;
typedef typename StringTypes<charT>::string_type StringT;
// verify nested types
typename Collate::char_type *pc = (charT*)0;
typename Collate::string_type *pstr = (StringT*)0;
_RWSTD_UNUSED (pc);
_RWSTD_UNUSED (pstr);
CollateDerived<charT>::test_protected_members ();
}
/***************************************************************************/
// time category
template <class charT, class IterT>
struct TimeGetDerived: std::time_get<charT, IterT>
{
typedef std::time_get<charT, IterT> TimeGet;
// verify that a member function is accessible and has the appropriate
// signature, including return type and exception specification
#undef MEMFUN
#define MEMFUN(result, name, arg_list) \
do { \
result (TimeGet::* pf) arg_list = &TimeGet::name; \
_RWSTD_UNUSED (pf); \
} while (0)
static void test_protected_members () {
// protected virtuals
MEMFUN (std::time_base::dateorder, do_date_order, () const);
MEMFUN (IterT, do_get_time,
(IterT, IterT, IosBase&, IoState&, std::tm*) const);
MEMFUN (IterT, do_get_date,
(IterT, IterT, IosBase&, IoState&, std::tm*) const);
MEMFUN (IterT, do_get_weekday,
(IterT, IterT, IosBase&, IoState&, std::tm*) const);
MEMFUN (IterT, do_get_monthname,
(IterT, IterT, IosBase&, IoState&, std::tm*) const);
MEMFUN (IterT, do_get_year,
(IterT, IterT, IosBase&, IoState&, std::tm*) const);
}
};
template <class charT, class IterT>
static void
test_time_get (const char* cname, const char* iname)
{
rw_info (0, __FILE__, __LINE__,
"std::time_get<%s, %s > synopsis", cname, iname);
typedef std::time_get<charT, IterT> TimeGet;
// verify that dateorder constants are constant integral expressions
std::time_base::dateorder ord = std::time_base::no_order;
switch (ord) {
case std::time_base::no_order:
case std::time_base::dmy: case std::time_base::mdy:
case std::time_base::ymd: case std::time_base::ydm:
break;
}
// verify values
rw_assert (0 == std::time_base::no_order, __FILE__, __LINE__,
"std::time_base::no_order");
rw_assert (1 == std::time_base::dmy, __FILE__, __LINE__,
"std::time_base::dmy");
rw_assert (2 == std::time_base::mdy, __FILE__, __LINE__,
"std::time_base::mdy");
rw_assert (3 == std::time_base::ymd, __FILE__, __LINE__,
"std::time_base::ymd");
rw_assert (4 == std::time_base::ydm, __FILE__, __LINE__,
"std::time_base::ydm");
// verify nested types
typename TimeGet::char_type *pc = (charT*)0;
typename TimeGet::iter_type *pi = (IterT*)0;
_RWSTD_UNUSED (pc);
_RWSTD_UNUSED (pi);
// public non-virtuals
MEMFUN (std::time_base::dateorder, date_order, () const);
MEMFUN (IterT, get_time,
(IterT, IterT, IosBase&, IoState&, std::tm*) const);
MEMFUN (IterT, get_date,
(IterT, IterT, IosBase&, IoState&, std::tm*) const);
MEMFUN (IterT, get_weekday,
(IterT, IterT, IosBase&, IoState&, std::tm*) const);
MEMFUN (IterT, get_monthname,
(IterT, IterT, IosBase&, IoState&, std::tm*) const);
MEMFUN (IterT, get_year,
(IterT, IterT, IosBase&, IoState&, std::tm*) const);
std::locale::id *pid = &TimeGet::id;
_RWSTD_UNUSED (pid);
TimeGetDerived<charT, IterT>::test_protected_members ();
}
template <class charT, class IterT>
struct TimePutDerived: std::time_put<charT, IterT>
{
typedef std::time_put<charT, IterT> TimePut;
// verify that a member function is accessible and has the appropriate
// signature, including return type and exception specification
#undef MEMFUN
#define MEMFUN(result, name, arg_list) \
do { \
result (TimePut::*pf) arg_list = &TimePut::name; \
_RWSTD_UNUSED (pf); \
} while (0)
static void test_protected_members () {
// protected virtuals
MEMFUN (IterT, do_put, (IterT, IosBase&, charT, const std::tm*,
char, char) const);
}
};
template <class charT, class IterT>
static void
test_time_put (const char* cname, const char* iname)
{
rw_info (0, __FILE__, __LINE__,
"std::time_put<%s, %s > synopsis", cname, iname);
typedef std::time_put<charT, IterT> TimePut;
// verify nested types
typename TimePut::char_type *pc = (charT*)0;
typename TimePut::iter_type *pi = (IterT*)0;
_RWSTD_UNUSED (pc);
_RWSTD_UNUSED (pi);
// public non-virtuals
MEMFUN (IterT, put, (IterT, IosBase&, charT, const std::tm*,
const charT*, const charT*) const);
MEMFUN (IterT, put, (IterT, IosBase&, charT, const std::tm*,
char, char) const);
std::locale::id *pid = &TimePut::id;
_RWSTD_UNUSED (pid);
TimePutDerived<charT, IterT>::test_protected_members ();
}
/***************************************************************************/
// monetary category
namespace std {
// (in the absence of support for partial specialization) provide explicit
// specializations of moneypunct on UDC necessary in order to exercise
// money_get<UDC> and money_put<UDC>
_RWSTD_SPECIALIZED_CLASS
struct moneypunct<UDC, false>: locale::facet, money_base
{
typedef UDC char_type;
typedef StringTypes<char_type>::string_type string_type;
// working around an MSVC 6.0 bug
typedef locale::facet Base;
explicit moneypunct (size_t refs = 0)
: Base (refs), money_base () { /* empty */ }
static locale::id id;
enum { intl = false };
char_type decimal_point () const { return char_type (); }
char_type thousands_sep () const { return char_type (); }
string grouping () const { return ""; }
string_type curr_symbol () const { return string_type (); }
string_type positive_sign () const { return string_type (); }
string_type negative_sign () const { return string_type (); }
int frac_digits () const { return 0; }
pattern pos_format () const { return pattern (); }
pattern neg_format () const { return pattern (); }
};
locale::id moneypunct<UDC, false>::id;
_RWSTD_SPECIALIZED_CLASS
struct moneypunct<UDC, true>: locale::facet, money_base
{
typedef UDC char_type;
typedef StringTypes<char_type>::string_type string_type;
// working around an MSVC 6.0 bug
typedef locale::facet Base;
explicit moneypunct (size_t refs = 0)
: Base (refs), money_base () { /* empty */ }
static locale::id id;
enum { intl = true };
char_type decimal_point () const { return char_type (); }
char_type thousands_sep () const { return char_type (); }
string grouping () const { return ""; }
string_type curr_symbol () const { return string_type (); }
string_type positive_sign () const { return string_type (); }
string_type negative_sign () const { return string_type (); }
int frac_digits () const { return 0; }
pattern pos_format () const { return pattern (); }
pattern neg_format () const { return pattern (); }
};
locale::id moneypunct<UDC, true>::id;
} // namespace std
template <class charT, bool Intl>
struct MoneyPunctDerived: std::moneypunct<charT, Intl>
{
typedef std::moneypunct<charT, Intl> MoneyPunct;
typedef typename StringTypes<charT>::string_type StringT;
// verify that a member function is accessible and has the appropriate
// signature, including return type and exception specification
#undef MEMFUN
#define MEMFUN(result, name, arg_list) \
do { \
result (MoneyPunct::* pf) arg_list = &MoneyPunct::name; \
_RWSTD_UNUSED (pf); \
} while (0)
static void test_protected_members () {
// protected virtuals
MEMFUN (charT, do_decimal_point, () const);
MEMFUN (charT, do_thousands_sep, () const );
MEMFUN (std::string, do_grouping, () const );
MEMFUN (StringT, do_curr_symbol, () const);
MEMFUN (StringT, do_positive_sign, () const);
MEMFUN (StringT, do_negative_sign, () const);
MEMFUN (int, do_frac_digits, () const);
MEMFUN (std::money_base::pattern, do_pos_format, () const);
MEMFUN (std::money_base::pattern, do_neg_format, () const);
}
};
template <class charT>
static void
test_moneypunct (const char* cname)
{
rw_info (0, __FILE__, __LINE__,
"std::moneypunct<%s, bool> synopsis", cname);
typedef std::moneypunct<charT, false> MoneyPunct;
typedef typename StringTypes<charT>::string_type StringT;
typename MoneyPunct::char_type *pc = (charT*)0;
typename MoneyPunct::string_type *ps = (StringT*)0;
_RWSTD_UNUSED (pc);
_RWSTD_UNUSED (ps);
MEMFUN (charT, decimal_point, () const );
MEMFUN (charT, thousands_sep, () const );
MEMFUN (std::string, grouping, () const );
MEMFUN (StringT, curr_symbol, () const);
MEMFUN (StringT, positive_sign, () const);
MEMFUN (StringT, negative_sign, () const);
MEMFUN (int, frac_digits, () const);
MEMFUN (std::money_base::pattern, pos_format, () const);
MEMFUN (std::money_base::pattern, neg_format, () const);
std::locale::id *pid = &MoneyPunct::id;
_RWSTD_UNUSED (pid);
MoneyPunctDerived<charT, false>::test_protected_members ();
}
template <class charT, class IterT>
struct MoneyGetDerived: std::money_get<charT, IterT>
{
typedef std::money_get<charT, IterT> MoneyGet;
typedef typename StringTypes<charT>::string_type StringT;
// verify that a member function is accessible and has the appropriate
// signature, including return type and exception specification
#undef MEMFUN
#define MEMFUN(result, name, arg_list) \
do { \
result (MoneyGet::*pf) arg_list = &MoneyGet::name; \
_RWSTD_UNUSED (pf); \
} while (0)
static void test_protected_members () {
// protected virtuals
#ifndef _RWSTD_NO_LONG_DOUBLE
MEMFUN (IterT, do_get, (IterT, IterT, bool, IosBase&,
IoState&, long double&) const);
#else // if defined _RWSTD_NO_LONG_DOUBLE
MEMFUN (IterT, do_get, (IterT, IterT, bool, IosBase&,
IoState&, double&) const);
#endif // _RWSTD_NO_LONG_DOUBLE
MEMFUN (IterT, do_get, (IterT, IterT, bool, IosBase&,
IoState&, StringT&) const);
}
};
template <class charT, class IterT>
static void
test_money_get (const char* cname, const char* iname)
{
rw_info (0, __FILE__, __LINE__,
"std::money_get<%s, %s > synopsis", cname, iname);
typedef std::money_get<charT, IterT> MoneyGet;
typedef typename StringTypes<charT>::string_type StringT;
// verify nested types
typename MoneyGet::char_type *pc = (charT*)0;
typename MoneyGet::iter_type *pi = (IterT*)0;
typename MoneyGet::string_type *ps = (StringT*)0;
_RWSTD_UNUSED (pc);
_RWSTD_UNUSED (pi);
_RWSTD_UNUSED (ps);
// public interface
MEMFUN (IterT, get, (IterT, IterT, bool, IosBase&,
IoState&, long double&) const);
MEMFUN (IterT, get, (IterT, IterT, bool, IosBase&,
IoState&, StringT&) const);
std::locale::id *pid = &MoneyGet::id;
_RWSTD_UNUSED (pid);
MoneyGetDerived<charT, IterT>::test_protected_members ();
}
template <class charT, class IterT>
struct MoneyPutDerived: std::money_put<charT, IterT>
{
typedef std::money_put<charT, IterT> MoneyPut;
typedef typename StringTypes<charT>::string_type StringT;
// verify that a member function is accessible and has the appropriate
// signature, including return type and exception specification
#undef MEMFUN
#define MEMFUN(result, name, arg_list) \
do { \
result (MoneyPut::*pf) arg_list = &MoneyPut::name; \
_RWSTD_UNUSED (pf); \
} while (0)
static void test_protected_members () {
// protected virtuals
#ifndef _RWSTD_NO_LONG_DOUBLE
MEMFUN (IterT, do_put, (IterT, bool, IosBase&, charT,
long double) const);
#else // if defined _RWSTD_NO_LONG_DOUBLE
MEMFUN (IterT, do_put, (IterT, bool, IosBase&, charT, double) const);
#endif // _RWSTD_NO_LONG_DOUBLE
MEMFUN (IterT, do_put, (IterT, bool, IosBase&, charT,
const StringT&) const);
}
};
template <class charT, class IterT>
static void
test_money_put (const char* cname, const char* iname)
{
rw_info (0, __FILE__, __LINE__,
"std::money_put<%s, %s > synopsis", cname, iname);
typedef std::money_put<charT, IterT> MoneyPut;
typedef typename StringTypes<charT>::string_type StringT;
//verify nested types
typename MoneyPut::char_type *pc = (charT*)0;
typename MoneyPut::iter_type *pi = (IterT*)0;
typename MoneyPut::string_type *ps = (StringT*)0;
_RWSTD_UNUSED (pc);
_RWSTD_UNUSED (pi);
_RWSTD_UNUSED (ps);
// public interface
MEMFUN (IterT, put, (IterT, bool, IosBase&, charT,
long double) const);
MEMFUN (IterT, put, (IterT, bool, IosBase&, charT,
const StringT&) const);
std::locale::id *pid = &MoneyPut::id;
_RWSTD_UNUSED (pid);
MoneyPutDerived<charT, IterT>::test_protected_members ();
}
/***************************************************************************/
// messges category
template <class charT>
struct MessagesDerived: std::messages<charT>
{
typedef std::messages<charT> Messages;
typedef typename StringTypes<charT>::string_type StringT;
// verify that a member function is accessible and has the appropriate
// signature, including return type and exception specification
#undef MEMFUN
#define MEMFUN(result, name, arg_list) \
do { \
result (Messages::* pf) arg_list = &Messages::name; \
_RWSTD_UNUSED (pf); \
} while (0)
static void test_protected_members () {
// protected virtuals
MEMFUN (int, do_open,
(const std::string&, const std::locale&) const);
MEMFUN (StringT, do_get, (int, int, int, const StringT&) const);
MEMFUN (void, do_close, (int) const);
}
};
template <class charT>
static void
test_messages (const char* cname)
{
rw_info (0, __FILE__, __LINE__,
"std::messages<%s> synopsis", cname);
typedef std::messages<charT> Messages;
typedef typename StringTypes<charT>::string_type StringT;
// verify nested types
std::messages_base::catalog *pcat = (int*)0;
typename Messages::char_type *pc = (charT*)0;
typename Messages::string_type *pstr = (StringT*)0;
_RWSTD_UNUSED (pcat);
_RWSTD_UNUSED (pc);
_RWSTD_UNUSED (pstr);
// public interface
MEMFUN (int, open, (const std::string&, const std::locale&) const);
MEMFUN (StringT, get, (int, int, int, const StringT&) const);
MEMFUN (void, close, (int) const);
std::locale::id *pid = &Messages::id;
_RWSTD_UNUSED (pid);
MessagesDerived<charT>::test_protected_members ();
}
/***************************************************************************/
static int
run_test (int /*unused*/, char* /*unused*/ [])
{
test_lc_defs ();
test_isxxx ();
// exercise the signatures of std::{has,use}_facet<>()
test_have_use_facet<char> ();
// exercise the signatures of the convenience locale interfaces
test_convenience_funs<char> ();
// test for the presence of the required facet templates
test_facets<char> ();
test_locale ();
// don't use _RWSTD_STRSTR so type macros (e.g. UDC) are not expanded
#undef FUN1
#define FUN1(fun, charT) \
fun< charT > (#charT)
// std::locale::collate category
FUN1 (test_collate, char);
// std::locale::ctype category
FUN1 (test_codecvt, char);
FUN1 (test_ctype, char);
#undef FUN2
#define FUN2(fun, charT, IterT) \
fun< charT, IterT > (#charT, #IterT)
// std::locale::monetary category
FUN1 (test_moneypunct, char);
FUN2 (test_money_get, char, std::istreambuf_iterator<char>);
FUN2 (test_money_get, char, const char*);
FUN2 (test_money_put, char, std::ostreambuf_iterator<char>);
FUN2 (test_money_put, char, char*);
// std::locale::numeric category
FUN1 (test_numpunct, char);
FUN2 (test_num_get, char, std::istreambuf_iterator<char>);
FUN2 (test_num_get, char, const char*);
FUN2 (test_num_put, char, std::ostreambuf_iterator<char>);
FUN2 (test_num_put, char, char*);
// std::locale::time category
FUN2 (test_time_get, char, std::istreambuf_iterator<char>);
FUN2 (test_time_get, char, const char*);
FUN2 (test_time_put, char, std::ostreambuf_iterator<char>);
FUN2 (test_time_put, char, char*);
// std::locale::messages category
FUN1 (test_messages, char);
#ifndef _RWSTD_NO_WCHAR_T
// same as above but for wchar_t
test_have_use_facet<wchar_t> ();
test_convenience_funs<wchar_t> ();
test_facets<wchar_t> ();
FUN1 (test_collate, wchar_t);
FUN1 (test_ctype, wchar_t);
FUN1 (test_codecvt, wchar_t);
FUN1 (test_moneypunct, wchar_t);
FUN2 (test_money_get, wchar_t, std::istreambuf_iterator<wchar_t>);
FUN2 (test_money_get, wchar_t, const wchar_t*);
FUN2 (test_money_put, wchar_t, std::ostreambuf_iterator<wchar_t>);
FUN2 (test_money_put, wchar_t, wchar_t*);
FUN1 (test_numpunct, wchar_t);
FUN2 (test_num_get, wchar_t, std::istreambuf_iterator<wchar_t>);
FUN2 (test_num_get, wchar_t, const wchar_t*);
FUN2 (test_num_put, wchar_t, std::ostreambuf_iterator<wchar_t>);
FUN2 (test_num_put, wchar_t, wchar_t*);
FUN2 (test_time_get, wchar_t, std::istreambuf_iterator<wchar_t>);
FUN2 (test_time_get, wchar_t, const wchar_t*);
FUN2 (test_time_put, wchar_t, std::ostreambuf_iterator<wchar_t>);
FUN2 (test_time_put, wchar_t, wchar_t*);
FUN1 (test_messages, wchar_t);
#endif // _RWSTD_NO_WCHAR_T
// test facet specializations on character types other than char and wchar_t
// and iterator types other than istreambuf_iterator and ostreambuf_iterator
// as per requirements in Table 52
FUN2 (test_money_get, UDC, std::istreambuf_iterator<UDC>);
FUN2 (test_money_get, UDC, const UDC*);
FUN2 (test_money_put, UDC, std::ostreambuf_iterator<UDC>);
FUN2 (test_money_put, UDC, UDC*);
FUN2 (test_num_get, UDC, std::istreambuf_iterator<UDC>);
FUN2 (test_num_get, UDC, const UDC*);
FUN2 (test_num_put, UDC, std::ostreambuf_iterator<UDC>);
FUN2 (test_num_put, UDC, UDC*);
FUN2 (test_time_get, char, const char*);
FUN2 (test_time_put, char, char*);
return 0;
}
/* extern */ int
main (int argc, char* argv [])
{
return rw_test (argc, argv, __FILE__,
"lib.locales", "header <locale> synopsis",
run_test, "|-enable-posix# ", &opt_enable_posix);
}