/************************************************************************
 *
 * 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;

// used to initialize an array of objects of type UserClass
static const char *xinit_begin;

static int xinit ()
{
    if (xinit_begin)
        return UChar (*xinit_begin++);

    return 0;
}


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);
}
