2014-01-15 40 views
0

如果我想有我自己的類象std::bitset擴展std::bitset的功能,我想重載operator()(size_t start, size_t end),使得它返回從thisstart位到end但移位,使得end現在處於最低位的位置。還應該支持從位集移動位大小不同:如何有效地支持像C++ 11類中的bitset中的「子位串」?

 **** +++ 
    FEDCBA-- position 
x=1010101010111000 -- bits 
     **** +++ 

x是mybitset<16>,y是一個mybitset<4>

我想什麼,能夠做的是:

y = x(2,4); // y is now 0100 see +++ above 
x(6,9)=y; // z is now 101010 0100 111000 see **** above 

這似乎很合理,使用std :: string轉換(x.to_string().substr()),但我想保持對性能的整體操作。

編輯:這需要與64以上的大小一起工作:例如mybitset<1024>

有沒有辦法在C++ 11中做到這一點?

回答

3
template<size_t bits> 
std::bitset<bits> subset(std::bitset<bits> set, int min, int max) 
{ 
    const int ignore_hi = bits-max; 
    std::bitset<bits> range = (~std::bitset<bits>() << ignore_hi) >> ignore_hi; 
    set &= range; 
    return set >> min; 
} 

測試:http://coliru.stacked-crooked.com/a/531831e9c4c029f8。我認爲它可以稍微優化,我認爲可以省略一個轉變,但我懶得分析它,並希望優化器能夠自行計算出來。

通常,如果你想要一個範圍的位,正確的答案是使用位域而不是位集。但是,由於您似乎有千位,請改爲使用類。

struct flags { 
    int height : 3; //3 bits 
    int is_square : 1; //1 bit (as if bool) 
    int width : 3; //3 bits 
}; //keep in mind that a 1 bit int has possible values of `0` and `-1`. 

如果你想wierdo截斷,這是未經測試的。這些操作可能作爲單個操作被更有效地完成,但它們也可能是方便的單獨操作。我不打擾優化,除非分析顯示它是必要的。

template<class dst_bits, src_bits> 
std::bitset<maxbit-minbit> convert_bitset(std::bitset<src_bits> src) { 
    std::bitset<maxbit-minbit> result; 
    for(int i=0; i<maxbit-minbit; i+=64) 
     result |= std::bitset<maxbit-minbit>((src>>i).to_ulllong())<<i; 
    return result; 
} 

template<size_t src_bits, minbit, maxbit> 
std::bitset<maxbit-minbit> subset(std::bitset<src_bits> set) 
{ 
    const int ignore_hi = src_bits-maxbit; 
    std::bitset<bits> range = (~std::bitset<bits>() << ignore_hi) >> ignore_hi; 
    set &= range; 
    return convert_bitset<maxbit-minbit>(set >> minbit); 
} 

如果您希望截斷運行時大小爲min/max,那麼您應該重新評估設計。這並不是錯誤的,但在繼續之前應該確認它是正確的。如果您仍然堅持繼續,那麼這裏的代理應該能夠隱式地從一種大小轉換爲另一種大小,只是修改第一個subset函數以返回proxy_bitset<bits>而不是std::bitset<bits>

template<size_t src_bits> 
struct proxy_bitset { 
    proxy_bitset(std::bitset<src_bits> src) :src(src) {} 
    template<size_t dst_bits> 
    operator std::bitset<dst_bits>() const {return convert_bitset<dst_bits>(src);} 
private: 
    std::bitset<src_bits> src; 
}; 
+0

editted問題,以反映這需要大尺寸的工作,但+1因爲你編輯 –

+0

編輯答案之前得到這個在反映大尺寸 –

+0

你不能這樣做'子集(x的需求, 6,9)= y'你需要超載它來創建一個新的對象,當它被分配到x的範圍內,並且當被分配的範圍從 – user3125280