QxOrm  1.5.0
C++ Object Relational Mapping library
bool_array.h
Go to the documentation of this file.
00001 // -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
00002 // vim:tabstop=4:shiftwidth=4:expandtab:
00003 
00004 /*
00005  * Copyright (C) 2004-2008 Wu Yongwei <adah at users dot sourceforge dot net>
00006  *
00007  * This software is provided 'as-is', without any express or implied
00008  * warranty.  In no event will the authors be held liable for any
00009  * damages arising from the use of this software.
00010  *
00011  * Permission is granted to anyone to use this software for any purpose,
00012  * including commercial applications, and to alter it and redistribute
00013  * it freely, subject to the following restrictions:
00014  *
00015  * 1. The origin of this software must not be misrepresented; you must
00016  *    not claim that you wrote the original software.  If you use this
00017  *    software in a product, an acknowledgement in the product
00018  *    documentation would be appreciated but is not required.
00019  * 2. Altered source versions must be plainly marked as such, and must
00020  *    not be misrepresented as being the original software.
00021  * 3. This notice may not be removed or altered from any source
00022  *    distribution.
00023  *
00024  * This file is part of Stones of Nvwa:
00025  *      http://sourceforge.net/projects/nvwa
00026  *
00027  */
00028 
00040 #ifndef QT_NO_DEBUG
00041 #ifndef _QX_MODE_RELEASE
00042 #if _QX_USE_MEM_LEAK_DETECTION
00043 
00044 #ifndef _BOOL_ARRAY_H
00045 #define _BOOL_ARRAY_H
00046 
00047 #ifdef _MSC_VER
00048 #pragma once
00049 #endif
00050 
00051 #include <assert.h>     // assert
00052 #include <stdlib.h>     // exit, free, and NULL
00053 #include <new>          // std::bad_alloc
00054 #include <stdexcept>    // std::out_of_range
00055 #include <string>       // for exception constructors
00056 
00057 namespace qx {
00058 namespace memory {
00059 
00060 #ifndef _BYTE_DEFINED
00061 #define _BYTE_DEFINED
00062 typedef unsigned char BYTE;
00063 #endif // !_BYTE_DEFINED
00064 
00079 class QX_DLL_EXPORT bool_array
00080 {
00082     class QX_DLL_EXPORT _Element
00083     {
00084     public:
00085         _Element(BYTE* __ptr, unsigned long __idx);
00086         bool operator=(bool ___value);
00087         operator bool() const;
00088     private:
00089         BYTE*   _M_byte_ptr;
00090         size_t  _M_byte_idx;
00091         size_t  _M_bit_idx;
00092     };
00093 
00094 public:
00095     bool_array() : _M_byte_ptr(NULL), _M_length(0) {}
00096     explicit bool_array(unsigned long __size);
00097     ~bool_array() { if (_M_byte_ptr != NULL) free(_M_byte_ptr); }
00098 
00099     bool create(unsigned long __size);
00100     void initialize(bool ___value);
00101 
00102     // Using unsigned type here can increase performance!
00103     _Element operator[](unsigned long __idx);
00104     bool at(unsigned long __idx) const;
00105     void reset(unsigned long __idx);
00106     void set(unsigned long __idx);
00107 
00108     unsigned long size() const { return _M_length; }
00109     unsigned long count() const;
00110     unsigned long count(unsigned long __beg, unsigned long __end) const;
00111     void flip();
00112 
00113 private:
00114     BYTE*           _M_byte_ptr;
00115     unsigned long   _M_length;
00116     static BYTE     _S_bit_count[256];
00117 };
00118 
00119 
00120 /* Inline functions */
00121 
00128 inline bool_array::_Element::_Element(BYTE* __ptr, unsigned long __idx)
00129 {
00130     _M_byte_ptr = __ptr;
00131     _M_byte_idx = (size_t)(__idx / 8);
00132     _M_bit_idx  = (size_t)(__idx % 8);
00133 }
00134 
00141 inline bool bool_array::_Element::operator=(bool ___value)
00142 {
00143     if (___value)
00144         *(_M_byte_ptr + _M_byte_idx) |= 1 << _M_bit_idx;
00145     else
00146         *(_M_byte_ptr + _M_byte_idx) &= ~(1 << _M_bit_idx);
00147     return ___value;
00148 }
00149 
00155 inline bool_array::_Element::operator bool() const
00156 {
00157     return *(_M_byte_ptr + _M_byte_idx) & (1 << _M_bit_idx) ? true : false;
00158 }
00159 
00167 inline bool_array::bool_array(unsigned long __size)
00168     : _M_byte_ptr(NULL), _M_length(0)
00169 {
00170     if (__size == 0)
00171         throw std::out_of_range("invalid bool_array size");
00172 
00173     if (!create(__size))
00174         throw std::bad_alloc();
00175 }
00176 
00182 inline bool_array::_Element bool_array::operator[](unsigned long __idx)
00183 {
00184     assert(_M_byte_ptr);
00185     assert(__idx < _M_length);
00186     return _Element(_M_byte_ptr, __idx);
00187 }
00188 
00196 inline bool bool_array::at(unsigned long __idx) const
00197 {
00198     size_t __byte_idx, __bit_idx;
00199     if (__idx >= _M_length)
00200         throw std::out_of_range("invalid bool_array subscript");
00201     __byte_idx = (size_t)(__idx / 8);
00202     __bit_idx  = (size_t)(__idx % 8);
00203     return *(_M_byte_ptr + __byte_idx) & (1 << __bit_idx) ? true : false;
00204 }
00205 
00212 inline void bool_array::reset(unsigned long __idx)
00213 {
00214     size_t __byte_idx, __bit_idx;
00215     if (__idx >= _M_length)
00216         throw std::out_of_range("invalid bool_array subscript");
00217     __byte_idx = (size_t)(__idx / 8);
00218     __bit_idx  = (size_t)(__idx % 8);
00219     *(_M_byte_ptr + __byte_idx) &= ~(1 << __bit_idx);
00220 }
00221 
00228 inline void bool_array::set(unsigned long __idx)
00229 {
00230     size_t __byte_idx, __bit_idx;
00231     if (__idx >= _M_length)
00232         throw std::out_of_range("invalid bool_array subscript");
00233     __byte_idx = (size_t)(__idx / 8);
00234     __bit_idx  = (size_t)(__idx % 8);
00235     *(_M_byte_ptr + __byte_idx) |= 1 << __bit_idx;
00236 }
00237 
00238 } // namespace memory
00239 } // namespace qx
00240 
00241 #endif // _BOOL_ARRAY_H
00242 #endif // _QX_USE_MEM_LEAK_DETECTION
00243 #endif // _QX_MODE_RELEASE
00244 #endif // QT_NO_DEBUG