_RWSTD_EXPORT int __rw_get_num (void *pval, const char *buf, int type, int flags, const char *groups, _RWSTD_SIZE_T ngroups, const char *grouping, _RWSTD_SIZE_T ngroupings) { // 22.2.2.1.2, p3: Stage 1 int err = 0; // errno value, ERANGE, or 0 _RWSTD_ASSERT (0 != buf); _RWSTD_ASSERT ('+' == *buf || '-' == *buf); if (!(type & __rw_facet::_C_floating)) { ////////////////////////////////////////////////////////////// // integral parsing (including void*) int base = unsigned (flags) >> _RWSTD_IOS_BASEOFF; if (!base) base = 10; union { #ifdef _RWSTD_LONG_LONG _RWSTD_LONG_LONG ll; unsigned _RWSTD_LONG_LONG ull; #endif // _RWSTD_LONG_LONG long l; unsigned long ul; } val; if (1 == base) { // treat numeric (i.e., non-Roman) input in base-1 as decimal const UChar digit = __rw_digit_map [UChar (buf [1])]; if (digit < 10) { val.ul = _RW::__rw_strtoul (buf, &err, 10); } else { _RWSTD_ASSERT ('+' == *buf); val.ul = __rw_get_roman (buf + 1); } val.l = _RWSTD_STATIC_CAST (long, val.ul); } else if (__rw_facet::_C_ullong == type) {
_RWSTD_SIZE_T gslice::next_ind () { _RWSTD_SIZE_T __n = _C_length.size (); while (__n && _C_r_length [__n - 1] == _C_length [__n - 1] - 1) --__n; if (0 == __n) { _C_reset = true; _C_r_length = 0; return _C_start; } if (_C_reset) { _C_reset = false; return _C_start; } _RWSTD_ASSERT (0 < __n); ++_C_r_length [__n - 1]; if (__n < _C_r_length.size ()) ::memset (&_C_r_length [__n], 0, (_C_r_length.size () - __n) * sizeof _C_r_length [__n]); else __n = _C_r_length.size (); _RWSTD_SIZE_T __inx = _C_start; for (_RWSTD_SIZE_T __i = 0; __i != __n; ++__i) __inx += _C_r_length [__i] * _C_stride [__i]; return __inx; }
/* virtual */ strstreambuf::int_type strstreambuf::underflow () { _RWSTD_ASSERT (_C_is_valid ()); if (gptr () < egptr ()) { // read position is available (see 27.5.1, p3, bullet 4) // D.7.1.3, p9, bullet 1 return traits_type::to_int_type (*gptr ()); } if (pptr () > egptr ()) { // D.7.1.3, p9, bullet 2 if (gptr ()) setg (eback (), gptr (), pptr ()); else setg (pbase (), pbase (), pptr ()); return traits_type::to_int_type (*gptr ()); } // D.7.1.3, p10 return traits_type::eof (); }
_RWSTD_EXPORT void* __rw_fopen (const char *fname, int openmode, long prot) { if (openmode & _RWSTD_IOS_STDIO) { // convert the iostream open mode to the C stdio file open mode const char* const fmode = __rw_stdio_mode (openmode); _RWSTD_ASSERT (0 != fmode); // fmode is the empty string on failure if ('\0' == *fmode) return 0; FILE *file; if (fname) { // open the named file using C stdio file = fopen (fname, fmode); } else { // FIXME: check openmode to make sure it's valid for "w+" // extension: create a temporary file for update ("w+") // that will be automatically deleted when all references // to the file are closed file = tmpfile (); } if (0 == file) return 0; return _RWSTD_STATIC_CAST (void*, file); } // convert the iostream open mode to the POSIX file access mode const int fdmode = __rw_io_mode (openmode); if (fdmode < 0) return 0; int fd; if (fname) { // open the named file fd = open (fname, fdmode, prot); } else { // extension: create a temporary file that will be deleted // when the last file descriptor that refers to it is closed fd = __rw_mkstemp (fdmode, prot); } if (fd < 0) return 0; return _RWSTD_REINTERPRET_CAST (void*, fd + 1); }
/* virtual */ strstreambuf::pos_type strstreambuf::seekpos (pos_type sp, ios::openmode which) { _RWSTD_ASSERT (_C_is_valid ()); // call seekoff() defined by strstreambuf, and // not an overridden() virtual if one exists return strstreambuf::seekoff (sp - pos_type (), ios::beg, which); }
/* virtual */ strstreambuf::~strstreambuf () { _RWSTD_ASSERT (_C_is_valid ()); if ( _C_buffer && _C_state & _C_allocated && !(_C_state & _C_frozen)) { if (_C_pfree) _C_pfree (_C_buffer); else delete[] _C_buffer; } }
static const void* __rw_get_numpunct (const __rw_facet *pfacet, int flags) { const int member = flags & ~(__rw_mon | __rw_wide | __rw_intl); const bool winx = !!(flags & __rw_wide); // wide or narrow index const void *pdata = pfacet->_C_data (); // mapped locale database if (pdata) { const __rw_punct_t* const pun = _RWSTD_STATIC_CAST (const __rw_punct_t*, pdata); const __rw_num_t *num; switch (member) { case __rw_dp: return pun->decimal_point (winx); case __rw_ts: return pun->thousands_sep (winx); case __rw_gr: return pun->grouping (); case __rw_tn: num = _RWSTD_STATIC_CAST (const __rw_num_t*, pun->get_ext ()); _RWSTD_ASSERT (num); return num->truename (winx); case __rw_fn: num = _RWSTD_STATIC_CAST (const __rw_num_t*, pun->get_ext ()); _RWSTD_ASSERT (num); return num->falsename (winx); default: _RWSTD_ASSERT (!"bad discriminant"); } return 0; } else if (0 == __rw_access::_C_get_name (*pfacet)) { // "C" locale
std::money_base::pattern set_pattern (const char *format) { std::money_base::pattern pat; for (unsigned i = 0; i != sizeof pat.field / sizeof *pat.field; ++i) { switch (format [i]) { case '\0': case '@': pat.field [i] = std::money_base::none; break; case '\1': case ' ': pat.field [i] = std::money_base::space; break; case '\2': case '$': pat.field [i] = std::money_base::symbol; break; case '\3': case '-': pat.field [i] = std::money_base::sign; break; case '\4': case '1': pat.field [i] = std::money_base::value; break; default: _RWSTD_ASSERT (!!"bad format specifier"); } } return pat; }
_RWSTD_EXPORT _RWSTD_SIZE_T __rw_rand (_RWSTD_SIZE_T limit) { _RWSTD_ASSERT (0 != limit); #ifdef _RWSTD_NO_TLS _RWSTD_MT_STATIC_GUARD (_RandGuardT); #endif // _RWSTD_NO_TLS if (0 == __rw_inx [0] && 0 == __rw_inx [1]) __rw_seed (161803398U); __rw_table [++__rw_inx [0] %= __rw_table_size] -= __rw_table [++__rw_inx [1] %= __rw_table_size]; return __rw_table [__rw_inx [0]] % limit; }
/* virtual */ strstreambuf::int_type strstreambuf::pbackfail (int_type c) { _RWSTD_ASSERT (_C_is_valid ()); typedef traits_type Traits; if (eback () < gptr ()) { // putback position is available (see 27.5.1, p3, bullet 3) if (Traits::eq_int_type (c, Traits::eof ())) { // D.7.1.3, p6, bullet 3 gbump (-1); return Traits::not_eof (c); } if (Traits::eq_int_type (Traits::to_int_type (*(gptr () - 1)), c)) { // D.7.1.3, p6, bullet 1 gbump (-1); return c; } if (!(_C_state & _C_constant)) { // D.7.1.3, p6, bullet 2 gbump (-1); Traits::assign (*gptr (), Traits::to_char_type (c)); return c; } } // D.7.1.3, p7 return Traits::eof (); }
// one-time initializer for the classic wide_tab static void __rw_init_classic_wide_tab () { # ifdef _RWSTDDEBUG static int init; // paranoid check: verify that one-time initialization works _RWSTD_ASSERT (0 == init); ++init; # endif // _RWSTDDEBUG // init the classic wide tab wchar_t wc_array [_STD::ctype<char>::table_size]; for (wchar_t wc = 0; wc < _STD::ctype<char>::table_size; ++wc) wc_array [wc] = wc; __rw_get_mask (0, wc_array, wc_array + _STD::ctype<char>::table_size, __rw_all, __rw_classic_wide_tab, false, false, "C"); }
/* virtual */ strstreambuf::int_type strstreambuf::overflow (int_type c) { _RWSTD_ASSERT (_C_is_valid ()); if (!_C_is_out () || !(_C_state & _C_dynamic)) return traits_type::eof (); if (_C_is_eof (c)) return traits_type::not_eof (c); // reallocate space if necessary if (!(pptr () < epptr ())) { const streamsize new_size = _C_bufsize ? _C_bufsize * 2 : _C_alsize ? _C_alsize : 128; // take care to avoid calling the overridden setbuf(), if any if (!strstreambuf::setbuf (0, new_size)) return traits_type::eof (); } return sputc (traits_type::to_char_type (c)); }
/* virtual */ streambuf* strstreambuf::setbuf (char_type* buf, streamsize bufsize) { _RWSTD_ASSERT (_C_is_valid ()); if ( !(_C_state & _C_dynamic) || (_C_state & _C_frozen) || (!buf && !bufsize)) { // lwg issue 66 return 0; } // determine the existing (possibly disjoint) sequences // in the (possibly two distinct) buffer(s) and copy // them into the new buffer // [.....] [.....] or [....[.]...] // ^ ^ ^ ^ ^ ^ // | | | | | | // | | | +- xend | +- xend, gap_beg, gap_end // | | +------- gap_end +------------ xbeg // | +---------- gap_beg // +---------------- xbeg const char_type* const xbeg = eback () && eback () < pbase () ? eback () : pbase (); const char_type* const xend = epptr () && epptr () < egptr () ? egptr () : epptr (); const char_type *gap_beg = pptr () < eback () ? pptr () : egptr () < pbase () ? egptr () : pbase (); const char_type *gap_end = pptr () < eback () ? eback () : egptr () < pbase () ? egptr () : pbase (); // if gap_end is before gap_beg, set both so as to make the gap zero size if (gap_end <= gap_beg) gap_beg = gap_end = xend; // compute the cumulative size of both sequences minus the gap const streamsize slen = streamsize ((xend - xbeg) - (gap_end - gap_beg)); if (bufsize < slen || !_C_is_out ()) return 0; // failure const bool free_old_buf = _C_own_buf (); if (!buf) { _TRY { // allocate a new buffer buf = _C_palloc ? _RWSTD_STATIC_CAST (char_type*, _C_palloc (bufsize)) : new char [bufsize]; } _CATCH (...) { // catch all exceptions, indicate failure by returning 0 } if (!buf) return 0; _C_own_buf (true); }
/* static */ __rw_locale* __rw_locale:: _C_get_body (__rw_locale *one, __rw_locale *other, const char *locname, int cat, const __rw_facet *pfacet) { __rw_chararray realname; // see if `locname' contains embedded "LC_XXX=..." sequences if (locname && !strncmp (locname, "LC_", 3)) { // convert a combined locale name (consisting of a sequence // of `sep'-separated LC_XXX=<name> substrings) to a normalized // form in the expected (internal) format and order const char *pcatnames [__rw_n_cats] = { 0 }; // try the libc "native" separator first, semicolon next const char *sep = strchr (locname, *_RWSTD_CAT_SEP); if (!sep) sep = ";"; for (const char *s = locname; *s; ) { const char *next = strchr (s, *sep); if (!next) next = s + strlen (s); const char* const endcat = strchr (s, '='); if (!endcat) return 0; // error: missing `=' after LC_XXX // go through the LC_XXX category names, trying to find // a match; if found, remember its position (duplicates // are not allowed) for (_RWSTD_SIZE_T i = 0; i != __rw_n_cats; ++i) { if (!strncmp (__rw_cats [i].name, s, endcat - s)) { if (pcatnames [i]) return 0; // error: duplicate LC_XXX pcatnames [i] = endcat + 1; break; } } s = *next ? next + 1 : next; } // compose a normalized locale name out of category names _RWSTD_SIZE_T size = 0; for (_RWSTD_SIZE_T i = 0; i != __rw_n_cats; ++i) { if (!pcatnames [i]) { // use "C" for missing LC_XXX values pcatnames [i] = "C"; } const char *endcat = strchr (pcatnames [i], *sep); if (!endcat) endcat = pcatnames [i] + strlen (pcatnames [i]); const _RWSTD_SIZE_T catsize = endcat - pcatnames [i]; // append name followed by the libc "native" separator realname.append (pcatnames [i], catsize); realname.append (_RWSTD_CAT_SEP, 1); size += catsize; } locname = realname.data (); } else if (locname && *locname == *_RWSTD_CAT_SEP) { // advance past the leading category separator if present ++locname; } if (!one && !other && !locname && _STD::locale::none == cat && !pfacet) { // implements default ctor: locale::locale () throw () __rw_locale* const global = __rw_locale::_C_manage (0, 0); _RWSTD_ASSERT (0 != global); return global; } if (one && !other && !locname && _STD::locale::none == cat && !pfacet) { // copy ctor: locale::locale (const locale&) // or combining ctor: locale::locale (const locale&, Facet*) // (in the second case with Facet* being 0) // body may or may not be globally managed // or locale::operator=(const locale&) _RWSTD_ATOMIC_PREINCREMENT (one->_C_ref, false); return one; } if (!one && !other && locname && _STD::locale::none == cat && !pfacet) { // ctor: locale::locale (const char*) // if successful, body is globally managed __rw_locale* const plocale = __rw_locale::_C_manage (0, locname); _RWSTD_ASSERT (!plocale || plocale->_C_is_managed (_STD::locale::none)); return plocale; } if (one && !other && !locname && _STD::locale::none == cat && pfacet) { // template ctor: locale::locale (const locale&, Facet*) // with `pfacet' being installed (e.g., adding or replacing // an existing one) // template <class Facet> locale::combine(const locale&) is // trivially implemented inline in terms of the template ctor __rw_locale* const plocale = one->_C_combine (pfacet); _RWSTD_ASSERT (0 != plocale); return plocale; } if (one && !other && locname && !pfacet) { // combining ctor: locale (const locale&, const char*, category) // construct a temporary locale from locale name `locname' const _STD::locale tmp (locname); // construct a locale combined from `one' and the temporary __rw_locale* const plocale = one->_C_combine (*tmp._C_body, cat); return plocale; } if (one && other && !locname && !pfacet) { // combining ctor: locale (const locale&, const locale&, category) return one->_C_combine (*other, cat); } _RWSTD_ASSERT (!"logic error: bad combination of arguments"); return 0; }
void __rw_locale:: _C_construct (const __rw_locale &rhs, const __rw_facet *pfacet) { // called from ctor only, members are not initialized _C_ref = 1; // copy standard facets from other locale #if defined (__i386__) || !defined (__GNUG__) || __GNUG__ < 3 memcpy (_C_std_facets, rhs._C_std_facets, _C_n_std_facets * sizeof *_C_std_facets); #else // !i86 || !gcc 3.x // Working around a bug (most probably) identical to the one described // and fixed in __rw_locale::__rw_locale, but related to the use of // memcpy. for(_RWSTD_SIZE_T i = 0; i != _C_n_std_facets; i++) _C_std_facets [i] = rhs._C_std_facets [i]; #endif // i86/gcc 3.x _RWSTD_ASSERT (!pfacet || pfacet->_C_pid); // get facet's index into one of the facet arrays _RWSTD_SIZE_T inx = pfacet ? rhs._C_get_facet_inx (*pfacet->_C_pid) : (_RWSTD_SIZE_T)(-1); // extend size if facet isn't installed in `rhs' _C_n_usr_facets = rhs._C_n_usr_facets + (inx > rhs._C_n_usr_facets + _C_n_std_facets); // allocate a buffer for user facets if necesary _C_usr_facets = _C_n_usr_facets ? new __rw_facet* [_C_n_usr_facets] : 0; // copy facets from other locale memcpy (_C_usr_facets, rhs._C_usr_facets, rhs._C_n_usr_facets * sizeof *_C_usr_facets); _RWSTD_ASSERT (rhs._C_name); _C_name = 0; // copy facet bits from `rhs' and adjust below as necessary _C_std_facet_bits = rhs._C_std_facet_bits; _C_byname_facet_bits = rhs._C_byname_facet_bits; if (pfacet) { __rw_facet* const pf = _RWSTD_CONST_CAST (__rw_facet*, pfacet); // overwrite an existing pointer or add a new one if (inx < _C_n_std_facets) { _C_std_facets [inx] = pf; const _RWSTD_SIZE_T facet_bit = 1UL << inx; // set or clear a corresponding bit based on whether // the facet is one of the standard facets or not // (user-defined objects even if they are of standard // facet types, are not considered standard facets) if (pf->_C_type > 0) _C_std_facet_bits |= facet_bit; else _C_std_facet_bits &= ~facet_bit; // ditto for named facet bitmap if (pf->_C_type & 1) // even types are _byname _C_byname_facet_bits &= ~facet_bit; else _C_byname_facet_bits |= facet_bit; // construct a new name // _C_name = // _C_make_name (_C_namebuf, sizeof _C_namebuf, rhs, *pfacet); } else if ((_RWSTD_SIZE_T)(-1) == inx) _C_usr_facets [_C_n_usr_facets - 1] = pf; else _C_usr_facets [inx - _C_n_std_facets] = pf; } if (!_C_name) { // simply copy name from `rhs' const _RWSTD_SIZE_T size = strlen (rhs._C_name) + 1; char* const name = size <= sizeof _C_namebuf ? _C_namebuf : new char [size]; memcpy (name, rhs._C_name, size); _C_name = name; } // increment reference counts for facets (including the newly added one) for (inx = 0; inx != _C_n_std_facets; ++inx) { if (_C_std_facets [inx]) _RWSTD_ATOMIC_PREINCREMENT (_C_std_facets [inx]->_C_ref, _C_std_facets [inx]->_C_mutex); } for (inx = 0; inx != _C_n_usr_facets; ++inx) { _RWSTD_ATOMIC_PREINCREMENT (_C_usr_facets [inx]->_C_ref, _C_usr_facets [inx]->_C_mutex); } }
void do_test (int line, // line number of test case const char *src, // source sequence std::size_t resoff, // offset of result ForwardIterator dummy_iter, const T*, const char* predname) { static const char* const itname = type_name (dummy_iter, (T*)0); const std::size_t nsrc = std::strlen (src); if (std::size_t (-1) == resoff) resoff = nsrc; // have the UserClass default ctor initialize objects from `src' xinit_begin = src; UserClass::gen_ = xinit; UserClass* const xsrc = new UserClass [nsrc]; const ForwardIterator first = make_iter (xsrc, xsrc, xsrc + nsrc, dummy_iter); const ForwardIterator last = make_iter (xsrc + nsrc, xsrc, xsrc + nsrc, dummy_iter); // reset predicate counters UserClass::n_total_op_eq_ = 0; EqualityPredicate<T, T>::funcalls_ = 0; // construct a predicate object const EqualityPredicate<T, T> pred (0, 0); const ForwardIterator res = predname ? std::adjacent_find (first, last, pred) : std::adjacent_find (first, last); // silence a bogus EDG eccp remark #550-D: // variable "res" was set but never used _RWSTD_UNUSED (res); const std::size_t n_total_pred = predname ? EqualityPredicate<T, T>::funcalls_ : UserClass::n_total_op_eq_; // verify that the returned iterator is set as expected int success = res.cur_ == first.cur_ + resoff; rw_assert (success, 0, line, "line %d: adjacent_find<%s>(it = \"%s\", ...)" " == (it + %zu), got (it + %td)", __LINE__, itname, src, resoff, res.cur_ - first.cur_); // verify the number of applications of the predicate (lwg issue 240): // Complexity: For a nonempty range, exactly // min((i - first) + 1, (last - first) - 1) // applications of the corresponding predicate, where i is // adjacent_find's return value. // compute the expected number of invocations of the predicate std::size_t n_expect_pred = 0; if (nsrc) { // test iterators are guaranteed to be in range _RWSTD_ASSERT (first.cur_ <= res.cur_ && res.cur_ <= last.cur_); n_expect_pred = std::size_t (res.cur_ - first.cur_) + 1; const std::size_t tmp = std::size_t (last.cur_ - first.cur_) - 1; if (tmp < n_expect_pred) n_expect_pred = tmp; } success = std::size_t (n_expect_pred) == n_total_pred; rw_assert (success, 0, line, "line %d: adjacent_find<%s>(\"%s\", ...) " "invoked %s %zu times, expected %td", __LINE__, itname, src, predname ? predname : "operator==()", n_total_pred, n_expect_pred); }
_RW::__rw_locale* __rw_locale:: _C_combine (const __rw_facet *pfacet) const { _RWSTD_ASSERT (pfacet); // template ctor: locale::locale (const locale&, Facet*) // with `facet' being installed (e.g., adding or replacing // an existing one) // verify that Facet::id has been initialized _RWSTD_ASSERT (pfacet->_C_pid); _RWSTD_ASSERT (*pfacet->_C_pid); // get the locale name ("C" if it's NUL) const char* const one_locname = _C_name ? _C_name : "C"; // get the name of the locale `*pfacet' belongs to const char* const facet_locname = pfacet->_C_name ? pfacet->_C_name : "C"; // get the locale::category that `*pfacet' belongs to const int facet_cat = _C_LC2category (__rw_get_cat (int (*pfacet->_C_pid))); bool managed = false; if (pfacet->_C_type && !_C_n_usr_facets) { // facet is one of the (perhaps byname) standard facets // compute the number of the bit in _C_std_facet_bits or //_C_byname_facet_bits corresponding to the facet being // used (i.e., `*pfacet') const _RWSTD_SIZE_T facet_bit = (_RWSTD_SIZE_T)1U << (*pfacet->_C_pid - 1U); // a locale object is globally managed if all its facets are objects // of standard facet types (ordinary or byname) that were constructed // by the library and within each locale category all facets belong // to the same facet // managed locales have names that completely describe their facets // and from which they can be unambiguously and fully constructed // // note that in the code snippet below, x0 is not a managed locale // (its name is "*"), but y0 is a managed locale (on SunOS, its name // is "/de_DE/de_DE/de_DE/de_DE/de_DE/en_US"); x1 is the same as x0 // and y1 is the same as de: // // locale de ("de_DE"); // locale en ("en_US"); // locale x0 = de.combine<messages<char> >(en); // locale y0 = x0.combine<messages<wchar_t> >(en); // locale x1 = y0.combine<messages<wchar_t> >(de); // locale y1 = x1.combine<messages<char> >(de); // assert (de == y1); // assert (x0 == x1); if (__rw_locale::_C_all == (_C_std_facet_bits | facet_bit)) { // compute the bitmask corresponding to all the facets in // the same category as the one to which `*pfacet' belongs const int cat_bits = _C_LC2facet_bits (facet_cat); // get the index into the _C_std_facets array for `pfacet' const _RWSTD_SIZE_T facet_inx = _C_get_facet_inx (*pfacet->_C_pid); managed = true; // iterate over all facets that belong the same category // as `*pfacet' and compare the name of each with the name // of `*pfacet' to determine if they all have the same name // _byname facets that are not installed yet (i.e., whose // pointers are 0 come from a locale whose name is given // by the name of the whole locale for (_RWSTD_SIZE_T i = 0; i != _C_n_std_facets; ++i) { // skip facets from other categories if (!((1 << i) & cat_bits)) continue; // skip the facet being replaced if (facet_inx == i) continue; const char* const ones_facet_locname = _C_std_facets [i] ? _C_std_facets [i]->_C_name ? _C_std_facets [i]->_C_name : "C" : one_locname; if (strcmp (facet_locname, ones_facet_locname)) { managed = false; break; } } } } __rw_locale *plocale; if (managed) { __rw_chararray locname; __rw_combine_names (locname, one_locname, facet_locname, facet_cat); plocale = __rw_locale::_C_manage (0, locname.data ()); _RWSTD_ASSERT (0 != plocale); _RWSTD_ASSERT (plocale->_C_is_managed (_STD::locale::none)); } else { plocale = new __rw_locale (*this, pfacet); _RWSTD_ASSERT (0 != plocale); _RWSTD_ASSERT (!plocale->_C_is_managed (_STD::locale::none)); } return plocale; }
void do_test (int line, // line number of test case const char *src, // source sequence std::size_t resoff, // offset of result ForwardIterator dummy_iter, const T*, const char* predicate) { static const char* const itname = type_name (dummy_iter, (T*)0); #ifdef __SYMBIAN32__ const size_t nsrc = strlen (src); #else const std::size_t nsrc = std::strlen (src); #endif //__SYMBIAN32__ if (std::size_t (-1) == resoff) resoff = nsrc; // have the X default ctor initialize objects from `src' xinit_begin = src; #ifndef __SYMBIAN32__ X::gen_ = xinit; #else gen_ = xinit; #endif X* const xsrc = new X [nsrc]; const ForwardIterator first = make_iter (xsrc, xsrc, xsrc + nsrc, dummy_iter); const ForwardIterator last = make_iter (xsrc + nsrc, xsrc, xsrc + nsrc, dummy_iter); // compute the number of invocations of the predicate #ifndef __SYMBIAN32__ std::size_t n_total_pred = X::n_total_op_eq_; #else std::size_t n_total_pred = n_total_op_eq_; #endif const ForwardIterator res = predicate ? std::adjacent_find (first, last, std::equal_to<X>()) : std::adjacent_find (first, last); // silence a bogus EDG eccp remark #550-D: // variable "res" was set but never used _RWSTD_UNUSED (res); #ifndef __SYMBIAN32__ n_total_pred =X::n_total_op_eq_ - n_total_pred; #else n_total_pred = n_total_op_eq_ - n_total_pred; #endif // verify that the returned iterator is set as expected int success = res.cur_ == first.cur_ + resoff; if(!success) { failures++; std_log(LOG_FILENAME_LINE,"Reason: Failing as expected iterator is not returned"); } rw_assert (success, 0, line, "line %d: adjacent_find<%s>(it = \"%s\", ...)" " == (it + %zu), got (it + %td)", __LINE__, itname, src, resoff, res.cur_ - first.cur_); // verify the number of applications of the predicate (lwg issue 240): // Complexity: For a nonempty range, exactly // min((i - first) + 1, (last - first) - 1) // applications of the corresponding predicate, where i is // adjacent_find's return value. // compute the expected number of invocations of the predicate std::size_t n_expect_pred = 0; if (nsrc) { // test iterators are guaranteed to be in range _RWSTD_ASSERT (first.cur_ <= res.cur_ && res.cur_ <= last.cur_); n_expect_pred = std::size_t (res.cur_ - first.cur_) + 1; const std::size_t tmp = std::size_t (last.cur_ - first.cur_) - 1; if (tmp < n_expect_pred) n_expect_pred = tmp; } success = std::size_t (n_expect_pred) == n_total_pred; if(!success) { failures ++; std_log(LOG_FILENAME_LINE,"Reason: Failing as iteratoris not in range"); } rw_assert (success, 0, line, "line %d: adjacent_find<%s>(\"%s\", ...) " "invoked %s %zu times, expected %td", __LINE__, itname, src, predicate ? predicate : "operator==()", n_total_pred, n_expect_pred); }
void __rw_locale:: _C_construct (const __rw_locale &one, const __rw_locale &other, int cat) { // category must be valid at this point (checked by caller) _RWSTD_ASSERT (_C_check_category (cat)); // called from ctor only, members are not initialized _C_ref = 1; // size is the same as that of `one' _C_n_usr_facets = one._C_n_usr_facets; // allocate only if internal buffer is insufficient _C_usr_facets = _C_n_usr_facets ? new __rw_facet* [_C_n_usr_facets] : 0; // copy standard facets to `one' from `other' memcpy (_C_std_facets, one._C_std_facets, _C_n_std_facets * sizeof *_C_std_facets); // copy user-defined facets (if any) memcpy (_C_usr_facets, one._C_usr_facets, _C_n_usr_facets * sizeof *_C_usr_facets); // compute and assign facet bitmaps const int bits = _C_LC2facet_bits (cat); _C_std_facet_bits = one._C_std_facet_bits & ~bits | other._C_std_facet_bits & bits; _C_byname_facet_bits = one._C_byname_facet_bits & ~bits | other._C_byname_facet_bits & bits; for (_RWSTD_SIZE_T i = 0; i != _C_n_std_facets; ++i) { // each facet is stored at an index equal to its (id - 1) // convert an LC_XXX constant to a locale::category value const int c = _C_LC2category (__rw_get_cat (int (i) + 1)); if (cat & c) { // assign/overwrite corresponding facets _C_std_facets [i] = other._C_std_facets [i]; } if (_C_std_facets [i]) { // bump up the facet's reference count of *this' facet _RWSTD_ATOMIC_PREINCREMENT (_C_std_facets [i]->_C_ref, _C_std_facets [i]->_C_mutex); } } // increment the ref count of user-defined facets (if any) for (_RWSTD_SIZE_T j = 0; j != _C_n_usr_facets; ++j) { _RWSTD_ASSERT (_C_usr_facets [j]); _RWSTD_ATOMIC_PREINCREMENT (_C_usr_facets [j]->_C_ref, _C_usr_facets [j]->_C_mutex); } __rw_chararray locname; __rw_combine_names (locname, one._C_name, other._C_name, cat); if (locname.size () >= one._C_namebuf_size) _C_name = locname.release (); else { _C_name = _C_namebuf; memcpy (_C_namebuf, locname.data (), locname.size () + 1); } }
void exception_loop (int line /* line number in caller*/, MemberFunction mfun /* deque member function */, const char *fcall /* function call string */, int exceptions /* enabled exceptions */, Deque &deq /* container to call function on */, const Deque::iterator &it /* iterator into container */, int n /* number of elements or offset */, const UserClass *x /* pointer to an element or 0 */, const Iterator &first /* beginning of range */, const Iterator &last /* end of range to insert */, int *n_copy /* number of copy ctors */, int *n_asgn /* number of assignments */) { std::size_t throw_after = 0; // get the initial size of the container and its begin() iterator // to detect illegal changes after an exception (i.e., violations // if the strong exception guarantee) const std::size_t size = deq.size (); const Deque::const_iterator begin = deq.begin (); const Deque::const_iterator end = deq.end (); #ifdef DEFINE_REPLACEMENT_NEW_AND_DELETE rwt_free_store* const pst = rwt_get_free_store (0); #endif // DEFINE_REPLACEMENT_NEW_AND_DELETE // repeatedly call the specified member function until it returns // without throwing an exception for ( ; ; ) { // detect objects constructed but not destroyed after an exception std::size_t x_count = UserClass::count_; _RWSTD_ASSERT (n_copy); _RWSTD_ASSERT (n_asgn); *n_copy = UserClass::n_total_copy_ctor_; *n_asgn = UserClass::n_total_op_assign_; #ifndef _RWSTD_NO_EXCEPTIONS // iterate for `n=throw_after' starting at the next call to operator // new, forcing each call to throw an exception, until the insertion // finally succeeds (i.e, no exception is thrown) # ifdef DEFINE_REPLACEMENT_NEW_AND_DELETE if (exceptions & NewThrows) { *pst->throw_at_calls_ [0] = pst->new_calls_ [0] + throw_after + 1; } # endif // DEFINE_REPLACEMENT_NEW_AND_DELETE if (exceptions & CopyCtorThrows) { UserClass::copy_ctor_throw_count_ = UserClass::n_total_copy_ctor_ + throw_after; } if (exceptions & AssignmentThrows) { UserClass::op_assign_throw_count_ = UserClass::n_total_op_assign_ + throw_after; } #endif // _RWSTD_NO_EXCEPTIONS _TRY { switch (mfun) { case Assign_n: _RWSTD_ASSERT (x); deq.assign (n, *x); break; case AssignRange: deq.assign (first, last); break; case Erase_1: deq.erase (it); break; case EraseRange: { const Deque::iterator erase_end (it + n); deq.erase (it, erase_end); break; } case Insert_1: _RWSTD_ASSERT (x); deq.insert (it, *x); break; case Insert_n: _RWSTD_ASSERT (x); deq.insert (it, n, *x); break; case InsertRange: deq.insert (it, first, last); break; } } _CATCH (...) { // verify that an exception thrown from the member function // didn't cause a change in the state of the container rw_assert (deq.size () == size, 0, line, "line %d: %s: size unexpectedly changed " "from %zu to %zu after an exception", __LINE__, fcall, size, deq.size ()); rw_assert (deq.begin () == begin, 0, line, "line %d: %s: begin() unexpectedly " "changed after an exception by %td", __LINE__, fcall, deq.begin () - begin); rw_assert (deq.end () == end, 0, line, "line %d: %s: end() unexpectedly " "changed after an exception by %td", __LINE__, fcall, deq.end () - end); // count the number of objects to detect leaks x_count = UserClass::count_ - x_count; rw_assert (x_count == deq.size () - size, 0, line, "line %d: %s: leaked %zu objects after an exception", __LINE__, fcall, x_count - (deq.size () - size)); if (exceptions) { // increment to allow this call to operator new to succeed // and force the next one to fail, and try to insert again ++throw_after; } else break; continue; } // count the number of objects to detect leaks x_count = UserClass::count_ - x_count; rw_assert (x_count == deq.size () - size, 0, line, "line %d: %s: leaked %zu objects " "after a successful insertion", __LINE__, fcall, x_count - (deq.size () - size)); break; }
/* virtual */ strstreambuf::pos_type strstreambuf::seekoff (off_type off, ios::seekdir way, ios::openmode which) { _RWSTD_ASSERT (_C_is_valid ()); // should implicitly hold as long as ios::seekdir is an enum _RWSTD_ASSERT (ios::beg == way || ios::cur == way || ios::end == way); _RWSTD_ASSERT (_C_is_valid ()); // determine seekable area - D.7.1, p4 char* const seeklo = eback (); char* const seekhi = epptr () ? epptr () : egptr (); const char* const xnext = which & ios::in ? gptr () : pptr (); const char* const xbeg = which & ios::in ? eback () : pbase (); // D.7.1.3, p13 if (!xnext) return pos_type (off_type (-1)); off_type saved_off = off; // compute new offset - D.7.1.3, p13, table 105 if (ios::cur == way) off += off_type (xnext - xbeg); else if (ios::end == way) off += off_type (seekhi - xbeg); // test conditions in D.7.1.3, p13, table 105, row 4 if (off < seeklo - xbeg || off > seekhi - xbeg) off = -1; // failure else if (which & ios::in) { // position input sequence // fail if `way' is `cur', otherwise position output sequence first if ( which & ios::out && ( way == ios::cur || pos_type (-1) == seekoff (saved_off, way, ios::out))) return pos_type (off_type (-1)); // adjust input sequence as necessary to maintain invariant if (off <= egptr () - eback ()) setg (eback (), eback () + off, egptr ()); else if (off <= pptr () - egptr ()) // advance egptr() setg (eback (), eback () + off, pptr ()); else // advance egptr() even further setg (eback (), eback () + off, epptr ()); } else if (which & ios::out) { // position output sequence if (seeklo + off < pbase ()) { // adjust beginning of output sequence, then increment pptr() setp (seeklo, epptr ()); pbump (off); } else { // reset pptr() first, then increment it by offset setp (pbase (), epptr ()); pbump (off - (pbase () - seeklo)); } } else off = -1; // failure _RWSTD_ASSERT (_C_is_valid ()); return pos_type (off); }
void run_test (intT, thr_args_base::tag_t tag) { static const char* const tname = rw_any_t (intT ()).type_name (); if (!rw_enabled (tname)) { rw_note (0, 0, 0, "%s test disabled", tname); return; } #ifdef _RWSTD_REENTRANT static const char* const fun = "__rw_atomic_exchange"; rw_info (0, 0, 0, "__rw::%s (%s&, %2$s): %d iterations in %d threads", fun, tname, rw_opt_nloops, rw_opt_nthreads); rw_thread_t tid [MAX_THREADS]; typedef thr_args<intT> Args; Args::nthreads_ = unsigned (rw_opt_nthreads); Args::type_tag_ = tag; Args::nincr_ = unsigned (rw_opt_nloops); Args::shared_ [0] = intT (1); Args::shared_ [1] = intT (1); _RWSTD_ASSERT (Args::nthreads_ < sizeof tid / sizeof *tid); Args args [sizeof tid / sizeof *tid]; for (unsigned long i = 0; i != Args::nthreads_; ++i) { args [i].threadno_ = i; args [i].niter_ = 0; args [i].nxchg_ = 0; rw_fatal (0 == rw_thread_create (tid + i, 0, thread_routine, args + i), 0, __LINE__, "thread_create() failed"); } for (unsigned long i = 0; i != Args::nthreads_; ++i) { rw_error (0 == rw_thread_join (tid [i], 0), 0, __LINE__, "thread_join() failed"); if (args [i].niter_) { // compute the percantage of thread iterations that resulted // in increments of one of the shared variables const unsigned long incrpcnt = (100U * Args::nincr_) / args [i].niter_; printf ("thread %lu performed %lu exchanges in %lu iterations " "(%lu%% increments)\n", args [i].threadno_, args [i].nxchg_, args [i].niter_, incrpcnt); } } // compute the expected result, "skipping" zeros by incrementing // expect twice when it overflows and wraps around to 0 (zero is // used as the lock variable in thread_routine() above) intT expect = intT (1); const unsigned long nincr = (Args::nthreads_ * Args::nincr_) / 2U; for (unsigned long i = 0; i != nincr; ++i) { if (intT () == ++expect) ++expect; } // verify that the final value of the variables shared among all // threads equals the number of increments performed by the threads rw_assert (Args::shared_ [0] == expect, 0, __LINE__, "1. %s (%s&, %2$s); %s == %s failed", fun, tname, TOSTR (Args::shared_ [0]), TOSTR (expect)); rw_assert (Args::shared_ [1] == expect, 0, __LINE__, "2. %s (%s&, %2$s); %s == %s failed", fun, tname, TOSTR (Args::shared_ [1]), TOSTR (expect)); #else // if !defined (_RWSTD_REENTRANT) _RWSTD_UNUSED (tag); #endif // _RWSTD_REENTRANT }
__rw_locale* __rw_locale:: _C_combine (const __rw_locale &other, int cat) { // convert a possible LC_XXX constant to a locale::category value cat = _C_LC2category (cat); // verify that the category argument is valid if (!_C_check_category (cat)) return 0; // combining ctor: locale (const locale&, const locale&, cat) if (this == &other || _STD::locale::none == cat) { // same as copy ctor (copying all facets from `*this') // body may or may not be globally managed _RWSTD_ATOMIC_PREINCREMENT (_C_ref, false); return this; } #if 0 // disabled // 22.1.1.2, p14: only facets that implement categories in `cat' are // to be copied from `other', i.e., not necessarily user-defined facets if (_RWSTD_LC_ALL == cat || _STD::locale::all == cat) { // same as copy ctor (copying all facets from `other') // body may or may not be globally managed _RWSTD_ATOMIC_PREINCREMENT (other._C_ref, false); return &other; } #endif // 0/1 if ( _C_is_managed (_STD::locale::all & ~cat) && other._C_is_managed (cat)) { // determine new locale name from `*this' and `other's, taking all of // this's category names except for those given by `cat', which come // from `other' const char *name_1 = _C_name; const char *name_2 = other._C_name; if (0 == strcmp (name_1, name_2)) { // if locale names are the same, return a globally managed body __rw_locale* const plocale = __rw_locale::_C_manage (0, name_1); _RWSTD_ASSERT (0 != plocale); _RWSTD_ASSERT (plocale->_C_is_managed (_STD::locale::none)); return plocale; } __rw_chararray locname; // compose the new name __rw_combine_names (locname, name_1, name_2, cat); // return a globally managed body __rw_locale* const plocale = __rw_locale::_C_manage (0, locname.data ()); _RWSTD_ASSERT (0 != plocale); _RWSTD_ASSERT (plocale->_C_is_managed (_STD::locale::none)); return plocale; } // one or both locales are not globally managed (one or more of // their facets are of use-defined types, possibly derived from // the standard facets), and thus the combined locale cannot be // globally managed either __rw_locale *plocale = new __rw_locale (*this, other, cat); _RWSTD_ASSERT (!plocale->_C_is_managed (_STD::locale::none)); return plocale; }