This repository has been archived on 2024-12-16. You can view files and clone it, but cannot push or open issues or pull requests.
CodeBlocksPortable/Borland/BCC55/Include/Rw/locimpl.h

478 lines
15 KiB
C
Raw Normal View History

#ifndef __LOCIMPL_H
#define __LOCIMPL_H
#pragma option push -b -a8 -pc -Vx- -Ve- -w-inl -w-aus -w-sig
// -*- C++ -*-
/***************************************************************************
*
* rw/locimpl - Declarations for the Standard Library locale private
* implementation classes.
*
***************************************************************************
*
* Copyright (c) 1994-1999 Rogue Wave Software, Inc. All Rights Reserved.
*
* This computer software is owned by Rogue Wave Software, Inc. and is
* protected by U.S. copyright laws and other laws and by international
* treaties. This computer software is furnished by Rogue Wave Software,
* Inc. pursuant to a written license agreement and may be used, copied,
* transmitted, and stored only in accordance with the terms of such
* license and with the inclusion of the above copyright notice. This
* computer software or any other copies thereof may not be provided or
* otherwise made available to any other person.
*
* U.S. Government Restricted Rights. This computer software is provided
* with Restricted Rights. Use, duplication, or disclosure by the
* Government is subject to restrictions as set forth in subparagraph (c)
* (1) (ii) of The Rights in Technical Data and Computer Software clause
* at DFARS 252.227-7013 or subparagraphs (c) (1) and (2) of the
* Commercial Computer Software <EFBFBD> Restricted Rights at 48 CFR 52.227-19,
* as applicable. Manufacturer is Rogue Wave Software, Inc., 5500
* Flatiron Parkway, Boulder, Colorado 80301 USA.
*
**************************************************************************/
#ifndef __STD_RW_LOCIMPL__
#define __STD_RW_LOCIMPL__
#include <stdcomp.h>
// Macro for declaring all the has_facet and use_facet functions to be friends.
#ifndef _RWSTD_NO_FRIEND_TEMPLATES
#ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
#define _RWSTD_FRIEND_USE_HAS_FACET \
template <class Facet> friend \
inline const Facet& use_facet (const locale&); \
template <class Facet> friend \
inline bool has_facet (const locale&) _RWSTD_THROW_SPEC_NULL;
#else
#define _RWSTD_FRIEND_USE_HAS_FACET \
template <class Facet> friend \
inline const Facet& use_facet (const locale&,Facet*); \
template <class Facet> friend \
inline bool has_facet (const locale&,Facet*) _RWSTD_THROW_SPEC_NULL;
#endif // _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
#else
#define _RWSTD_FRIEND_USE_HAS_FACET public:
#endif
#ifndef _RWSTD_NO_NAMESPACE
namespace __rwstd {
using std::use_facet;
using std::locale;
#endif
// Implementation class template -- timepunct<charT>
//
// A facet such as this should have been included in the standard. We just
// declare it here; the definition occurs below, after locale::facet has been
// defined.
template <class charT> class timepunct;
#ifdef __TURBOC__
// Instantiations that go in the library:
template class _RWSTDExport timepunct<char>;
#ifndef _RWSTD_NO_WIDE_CHAR
template class _RWSTDExport timepunct<wchar_t>;
#endif
#endif // __TURBOC__
// Implementation forward declarations:
class _RWSTDExport locale_imp;
class _RWSTDExport facet_imp;
class _RWSTDExport digit_map_base;
template <class charT> class _RWSTDExportTemplate digit_map;
template <class charT> class _RWSTDExportTemplate keyword_def;
template <class charT> class _RWSTDExportTemplate keyword_map;
template <class charT> class _RWSTDExportTemplate keyword_cracker;
class _RWSTDExport digit_reader_base;
template <class charT> class digit_reader_base_1;
template <class charT,class InputIterator>
class _RWSTDExportTemplate digit_reader;
class _RWSTDExport digit_writer_base;
template <class charT>
class _RWSTDExportTemplate digit_writer_base_1;
template <class charT,class OutputIterator>
class _RWSTDExportTemplate digit_writer;
// ------------------------------------
// Implementation class -- ref_counted.
// ------------------------------------
// Common base class for reference-counted classes. Currently used only by
// locale_imp and facet_imp, but could be used more generally.
class _RWSTDExport ref_counted {
friend class _RW_STD::locale;
size_t __ref_count;
#ifdef _RWSTD_MULTI_THREAD
_RWSTDMutex __mutex;
#endif
protected:
ref_counted (size_t initial_refs):
__ref_count(initial_refs) { }
// Ensure derived class destructors are always virtual.
virtual ~ref_counted (void);
// Does protected access make these accessible to friends of derived classes?
// We're about to find out ...
static void add_reference (ref_counted *ob) {
STDGUARD(ob->__mutex);
++ob->__ref_count;
}
static void remove_reference (ref_counted *ob) {
size_t refs;
{
STDGUARD(ob->__mutex);
refs=--ob->__ref_count;
}
if (!refs)
delete ob;
}
static void add_possible_reference (ref_counted *ob) {
if (ob)
add_reference(ob);
}
static void remove_possible_reference (ref_counted *ob) {
if (ob)
remove_reference(ob);
}
};
// We would prefer to define locale::id and locale::facet entirely as nested
// classes of locale, but current compilers have problems with out-of-line
// definition of members of such classes, so we have to derive most of their
// behavior from unnested implementation classes:
// --------------------------------------
// Implementation class -- locale_id_imp.
// --------------------------------------
class _RWSTDExport locale_id_imp {
protected:
_MUTABLE size_t __id_value;
static size_t __last_used_id;
locale_id_imp() : __id_value(0) {;}
#ifdef _RWSTD_MULTI_THREAD
static _RWSTDMutex __mutex;
#endif
void __initid () const;
};
// ----------------------------------
// Implementation class -- facet_imp.
// ----------------------------------
class _RWSTDExport facet_imp: public ref_counted
{
_RWSTD_FRIEND_USE_HAS_FACET
friend class locale_imp;
friend class _RW_STD::locale;
public:
enum {
__facet_cat = 0,
__ok_implicit = 0,
__initdone = 1
};
private:
int __flags;
int __category; // Should be same type as locale::category
protected:
facet_imp (size_t refs, int cat=0):
ref_counted(refs), __flags(0), __category(cat) { }
// __initfacet() is called by locale::__install the first time a facet is
// installed in its first locale. Some facets override it to set up private
// data that depends on return values of virtual do_xxx functions that can't
// be called yet in a constructor.
virtual void __initfacet (const locale*) { }
};
#ifndef _RWSTD_NO_NAMESPACE
}
#endif
#include <rw/locvector>
#ifndef _RWSTD_NO_NAMESPACE
namespace __rwstd {
#endif
// -----------------------------------
// Implementation class -- locale_imp.
// -----------------------------------
class _RWSTDExport locale_imp: public ref_counted
{
_RWSTD_FRIEND_USE_HAS_FACET
friend class _RW_STD::locale;
// Same type as locale::category ...
typedef int locale_category;
locale_vector<_RW_STD::string> names_;
locale_vector<facet_imp*> vec_;
locale_category native_cats_;
locale_category named_cats_;
_RW_STD::string big_name_;
bool named_;
locale_imp (size_t sz=36, size_t refs=0);
locale_imp (const locale_imp&,size_t refs);
~locale_imp ();
public:
inline facet_imp *get_facet (size_t i) const
{ return i<vec_.size()? vec_[i] : NULL; }
private:
const char *category_name (locale_category) const;
// Map C library LC_xxx constants into facet categories.
static locale_category map_category (locale_category);
// Parse a locale name into category names.
static bool parse_name (locale_vector<_RW_STD::string>&,const char*);
// Clean up name if necessary
static _RW_STD::string clean_name(_RW_STD::string s)
{
#ifdef __BORLANDC__
return _RW_STD::string(s,s.find('=')+1);
#else
return s;
#endif // __BORLANDC__
}
// Combine category names to create a locale name.
static bool build_name (_RW_STD::string&,const locale_vector<_RW_STD::string>&);
};
// ---------------------------------------
// Implementation class -- digit_map_base.
// ---------------------------------------
// A place to stash some static constants, so that each instantiation of the
// derived class rwstd::digit_map does not have to have a separate copy.
struct _RWSTDExport digit_map_base {
enum { zero, minus, plus, X, x, E, e };
static const char punct_chars[7]; // "0-+XxEe"
static const char digit_chars[22]; // "0123456789ABCDEFabcdef"
static const char char_values[22]; // Corresponding values in range 0-15
};
// --------------------------------------------------
// Implementation class template -- digit_map<charT>.
// --------------------------------------------------
// Maps digits into their corresponding numeric values, and caches widened
// equivalents of some number-related punctuation characters that don't depend
// on the numpunct facet. A private instance of this class is hidden in
// ctype<charT> for use by numeric conversion facets. A call to init must
// precede the first call to eval if is_inited() is false. Eval returns 0-15
// if argument is a valid digit, a negative value otherwise.
//
// Specialized for char for performance. The specialization assumes digits
// fit into the char code-set in an ASCII-like manner ('0'..'9' contiguous,
// 'A'..'F' contiguous, 'a'..'f' contiguous, '0' < 'A' < 'a').
_RWSTD_TEMPLATE
class _RWSTDExportTemplate digit_map<char>:
public digit_map_base
{
public:
typedef char char_type;
bool is_inited (void) const { return true; }
const char *get_punct (void) const { return punct_chars; }
inline int eval (char c) const;
static inline const digit_map<char>&
get_digit_map (const _RW_STD::ctype<char>&);
};
// Inline members of digit_map<char>:
//
// (Note that the definition of get_digit_map is in <rw/ctype> because it
// has to come after the definition of ctype<char>.)
inline int digit_map<char>::eval (char c) const {
int num=c;
if ((num-='0')>9) {
if (((num-=('A'-'0'))>5 && (num-=('a'-'A'))>5) || (num+=10)<10)
num=-1;
}
return num;
}
template <class charT>
class _RWSTDExportTemplate digit_map:
public digit_map_base
{
bool inited;
charT punct_array[7];
charT digit_array[22];
char value_array[22];
public:
typedef charT char_type;
digit_map (void): inited(false) { }
bool is_inited (void) const { return inited; }
void init (const _RW_STD::ctype<charT>& ct);
const charT *get_punct (void) const { return punct_array; }
int eval (charT) const;
// Can-opener for getting the digit_map out of a ctype. (Works because of
// the friend declaration in ctype_helper<charT> below.)
static inline const digit_map<charT>&
get_digit_map (const _RW_STD::ctype<charT>& ct)
{
if (!ct.__digit_map.inited)
(_RWSTD_CONST_CAST(digit_map<char_type>&,ct.__digit_map))
.init(ct);
return ct.__digit_map;
}
};
// ----------------------------------------------------
// Implementation class template -- keyword_def<charT>.
// ----------------------------------------------------
// Helper class used in parsing keywords from input (such as true/false in
// num_get, month and day names in time_get, etc).
template <class charT>
class _RWSTDExportTemplate keyword_def {
public:
const charT *s;
int v;
};
// ----------------------------------------------------
// Implementation class template -- keyword_map<charT>.
// ----------------------------------------------------
// Defines a set of keywords to be recognized on input and to be written to
// output. Private instances are hidden in numpunct (for true/false) and
// rwstd::timepunct (for month and weekday names).
template <class charT>
class _RWSTDExportTemplate keyword_map {
public:
int num_defs_;
const keyword_def<charT> *defs_;
};
// ---------------------------------------------------
// Implementation class template -- punct_data<charT>.
// ---------------------------------------------------
// Common base class for rwstd::numpunct_data and rwstd::moneypunct_data.
template <class charT>
class _RWSTDExportTemplate punct_data {
friend class digit_reader_base_1<charT>;
friend class digit_writer_base_1<charT>;
public:
typedef _RW_STD::basic_string<charT,_RW_STD::char_traits<charT>,_RW_STD::allocator<charT> > string_type;
protected:
charT dp_, ts_;
_RW_STD::string gr_;
};
// ------------------------------------------------------
// Implementation function templates -- create_xxx_facet.
// ------------------------------------------------------
// The facet_maker<Facet>::maker_func functions described above delegate the
// actual construction of facets to three inline function templates named
// create_xxx_facet, where xxx is 'classic' or 'native' or 'named'. The
// default (template) versions of these functions construct facets as follows:
//
// classic -- default constructor for the facet with only the refs argument.
// native -- calls create_named_facet with a name of "".
// named -- calls create_classic_facet, ignoring the passed name.
//
// This default behavior is overridden (specialized) for certain facet types.
// In particular, create_named_facet is specialized for all facet types that
// have a derived _byname version, to construct that version with the passed
// name (see <rw/rwlocale>) and create_native_facet is specialized for all
// facet types whose "native" behavior (as determined by the vendor) differs
// from the byname facet with a name of "" (see <rw/vendor>).
template <class Facet>
inline Facet* _RWSTDExportTemplate create_named_facet
(Facet*,const char*,size_t refs);
template <class Facet>
inline Facet* _RWSTDExportTemplate create_native_facet (Facet*);
template <class Facet>
inline Facet* _RWSTDExportTemplate create_classic_facet (Facet*)
{
return new Facet(1);
}
// ----------------------------------------------------
// Implementation class template -- facet_maker<Facet>.
// ----------------------------------------------------
// When use_facet (inline) finds that a locale does not contain an explicit
// facet of the requested type, it calls locale::__make_explicit (non-template)
// to create or find the facet in a cache, and install it in the locale. As a
// parameter to __make_explicit, use_facet passes a call-back function which
// __make_explicit can call to construct a facet of the requested type if
// needed. The call-back functions are obtained by instantiating the following
// helper class template:
template <class Facet>
class _RWSTDExportTemplate facet_maker {
public:
static facet_imp *maker_func (int t, const char* name, size_t refs)
{
if (t==0)
return create_classic_facet ((Facet*)0);
else if (t==1)
return create_native_facet ((Facet*)0);
else
return create_named_facet ((Facet*)0,name,refs);
}
};
// Typedef for the above facet_maker functions, for use in the declaration
// of locale::__make_explicit.
typedef facet_imp *facet_maker_func (int,const char*,size_t);
#ifndef _RWSTD_NO_NAMESPACE
} // namespace __rwstd
#endif
#ifdef _RWSTD_COMPILE_INSTANTIATE
#include <rw/locimpl.cc>
#endif
#endif // __STD_RW_LOCIMPL__
#pragma option pop
#endif /* __LOCIMPL_H */