解決辦法很簡單:
#include <tuple>
using std::get;
using std::tuple;
using std::make_tuple;
#include <boost/dynamic_bitset.hpp>
using boost::dynamic_bitset;
template <typename Block, typename Allocator>
unsigned block_index(const boost::dynamic_bitset<Block, Allocator>& b, unsigned pos)
{ return pos/b.bits_per_block; }
namespace boost {
template <>
inline void
to_block_range(const dynamic_bitset<>& b, tuple<unsigned, unsigned, unsigned long&> param)
{
{
unsigned beg = get<0>(param);
unsigned len = get<1>(param);
unsigned block1 = block_index(b, beg);
unsigned block2 = block_index(b, beg + len -1);
unsigned bit_index = beg % b.bits_per_block;
unsigned long bitmask = (1 << len) - 1;
get<2>(param) = ((b.m_bits[block1] >> bit_index) |
(b.m_bits[block2] << (b.bits_per_block - bit_index) )) &
bitmask;
return;
}
}
}
unsigned long res;
to_block_range(bits, make_tuple(pos, len, std::ref(res)));
要撥打:
boost::dynamic_bitset<> bits;
unsigned long result;
to_block_range(bits, t_extract_range{begin_bit, length_bits, result});
有一個在dynamic_bitset
沒有直接的,原生支持。
要獲得一系列位數,您必須進入dynamic_bitset
,訪問底層存儲並自行提取數據。
執行此操作的代碼很簡單,但數據(dynamic_bitset::m_bits
)位於類的專用部分內。有三種方法可以破解私人牆:
- 假裝你的編譯器不符合要求。
#define BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS
。這通過更改BOOST_DYNAMIC_BITSET_PRIVATE
將private
更改爲public
。
- 黑客
dynamic_bitset.hpp
標題暴露m_bits
。
- 第三種解決方法是解決當前的代碼。
(1)和(2)是脆弱的,正面的攻擊,這將是一個維修的噩夢。
幸運的是,(3)的模板函數爲dynamic_bitset
的friend
s。我們可以用我們自己的函數替代(專門化)這個模板來做我們自己的提取。
template <typename Block, typename Allocator, typename BlockOutputIterator>
inline void
to_block_range(const dynamic_bitset<Block, Allocator>& b,
BlockOutputIterator result)
{
std::copy(b.m_bits.begin(), b.m_bits.end(), result);
}
的規範模板函數將整個位集到迭代器BlockOutputIterator
這是不我們想要的。
我們將使用代替BlockOutputIterator
一個自定義類型將舉行所有3個I/O參數專門boost::to_block_range
:即
begin_bit
,
length_of_range
和
- 目的地。
提供你叫to_block_range
以必要的類型,它會調用自己的函數,而不是標準的模板,但完全進入內部也是如此。你基本上已經顛覆了C++訪問規範體系!
N.B.示例代碼不會檢查錯誤。沒有嘗試,以確保
- 的範圍unsigned long類型適合或
- 該範圍不超過此位集或
- 的界限位集使用無符號多頭內部。