209 lines
6.3 KiB
C++
209 lines
6.3 KiB
C++
#ifndef __BITSET_CC
|
||
#define __BITSET_CC
|
||
#pragma option push -b -a8 -pc -Vx- -Ve- -w-inl -w-aus -w-sig
|
||
/***************************************************************************
|
||
*
|
||
* bitset - class bitset declaration
|
||
*
|
||
***************************************************************************
|
||
*
|
||
* Copyright (c) 1994-1999 Rogue Wave Software, Inc. All Rights Reserved.
|
||
*
|
||
* This computer software is owned by Rogue Wave Software, Inc. and is
|
||
* protected by U.S. copyright laws and other laws and by international
|
||
* treaties. This computer software is furnished by Rogue Wave Software,
|
||
* Inc. pursuant to a written license agreement and may be used, copied,
|
||
* transmitted, and stored only in accordance with the terms of such
|
||
* license and with the inclusion of the above copyright notice. This
|
||
* computer software or any other copies thereof may not be provided or
|
||
* otherwise made available to any other person.
|
||
*
|
||
* U.S. Government Restricted Rights. This computer software is provided
|
||
* with Restricted Rights. Use, duplication, or disclosure by the
|
||
* Government is subject to restrictions as set forth in subparagraph (c)
|
||
* (1) (ii) of The Rights in Technical Data and Computer Software clause
|
||
* at DFARS 252.227-7013 or subparagraphs (c) (1) and (2) of the
|
||
* Commercial Computer Software – Restricted Rights at 48 CFR 52.227-19,
|
||
* as applicable. Manufacturer is Rogue Wave Software, Inc., 5500
|
||
* Flatiron Parkway, Boulder, Colorado 80301 USA.
|
||
*
|
||
**************************************************************************/
|
||
|
||
#include <stdcomp.h>
|
||
|
||
#ifdef _HPACC_
|
||
#ifdef _RW_STD_IOSTREAM
|
||
#include <iostream>
|
||
#else
|
||
#include <iostream.h>
|
||
#endif
|
||
#endif //_HPACC_
|
||
|
||
#ifndef _RWSTD_NO_NAMESPACE
|
||
namespace std {
|
||
#endif
|
||
|
||
#ifndef _NELEMENTS
|
||
# ifndef _RWSTD_BC5_ENUM_BUG
|
||
#define _NELEMENTS NumOfElems
|
||
# else
|
||
#define _NELEMENTS NumOfElems()
|
||
# endif /*_RWSTD_BC5_ENUM_BUG*/
|
||
#endif /* _NELEMENTS */
|
||
|
||
#ifndef _RWSTD_MSC22_STATIC_INIT_BUG
|
||
template <size_t N>
|
||
const size_t bitset<N>::bitset_size
|
||
#ifdef _RWSTD_NO_STI_TEMPLATE
|
||
= N
|
||
#endif
|
||
;
|
||
#endif /* _RWSTD_MSC22_STATIC_INIT_BUG */
|
||
template <size_t N>
|
||
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
|
||
template <class charT, class traits, class Allocator>
|
||
bitset<N>::bitset (const basic_string<charT,traits,Allocator> &str,
|
||
_TYPENAME basic_string<charT,traits,Allocator>::size_type pos,
|
||
_TYPENAME basic_string<charT,traits,Allocator>::size_type n)
|
||
#else
|
||
bitset<N>::bitset (const string& str,
|
||
size_t pos,
|
||
size_t n)
|
||
#endif // _RWSTD_NO_MEMBER_TEMPLATES
|
||
_RWSTD_THROW_SPEC((out_of_range, invalid_argument))
|
||
#ifdef _RWSTD_MSC22_STATIC_INIT_BUG
|
||
: bitset_size(N)
|
||
#endif
|
||
{
|
||
size_t slen = str.size();
|
||
|
||
_RWSTD_THROW(pos > slen,out_of_range,
|
||
__RWSTD::except_msg_string(__RWSTD::__rw_bitset_InvalidPosition,
|
||
"bitset::bitset(const string&,size_t,size_t)",pos,slen).msgstr());
|
||
|
||
size_t rlen = n < (slen - pos) ? n : slen - pos;
|
||
size_t M = N >= rlen ? rlen : N;
|
||
#ifndef _RWSTD_BC5_ENUM_BUG
|
||
memset(bits, 0, sizeof(bits));
|
||
#else
|
||
bits = new VectorType[_NELEMENTS];
|
||
memset(bits, 0, _NELEMENTS*sizeof(VectorType));
|
||
#endif /*_RWSTD_BC5_ENUM_BUG*/
|
||
for (size_t i = pos; i < M + pos; i++)
|
||
{
|
||
char c = str[slen - i - 1];
|
||
|
||
_RWSTD_THROW(!(c == '0' || c == '1'), invalid_argument,
|
||
__RWSTD::except_msg_string(__RWSTD:: __rw_bitset_InvalidCtorArgument,
|
||
"bitset::bitset(const string&,size_t,size_t)").msgstr());
|
||
|
||
if (c == '1') set(i - pos);
|
||
}
|
||
}
|
||
|
||
//
|
||
// Constructs an object of type string and initializes it
|
||
// to a string of length N characters. Each character is
|
||
// determined by the value of its corresponding bit position
|
||
// in *this. Character position N-1 corresponds to bit
|
||
// position zero. Subsequent decreasing character positions
|
||
// correspond to increasing bit positions. Bit value zero becomes
|
||
// the character 0, bit value one becomes the character 1.
|
||
//
|
||
|
||
template <size_t N>
|
||
#if !defined ( _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE) && !defined (_HPACC_) && !defined(_RWSTD_NO_EXPLICIT_ARGS)
|
||
template <class charT, class traits, class Allocator>
|
||
basic_string<charT,traits,Allocator>
|
||
#else
|
||
string
|
||
#endif
|
||
bitset<N>::to_string () const
|
||
{
|
||
#if !defined ( _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE) && !defined (_HPACC_) && !defined(_RWSTD_NO_EXPLICIT_ARGS)
|
||
basic_string<charT,traits,Allocator> s;
|
||
#else
|
||
string s;
|
||
#endif
|
||
for (long i = N - 1; i >= 0; --i)
|
||
s.append(1, test(i) ? '1' : '0');
|
||
return s;
|
||
}
|
||
|
||
//
|
||
// If the integral value x corresponding to the bitset in *this
|
||
// cannot be represented as type unsigned long, throws overflow_error.
|
||
//
|
||
|
||
template <size_t N>
|
||
unsigned long
|
||
bitset<N>::to_ulong () const _RWSTD_THROW_SPEC((overflow_error))
|
||
{
|
||
const size_t size_long = sizeof(unsigned long);
|
||
|
||
for (size_t i = _NELEMENTS-1; size_long/sizeof(VectorType) <= i; --i)
|
||
|
||
_RWSTD_THROW(bits[i], overflow_error,
|
||
__RWSTD::except_msg_string(__RWSTD::__rw_bitset_ConversionOverflow,
|
||
"bitset::to_ulong() const").msgstr());
|
||
unsigned long result = 0;
|
||
|
||
for (size_t pos = 0; pos < N; pos++)
|
||
if (test(pos))
|
||
result |= 1UL << pos;
|
||
|
||
return result;
|
||
}
|
||
|
||
//
|
||
// Returns the count of the number of set bits.
|
||
//
|
||
|
||
template <size_t N>
|
||
size_t
|
||
bitset<N>::count () const _RWSTD_THROW_SPEC_NULL
|
||
{
|
||
size_t sum = 0;
|
||
|
||
#if UINT_MAX <= 4294967295
|
||
//
|
||
// A sophisticated implementaton that works if BitsPerChunk < 63
|
||
//
|
||
for (size_t i = 0; i < _NELEMENTS; i++)
|
||
{
|
||
unsigned long n = bits[i];
|
||
unsigned long t = n - ((n>>1) & 033333333333) - ((n>>2) & 011111111111);
|
||
t = ((t + (t >> 3)) & 030707070707);
|
||
|
||
unsigned long x = t & 07700770077;
|
||
unsigned long y = (t >> 6) & 07700770077;
|
||
|
||
t = x + y;
|
||
t = ((t >> 12) + (t >> 24) + t) & 0777;
|
||
t = (t >> 6) + (t & 077);
|
||
t = t + 1;
|
||
|
||
sum += (t >> 6) + (t & 077) - 1;
|
||
}
|
||
#else
|
||
//
|
||
// The more naive implementation that always works.
|
||
//
|
||
for (size_t i = 0; i < _NELEMENTS; i++)
|
||
{
|
||
unsigned long n = bits[i];
|
||
while (n)
|
||
{
|
||
n &= n-1;
|
||
sum++;
|
||
}
|
||
}
|
||
#endif
|
||
return sum;
|
||
}
|
||
#ifndef _RWSTD_NO_NAMESPACE
|
||
}
|
||
#endif
|
||
#pragma option pop
|
||
#endif /* __BITSET_CC */
|