188 lines
5.8 KiB
C++
188 lines
5.8 KiB
C++
/***************************************************************************
|
|
*
|
|
* 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 <class _CharT, class _Traits>
|
|
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
|