src/Lib/shttl/bitset.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 //
00033 // STL compatible light-weight bitset 
00034 //
00035 
00036 #ifndef SHTTL_BITSET_H
00037 #define SHTTL_BITSET_H
00038 
00039 #include <bitset>
00040 #include <string>
00041 #include <stdexcept>
00042 #include <cassert>
00043 #include <climits>
00044 
00045 #include "bit.h"
00046 
00047 namespace shttl
00048 {
00049 
00050     //
00051     //  shttl_bitset<N, T> : bitset<N> only for smaller N's 
00052     //
00053 
00054     template<size_t N, class T = u64>
00055     class shttl_bitset {
00056 
00057         friend class reference;
00058 
00059     public:
00060 
00061         typedef T                   value_type;
00062         typedef shttl_bitset<N, T>  this_type;
00063         typedef size_t              size_type;
00064 
00065     protected:
00066 
00067         // Value
00068 
00069         value_type _v;
00070 
00071     public:
00072 
00073         // Constructors
00074 
00075         shttl_bitset(u64 v = 0) :
00076           _v( (value_type)( v & umax(size()) ) )
00077         {
00078         }
00079 
00080         template<class C, class R, class A>
00081         explicit
00082             shttl_bitset(
00083                 const    std::basic_string<C, R, A>& s,
00084                 typename std::basic_string<C, R, A>::size_type p = 0,
00085                 typename std::basic_string<C, R, A>::size_type l = -1
00086             )
00087         {
00088             std::bitset<u64_bits> bs;
00089             try {
00090                 bs = std::bitset<u64_bits>(s, p, l);
00091             }
00092             catch (std::invalid_argument) {
00093                 throw std::invalid_argument("shttl_bitset::shttl_bitset");
00094             }
00095             _v = (value_type)( bs.to_ulong() & umax(size()) );
00096         }
00097 
00098         // bit reference 
00099 
00100         class reference {
00101         protected:
00102 
00103             this_type& _i;
00104             const size_type  _p;
00105 
00106             reference(this_type& i, size_type p) : _i(i), _p(p) {}
00107 
00108         public:
00109 
00110             operator bool()  const { return  _i.test(_p); }
00111             bool operator~() const { return !_i.test(_p); }
00112 
00113             reference& operator=(bool v) {
00114                 _i.set(_p, v);
00115                 return *this;
00116             }
00117 
00118             reference& operator=(const reference& r) {
00119                 _i.set(_p, r.operator bool());
00120                 return *this;
00121             }
00122 
00123             reference& flip() {
00124                 _i.flip(_p);
00125                 return *this;
00126             }
00127 
00128         };
00129 
00130         // Bitwise Operators and Bitwise Operator Assignment
00131 
00132         this_type& operator&=(const this_type& i) { _v &= i._v;   return *this;  }
00133         this_type& operator|=(const this_type& i) { _v |= i._v;   return *this;  }
00134         this_type& operator^=(const this_type& i) { _v ^= i._v;   return *this;  }
00135 
00136         this_type& operator<<=(size_type w) { 
00137             _v <<= w;
00138             _v &= umax(size());  
00139             return *this; 
00140         }
00141         this_type& operator>>=(size_type w) { 
00142             _v >>= w;
00143             _v &= umax(size());  
00144             return *this;  
00145         }
00146 
00147 
00148         // Set, Reset, Flip
00149 
00150         this_type& set() {
00151             _v = umax(size());
00152             return *this;
00153         }
00154 
00155         this_type& set(size_type p, int v = 1) {
00156             if (p < 0 || size() <= p)
00157                 throw std::out_of_range("shttl_bitset<N, T>::set");
00158             if (v) 
00159                 _v |=  mask(p);
00160             else
00161                 _v &= ~mask(p);
00162             return *this;
00163         }
00164 
00165         this_type& reset() {
00166             _v = 0;
00167             return *this;
00168         }
00169 
00170         this_type& reset(size_type p) {
00171             if (p < 0 || size() <= p)
00172                 throw std::out_of_range("shttl_bitset<N, T>::reset");
00173             _v &= ~mask(p);
00174             return *this;
00175         }
00176 
00177         this_type operator~() const {
00178             return this_type(~_v & umax(size()));
00179         }
00180 
00181         this_type& flip() {
00182             _v = ~_v & umax(size());
00183             return *this;
00184         }
00185 
00186         this_type& flip(size_type p) {
00187             if (p < 0 || size() <= p)
00188                 throw std::out_of_range("shttl_bitset<N, T>::flip");
00189             _v ^= mask(p);
00190             return *this;
00191         }
00192 
00193 
00194         // Element Access
00195 
00196         reference operator[](size_type p) { 
00197             SHTTL_ASSERT(0 <= p || p < size());
00198             return reference(*this, p); 
00199         }
00200 
00201         reference at(size_type p)
00202         { 
00203             if (p < 0 || size() <= p)
00204                 throw std::out_of_range("shttl_bitset<N, T>::at");
00205             return reference(*this, p); 
00206         }
00207 
00208         u64 to_ulong() const {
00209             SHTTL_ASSERT(_v <= umax(size()));
00210             return _v;
00211         }
00212 
00213         std::string to_string() const;
00214 
00215         size_t count() const;
00216         size_t size() const { return N; }
00217 
00218         bool operator==(const this_type& i) const { return _v == i._v; }
00219         bool operator!=(const this_type& i) const { return _v != i._v; }
00220 
00221         bool test(size_type p) const {
00222             if (p < 0 || size() <= p)
00223                 throw std::out_of_range("shttl_bitset::test");
00224             return shttl::test(_v, p);
00225         }
00226 
00227         bool any()  const { return _v != 0; }
00228         bool none() const { return _v == 0; }
00229 
00230         this_type operator<<(size_type s) const { 
00231             return this_type((_v << s) & umax(size()));
00232         }
00233         this_type operator>>(size_type s) const {
00234             return this_type((_v >> s) & umax(size()));
00235         }
00236 
00237     }; // class shttl_bitset
00238 
00239 
00240     // Non-member Operators
00241 
00242     template<size_t N, class T>
00243     inline
00244         shttl_bitset<N, T> 
00245         operator&(const shttl_bitset<N, T>& l, const shttl_bitset<N, T>& r) {
00246             return shttl_bitset<N, T>(l.to_ulong() & r.to_ulong());
00247     }
00248 
00249     template<size_t N, class T>
00250     inline
00251         shttl_bitset<N, T> 
00252         operator|(const shttl_bitset<N, T>& l, const shttl_bitset<N, T>& r) {
00253             return shttl_bitset<N, T>(l.to_ulong() | r.to_ulong());
00254     }
00255 
00256     template<size_t N, class T>
00257     inline
00258         shttl_bitset<N, T> 
00259         operator^(const shttl_bitset<N, T>& l, const shttl_bitset<N, T>& r) {
00260             return shttl_bitset<N, T>(l.to_ulong() ^ r.to_ulong());
00261     }
00262 
00263     template<size_t N, class T>
00264     inline
00265         std::istream& operator>>(std::istream& is, shttl_bitset<N, T>& i) {
00266             std::string s;
00267             is >> s;
00268             i = shttl_bitset<N, T>(s);
00269             return is;
00270     }
00271 
00272     template<size_t N, class T>
00273     inline
00274         std::ostream& operator<<(std::ostream& os, const shttl_bitset<N, T>& i) {
00275             std::string s;
00276             s = i.to_string();
00277             os << s;
00278             return os;
00279     }
00280 
00281 
00282     // Non-inline Member Fucntions
00283     template<size_t N, class T>
00284     std::string
00285         shttl_bitset<N, T>::to_string() const 
00286     {
00287         std::string s;
00288         for (int p = (int)size() - 1; p >= 0; --p) 
00289             s += test(p) ? '1' : '0';
00290         return s;
00291     }
00292 
00293     template<size_t N, class T>
00294     size_t 
00295         shttl_bitset<N, T>::count() const 
00296     {
00297         int s = 0;
00298         for (int p = 0; p < size(); ++p) 
00299             if (test(p))
00300                 ++s;
00301         return s;
00302     }
00303 
00304 }; // namespace shttl;
00305 
00306 
00307 #endif // SHTTL_BITSET_H

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