Menu

ByteCount.h

Go to the documentation of this file.
00001 /*******************************************************************************
00002  *
00003  * Copyright (c) 2008-2010 Michael Schulze <mschulze@ivs.cs.uni-magdeburg.de>
00004  *                    2010 Marcus Foerster <MarcusFoerster1@gmx.de>
00005  * All rights reserved.
00006  *
00007  *    Redistribution and use in source and binary forms, with or without
00008  *    modification, are permitted provided that the following conditions
00009  *    are met:
00010  *
00011  *    * Redistributions of source code must retain the above copyright
00012  *      notice, this list of conditions and the following disclaimer.
00013  *
00014  *    * Redistributions in binary form must reproduce the above copyright
00015  *      notice, this list of conditions and the following disclaimer in
00016  *      the documentation and/or other materials provided with the
00017  *      distribution.
00018  *
00019  *    * Neither the name of the copyright holders nor the names of
00020  *      contributors may be used to endorse or promote products derived
00021  *      from this software without specific prior written permission.
00022  *
00023  *
00024  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00025  *    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00026  *    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00027  *    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00028  *    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00029  *    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00030  *    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00031  *    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00032  *    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00033  *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00034  *    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035  *
00036  *
00037  * $Id$
00038  *
00039  ******************************************************************************/
00040 
00041 #ifndef _ByteCount_h_
00042 #define _ByteCount_h_
00043 
00044 #include <stdint.h>
00045 
00046 #include "boost/mpl/eval_if.hpp"
00047 #include "boost/mpl/int.hpp"
00048 #include "boost/mpl/plus.hpp"
00049 
00050 
00058 template <typename ValueType, ValueType Value>
00059 struct BitCount {
00063         typedef ValueType value_type;
00067         typedef boost::mpl::integral_c_tag tag;
00071         typedef BitCount type;
00072 
00079         static const uint16_t value = boost::mpl::eval_if_c<(Value != 0),
00080                                                             boost::mpl::plus<BitCount<ValueType, (Value >> 1)>,
00081                                                                              boost::mpl::int_<1>
00082                                                                             >,
00083                                                             boost::mpl::int_<0>
00084                                                            >::type::value;
00085 };
00086 
00087 template <>
00088 struct BitCount<bool, true> {
00092         typedef bool value_type;
00096         typedef boost::mpl::integral_c_tag tag;
00100         typedef BitCount type;
00101 
00102         static const uint16_t value = 1;
00103 };
00104 
00105 template <>
00106 struct BitCount<bool, false> {
00110         typedef bool value_type;
00114         typedef boost::mpl::integral_c_tag tag;
00118         typedef BitCount type;
00119 
00120         static const uint16_t value = 0;
00121 };
00122 
00126 #define BitCountSigned(stype)                                               \
00127     template <stype Value>                                                  \
00128     struct BitCount<stype, Value> {                                         \
00129                                                                             \
00130         typedef stype value_type;                                           \
00131                                                                             \
00132         typedef boost::mpl::integral_c_tag tag;                             \
00133                                                                             \
00134         typedef BitCount type;                                              \
00135                                                                             \
00136         static const uint16_t value = (Value < 0) ?                         \
00137                                       (sizeof(stype) * 8) :                 \
00138                                       BitCount<                             \
00139                                         uint64_t,                           \
00140                                         static_cast<uint64_t>(Value)        \
00141                                       >::value;                             \
00142     }
00143 
00144 BitCountSigned(int8_t);
00145 BitCountSigned(int16_t);
00146 BitCountSigned(int32_t);
00147 BitCountSigned(int64_t);
00148 
00149 #undef BitCountSigned
00150 
00161 template <typename ValueType, ValueType Value>
00162 struct ByteCount {
00163     private:
00164         static const uint16_t bitCount = BitCount<ValueType, Value>::value;
00165 
00166     public:
00170         static const uint16_t value = (bitCount % 8 == 0) ?
00171                                           (bitCount / 8) :
00172                                           ((bitCount / 8) + 1);
00173 };
00174 
00175 // Runtime bit / byte count calculation
00176 
00185 inline const uint16_t getBitCount(uint64_t value) {
00186     uint16_t result = 0;
00187 
00188     while (value > 0) {
00189         ++result;
00190 
00191         value >>= 1;
00192     }
00193 
00194     return (result);
00195 }
00196 
00205 static inline const uint16_t getBitCount(uint8_t value) {
00206     return (getBitCount(static_cast<uint64_t>(value)));
00207 }
00208 
00217 static inline const uint16_t getBitCount(uint16_t value) {
00218     return (getBitCount(static_cast<uint64_t>(value)));
00219 }
00220 
00229 static inline const uint16_t getBitCount(uint32_t value) {
00230     return (getBitCount(static_cast<uint64_t>(value)));
00231 }
00232 
00242 static inline const uint16_t getBitCount(bool value) {
00243     return ((value) ? 1 : 0);
00244 }
00245 
00254 static inline const uint16_t getBitCount(int8_t value) {
00255     return ((value < 0) ? sizeof(int8_t) : getBitCount(static_cast<uint64_t>(value)));
00256 }
00265 static inline const uint16_t getBitCount(int16_t value) {
00266     return ((value < 0) ? sizeof(int16_t) : getBitCount(static_cast<uint64_t>(value)));
00267 }
00276 static inline const uint16_t getBitCount(int32_t value) {
00277     return ((value < 0) ? sizeof(int32_t) : getBitCount(static_cast<uint64_t>(value)));
00278 }
00287 static inline const uint16_t getBitCount(int64_t value) {
00288     return ((value < 0) ? sizeof(int64_t) : getBitCount(static_cast<uint64_t>(value)));
00289 }
00290 
00299 inline const uint16_t bitCountToByteCount(const uint16_t value) {
00300     // Similar to
00301     //  return (((value % 8) == 0) ? (value / 8) : ((value / 8) + 1));
00302     //
00303     return (((value & 0x7) == 0) ? (value >> 3) : ((value >> 3) + 1));
00304 }
00305 
00306 #endif