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

    default:
        // should never get here (silences bogus HP aCC/cadvise
        // warning #20200-D: Potential null pointer dereference)
        RW_ASSERT (!"unhandled case");
        return;
    }

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

    // this should trivially hold given the above but the assert
    // silences bogus HP aCC/cadvise warning #20200-D: Potential
    // null pointer dereference
    RW_ASSERT (0 != array);

    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;   // pointer to rw_vsnprintf's va_list
    bool     fl_plus  =  false;
    bool     fl_pound =  false;
    int      nelems   = -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 = int (strtol (fmt, &end, 10));
        if ('$' != *end)
            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 = int (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

    const char* pointer [2];

    for (const UserClass *px = xbeg; px != xbeg + nelems; ++px) {

        if (px == pelem) {
            pointer [0] = ">";
            pointer [1] = "<";
        }
        else {
            pointer [0] = "";
            pointer [1] = "";
        }

        const int n =
            rw_asnprintf (pbuf, pbufsize,
                          "%{+}%s"                        // '>'
                          "%{?}%d:%{;}"
                          "%{?}%d%s%{?},%{;}%{:}%{lc}%{;}",
                          pointer [0],                    // ">" or ""
                          fl_pound, px->id_,              // "<id>:"
                          fl_plus, px->data_.val_,        // <val>
                          pointer [1],                    // "<" or ""
                          px + 1 < xbeg + nelems,         // ','
                          px->data_.val_,                 // <val>
                          pointer [1]);                   // "<" or ""
        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);
}
