/***************************************************************************
 *
 * locale_body.h - definition of the __rw_locale class
 *
 * This is an internal header file used to implement the C++ Standard
 * Library. It should never be #included directly by a program.
 *
 * $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-2006 Rogue Wave Software.
 * 
 **************************************************************************/

#ifndef _RWSTD_LOC_RW_LOCALE_H_INCLUDED
#define _RWSTD_LOC_RW_LOCALE_H_INCLUDED


#include <loc/_facet.h>
#include <loc/_locale.h>
#include <string.h>

#include "podarray.h"

#include <rw/_defs.h>


_RWSTD_NAMESPACE (std) { 

struct _RWSTD_CLASS_EXPORT locale;

}   // namespace std


_RWSTD_NAMESPACE (__rw) { 


class _RWSTD_EXPORT __rw_locale
{
public:
    // total number of standard facets (char and wchar specializations)
    // ordinary (unnamed) and byname facets share the same array slot
    enum { _C_n_std_facets = __rw_facet::_C_last_type / 2 };
    enum { _C_namebuf_size = 40 };

private:
    // standard facets are always present, user defined facets (i.e.,
    // non-standard specializations of standard facets, or user-defined
    // facets with own id's) are dynamically allocated only if installed

    // each standard facet is stored at an index, inx, computed from its
    // numeric id, as follows: inx = (Facet::id._C_id - 1) / 2
    // each slot holds either an ordinary (unnamed) or a byname standard
    // facet (if the latter exists)
    __rw_facet     *_C_std_facets [_C_n_std_facets];
    __rw_facet    **_C_usr_facets;     // array of pointers to user facets
    _RWSTD_SIZE_T   _C_n_usr_facets;   // number of user-defined facets

    // name buffer sufficiently large to accommodate 6 basic 5-character
    // POSIX locale names such as "en_US" (one for each LC_XXX category)
    char           _C_namebuf [_C_namebuf_size];
    const char    *_C_name;        // name of locale (!= 0)
    _RWSTD_SIZE_T  _C_ref;         // reference count (>= 0)

    // a bit is set for each standard ordinary (unnamed) or byname facet that
    // is installed in the locale, and clear for each standard facet that has
    // been replaced with a user-defined (or user-constructed) object (i.e.,
    // one with the same id) in the locale object
    _RWSTD_SIZE_T _C_std_facet_bits;

    // a bit is set for each standard byname facet that is installed in
    // the locale object, and clear for each standard byname facet that
    // has been replaced with a user-defined (or user-constructed) object
    // (i.e., one with the same id) in the locale object
    _RWSTD_SIZE_T _C_byname_facet_bits;

    __rw_mutex    _C_mutex;

    friend struct _STD::locale;

public:

    enum {

#define _FACET_BIT(name)   (1U << (__rw_facet::_C_##name - 1U) / 2U)

        // bitmaps of standard facet types for each category
        // used to set and test the value _C_{std,byname}_facet_bits
        // to quickly determine the composition of a locale object

        _C_collate  = _FACET_BIT (collate) | _FACET_BIT (wcollate),
        _C_ctype    =   _FACET_BIT (codecvt) | _FACET_BIT (ctype)
                      | _FACET_BIT (wcodecvt) | _FACET_BIT (wctype),
        _C_monetary =   _FACET_BIT (moneypunct) | _FACET_BIT (moneypunct_intl)
                      | _FACET_BIT (wmoneypunct) | _FACET_BIT (wmoneypunct_intl)
                      | _FACET_BIT (money_get) | _FACET_BIT (money_put)
                      | _FACET_BIT (wmoney_get) | _FACET_BIT (wmoney_put),
        _C_numeric  =   _FACET_BIT (numpunct) | _FACET_BIT (wnumpunct)
                      | _FACET_BIT (num_get) | _FACET_BIT (num_put)
                      | _FACET_BIT (wnum_get) | _FACET_BIT (wnum_put),
        _C_time     =   _FACET_BIT (time_get) | _FACET_BIT (time_put)
                      | _FACET_BIT (wtime_get) | _FACET_BIT (wtime_put),
        _C_messages = _FACET_BIT (messages) | _FACET_BIT (wmessages),
        _C_all      =   _C_collate | _C_ctype | _C_monetary
                      | _C_numeric | _C_time  | _C_messages

#undef _FACET_BIT

    };

    // create a locale body from the name of a locale
    __rw_locale (const char*);

    // create a locale body from the name of a locale combined with a facet
    __rw_locale (const char *__name, const __rw_facet *__facet) {
        __rw_locale __tmp (__name);
        _C_construct (__tmp, __facet);
    }

    // create a locale body from another locale combined with a facet
    __rw_locale (const __rw_locale &__rhs, const __rw_facet *__facet) {
        _C_construct (__rhs, __facet);
    }

    // create a locale body from two locales taking cats from the named one
    __rw_locale (const __rw_locale &__rhs, const char *__name, int __cat) {
        __rw_locale __tmp (__name);
        _C_construct (__rhs, __tmp, __cat);
    }

    // create a locale body from two locales taking cats from `l2'
    __rw_locale (const __rw_locale &__l1, const __rw_locale &__l2, int __cat) {
        _C_construct (__l1, __l2, __cat);
    }

    ~__rw_locale () _THROWS (());

    // returns the name of the locale
    const char* _C_get_name () const {
        return _C_name;
    }

    static _RWSTD_SIZE_T _C_add_ref (__rw_facet &__facet) {
        return _RWSTD_ATOMIC_PREINCREMENT (__facet._C_ref, false);
    }

    static _RWSTD_SIZE_T _C_remove_ref (__rw_facet &__facet) {
        return _RWSTD_ATOMIC_PREDECREMENT (__facet._C_ref, false);
    }

    _RWSTD_SIZE_T _C_add_ref () {
        return _RWSTD_ATOMIC_PREINCREMENT (_C_ref, _C_mutex);
    }

    _RWSTD_SIZE_T _C_remove_ref () {
        return _RWSTD_ATOMIC_PREDECREMENT (_C_ref, _C_mutex);
    }

    // access private facet name
    static const char* _C_get_cat_name (const __rw_facet &__facet) {
        return __facet._C_name;
    }

    // get a string of locale names, one for each installed standard
    // facet's category; will dynamically allocate string if buf is 0
    char* _C_get_cat_names (char*, _RWSTD_SIZE_T) const /* may throw */;

    // returns true iff all categories of facets (given by the bitmap)
    // in *this are being globally managed, i.e., iff all of *this facets
    // whose category matches the bitmap are also being globally managed
    // (when the category is locale::none, the function fails for all
    // locales that contain any user-defined facets; otherwise only
    // standard facets are considered)
    bool _C_is_managed (int) const _THROWS (());

    // converts a LC_XXX constant to a locale::category value
    static int _C_LC2category (int) _THROWS (());

    // converts a LC_XXX constant to an internal bitset of facets
    static int _C_LC2facet_bits (int) _THROWS (());

    static bool _C_check_category (int) _THROWS (());

    // returns the type of the standard facet object or `unknown'
    // if the facet is of a user-defined type
    static __rw_facet::_C_facet_type
    _C_get_facet_type (const __rw_facet&) _THROWS (());

private:

    // globally manages all named locales; implements default locale
    // ctor, dtor, and locale::global()
    static __rw_locale* _C_manage (__rw_locale*, const char*);

    // implements all but the default locale ctor; the function
    // may construct a new object, return one of its first two
    // arguments, or return a pointer to a cached locale object
    static __rw_locale*
    _C_get_body (__rw_locale*, __rw_locale*,
                 const char*, int, const __rw_facet*);

    // called from ctors (only) to fully construct a combined locale
    void _C_construct (const __rw_locale&, const __rw_facet*);
    void _C_construct (const __rw_locale&, const __rw_locale&, int);

    // implements locale template ctor: locale::locale (const locale&, Facet*)
    __rw_locale* _C_combine (const __rw_facet*) const;

    // implements locale ctor: locale (const locale&, const locale&, category)
    __rw_locale* _C_combine (const __rw_locale&, int);

    // returns the index into one of the facet arrays
    // corresponding to the given facet id:
    //   -1       if the facet isn't installed
    //   value <  _C_n_std_facets for a standard facet
    //   value >= _C_n_std_facets otherwise (i.e., for user defined facets)
    _RWSTD_SIZE_T _C_get_facet_inx (_RWSTD_SIZE_T) const _THROWS (());
};


/* static */ inline bool
__rw_locale::
_C_check_category (int cat) _THROWS (())
{
    // `cat' is assumed to be a C++ locale category (i.e., not an LC_XXX)
    _RWSTD_ASSERT (cat == _C_LC2category (cat));

    return __rw_cat_none == cat || !(cat & ~__rw_cat_all);
}


/* static */ inline __rw_facet::_C_facet_type
__rw_locale::
_C_get_facet_type (const __rw_facet &__facet) _THROWS (())
{
    _RWSTD_ASSERT (0 != __facet._C_pid);
    _RWSTD_ASSERT (0 != *__facet._C_pid);

    // compute the numeric value of the facet's type
    const _RWSTD_SIZE_T __numtype =
        *__facet._C_pid * 2 - 1 + (0 != __facet._C_name);

    // return `unknown' for user-defined facets
    return __numtype > __rw_facet::_C_last_type ?
        __rw_facet::_C_unknown : __rw_facet::_C_facet_type (__numtype);
}


// a one-character string to separate LC_XXX categories in locale names
#ifndef _RWSTD_CAT_SEP
#  define _RWSTD_CAT_SEP ""
#endif


// maps LC_XXX category values to their names
extern const struct __rw_cats_t
{
    int         cat;          // LC_XXX category
    const char *name;         // LC_XXX name
    int         facet_bits;   // bitmap of facet types
} __rw_cats [6];

static const _RWSTD_SIZE_T __rw_n_cats = 6;


// computes LC_XXX category from a numeric facet id, returns the
// LC_XXX category for standard facets, LC_ALL for all others
inline int __rw_get_cat (int id) _THROWS (())
{
#if _RWSTD_LC_MIN >= 0 && _RWSTD_LC_MAX < _RWSTD_UCHAR_MAX
    typedef unsigned char LC_type;
#else
    typedef int LC_type;
#endif   // _RWSTD_LC_MIN >= 0 && _RWSTD_LC_MAX < _RWSTD_UCHAR_MAX

    const LC_type lc_cats[] = {
        _RWSTD_LC_COLLATE,
        // _C_codecvt, _C_ctype (all derivatives and specialiations)
        _RWSTD_LC_CTYPE, _RWSTD_LC_CTYPE,
        // _C_moneypunct, _C_moneypunct_intl, _C_money_get, _C_money_put
        _RWSTD_LC_MONETARY, _RWSTD_LC_MONETARY,
        _RWSTD_LC_MONETARY, _RWSTD_LC_MONETARY,
        // _C_numpunct, _C_num_get, _C_num_put
        _RWSTD_LC_NUMERIC, _RWSTD_LC_NUMERIC, _RWSTD_LC_NUMERIC,
        // _C_time_get, _C_time_put
        _RWSTD_LC_TIME, _RWSTD_LC_TIME,
#ifdef _RWSTD_LC_MESSAGES
        // _C_messages
        _RWSTD_LC_MESSAGES
#else
        _RWSTD_LC_MAX + 1
#endif
    };

    return id > 0 && id <= __rw_locale::_C_n_std_facets ?
          lc_cats [((id - 1) % (sizeof lc_cats / sizeof *lc_cats))]
        : _RWSTD_LC_ALL;
}


#ifndef _RWSTD_NO_CONDENSED_NAME

static const char __rw_C_locale_name[] = "C";

#else   // if defined (_RWSTD_NO_CONDENSED_NAME)

static const char __rw_C_locale_name[] = {
    'C', *_RWSTD_CAT_SEP, 'C', *_RWSTD_CAT_SEP, 'C', *_RWSTD_CAT_SEP,
    'C', *_RWSTD_CAT_SEP, 'C', *_RWSTD_CAT_SEP, 'C', '\0'
};

#endif   // _RWSTD_NO_CONDENSED_NAME


// returns true iff `name' is a name of the classic C locale
static inline bool __rw_is_C (const char *name) _THROWS (())
{
    _RWSTD_ASSERT (0 != name);

    return    'C' == name [0] && '\0' == name [1]

#ifdef _RWSTD_NO_CONDENSED_NAME

           || !strcmp (__rw_C_locale_name, name)

#endif   // _RWSTD_NO_CONDENSED_NAME

        ;
}


}   // namespace __rw


#endif   // _RWSTD_LOC_RW_LOCALE_H_INCLUDED
