src/Lib/shttl/bit.h

説明を見る。
00001 // 
00002 // Copyright (c) 2005-2008 Kenichi Watanabe.
00003 // Copyright (c) 2005-2008 Yasuhiro Watari.
00004 // Copyright (c) 2005-2008 Hironori Ichibayashi.
00005 // Copyright (c) 2008-2009 Kazuo Horio.
00006 // Copyright (c) 2009-2013 Naruki Kurata.
00007 // Copyright (c) 2005-2013 Ryota Shioya.
00008 // Copyright (c) 2005-2013 Masahiro Goshima.
00009 // 
00010 // This software is provided 'as-is', without any express or implied
00011 // warranty. In no event will the authors be held liable for any damages
00012 // arising from the use of this software.
00013 // 
00014 // Permission is granted to anyone to use this software for any purpose,
00015 // including commercial applications, and to alter it and redistribute it
00016 // freely, subject to the following restrictions:
00017 // 
00018 // 1. The origin of this software must not be misrepresented; you must not
00019 // claim that you wrote the original software. If you use this software
00020 // in a product, an acknowledgment in the product documentation would be
00021 // appreciated but is not required.
00022 // 
00023 // 2. Altered source versions must be plainly marked as such, and must not be
00024 // misrepresented as being the original software.
00025 // 
00026 // 3. This notice may not be removed or altered from any source
00027 // distribution.
00028 // 
00029 // 
00030 
00031 
00032 #ifndef SHTTL_BIT_H
00033 #define SHTTL_BIT_H
00034 
00035 #include <cassert>
00036 #include <limits>
00037 #include <iostream>
00038 #include <iomanip>
00039 
00040 #include "shttl_types.h"
00041 
00042 namespace shttl
00043 {
00044 
00045     static std::numeric_limits<u64> u64_limits;
00046     static const u64 u64_bits = 64; // for older compiler
00047 
00048     // signed/unsigned minimum/maximum values in N-bit sequence
00049     inline static u64 umax(const ssize_t bit_num) 
00050     {
00051         SHTTL_ASSERT(0 <= bit_num && bit_num <= u64_limits.digits);
00052         u64 bit = ((bit_num >> 6) & 1) ^ 1;
00053         return (bit << (bit_num & 63)) - 1ull;
00054     }
00055 
00056     inline static u64 umin(const ssize_t bit_num) 
00057     {
00058         SHTTL_ASSERT(0 <= bit_num && bit_num <= u64_limits.digits);
00059         return 0;
00060     }
00061 
00062     inline static s64 smax(const ssize_t bit_num) 
00063     {
00064         SHTTL_ASSERT(2 <= bit_num && bit_num <= u64_limits.digits);
00065         return static_cast<s64>(umax(bit_num - 1));
00066     }
00067 
00068     inline static s64 smin(const ssize_t bit_num) 
00069     {
00070         SHTTL_ASSERT(2 <= bit_num && bit_num <= u64_limits.digits);
00071         return static_cast<s64>(~0ull << (bit_num - 1));
00072     }
00073 
00074 
00075     // bit mask and bit test
00076 
00077     inline static u64 mask(const ssize_t bit_pos, const ssize_t bit_width = 1) 
00078     {
00079         const ssize_t p = bit_pos;
00080         const ssize_t w = bit_width;
00081         SHTTL_ASSERT(0 <= p     && p            <  u64_limits.digits);
00082         SHTTL_ASSERT(0 <=     w &&     w      <= u64_limits.digits);
00083         SHTTL_ASSERT(0 <= p + w && p + w - 1  <  u64_limits.digits);
00084         return umax(w) << p;
00085     }
00086 
00087     inline static bool test(const u64 value, const ssize_t bit_pos) 
00088     {
00089         return (value & mask(bit_pos)) != 0;
00090     }
00091 
00092     inline static u64 field(
00093         const u64 value, 
00094         const ssize_t bit_pos, 
00095         const ssize_t bit_width ) 
00096     {
00097         return (value >> bit_pos) & mask(0, bit_width);
00098     }
00099 
00100     inline static u64 set_bit(const u64 src, const ssize_t bit_pos) 
00101     {
00102         return src |  mask(bit_pos);
00103     }
00104     inline static u64 reset_bit(const u64 src, const ssize_t bit_pos) 
00105     {
00106         return src & ~mask(bit_pos);
00107     }
00108 
00109     inline static u64 deposit(
00110         const u64 value, 
00111         const ssize_t bit_pos, 
00112         const ssize_t bit_width, 
00113         const u64 r ) 
00114     {
00115         const u64 u =  value & ~mask(bit_pos, bit_width);
00116         const u64 s = (r &  mask(0, bit_width)) << bit_pos;
00117         return u | s;
00118     }
00119 
00120 
00121     // Sign Extension
00122     inline static s64 sign_ext(const u64 value, const ssize_t bit_num) 
00123     {
00124         SHTTL_ASSERT(1 < bit_num && bit_num <= u64_limits.digits);
00125         u64 sign_mask = (u64)1 << (bit_num - 1);
00126         u64 bit_mask  = sign_mask - 1;
00127         return (s64)( 
00128             (0ull - (value & sign_mask)) | (value & bit_mask));
00129 
00130     }
00131 
00132     // value Cbit_num rbgll count rbg[e[g
00133     inline static u64 rotate_left(u64 value, ssize_t bit_num, int count)
00134     {
00135         value &= mask(0, bit_num);
00136         count %= bit_num;
00137 
00138         if (count == 0)
00139             return value;
00140         else
00141             return ((value << count) | (value >> (bit_num-count))) & mask(0, bit_num);
00142     }
00143 
00144     // value Cbit_num rbgll count rbgE[e[g
00145     inline static u64 rotate_right(u64 value, ssize_t bit_num, int count)
00146     {
00147         value &= mask(0, bit_num);
00148         count %= bit_num;
00149 
00150         if (count == 0)
00151             return value;
00152         else
00153             return ((value >> count) | (value << (bit_num-count))) & mask(0, bit_num);
00154     }
00155 
00156     // value , bit_length XOR
00157     inline static u64 xor_convolute(u64 value, int bit_length)
00158     {
00159         SHTTL_ASSERT(bit_length <= u64_limits.digits);
00160 
00161         u64 ret = 0;
00162         for(int bit_pos = 0; bit_pos < u64_limits.digits; bit_pos += bit_length){
00163             ret ^= field(value, bit_pos, bit_length);
00164         }
00165         return ret;
00166     }
00167 
00168 }; // namespace shttl
00169 
00170 #endif // SHTTL_BIT_H

Onikiri2に対してTue Jun 18 14:34:21 2013に生成されました。  doxygen 1.4.7