mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-07-15 02:20:35 +08:00
23e8d5321a
git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5300 42af7a65-404d-4744-a932-0658087f49c3
580 lines
11 KiB
Plaintext
580 lines
11 KiB
Plaintext
/* Copyright (C) 2004 Garrett A. Kajmowicz
|
|
*
|
|
* This file is part of the uClibc++ Library.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#include <basic_definitions>
|
|
#include <cstddef>
|
|
#include <climits>
|
|
#include <func_exception>
|
|
#include <string>
|
|
#include <iosfwd>
|
|
|
|
#ifndef __STD_BITSET_HEADER
|
|
#define __STD_BITSET_HEADER 1
|
|
|
|
#pragma GCC visibility push(default)
|
|
|
|
extern "C++"
|
|
{
|
|
namespace std
|
|
{
|
|
template <size_t N> class bitset;
|
|
|
|
template <size_t N> bitset<N> operator&(const bitset<N>&, const bitset<N>&);
|
|
template <size_t N> bitset<N> operator|(const bitset<N>&, const bitset<N>&);
|
|
template <size_t N> bitset<N> operator^(const bitset<N>&, const bitset<N>&);
|
|
template <class charT, class traits, size_t N> basic_istream<charT, traits>&
|
|
operator>>(basic_istream<charT, traits>& is, bitset<N>& x);
|
|
|
|
template <class charT, class traits, size_t N> basic_ostream<charT, traits>&
|
|
operator<<(basic_ostream<charT, traits>& os, const bitset<N>& x);
|
|
|
|
// Actual Code
|
|
|
|
template<size_t N> class _UCXXEXPORT bitset {
|
|
private:
|
|
//Number of characters allocated to hold the bits
|
|
|
|
static const size_t WORD_SIZE = CHAR_BIT; //Use int maybe?
|
|
static const size_t num_bytes = (N + WORD_SIZE - 1) / WORD_SIZE;
|
|
|
|
//From the bit number, figure out which byte we are working with
|
|
|
|
size_t byte_num(size_t bit_num) const
|
|
{
|
|
if (WORD_SIZE == 8)
|
|
{
|
|
return (bit_num >> 3);
|
|
}
|
|
|
|
if (WORD_SIZE == 16)
|
|
{
|
|
return (bit_num >> 4);
|
|
}
|
|
|
|
if (WORD_SIZE == 32)
|
|
{
|
|
return (bit_num >> 5);
|
|
}
|
|
|
|
if (WORD_SIZE == 64)
|
|
{
|
|
return (bit_num >> 6);
|
|
}
|
|
|
|
return bit_num / WORD_SIZE;
|
|
}
|
|
|
|
// From the bit number, figure out which bit inside the byte we need
|
|
|
|
size_t bit_num(const size_t bit_num) const
|
|
{
|
|
return bit_num % WORD_SIZE;
|
|
}
|
|
|
|
//Point to the actual data
|
|
|
|
char data[num_bytes];
|
|
|
|
public:
|
|
|
|
class _UCXXEXPORT reference
|
|
{
|
|
friend class bitset;
|
|
reference() : bit_num(0), parent(0) { }
|
|
size_t bit_num;
|
|
bitset * parent;
|
|
public:
|
|
~reference() { }
|
|
|
|
reference& operator=(bool x)
|
|
{
|
|
// for b[i] = x;
|
|
|
|
parent->set(bit_num, x);
|
|
return *this;
|
|
}
|
|
|
|
reference& operator=(const reference& x)
|
|
{
|
|
// for b[i] = b[j];
|
|
|
|
parent->set(bit_num, x);
|
|
return *this;
|
|
}
|
|
|
|
bool operator~() const
|
|
{
|
|
// flips the bit
|
|
|
|
return !parent->test(bit_num);
|
|
}
|
|
|
|
operator bool() const
|
|
{
|
|
// for x = b[i];
|
|
|
|
return parent->test(bit_num);
|
|
}
|
|
|
|
reference& flip()
|
|
{
|
|
// for b[i].flip();
|
|
|
|
parent->flip(bit_num);
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
bitset()
|
|
{
|
|
reset();
|
|
}
|
|
|
|
bitset(unsigned long val)
|
|
{
|
|
reset();
|
|
size_t count = sizeof(val) * CHAR_BIT;
|
|
if (count > N)
|
|
{
|
|
count = N;
|
|
}
|
|
|
|
for (size_t i = 0; i < count; ++i)
|
|
{
|
|
set(i, ((val >> i) & 1));
|
|
}
|
|
}
|
|
|
|
bitset(const bitset & val)
|
|
{
|
|
for (size_t i = 0; i < num_bytes; ++i)
|
|
{
|
|
data[i] = val.data[i];
|
|
}
|
|
}
|
|
|
|
template<class charT, class traits, class Allocator> _UCXXEXPORT
|
|
explicit bitset
|
|
(
|
|
const basic_string<charT,traits,Allocator>& str,
|
|
typename basic_string<charT,traits,Allocator>::size_type pos = 0,
|
|
typename basic_string<charT,traits,Allocator>::size_type n =
|
|
basic_string<charT>::npos
|
|
|
|
)
|
|
{
|
|
reset();
|
|
if (n > str.length())
|
|
{
|
|
n = str.length();
|
|
}
|
|
|
|
size_t width = n;
|
|
if (width + pos > str.length())
|
|
{
|
|
width = str.length() - pos;
|
|
}
|
|
|
|
for (size_t i = 0; i < width; ++i)
|
|
{
|
|
switch (str[pos + width - i - 1])
|
|
{
|
|
case '0':
|
|
break;
|
|
case '1':
|
|
set(i);
|
|
break;
|
|
default:
|
|
__throw_invalid_argument();
|
|
}
|
|
}
|
|
}
|
|
|
|
bitset<N>& operator&=(const bitset<N>& rhs)
|
|
{
|
|
for (size_t i =0; i < num_bytes; ++i)
|
|
{
|
|
data[i] &= rhs.data[i];
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
bitset<N>& operator|=(const bitset<N>& rhs)
|
|
{
|
|
for (size_t i =0; i < num_bytes; ++i)
|
|
{
|
|
data[i] |= rhs.data[i];
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
bitset<N>& operator^=(const bitset<N>& rhs)
|
|
{
|
|
for (size_t i=0; i < num_bytes; ++i)
|
|
{
|
|
data[i] ^= rhs.data[i];
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
bitset<N>& operator<<=(size_t pos)
|
|
{
|
|
for (size_t i = N-1; i >=pos; --i)
|
|
{
|
|
set(i, test(i - pos));
|
|
}
|
|
|
|
for (size_t i = 0; i < pos; ++i)
|
|
{
|
|
reset(i);
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
bitset<N>& operator>>=(size_t pos)
|
|
{
|
|
for (size_t i = 0; i < (N - pos); ++i)
|
|
{
|
|
set(i, test(i + pos));
|
|
}
|
|
|
|
for (size_t i = pos; i > 0; --i)
|
|
{
|
|
reset(N - i);
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
bitset<N>& set()
|
|
{
|
|
size_t i;
|
|
for (i = 0; i < N ; ++i)
|
|
{
|
|
data[byte_num(i)] |= (1<<bit_num(i));
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
bitset<N>& set(size_t pos, int val = true)
|
|
{
|
|
if (val == true)
|
|
{
|
|
data[byte_num(pos)] |= (1<<bit_num(pos));
|
|
}
|
|
else
|
|
{
|
|
data[byte_num(pos)] &= ~(1<<bit_num(pos));
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
bitset<N>& reset()
|
|
{
|
|
for (size_t i = 0; i < num_bytes; ++i)
|
|
{
|
|
data[i] = 0;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
bitset<N>& reset(size_t pos)
|
|
{
|
|
data[byte_num(pos)] &= ~(1<<bit_num(pos));
|
|
return *this;
|
|
}
|
|
|
|
bitset<N> operator~() const
|
|
{
|
|
bitset<N> retval(*this);
|
|
retval.flip();
|
|
return retval;
|
|
}
|
|
|
|
bitset<N>& flip()
|
|
{
|
|
for (size_t i = 0; i < num_bytes; ++i)
|
|
{
|
|
data[i] = ~data[i];
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
bitset<N>& flip(size_t pos)
|
|
{
|
|
char temp = data[byte_num(pos)] & (1 << bit_num(pos));
|
|
if (temp == 0)
|
|
{
|
|
// Bit was 0
|
|
|
|
data[byte_num(pos)] |= (1 << bit_num(pos));
|
|
}
|
|
else
|
|
{
|
|
// Bit was 1
|
|
|
|
data[byte_num(pos)] &= ~(1<<bit_num(pos));
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
reference operator[](size_t pos)
|
|
{
|
|
// for b[i];
|
|
|
|
reference retval;
|
|
retval.parent = this;
|
|
retval.bit_num = pos;
|
|
return retval;
|
|
}
|
|
|
|
unsigned long to_ulong() const
|
|
{
|
|
if (N > sizeof(unsigned long) * CHAR_BIT)
|
|
{
|
|
__throw_overflow_error();
|
|
}
|
|
|
|
unsigned long retval = 0;
|
|
size_t count = N;
|
|
for (size_t i = count; i > 0; --i)
|
|
{
|
|
if (test(i))
|
|
{
|
|
retval +=1;
|
|
}
|
|
|
|
retval <<= 1;
|
|
}
|
|
|
|
if (test(0))
|
|
{
|
|
retval +=1;
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
template <class charT, class traits, class Allocator>
|
|
basic_string<charT, traits, Allocator> to_string() const
|
|
{
|
|
basic_string<charT, traits, Allocator> retval;
|
|
retval.reserve(N);
|
|
for (size_t i = N ; i > 0; --i)
|
|
{
|
|
if (test(i-1) == true)
|
|
{
|
|
retval.append("1");
|
|
}
|
|
else
|
|
{
|
|
retval.append("0");
|
|
}
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
size_t count() const
|
|
{
|
|
size_t retval = 0;
|
|
for (size_t i =0; i < N; ++i)
|
|
{
|
|
if (test(i))
|
|
{
|
|
++retval;
|
|
}
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
size_t size() const
|
|
{
|
|
return N;
|
|
}
|
|
|
|
bitset<N>& operator=(const bitset<N> & rhs)
|
|
{
|
|
if (&rhs == this)
|
|
{
|
|
return *this;
|
|
}
|
|
|
|
for (size_t i = 0; i <= byte_num(N); ++i)
|
|
{
|
|
data[i] = rhs.data[i];
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
bool operator==(const bitset<N>& rhs) const
|
|
{
|
|
for (size_t i =0; i< N; ++i)
|
|
{
|
|
if (test(i) != rhs.test(i))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool operator!=(const bitset<N>& rhs) const
|
|
{
|
|
for (size_t i =0; i< N; ++i)
|
|
{
|
|
if (test(i) != rhs.test(i))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool test(size_t pos) const
|
|
{
|
|
return (data[byte_num(pos)] & (1<<bit_num(pos)) ) != 0;
|
|
}
|
|
|
|
bool any() const
|
|
{
|
|
for (size_t i = 0; i< N; ++i)
|
|
{
|
|
if (test(i)==true)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool none() const
|
|
{
|
|
if (any() == true)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bitset<N> operator<<(size_t pos) const
|
|
{
|
|
bitset retval(*this);
|
|
retval<<=pos;
|
|
return retval;
|
|
}
|
|
|
|
bitset<N> operator>>(size_t pos) const
|
|
{
|
|
bitset retval(*this);
|
|
retval>>=pos;
|
|
return retval;
|
|
}
|
|
};
|
|
|
|
// Non-member functions
|
|
|
|
template <size_t N> _UCXXEXPORT bitset<N> operator&(const bitset<N>& lhs, const bitset<N>& rhs)
|
|
{
|
|
bitset<N> retval(lhs);
|
|
retval &= rhs;
|
|
return retval;
|
|
}
|
|
|
|
template <size_t N> _UCXXEXPORT bitset<N> operator|(const bitset<N>& lhs, const bitset<N>& rhs)
|
|
{
|
|
bitset<N> retval(lhs);
|
|
retval |= rhs;
|
|
return retval;
|
|
}
|
|
|
|
template <size_t N> _UCXXEXPORT bitset<N> operator^(const bitset<N>& lhs, const bitset<N>& rhs)
|
|
{
|
|
bitset<N> retval(lhs);
|
|
retval ^= rhs;
|
|
return retval;
|
|
}
|
|
|
|
template <class charT, class traits, size_t N> _UCXXEXPORT basic_istream<charT, traits>&
|
|
operator>>(basic_istream<charT, traits>& is, bitset<N>& x)
|
|
{
|
|
string s;
|
|
charT c;
|
|
for (size_t i = 0; i < N; ++i)
|
|
{
|
|
is.get(c);
|
|
if (!is.good())
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (c != '1' && c !='0')
|
|
{
|
|
is.putback(c);
|
|
break;
|
|
}
|
|
|
|
s += c;
|
|
}
|
|
|
|
bitset<N> temp(s);
|
|
x = temp;
|
|
return is;
|
|
}
|
|
|
|
template <class charT, class traits, size_t N> _UCXXEXPORT basic_ostream<charT, traits>&
|
|
operator<<(basic_ostream<charT, traits>& os, const bitset<N>& x)
|
|
{
|
|
for (size_t i = N ; i > 0; --i)
|
|
{
|
|
if (x.test(i-1) == true)
|
|
{
|
|
os << "1";
|
|
}
|
|
else
|
|
{
|
|
os << "0";
|
|
}
|
|
}
|
|
|
|
return os;
|
|
}
|
|
|
|
} // namespace
|
|
} // extern "C++"
|
|
|
|
#pragma GCC visibility pop
|
|
|
|
#endif
|