/************************************************************************
 *
 * value.cpp - definitions of UserClass and UserPOD class members
 *
 * $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-2005 Rogue Wave Software.
 * 
 **************************************************************************/

// expand _TEST_EXPORT macros
#define _RWSTD_TEST_SRC

#include <ctype.h>      // for isdigit()
#include <stdarg.h>     // for va_arg, va_list, ...
#include <stdlib.h>     // for strtol()
#include <string.h>     // for size_t, strlen()


#include <rw_value.h>
#include <rw_char.h>    // for rw_expand()
#include <rw_printf.h>


/* static */ size_t UserClass::count_;
/* static */ int    UserClass::id_gen_;   // generates unique non-zero ids
/* static */ int  (*UserClass::gen_)();   // extern "C++" int (*)()

/* static */ size_t UserClass::n_total_def_ctor_;
/* static */ size_t UserClass::n_total_copy_ctor_;
/* static */ size_t UserClass::n_total_dtor_;
/* static */ size_t UserClass::n_total_op_assign_;
/* static */ size_t UserClass::n_total_op_plus_assign_;
/* static */ size_t UserClass::n_total_op_minus_assign_;
/* static */ size_t UserClass::n_total_op_times_assign_;
/* static */ size_t UserClass::n_total_op_div_assign_;
/* static */ size_t UserClass::n_total_op_eq_;
/* static */ size_t UserClass::n_total_op_lt_;

// default values of pointers
/* static */ size_t* UserClass::def_ctor_throw_ptr_ =
    &UserClass::def_ctor_throw_count_;
/* static */ size_t* UserClass::copy_ctor_throw_ptr_ =
    &UserClass::copy_ctor_throw_count_;
/* static */ size_t* UserClass::dtor_throw_ptr_ =
    &UserClass::dtor_throw_count_;
/* static */ size_t* UserClass::op_assign_throw_ptr_ =
    &UserClass::op_assign_throw_count_;
/* static */ size_t* UserClass::op_plus_assign_throw_ptr_ =
    &UserClass::op_plus_assign_throw_count_;
/* static */ size_t* UserClass::op_minus_assign_throw_ptr_ =
    &UserClass::op_minus_assign_throw_count_;
/* static */ size_t* UserClass::op_times_assign_throw_ptr_ =
    &UserClass::op_times_assign_throw_count_;
/* static */ size_t* UserClass::op_div_assign_throw_ptr_ =
    &UserClass::op_div_assign_throw_count_;
/* static */ size_t* UserClass::op_eq_throw_ptr_ =
    &UserClass::op_eq_throw_count_;
/* static */ size_t* UserClass::op_lt_throw_ptr_ =
    &UserClass::op_lt_throw_count_;

// exception throwing initially disabled
/* static */ size_t UserClass::def_ctor_throw_count_        = size_t (-1);
/* static */ size_t UserClass::copy_ctor_throw_count_       = size_t (-1);
/* static */ size_t UserClass::dtor_throw_count_            = size_t (-1);
/* static */ size_t UserClass::op_assign_throw_count_       = size_t (-1);
/* static */ size_t UserClass::op_plus_assign_throw_count_  = size_t (-1);
/* static */ size_t UserClass::op_minus_assign_throw_count_ = size_t (-1);
/* static */ size_t UserClass::op_times_assign_throw_count_ = size_t (-1);
/* static */ size_t UserClass::op_div_assign_throw_count_   = size_t (-1);
/* static */ size_t UserClass::op_eq_throw_count_           = size_t (-1);
/* static */ size_t UserClass::op_lt_throw_count_           = size_t (-1);


UserClass::UserClass ()
    : data_ (), id_ (++id_gen_), origin_ (id_), src_id_ (id_),
      n_copy_ctor_ (0), n_op_assign_ (0), n_op_eq_ (0), n_op_lt_ (0)
{
    // increment the total number of invocations of the default ctor
    // (do so even if the function throws an exception below)
    ++n_total_def_ctor_;

#ifndef _RWSTD_NO_EXCEPTIONS

    if (def_ctor_throw_ptr_ && n_total_def_ctor_ == *def_ctor_throw_ptr_) {
        DefCtor ex;
        ex.id_ = id_;
        throw ex;
    }

#endif   // _RWSTD_NO_EXCEPTIONS

    // initialize the object's value
    if (gen_)
        data_.val_ = gen_ ();

    // increment the number of successfully constructed objects
    ++count_;
}


UserClass::UserClass (const UserClass &rhs)
    : data_ (rhs.data_), id_ (++id_gen_), origin_ (rhs.origin_),
      src_id_ (rhs.id_),
      n_copy_ctor_ (0), n_op_assign_ (0), n_op_eq_ (0), n_op_lt_ (0)
{
    // verify id validity
    RW_ASSERT (rhs.id_ && rhs.id_ < id_gen_);

    // increment the number of times `rhs' has been copied
    // (do so even if the function throws an exception below)
    ++_RWSTD_CONST_CAST (UserClass*, &rhs)->n_copy_ctor_;

    // increment the total number of invocations of the copy ctor
    // (do so even if the function throws an exception below)
    ++n_total_copy_ctor_;

#ifndef _RWSTD_NO_EXCEPTIONS

    // throw an exception if the number of calls
    // to the copy ctor reaches the given value
    if (copy_ctor_throw_ptr_ && n_total_copy_ctor_ == *copy_ctor_throw_ptr_) {
        CopyCtor ex;
        ex.id_ = id_;
        throw ex;
    }

#endif   // _RWSTD_NO_EXCEPTIONS

    // increment the number of successfully constructed objects
    ++count_;
}


UserClass::~UserClass ()
{
    // verify id validity
    RW_ASSERT (id_ && id_ <= id_gen_);

    // increment the total number of invocations of the dtor
    // (do so even if the function throws an exception below)
    ++n_total_dtor_;

#ifndef _RWSTD_NO_EXCEPTIONS

    // throw an exception if the number of calls
    // to the class dtor reaches the given value
    if (dtor_throw_ptr_ && n_total_dtor_ == *dtor_throw_ptr_) {
        Dtor ex;
        ex.id_ = id_;
        throw ex;
    }

#endif   // _RWSTD_NO_EXCEPTIONS

    // decrement the number of objects in existence
    --count_;

    // invalidate id
    _RWSTD_CONST_CAST (int&, this->id_) = 0;
}


void UserClass::
assign (assign_op which, const UserClass &rhs)
{
    // verify id validity and uniqueness:
    // a valid id is non-zero (dtor resets)
    RW_ASSERT (id_ && id_ <= id_gen_);
    RW_ASSERT (rhs.id_ && rhs.id_ <= id_gen_);

    // no two id's have the same value
    RW_ASSERT (this == &rhs || id_ != rhs.id_);

    size_t *p_total_op = 0;
    size_t *p_op       = 0;
    size_t *p_throw    = 0;

    Exception *pex = 0; 

    OpAssign      ex_assign;
    OpPlusAssign  ex_plus_assign;
    OpMinusAssign ex_minus_assign;
    OpTimesAssign ex_times_assign;
    OpDivAssign   ex_div_assign;

    int new_val;

    switch (which) {
    case op_assign:
        p_total_op = &n_total_op_assign_;
        p_op       = &n_op_assign_;
        p_throw    = op_assign_throw_ptr_;
        pex        = &ex_assign;
        new_val    = rhs.data_.val_;
        break;

    case op_plus_assign:
        p_total_op = &n_total_op_plus_assign_;
        p_op       = &n_op_plus_assign_;
        p_throw    = op_plus_assign_throw_ptr_;
        pex        = &ex_plus_assign;
        new_val    = data_.val_ + rhs.data_.val_;
        break;

    case op_minus_assign:
        p_total_op = &n_total_op_minus_assign_;
        p_op       = &n_op_minus_assign_;
        p_throw    = op_minus_assign_throw_ptr_;
        pex        = &ex_minus_assign;
        new_val    = data_.val_ - rhs.data_.val_;
        break;

    case op_times_assign:
        p_total_op = &n_total_op_times_assign_;
        p_op       = &n_op_times_assign_;
        p_throw    = op_times_assign_throw_ptr_;
        pex        = &ex_times_assign;
        new_val    = data_.val_ * rhs.data_.val_;
        break;

    case op_div_assign:
        p_total_op = &n_total_op_div_assign_;
        p_op       = &n_op_div_assign_;
        p_throw    = op_div_assign_throw_ptr_;
        pex        = &ex_div_assign;
        new_val    = data_.val_ / rhs.data_.val_;
        break;
    }

    // increment the number of invocations of the operator
    // (do so even if the function throws an exception below)

    ++*p_total_op;
    ++*p_op;

#ifndef _RWSTD_NO_EXCEPTIONS

    // throw an exception if the number of calls to
    // the assignment operator reaches the given value

    if (p_throw && *p_throw == *p_total_op) {
        pex->id_ = id_;
        throw *pex;
    }

#endif   // _RWSTD_NO_EXCEPTIONS

    // overwrite value and source id only when the operation
    // is successful (i.e., only when it doesn't throw)

    origin_ = rhs.origin_;
    src_id_ = rhs.id_;
    data_.val_    = new_val;
}


UserClass& UserClass::
operator= (const UserClass &rhs)
{
    assign (op_assign, rhs);

    return *this;
}


UserClass& UserClass::
operator+= (const UserClass &rhs)
{
    assign (op_plus_assign, rhs);

    return *this;
}


UserClass& UserClass::
operator-= (const UserClass &rhs)
{
    assign (op_minus_assign, rhs);

    return *this;
}


UserClass& UserClass::
operator*= (const UserClass &rhs)
{
    assign (op_times_assign, rhs);

    return *this;
}


UserClass& UserClass::
operator/= (const UserClass &rhs)
{
    assign (op_div_assign, rhs);

    return *this;
}


bool
UserClass::operator== (const UserClass &rhs) const
{
    // verify id validity and uniqueness
    RW_ASSERT (id_ && id_ <= id_gen_);
    RW_ASSERT (rhs.id_ && rhs.id_ <= id_gen_);
    RW_ASSERT (this == &rhs || id_ != rhs.id_);

    // increment the number of times each distinct object
    // has been used as the argument to operator==
    // (do so even if the function throws an exception below)
    ++_RWSTD_CONST_CAST (UserClass*, this)->n_op_eq_;

    if (this != &rhs)
        ++_RWSTD_CONST_CAST (UserClass*, &rhs)->n_op_eq_;

    // increment the total number of invocations of the operator
    // (do so even if the function throws an exception below)
    ++n_total_op_eq_;

#ifndef _RWSTD_NO_EXCEPTIONS

    // throw an exception if the number of calls
    // to operator== reaches the given value

    if (op_eq_throw_ptr_ && n_total_op_eq_ == *op_eq_throw_ptr_) {
        OpEq ex;
        ex.id_ = id_;
        throw ex;
    }

#endif   // _RWSTD_NO_EXCEPTIONS

    return data_.val_ == rhs.data_.val_;
}


bool
UserClass::operator< (const UserClass &rhs) const
{
    // verify id validity and uniqueness
    RW_ASSERT (id_ && id_ <= id_gen_);
    RW_ASSERT (rhs.id_ && rhs.id_ <= id_gen_);
    RW_ASSERT (this == &rhs || id_ != rhs.id_);

    // increment the number of times each distinct object
    // has been used as the argument to operator<
    // (do so even if the function throws an exception below)
    ++_RWSTD_CONST_CAST (UserClass*, this)->n_op_lt_;

    if (this != &rhs)
        ++_RWSTD_CONST_CAST (UserClass*, &rhs)->n_op_lt_;

    // increment the total number of invocations of the operator
    // (do so even if the function throws an exception below)
    ++n_total_op_lt_;

#ifndef _RWSTD_NO_EXCEPTIONS

    // throw an exception if the number of calls
    // to operator== reaches the given value

    if (op_lt_throw_ptr_ && n_total_op_lt_ == *op_lt_throw_ptr_) {
        OpLt ex;
        ex.id_ = id_;
        throw ex;
    }

#endif   // _RWSTD_NO_EXCEPTIONS

    return data_.val_ < rhs.data_.val_;
}


bool UserClass::
is_count (size_t n_copy_ctor,
          size_t n_op_assign,
          size_t n_op_eq,
          size_t n_op_lt) const
{
    // verify id validity
    RW_ASSERT (id_ && id_ <= id_gen_);

    return    (size_t (-1) == n_copy_ctor || n_copy_ctor_ == n_copy_ctor)
           && (size_t (-1) == n_op_assign || n_op_assign_ == n_op_assign)
           && (size_t (-1) == n_op_eq     || n_op_eq_     == n_op_eq)
           && (size_t (-1) == n_op_lt     || n_op_lt_     == n_op_lt);
}


/* static */ bool UserClass::
is_total (size_t cnt,
          size_t n_def_ctor,
          size_t n_copy_ctor,
          size_t n_op_assign,
          size_t n_op_eq,
          size_t n_op_lt)
{
    return    (size_t (-1) == cnt         || count_             == cnt)
           && (size_t (-1) == n_def_ctor  || n_total_def_ctor_  == n_def_ctor)
           && (size_t (-1) == n_copy_ctor || n_total_copy_ctor_ == n_copy_ctor)
           && (size_t (-1) == n_op_assign || n_total_op_assign_ == n_op_assign)
           && (size_t (-1) == n_op_eq     || n_total_op_eq_     == n_op_eq)
           && (size_t (-1) == n_op_lt     || n_total_op_lt_     == n_op_lt);
}


/* static */ const UserClass*
UserClass::first_less (const UserClass *xarray, size_t nelems)
{
    size_t inx = nelems;

    if (1 < nelems) {
        for (inx = 1; inx != nelems; ++inx) {
            if (xarray [inx] < xarray [inx - 1])
                break;
        }
    }
    
    return inx < nelems ? xarray + inx : 0;
}


/* static */ void
UserClass::reset_totals ()
{
    n_total_def_ctor_  =
    n_total_copy_ctor_ =
    n_total_dtor_      =
    n_total_op_assign_ =
    n_total_op_eq_     =
    n_total_op_lt_     = 0;
}


typedef unsigned char UChar;

template <class T>
static T*
__rw_from_char (T*, const char *str, size_t len, bool sorted)
{
    // handle null pointers
    if (!str)
        return 0;

    // expand source string
    char str_buf_ [256];
    size_t strlen_ = sizeof (str_buf_);
    const char* const str_ = rw_expand (str_buf_, str, len, &strlen_);

    if (sorted) {
        // verify that the sequence is sorted
        for (size_t i = 1; i < strlen_; ++i) {
            if (str_ [i] < str_ [i - 1]) {
                if (str_buf_ != str_)
                    delete[] str_;
                return 0;
            }
        }
    }

    T*array = 0;

    _TRY {
        array = new T [strlen_];
    }
    _CATCH (...) {

        if (str_buf_ != str_)
            delete[] str_;

        _RETHROW;
    }

    typedef unsigned char UChar;

    for (size_t i = 0; i < strlen_; ++i)
        array [i].data_.val_ = UChar (str_ [i]);

    if (str_buf_ != str_)
        delete[] str_;

    return array;
}


template <class T>
static const T*
__rw_mismatch (const T *xarray, const char *str, size_t len)
{
    if (!str)
        return xarray;

    if (size_t (-1) == len)
        len = strlen (str);

    for (size_t i = 0; i != len; ++i) {

        const int val = UChar (str [i]);

        if (val != xarray [i].data_.val_)
            return xarray + i;
    }

    return 0;
}


/* static */ UserClass*
UserClass::from_char (const char *str, size_t len /* = -1 */,
                      bool sorted /* = false */)
{
    return __rw_from_char ((UserClass*)0, str, len, sorted);
}


/* static */ const UserClass*
UserClass::mismatch (const UserClass *xarray, const char *str,
                     size_t len /* = -1 */)
{
    return __rw_mismatch (xarray, str, len);
}


/* static */ int
UserClass::compare (const UserClass *xarray, const char *str,
                    size_t len /* = -1 */)
{
    const UserClass* const px = mismatch (xarray, str, len);

    if (px) {
        RW_ASSERT (size_t (px - xarray) < len);

        return px->data_.val_ - int (UChar (str [px - xarray]));
    }

    return 0;
}


/* static */ int
UserClass::compare (const char *str, const UserClass *xarray,
                    size_t len /* = -1 */)
{
    return -UserClass::compare (xarray, str, len);
}


/* static */ int
UserClass::compare (const UserClass *x, const UserClass *y, size_t count)
{
    for (size_t i = 0; i != count; ++i) {
        if (x [i].data_.val_ != y [i].data_.val_)
            return x [i].data_.val_ - y [i].data_.val_;
    }

    return 0;
}


/* static */ UserPOD*
UserPOD::from_char (const char *str, size_t len /* = -1 */,
                    bool sorted /* = false */)
{
    return __rw_from_char ((UserPOD*)0, str, len, sorted);
}


/* static */ const UserPOD*
UserPOD::mismatch (const UserPOD *xarray, const char *str,
                   size_t len /* = -1 */)
{
    return __rw_mismatch (xarray, str, len);
}


/* static */ size_t UnaryPredicate::n_total_op_fcall_;


UnaryPredicate::
UnaryPredicate ()
{
    // no-op
}


UnaryPredicate::
UnaryPredicate (const UnaryPredicate&)
{
    // no-op
}


UnaryPredicate& UnaryPredicate::
operator= (const UnaryPredicate&)
{
    return *this;
}


/* virtual */ UnaryPredicate::~UnaryPredicate ()
{
    // no-op
}


/* virtual */ conv_to_bool UnaryPredicate::
operator()(const UserClass&) const
{
    ++n_total_op_fcall_;

    return conv_to_bool::make (true);
}


/* static */ size_t BinaryPredicate::n_total_op_fcall_;


BinaryPredicate::
BinaryPredicate (binary_op op): op_ (op)
{
    // no-op
}


/* virtual */ BinaryPredicate::~BinaryPredicate ()
{
    // no-op
}


/* virtual */ conv_to_bool BinaryPredicate::
operator()(const UserClass &lhs, const UserClass &rhs) /* non-const */
{
    ++n_total_op_fcall_;

    bool result;

    switch (op_) {
    case op_equals:        result = lhs.data_.val_ == rhs.data_.val_; break;
    case op_not_equals:    result = !(lhs.data_.val_ == rhs.data_.val_); break;
    case op_less:          result = lhs.data_.val_ < rhs.data_.val_; break;
    case op_less_equal:    result = !(rhs.data_.val_ < lhs.data_.val_); break;
    case op_greater:       result = rhs.data_.val_ < lhs.data_.val_; break;
    case op_greater_equal: result = !(rhs.data_.val_ < lhs.data_.val_); break;
    }

    return conv_to_bool::make (result);
}


static int
_rw_fmtxarrayv (char **pbuf, size_t *pbufsize, const char *fmt, va_list va)
{
    RW_ASSERT (0 != pbuf);
    RW_ASSERT (0 != pbufsize);
    RW_ASSERT (0 != fmt);

    va_list* pva      =  0;
    bool     fl_plus  =  false;
    bool     fl_pound =  false;
    int      nelems   = -1;
    int      paramno  = -1;
    int      cursor   = -1;

    const UserClass* pelem    = 0;

    // directive syntax:
    // "X=" [ '#' ] [ '+' ] [ '*' | <n> ] [ '.' [ '*' | '@' | <n> ] ]
    // where
    // '#' causes UserClass::id_ to be included in output
    // '+' forces UserClass::data_.val_ to be formatted as an integer (
    //     otherwise it is formatted as an (optionally escaped) character
    // '*' or <n> is the number of elements in the sequence (the
    //     first occurrence)
    // '*', <n> is the offset of the cursor within the sequence
    //          (where the cursor is a pair of pointy brackets
    //          surrounding the element, e.g., >123<)
    // '@' is the pointer to the element to be surrended by the
    //     pair of pointy brackets

    if ('X' != fmt [0] || '=' != fmt [1])
        return _RWSTD_INT_MIN;

    fmt += 2;

    if ('+' == *fmt) {
        // use numerical formatting for UserClass::data_.val_
        fl_plus = true;
        ++fmt;
    }

    if ('#' == *fmt) {
        // include UserClass::id_ in output
        fl_pound = true;
        ++fmt;
    }

    if ('*' == *fmt) {
        // process width
        pva = va_arg (va, va_list*);

        RW_ASSERT (0 != pva);

        // extract the width from rw_snprintfa's variable argument
        // list pass through to us by the caller
        nelems = va_arg (*pva, int);
        ++fmt;
    }
    else if (isdigit (*fmt)) {
        // process positional parameter or width
        char* end = 0;
        const int arg = strtol (fmt, &end, 10);
        if ('$' == *end)
            paramno = arg;
        else
            nelems = arg;

        fmt = end;
    }

    if ('.' == *fmt) {
        // process precision (cursor)
        if ('*' == *++fmt) {
            if (0 == pva)
                pva = va_arg (va, va_list*);

            RW_ASSERT (0 != pva);

            // extract the width from rw_snprintfa's variable argument
            // list passed through to us by the caller
            cursor = va_arg (*pva, int);
            ++fmt;
        }
        else if ('@' == *fmt) {
            if (0 == pva)
                pva = va_arg (va, va_list*);

            RW_ASSERT (0 != pva);

            // extract the pointer from rw_snprintfa's variable argument
            // list passed through to us by the caller
            pelem = va_arg (*pva, UserClass*);

            ++fmt;
        }
        else if (isdigit (*fmt)) {
            char* end = 0;
            cursor = strtol (fmt, &end, 10);

            fmt = end;
        }
    }

    RW_ASSERT ('\0' == *fmt);

    // extract the address of the caller's variable argument list
    if (0 == pva)
        pva = va_arg (va, va_list*);

    RW_ASSERT (0 != pva);

    // extract a pointer to UserClass from rw_snprintfa's variable argument
    // list pass through to us by the caller 
    const UserClass* const xbeg = va_arg (*pva, UserClass*);

    if (-1 != cursor) {
        RW_ASSERT (-1 < cursor);
        RW_ASSERT (0 == pelem);

        pelem = xbeg + cursor;
    }

    // extract the address where to store the extracted argument
    // for use by any subsequent positional paramaters
    const UserClass** const pparam = va_arg (va, const UserClass**);

    RW_ASSERT (0 != pparam);

    // store the extracted argument
    *pparam = xbeg;

    // compute the length of the buffer formatted so far
    const size_t buflen_0 = *pbuf ? strlen (*pbuf) : 0;

    int nbytes = 0;

    //////////////////////////////////////////////////////////////////
    // invoke rw_asnprintf() recursively to format our arguments
    // and append the result to the end of the buffer; pass the
    // value returned from rw_asnprintf() (i.e., the number of
    // bytes appended) back to the caller

    for (const UserClass *px = xbeg; px != xbeg + nelems; ++px) {
        const int n =
            rw_asnprintf (pbuf, pbufsize,
                          "%{+}%{?}>%{;}"
                          "%{?}%d:%{;}"
                          "%{?}%d%{?},%{;}%{:}%{lc}%{;}"
                          "%{?}<%{;}",
                          px == pelem,                    // '>'
                          fl_pound, px->id_,              // "<id>:"
                          fl_plus, px->data_.val_,        // <val>
                          px + 1 < xbeg + nelems,         // ','
                          px->data_.val_,                 // <val>
                          px == pelem);                   // '<'
        if (n < 0)
            return n;

        nbytes += n;
    }

    //////////////////////////////////////////////////////////////////

    // compute the new length of the buffer
    const size_t buflen_1 = *pbuf ? strlen (*pbuf) : 0;

    // assert that the function really appended as many characters
    // as it said it did (assumes no NULs embedded in the output)
    // and that it didn't write past the end of the buffer
    RW_ASSERT (buflen_1 == buflen_0 + nbytes);
    RW_ASSERT (buflen_1 < *pbufsize);

    return nbytes;
}


static int
_rw_fmtxarray (char **pbuf, size_t *pbufsize, const char *fmt, ...)
{
    va_list va;
    va_start (va, fmt);

    const int nbytes = _rw_fmtxarrayv (pbuf, pbufsize, fmt, va);

    va_end (va);

    return nbytes;
}


UserClassFmatInit::
UserClassFmatInit ()
{
    // push a new formatter function on top of the stack
    // of user-defined formatting callbacks invoked by
    // rw_printf() at al to process extended directives
    static int format_init = rw_printf ("%{+!}", _rw_fmtxarray);

    _RWSTD_UNUSED (format_init);
}
