特定のファイル形式を読み取るライブラリを作成しています。ファイルは、メモリ マップ ファイル (boost::interprocess
テンプレート) で読み取られています。これらのファイルでは、std::regex
. 不必要なコピーを避けるために、メモリ マップ ファイルを (C スタイルの char 配列として) 直接使用したいと考えています。
しばらく調査した後、次の2つのアプローチを思い付きました。
- オブジェクトの
pubsetbuf
メソッドを使用するstreambuf
char*
ポインターを反復子として使用する
しかし、最初の実装は STL ベンダーにとってオプションであるため、私は 2 番目のアプローチにこだわっています。のコンストラクターstd::string::iterator
はプライベートとして宣言されているため、イテレーターの実装全体もベンダー固有のようです。私は自分のイテレータを書きました:
template<typename T>
class PointerIterator: std::iterator<std::input_iterator_tag, T> {
public:
PointerIterator(T* first, std::size_t count): first_(first), last_(first + count) {}
PointerIterator(T* first, T* last): first_(first), last_(last) {}
class iterator {
public:
iterator(T* p): ptr_(p) {}
iterator(const iterator& it): ptr_(it.ptr_) {}
iterator& operator++() {
++ptr_;
return *this;
}
iterator operator++(int) {
iterator temp(*this);
++ptr_;
return temp;
}
bool operator==(const iterator& it) { return ptr_ == it.ptr_; }
bool operator!=(const iterator& it) { return ptr_ != it.ptr_; }
T& operator*() { return *ptr_; }
private:
T* ptr_;
};
iterator begin() {
return iterator(first_);
}
iterator end() {
return iterator(last_);
}
private:
T* first_;
T* last_;
};
反復子は機能していますが、std::regex_search
メソッド (または他の char 関連の STL メソッド) で使用するには、STL 反復子と同じ型である必要があります。
イテレータを STL のもの (STL 実装で移植可能) にキャストする、または言及していない別のアプローチで全体を達成するための一般的なアプローチはありますか?
編集:
を使用したソースstd::regex_search
:
std::regex re(...);
boost::interprocess::mapped_region region(...);
char* first = static_cast<char*>(region.get_address());
char* last = first + 5000;
// ...
PointerIterator<char> wrapper(first, last);
std::smatch match;
while (std::regex_search(wrapper.begin(), wrapper.end(), match, re)) { // Error: No matching function call to 'regex_search'
// do something
}
ありがとう