Boost.Range

工具

以一個抽像概念封裝一對迭代器是非常有用的。標準庫在某些環境下使用 std::pair, 但是這個類用起來有點麻煩,因為我們必須要指定兩個模板參數,而對於所有區間算法來說,我們必須強制讓兩個模板參數相同。此外,std::pair<iterator,iterator> 很難起一個易懂的類名。因此我們提供了兩個類:

iterator_range 類以一個 前向遍歷迭代器 為模板參數,用於適合的泛型代碼所需要的地方。sub_range 類則以一個 前向區間 為模板參數,通用性稍差,但是更易於使用,因為它的模板參數更容易指定。兩者之間的最大差別在於,sub_range 可以傳播常量性,因為它知道對應的 const_iterator 是什麼。

這兩個類都可用作區間,因為它們實現了可自動工作所要求的 最小接口


類 iterator_range

iterator_range 類的目的是封裝兩個迭代器,讓它們實現 前向區間 的概念。另外為了方便使用,還提供了幾個其它函數。

如果模板參數不符合前向遍歷迭代器,你還可以使用該接口的子集。例如,size() 要求前向遍歷迭代器,而 empty() 只要求單遍迭代器。

由於許多缺省構造的迭代器都是異常的,只能用於賦值而不能進行比較、遞增或其它操作。同樣,如果你創建一個缺省構造的 iterator_range, 那麼就必須小心不要做除了複製以外的任何動作。

摘要

namespace boost
{
template< class ForwardTraversalIterator >
class iterator_range
{
public: // 前向區間類型
typedef ForwardTraversalIterator iterator;
typedef ForwardTraversalIterator const_iterator; typedef iterator_difference<iterator>::type difference_type; public: // 構造,賦值
template< class ForwardTraversalIterator2 >
iterator_range( ForwardTraversalIterator2 Begin, ForwardTraversalIterator2 End );

template< class ForwardRange >
iterator_range( ForwardRange& r );

template< class ForwardRange >
iterator_range( const ForwardRange& r );

template< class ForwardRange >
iterator_range& operator=( ForwardRange& r );

template< class ForwardRange >
iterator_range& operator=( const ForwardRange& r );

public: // 前向區間函數
iterator begin() const;
iterator end() const;
difference_type size() const;
bool empty() const;

public: // 工具
operator unspecified_bool_type() const;
bool equal( const iterator_range& ) const; reference front() const; reference back() const; iterator_range& advance_begin( difference_type n ); iterator_range& advance_end( difference_type n ); // 僅用於隨機訪問區間: reference operator[]( difference_type at ) const; value_type operator()( difference_type at ) const; };

// 流輸出
template< class ForwardTraversalIterator, class T, class Traits >
std::basic_ostream<T,Traits>&
operator<<( std::basic_ostream<T,Traits>& Os,
const iterator_range<ForwardTraversalIterator>& r );

// 比較 template< class ForwardTraversalIterator, class ForwardTraversalIterator2 >
bool operator==( const iterator_range<ForwardTraversalIterator>& l,
const iterator_range<ForwardTraversalIterator2>& r );

template< class ForwardTraversalIterator, class ForwardRange >
bool operator==( const iterator_range<ForwardTraversalIterator>& l,
const ForwardRange& r );

template< class ForwardTraversalIterator, class ForwardRange >
bool operator==( const ForwardRange& l,
const iterator_range<ForwardTraversalIterator>& r );

template< class ForwardTraversalIterator, class ForwardTraversalIterator2 >
bool operator!=( const iterator_range<ForwardTraversalIterator>& l,
const iterator_range<ForwardTraversalIterator2>& r );

template< class ForwardTraversalIterator, class ForwardRange >
bool operator!=( const iterator_range<ForwardTraversalIterator>& l,
const ForwardRange& r );

template< class ForwardTraversalIterator, class ForwardRange >
bool operator!=( const ForwardRange& l,
const iterator_range<ForwardTraversalIterator>& r );

template< class ForwardTraversalIterator, class ForwardTraversalIterator2 >
bool operator<( const iterator_range<ForwardTraversalIterator>& l,
const iterator_range<ForwardTraversalIterator2>& r );

template< class ForwardTraversalIterator, class ForwardRange >
bool operator<( const iterator_range<ForwardTraversalIterator>& l,
const ForwardRange& r );

template< class ForwardTraversalIterator, class ForwardRange >
bool operator<( const ForwardRange& l,
const iterator_range<ForwardTraversalIterator>& r ); // 外部構造
template< class ForwardTraversalIterator >
iterator_range< ForwardTraversalIterator >
make_iterator_range( ForwardTraversalIterator Begin,
ForwardTraversalIterator End );

template< class ForwardRange >
iterator_range< typename range_iterator<ForwardRange>::type >
make_iterator_range( ForwardRange& r );

template< class ForwardRange >
iterator_range< typename range_iterator<const ForwardRange>::type >
make_iterator_range( const ForwardRange& r );
template< class Range > iterator_range< typename range_iterator<Range>::type > make_iterator_range( Range& r,
typename range_difference<Range>::type advance_begin,
typename range_difference<Range>::type advance_end );
template< class Range > iterator_range< typename range_iterator<const Range>::type > make_iterator_range( const Range& r,
typename range_difference<Range>::type advance_begin,
typename range_difference<Range>::type advance_end ); // 工具
template< class Sequence, class ForwardRange >
Sequence copy_range( const ForwardRange& r );
} // namespace 'boost'

如果一個 iterator_range 實例是由用戶以兩個迭代器構造的,用戶必須確保這兩個迭代器界定了一個有效的半開閉區間 [begin,end).

值得注意的是,模板構造函數和賦值操作符允許從 iterator_range<iterator> 轉換為 iterator_range<const_iterator>. 類似的,由於比較操作符有兩個模板參數,所以我們可以對區間進行比較,只要其迭代器是可比較的;例如,在我們處理同一個容器的常量和非常量迭代器時。

成員函數細節

operator unspecified_bool_type() const;

返回 !empty();

bool equal( iterator_range& r ) const;

返回 begin() == r.begin() && end() == r.end();

非成員函數細節

bool operator==( const ForwardRange1& l, const ForwardRange2& r );

返回 size(l) != size(r) ? false : std::equal( begin(l), end(l), begin(r) );

bool operator!=( const ForwardRange1& l, const ForwardRange2& r );
返回 !( l == r );
bool operator<( const ForwardRange1& l, const ForwardRange2& r );
返回 std::lexicographical_compare( begin(l), end(l), begin(r), end(r) );

iterator_range make_iterator_range( Range& r, 
typename range_difference<Range>::type advance_begin,
typename range_difference<Range>::type advance_end );
作用:
iterator new_begin = begin( r ),
iterator new_end = end( r );
std::advance( new_begin, advance_begin );
std::advance( new_end, advance_end );
return make_iterator_range( new_begin, new_end );

Sequence copy_range( const ForwardRange& r );

返回 Sequence( begin(r), end(r) );


類 sub_range

sub_range 類從 iterator_range 類繼承了所有功能。sub_range 類更易於使用,因為你要給出的模板參數是一個 前向區間 而不是一個迭代器。此外,sub_range 類可以傳播常量性,因為它知道對應的 const_iterator 是什麼。

摘要

namespace boost
{
template< class ForwardRange >
class sub_range : public iterator_range< typename range_iterator<ForwardRange>::type >
{
public: typedef typename range_iterator<ForwardRange>::type iterator; typedef typename range_iterator<const ForwardRange>::type const_iterator; typedef typename iterator_difference<iterator>::type difference_type; public: // 構造,賦值
template< class ForwardTraversalIterator >
sub_range( ForwardTraversalIterator Begin, ForwardTraversalIterator End );

template< class ForwardRange2 >
sub_range( ForwardRange2& r );

template< class ForwardRange2 >
sub_range( const ForwardRange2& r );

template< class ForwardRange2 >
sub_range& operator=( ForwardRange2& r );

template< class ForwardRange2 >
sub_range& operator=( const ForwardRange2& r );
public: // 前向區間函數
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;

public: // 工具
value_type& front(); const value_type& front() const; value_type& back(); const value_type& back() const; // 僅用於隨機訪問區間: value_type& operator[]( difference_type at ); const value_type& operator[]( difference_type at ) const; public:
// 其它接口繼承自 iterator_range };
} // namespace 'boost'

這個類的用法非常簡單,請看下文。設想我們有一個算法,在一個字符串中查找子字符串。結果是一個 iterator_range, 界定了匹配的子串。我們需要保存該算法的結果。下面的例子示範了在如何使用或不用 sub_range 來實現:

    std::string str("hello");
    iterator_range<std::string::iterator> ir = find_first( str, as_literal("ll") );
    sub_range<std::string>               sub = find_first( str, as_literal("ll") );


© Copyright Thorsten Ottosen 2008.

Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at www.boost.org/LICENSE_1_0.txt)