svcore  1.9
ResizeableBitset.h
Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
00002 
00003 /*
00004     Sonic Visualiser
00005     An audio file viewer and annotation editor.
00006     Centre for Digital Music, Queen Mary, University of London.
00007     This file copyright 2006 Chris Cannam.
00008     
00009     This program is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU General Public License as
00011     published by the Free Software Foundation; either version 2 of the
00012     License, or (at your option) any later version.  See the file
00013     COPYING included with this distribution for more information.
00014 */
00015 
00016 #ifndef _RESIZEABLE_BITMAP_H_
00017 #define _RESIZEABLE_BITMAP_H_
00018 
00019 #include <vector>
00020 #include <stdint.h>
00021 #include <stddef.h>
00022 #include <stdlib.h>
00023 
00024 class ResizeableBitset {
00025 
00026 public:
00027     ResizeableBitset() : m_bits(0), m_size(0) {
00028     }
00029     ResizeableBitset(size_t size) : m_bits(new std::vector<uint8_t>), m_size(size) {
00030         m_bits->assign((size >> 3) + 1, 0);
00031     }
00032     ResizeableBitset(const ResizeableBitset &b) {
00033         m_bits = new std::vector<uint8_t>(*b.m_bits);
00034     }
00035     ResizeableBitset &operator=(const ResizeableBitset &b) {
00036         if (&b != this) return *this;
00037         delete m_bits;
00038         m_bits = new std::vector<uint8_t>(*b.m_bits);
00039         return *this;
00040     }
00041     ~ResizeableBitset() {
00042         delete m_bits;
00043     }
00044     
00045     void resize(size_t size) { // retaining existing data; not thread safe
00046         size_t bytes = (size >> 3) + 1;
00047         if (m_bits && bytes == m_bits->size()) return;
00048         std::vector<uint8_t> *newbits = new std::vector<uint8_t>(bytes);
00049         newbits->assign(bytes, 0);
00050         if (m_bits) {
00051             for (size_t i = 0; i < bytes && i < m_bits->size(); ++i) {
00052                 (*newbits)[i] = (*m_bits)[i];
00053             }
00054             delete m_bits;
00055         }
00056         m_bits = newbits;
00057         m_size = size;
00058     }
00059     
00060     bool get(size_t column) const {
00061         return ((*m_bits)[column >> 3]) & (1u << (column & 0x07));
00062     }
00063     
00064     void set(size_t column) {
00065         ((*m_bits)[column >> 3]) |=  (uint8_t(1) << (column & 0x07));
00066     }
00067 
00068     void reset(size_t column) {
00069         ((*m_bits)[column >> 3]) &= ~(uint8_t(1) << (column & 0x07));
00070     }
00071 
00072     void copy(size_t source, size_t dest) {
00073         get(source) ? set(dest) : reset(dest);
00074     }
00075 
00076     bool isAllOff() const {
00077         for (size_t i = 0; i < m_bits->size(); ++i) {
00078             if ((*m_bits)[i]) return false;
00079         }
00080         return true;
00081     }
00082 
00083     bool isAllOn() const {
00084         for (size_t i = 0; i + 1 < m_bits->size(); ++i) {
00085             if ((*m_bits)[i] != 0xff) return false;
00086         }
00087         for (size_t i = (m_size / 8) * 8; i < m_size; ++i) {
00088             if (!get(i)) return false;
00089         }
00090         return true;
00091     }
00092 
00093     size_t size() const {
00094         return m_size;
00095     }
00096     
00097 private:
00098     std::vector<uint8_t> *m_bits;
00099     size_t m_size;
00100 };
00101 
00102 
00103 #endif
00104