设为首页 加入收藏

TOP

31.4.2. acestl::message_queue_sequence::iterator
2013-10-07 00:33:56 来源: 作者: 【 】 浏览:63
Tags:31.4.2. acestl::message_queue_sequence::iterator

31.4.2. acestl::message_queue_sequence::iterator

清单31.8展示了acestl::message_queue_sequence::iterator类的定义。基于之前的经验,这里的很多内容我们都不感到陌生。(至此我希望你对这些技术已经有所熟悉,既能认识到它们之间的相似之处,在不同的应用场景中,也可以指出改变的地方。当然,我也希望你自己编写STL扩展时同样从中受益。)迭代器的类别是输入迭代器(1.3.1节)。元素引用类别(3.3节)是瞬时引用或更高的精化;不过事实上就是固定引用,但是需要注意,不论在定义底层消息队列的线程之内或之外,都不能有别的代码改变队列或其中的块(否则会使引用失效)。迭代器的实现基于shared_handle,很快会讨论。因为我们在别的序列(19.3节和20.5节)中已经见识了使用shared_handle的规范方式,所以在下面的构造方法中不再赘述。

清单 31.8. message_queue_sequence::iterator 的定义

Code View: Scroll / Show All
class message_queue_sequence<. . .>::iterator
: public std::iterator<std::input_iterator_tag
, char, ptrdiff_t
, char*, char&
>
{
private: // Member Types
friend class message_queue_sequence<ACE_SYNCH_USE>;
typedef ACE_Message_Queue_Iterator<ACE_SYNCH_USE>   mq_iterator_type;
struct                                              shared_handle;
public:
typedef iterator                                    class_type;
typedef char                                        value_type;
private: // Construction
iterator(sequence_type& mq)
: m_handle(new shared_handle(mq))
{}
public:
iterator()
: m_handle(NULL)
{}
iterator(class_type const& rhs); // Share handle via AddRef() (+)
~iterator() throw(); // Call Release() (-) if non-NULL
class_type& operator =(class_type const& rhs); // (+) new; (-) old
public: // Input Iteration
class_type& operator ++()
{
ACESTL_ASSERT(NULL != m_handle);
if(!m_handle->advance())
{
m_handle->Release();
m_handle = NULL;
}
return *this;
}
class_type operator ++(int); // Canonical implementation
value_type& operator *()
{
ACESTL_ASSERT(NULL != m_handle);
return m_handle->current();
}
value_type operator *() const
{
ACESTL_ASSERT(NULL != m_handle);
return m_handle->current();
}
bool equal(class_type const& rhs) const
{
return lhs.is_end_point() == rhs.is_end_point();
}
private: // Implementation
bool is_end_point() const
{
return NULL == m_handle || m_handle->is_end_point();
}
private: // Member Variables
shared_handle*  m_handle;
};

迭代方法都实现在shared_handle方法的基础上。有两种方式表示终点状态:m_handle是空指针,或者其本身就代表终点 。前自增运算符调用shared_handle::advance()使迭代过程前进,但如果后者返回值为false,就释放m_handle。解引用运算符的重载实现基于shared_handle的current()方法的重载版本。注意其中的变动性(非const)重载返回变动性引用,而非变动性(const)重载返回char值。

主要的动作都放在shared_handle之中,其实现见清单31.9。现在我施展另一个诡计,不去解释算法的细节,而是留给你作为练习。但为了公平起见,我还是给个提示吧,shared_handle跳过了空白的ACE_Message_Block实例,这就是为什么终点条件的判断逻辑如此简单。

清单 31.9. shared_handle 的定义

Code View: Scroll / Show All
struct message_queue_sequence<. . .>::iterator::shared_handle
{
public: // Member Types
typedef shared_handle   class_type;
public: // Member Variables
mq_iterator_type    m_mqi;
ACE_Message_Block*  m_entry;
size_t              m_entryLength;
size_t              m_entryIndex;
private:
sint32_t            m_refCount;
public: // Construction
explicit shared_handle(sequence_type& mq)
: m_mqi(mq)
, m_entry(NULL)
, m_entryLength(0)
, m_entryIndex(0)
, m_refCount(1)
{
if(m_mqi.next(m_entry))
{
for(;;)
{
if(0 != (m_entryLength = m_entry->length()))
{
break;
}
else if(NULL == (m_entry = nextEntry()))
{
break;
}
}
}
}
private:
~shared_handle() throw()
{
ACESTL_MESSAGE_ASSERT("Shared handle destroyed with outstanding     
references!", 0 == m_refCount);                                         
}
public:
sint32_t AddRef();  // Canonical implementation
sint32_t Release(); // Canonical implementation
public: // Iteration Methods
bool is_end_point() const
{
return m_entryIndex == m_entryLength;
}
char&   current()
{
ACESTL_ASSERT(NULL != m_entry);
ACESTL_ASSERT(m_entryIndex != m_entryLength);
return m_entryIndex[m_entry->rd_ptr()];
}
char    current() const
{
ACESTL_ASSERT(NULL != m_entry);
ACESTL_ASSERT(m_entryIndex != m_entryLength);
return m_entryIndex[m_entry->rd_ptr()];
}
bool   advance()
{
ACESTL_MESSAGE_ASSERT("Invalid index", m_entryIndex <               
m_entryLength);                                                         
if(++m_entryIndex == m_entryLength)
{
m_entryIndex = 0;
for(;;)
{
if(NULL == (m_entry = nextEntry()))
{
return false;
}
else if(0 != (m_entryLength = m_entry->length()))
{
break;
}
}
}
return true;
}
private: // Implementation
ACE_Message_Block* nextEntry()
{
ACE_Message_Block* entry = NULL;
return m_mqi.advance() (m_mqi.next(entry), entry) : NULL;
}
private: // Not to be implemented
shared_handle(class_type const&);
class_type& operator =(class_type const&);
};
【责任编辑:董书 TEL:(010)68476606】

回书目   上一节   下一节

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇31.5.2. acestl::message_queue_s.. 下一篇31.4.1. acestl::message_queue_s..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: