Bitfield.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2005 Palmsource, Inc.
00003  * 
00004  * This software is licensed as described in the file LICENSE, which
00005  * you should have received as part of this distribution. The terms
00006  * are also available at http://www.openbinder.org/license.html.
00007  * 
00008  * This software consists of voluntary contributions made by many
00009  * individuals. For the exact contribution history, see the revision
00010  * history and logs, available at http://www.openbinder.org
00011  */
00012 
00013 #ifndef _SUPPORT_BITFIELD_H_
00014 #define _SUPPORT_BITFIELD_H_
00015 
00021 #include <support/SupportDefs.h>
00022 
00023 #if _SUPPORTS_NAMESPACE
00024 namespace palmos {
00025 namespace support {
00026 #endif
00027 
00032 /**************************************************************************************/
00033 
00035 
00041 class SBitfield
00042 {
00043     struct bitfield_bit;
00044     friend struct bitfield_bit;
00045 
00046 public:
00047                         SBitfield(size_t size = 0);             
00048                         SBitfield(size_t size, bool intial);    
00049                         SBitfield(const SBitfield& copy);
00050                         ~SBitfield();
00051 
00052             bool        operator == (const SBitfield& other);   
00053             status_t    Resize(size_t bits);                    
00054     inline  size_t      CountBits() const;                      
00055             status_t    InitCheck() const;                      
00056     
00058     inline  bool        Test(size_t bit) const;                 
00059 
00061             status_t    Set(size_t start, size_t len);
00062     inline  void        Set(size_t bit);                        
00063 
00065             bool        TestAndSet(size_t bit);                 
00066 
00068             status_t    Clear(size_t start, size_t len);
00069     inline  void        Clear(size_t bit);                      
00070 
00072             ssize_t     FirstSet() const;
00073 
00075             ssize_t     FirstClear() const;
00076     
00078     inline  bitfield_bit    operator[] (size_t bit)         { return bitfield_bit(*this, bit); }
00079     inline  bool            operator[] (size_t bit) const   {  return Test(bit); }
00080 
00081 private:
00082     struct bitfield_bit {
00083         inline bitfield_bit(SBitfield& bitfield, size_t bit) : m_bitfield(bitfield), m_bit(bit) { }
00084         inline bitfield_bit& operator = (bool value);
00085         inline operator bool();
00086     private:
00087         SBitfield& m_bitfield;
00088         size_t m_bit;
00089     };
00090 
00091     inline size_t alloc_size(size_t size);
00092 
00093     struct bitfield_fill_info;
00094     static void compute_masks(size_t start, size_t len, bitfield_fill_info&);
00095     static int32_t SBitfield::word_set(uint32_t word);
00096     bool is_inline() const;
00097     union {
00098         uint32_t *  m_bits;
00099         uint32_t    m_inlineBits;
00100     };
00101     ssize_t m_numBits;
00102 };
00103 
00106 /*-------------------------------------------------------------*/
00107 /*---- No user serviceable parts after this -------------------*/
00108 
00109 #define BF_NUM_INLINE_BITS  (32)
00110 
00111 inline size_t SBitfield::CountBits() const
00112 {
00113     return m_numBits;
00114 }
00115 
00116 inline bool SBitfield::Test(size_t bit) const
00117 {
00118     return ( ((m_numBits > BF_NUM_INLINE_BITS) ? (m_bits[bit>>5]) : (m_inlineBits)) & (0x80000000LU >> (bit & 0x1F)) ) != 0;
00119     //This was in the BeOS tree:
00120     //return (bool)( ( ((m_numBits > BF_NUM_INLINE_BITS) ? (m_bits[bit>>5]) : m_inlineBits) >> ((~bit) & 0x1F) ) & 0x1LU );
00121 }
00122 
00123 inline void SBitfield::Set(size_t bit)
00124 {
00125     ((m_numBits > BF_NUM_INLINE_BITS) ? (m_bits[bit>>5]) : (m_inlineBits)) |= (0x80000000LU >> (bit & 0x1F));
00126 }
00127 
00128 inline size_t SBitfield::alloc_size(size_t size)
00129 {
00130     // allocate always in multiple of 32
00131     // so we round up to multiple of 32 and then divide by 8
00132     // to return number of bytes
00133 
00134     return ((size+31) & ~31) >> 3; 
00135 }
00136 
00137 inline void SBitfield::Clear(size_t bit)
00138 {
00139     ((m_numBits > BF_NUM_INLINE_BITS) ? (m_bits[bit>>5]) : (m_inlineBits)) &= ~(0x80000000LU >> (bit & 0x1F));
00140 }
00141 
00142 inline SBitfield::bitfield_bit& SBitfield::bitfield_bit::operator = (bool value)
00143 {
00144     if (value)  m_bitfield.Set(m_bit);
00145     else m_bitfield.Clear(m_bit);
00146     return *this;
00147 }
00148 
00149 inline SBitfield::bitfield_bit::operator bool()
00150 {
00151     return m_bitfield.Test(m_bit);
00152 }
00153 
00154 /**************************************************************************************/
00155 
00156 #if _SUPPORTS_NAMESPACE
00157 } } // namespace palmos::support
00158 #endif
00159 
00160 #endif  /* _SUPPORT_BITFIELD_H_ */