/*************************************************************************** * * bitset - definitions of out-of-line bitset members * * $Id: bitset.cc 465512 2006-10-19 06:53:06Z faridz $ * *************************************************************************** * * 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 2004-2005 Rogue Wave Software. * **************************************************************************/ _RWSTD_NAMESPACE (__rw) { #if 8 == _RWSTD_CHAR_BIT # define _RWSTD_LOG2_CHAR_BITS 3 #elif 16 == _RWSTD_CHAR_BIT # define _RWSTD_LOG2_CHAR_BITS 4 #elif 32 == _RWSTD_CHAR_BIT # define _RWSTD_LOG2_CHAR_BITS 5 #elif 64 == _RWSTD_CHAR_BIT # define _RWSTD_LOG2_CHAR_BITS 6 #endif #if 1 == _RWSTD_LONG_SIZE # define _RWSTD_LOG2_LONG_SIZE 0 #elif 2 == _RWSTD_LONG_SIZE # define _RWSTD_LOG2_LONG_SIZE 1 #elif 4 == _RWSTD_LONG_SIZE # define _RWSTD_LOG2_LONG_SIZE 2 #elif 8 == _RWSTD_LONG_SIZE # define _RWSTD_LOG2_LONG_SIZE 3 #elif 16 == _RWSTD_LONG_SIZE # define _RWSTD_LOG2_LONG_SIZE 4 #endif _EXPORT template void __rw_bitset (unsigned long *__bits, _RWSTD_SIZE_T __maxbits, const _CharT *__str, _RWSTD_SIZE_T __slen, const _Traits*, _CharT __b0, _CharT __b1, _RWSTD_SIZE_T __pos, _RWSTD_SIZE_T __n, const char *__file, const char *__fun) { const _RWSTD_SIZE_T __wordbits = sizeof *__bits * _RWSTD_CHAR_BIT; if (_RWSTD_SIZE_MAX == __slen) __slen = _Traits::length (__str); // verify that `pos' is a valid offset into `str' _RWSTD_REQUIRES (__pos <= __slen, (_RWSTD_ERROR_OUT_OF_RANGE, __file, __fun, __pos, __slen)); // compute the number of characters in `str' past the offset `pos' // that will be checked (although not all of them may necessarily // be used) const _RWSTD_SIZE_T __nchars = __n < (__slen - __pos) ? __n : __slen - __pos; // compute the number of bits to initialize from `str' const _RWSTD_SIZE_T __nbits = __nchars < __maxbits ? __nchars : __maxbits; __str += __pos; // compute the number of bytes occupied by `bits' #if defined (_RWSTD_LOG2_CHAR_BITS) && defined (_RWSTD_LOG2_LONG_SIZE) const _RWSTD_SIZE_T __nbytes = ((__maxbits >> (_RWSTD_LOG2_CHAR_BITS + _RWSTD_LOG2_LONG_SIZE)) + (0 != (__maxbits & (__wordbits - 1)))) << _RWSTD_LOG2_LONG_SIZE; #else // #if !defined (_RWSTD_LOG2_CHAR_BITS) || !defined (_RWSTD_LOG2_LONG_SIZE) const _RWSTD_SIZE_T __nbytes = (__maxbits / __wordbits + (0 != __maxbits % __wordbits)) * sizeof (*__bits); #endif // _RWSTD_LOG2_CHAR_BITS && _RWSTD_LOG2_LONG_SIZE _RWSTD_MEMSET (__bits, 0, __nbytes); // set all bits but also check any extra characters as required for (_RWSTD_SIZE_T __i = 0; __i != __nchars; ++__i) { if (_Traits::eq (__b1, __str [__i])) { const _RWSTD_SIZE_T __bitno = __nbits - __i - 1; if (__i < __nbits) __bits [__bitno / __wordbits] |= 1UL << __bitno % __wordbits; } else { // verify that the character is valid _RWSTD_REQUIRES (_Traits::eq (__b0, __str [__i]), (_RWSTD_ERROR_INVALID_ARGUMENT, __file, __fun)); } } } #undef _RWSTD_LOG2_CHAR_BITS #undef _RWSTD_LOG2_ULONG_SIZE _EXPORT template <_RWSTD_SIZE_T _Size, class _CharT, class _Traits> _STD::basic_istream<_CharT, _Traits>& __rw_extract_bitset (_STD::basic_istream<_CharT, _Traits> &__strm, _STD::bitset<_Size> &__x) { typedef _STD::basic_istream<_CharT, _Traits> _Istream; _TYPENAME _Istream::iostate __err (__strm.goodbit); _STD::bitset<_Size> __tmp; _RWSTD_SIZE_T __bit = _Size; _TRY { // sentry may throw an exception const _TYPENAME _Istream::sentry __ipfx (__strm); if (__ipfx) { // 23.3.5.3, p5 - extract at most _Size chars // get next char without extracting _TYPENAME _Traits::int_type __c = __strm.rdbuf ()->sgetc (); for ( ; __bit; --__bit) { if (_Traits::eq_int_type (_Traits::eof (), __c)) { __err = __strm.eofbit; break; } // convert to char_type and narrow to char const char __ch = __strm.narrow (_Traits::to_char_type (__c), _CharT ()); if ('1' == __ch) __tmp [__bit - 1] = 1; else if ('0' != __ch) break; __c = __strm.rdbuf ()->snextc (); } // shift tmp right by the number of outstanding bits __tmp >>= __bit; } } _CATCH (...) { __strm.setstate (__strm.badbit | _RW::__rw_rethrow); } if (_Size && _Size == __bit) __err |= __strm.failbit; else __x = __tmp; if (__err) __strm.setstate (__err); return __strm; } } // namespace __rw