/*************************************************************************** * * Copyright (c) 2008 Baidu.com, Inc. All Rights Reserved * $Id: Array.h,v 1.4 2010/04/28 12:45:33 scmpf Exp $ * **************************************************************************/ /** * @file Array.h * @author chenxm(chenxiaoming@baidu.com) * @date 2008/09/24 01:36:18 * @version $Revision: 1.4 $ * @brief * **/ #ifndef __BSL_VAR_ARRAY_H__ #define __BSL_VAR_ARRAY_H__ #include #include "bsl/pool/bsl_pool.h" #include "bsl/var/IVar.h" #include "bsl/var/Ref.h" #include "bsl/var/Null.h" #include "bsl/var/utils.h" namespace bsl{ namespace var{ //typedefs //templateclass allocator_t> template class BasicArray; /** * @brief 封装了std::deque >的数组类型 * **/ typedef BasicArray > > Array; /** * @brief var::Array数组类型,与var::Dict保持类似的接口 * implement_t为BasicArray的内部实现 * * */ template class BasicArray: public IVar{ public: /** * @brief Var::Array的string类型 * */ typedef IVar::string_type string_type; /** * @brief Var::Array的字段类型 */ typedef IVar::field_type field_type; /** * @brief Var::Array的allocator */ typedef typename implement_t::allocator_type allocator_type; /** * @brief Var::Array的迭代器 */ typedef ArrayIterator array_iterator; /** * @brief Var::Array的const迭代器 */ typedef ArrayConstIterator array_const_iterator; /** * @brief Var::Array的reference_type */ typedef Ref reference_type; /** * @brief var::Array内部的数组实现别名 * **/ typedef implement_t array_type; public: BasicArray() :_array() { } /** * @brief BasicArray的构造函数 * * @param [in] allocator : allocator_type& * @return * @retval * @see * @author liaoshangbin * @data 2010/08/10 11:27:05 **/ explicit BasicArray( const allocator_type& _alloc ) :_array(_alloc){} /** * @brief BasicArray的复制构造函数 * * @param [in] other : const BasicArray& * @return * @retval * @see * @author liaoshangbin * @data 2010/08/10 11:27:58 **/ BasicArray( const BasicArray& other ) :IVar(other), _array(other._array){} /** * @brief BasicArray的复制赋值运算符 * * @param [in] other : const BasicArray& * @return * @retval * @see * @author liaoshangbin * @data 2010/08/10 11:28:47 **/ BasicArray& operator = ( const BasicArray& other ){ try{ _array = other._array; }catch(bsl::Exception& e){ e<<"{"<<__PRETTY_FUNCTION__<<"("<(var)); }else if ( var.is_array() ){ size_t var_size = var.size(); try{ _array.resize( var_size ); }catch(bsl::Exception& e){ throw; }catch(std::exception& e){ throw StdException(e)<= _array.size() ){ return bsl::var::Null::null; } return _array[idx]; } /** * @brief 获取下标idx处的IVar对象的引用对象 * 如果下标越界,返回一个默认值 * * @param [in] idx : size_t * @param [in] default_value : IVar& * @return IVar& * @retval * @see * @author liaoshangbin * @data 2010/08/10 11:39:57 **/ virtual IVar& get( size_t idx, IVar& default_value ) { if ( idx >= _array.size() ){ return default_value; } return _array[idx]; } /** * @brief 获取下标idx处的IVar对象的引用对象 * 如果下标越界,返回var::Null * * @param [in] idx : size_t * @param [in] default_value : IVar& * @return IVar& * @retval * @see * @author liaoshangbin * @data 2010/08/11 15:54:07 **/ virtual const IVar& get( size_t idx ) const { if ( idx >= _array.size() ){ return bsl::var::Null::null; } return _array[idx]; } /** * @brief 获取下标idx处的IVar对象的引用对象 * 如果下标越界,返回一个默认值,const版本 * * @param [in] idx : size_t * @param [in] default_value : const IVar& * @return const IVar& * @retval * @see * @author liaoshangbin * @data 2010/08/12 15:54:57 **/ virtual const IVar& get( size_t idx, const IVar& default_value ) const { if ( idx >= _array.size() ){ return default_value; } return _array[idx]; } /** * @brief 设置下标idx上的绑定 * * @param [in] idx : size_t * @param [in] value : IVar& * @return * @retval * @see * @author liaoshangbin * @data 2010/08/12 15:56:03 **/ virtual void set( size_t idx, IVar& value ){ if ( idx >= _array.size() ){ try{ _array.resize(idx + 1); }catch(bsl::Exception& e){ throw; }catch(std::exception& e){ throw StdException(e)<= _array.size() || _array[idx].is_null() ){ return false; }else{ _array[idx] = Null::null; return true; } } /** * @brief 返回只读起始数组迭代器 * is_array()返回true的IVar实现类都必须支持该方法 * * @param * @return array_const_iterator * @retval * @see * @author liaoshangbin * @data 2010/08/12 15:59:58 **/ virtual array_const_iterator array_begin() const { return array_const_iterator( _s_create_const_iterator( &_array, 0 ), _s_clone_const_iterator, _s_destroy_const_iterator ); } /** * @brief 返回起始数组迭代器 * * @param * @return array_iterator * @retval * @see * @author liaoshangbin * @data 2010/08/12 16:01:21 **/ virtual array_iterator array_begin() { return array_iterator( _s_create_iterator( &_array, 0 ), _s_clone_iterator, _s_destroy_iterator ); } /** * @brief 返回只读末尾数组迭代器 * * @param * @return array_const_iterator * @retval * @see * @author liaoshangbin * @data 2010/08/12 16:01:53 **/ virtual array_const_iterator array_end() const { return array_const_iterator( _s_create_const_iterator( &_array, _array.size() ), _s_clone_const_iterator, _s_destroy_const_iterator ); } /** * @brief 返回数组末尾迭代器 * * @param * @return array_iterator * @retval * @see * @author liaoshangbin * @data 2010/08/12 16:02:29 **/ virtual array_iterator array_end() { return array_iterator( _s_create_iterator( &_array, _array.size() ), _s_clone_iterator, _s_destroy_iterator ); } /** * @brief 返回/设置下标绑定 * * @param [in] idx : int * @return const IVar& * @retval * @see * @author liaoshangbin * @data 2010/08/12 16:03:09 **/ virtual const IVar& operator []( int idx ) const { return this->get( idx >= 0 ? size_t(idx) : size_t(_array.size() + idx) ); } /** * @brief 返回/设置下标绑定 * * @param [in] idx : int * @return IVar& * @retval * @see * @author liaoshangbin * @data 2010/08/12 16:05:00 **/ virtual IVar& operator []( int idx ){ if ( idx >= int(_array.size()) ){ try{ _array.resize( idx + 1 ); //自动扩展数组大小 }catch(bsl::Exception& e){ throw; }catch(std::exception& e){ throw StdException(e)<get( idx >= 0 ? size_t(idx) : size_t(_array.size() + idx) ); } //methods for dict #if __GNUC__ > 2 using IVar::operator []; using IVar::get; using IVar::set; using IVar::del; #else //avoid using bug of g++ 2.96 /** * @brief 返回字段名绑定 * 所有is_dict()返回true的IVar实现类都必须支持该方法 * * @param * @return * @retval * @see * @author liaoshangbin * @data 2010/08/12 16:06:54 **/ virtual IVar& get( const field_type& name ) { throw bsl::InvalidOperationException()<(&other); if ( !p ){ throw bsl::BadCastException() <_p_array; _offset = p->_offset; } /** * @brief 判断是否等于其它数组类型迭代器 * * @param [in] other : const IArrayIteratorImpl& * @return bool * @retval * @see * @author liaoshangbin * @data 2010/08/12 17:18:51 **/ virtual bool equal_to( const IArrayIteratorImpl& other ) const; /** * @brief 判断是否等于其它只读数组类型迭代器 * * @param [in] other : const IArrayConstIteratorImpl& * @return bool * @retval * @see * @author liaoshangbin * @data 2010/08/12 17:19:54 **/ virtual bool equal_to( const IArrayConstIteratorImpl& other ) const; private: /** * @brief 数组指针 * **/ array_type *_p_array; /** * @brief 数组指针的偏移位置 * **/ size_t _offset; }; /** * @brief 只读数组类型代器实现 * **/ class ArrayConstIteratorImpl: public IArrayConstIteratorImpl{ friend class ArrayIteratorImpl; public: /** * @brief 只读数组类型迭代器的构造函数 * * @param [in] p_array : const array_type* * @param [in] offset : size_t * @return * @retval * @see * @author liaoshangbin * @data 2010/08/12 16:32:33 **/ ArrayConstIteratorImpl( const array_type* p_array, size_t offset ) :_p_array(p_array), _offset(offset){} virtual ~ArrayConstIteratorImpl() { //pass } /** * @brief 得到偏移位置 * **/ virtual size_t key() const { return _offset; } /** * @brief 得到偏移位置上的绑定值 * * **/ virtual const IVar& value() const { return (*_p_array)[_offset]; } /** * @brief 偏移位置后移 * **/ virtual void iterate(){ ++ _offset; } /** * @brief 将其它数组类型迭代器对其赋值 * * @param [in] other : const IArrayIteratorImpl& * @return * @retval * @see * @author liaoshangbin * @data 2010/08/12 17:23:51 **/ virtual void assign( const IArrayIteratorImpl& other ) { const ArrayIteratorImpl *p = dynamic_cast(&other); if ( !p ){ throw bsl::BadCastException() <_p_array; _offset = p->_offset; } /** * @brief 将其它只读数组类型迭代器对其赋值 * * @param [in] other : const IArrayConstIteratorImpl& * @return * @retval * @see * @author liaoshangbin * @data 2010/08/12 17:24:55 **/ virtual void assign( const IArrayConstIteratorImpl& other ) { const ArrayConstIteratorImpl *p = dynamic_cast(&other); if ( !p ){ throw bsl::BadCastException() <_p_array; _offset = p->_offset; } /** * @brief 判断是否等于其它只读数组类型迭代器 * * @param [in] other : const IArrayConstIteratorImpl& * @return bool * @retval * @see * @author liaoshangbin * @data 2010/08/12 17:26:22 **/ virtual bool equal_to( const IArrayConstIteratorImpl& other ) const; /** * @brief 判断是否等于其它数组类型迭代器 * * @param [in] other : const IArrayIteratorImpl& * @return bool * @retval * @see * @author liaoshangbin * @data 2010/08/12 17:27:09 **/ virtual bool equal_to( const IArrayIteratorImpl& other ) const; private: /** * @brief 数组指针 * **/ const array_type * _p_array; /** * @brief 数组指针的偏移位置 * **/ size_t _offset; }; /** * @brief 创建一个数组的迭代器 * * @param [in] p_array : array_type* * @param [in] offset : size_t * @return IArrayIteratorImpl * * @retval * @see * @author liaoshangbin * @data 2010/08/12 16:14:45 **/ static IArrayIteratorImpl * _s_create_iterator( array_type* p_array, size_t offset){ typedef typename allocator_type:: template rebind::other impl_alloc_t; IArrayIteratorImpl *p = impl_alloc_t().allocate(1); //throw new(p) ArrayIteratorImpl(p_array, offset ); //nothrow return p; } /** * @brief 创建一个只读数组的迭代器 * @param [in] p_array : const array_type* * @param [in] offset : size_t * @return IArrayConstIteratorImpl * * @retval * @see * @author liaoshangbin * @data 2010/08/12 16:16:18 **/ static IArrayConstIteratorImpl * _s_create_const_iterator( const array_type* p_array, size_t offset ){ typedef typename allocator_type:: template rebind::other impl_alloc_t; IArrayConstIteratorImpl *p = impl_alloc_t().allocate(1); //throw new(p) ArrayConstIteratorImpl(p_array, offset ); //nothrow return p; } /** * @brief 克隆数组的迭代器 * * @param [in] p_other : const IArrayIteratorImpl* * @return IArrayIteratorImpl* * @retval * @see * @author liaoshangbin * @data 2010/08/12 16:17:48 **/ static IArrayIteratorImpl * _s_clone_iterator( const IArrayIteratorImpl *p_other ){ typedef typename allocator_type:: template rebind::other impl_alloc_t; const ArrayIteratorImpl *psrc = dynamic_cast(p_other); if ( !psrc ){ throw bsl::BadCastException() <::other impl_alloc_t; const ArrayConstIteratorImpl *psrc = dynamic_cast(p_other); if ( !psrc ){ throw bsl::BadCastException() <::other impl_alloc_t; ArrayIteratorImpl *_p = dynamic_cast(p); if ( _p ){ _p->~ArrayIteratorImpl(); impl_alloc_t().deallocate( _p, 1 ); } } /** * @brief 销毁只读数组的迭代器 * @param [in] p : IArrayIteratorImpl * @return void * @retval * @see * @author liaoshangbin * @data 2010/08/12 16:20:38 **/ static void _s_destroy_const_iterator( IArrayConstIteratorImpl * p){ typedef typename allocator_type:: template rebind::other impl_alloc_t; ArrayConstIteratorImpl *_p = dynamic_cast(p); if ( _p ){ _p->~ArrayConstIteratorImpl(); impl_alloc_t().deallocate( _p, 1 ); } } /** * @brief 内部封装的数组 * **/ array_type _array; }; /** * @brief 判断数组两个迭代器是否相同 * * @param [in] other : const IArrayIteratroImpl& * @return bool * @retval * @see * @author liaoshangbin * @data 2010/08/12 16:26:48 **/ template inline bool BasicArray:: ArrayIteratorImpl::equal_to( const IArrayIteratorImpl& other ) const { const ArrayIteratorImpl *p = dynamic_cast(&other); return p != NULL && _p_array == p->_p_array && _offset == p->_offset; } /** * @brief 判断数组的迭代器与只读数组的迭代器是否相同 * * @param [in] other : const IArrayConstIteratroImpl& * @return bool * @retval * @see * @author liaoshangbin * @data 2010/08/12 16:27:47 **/ template inline bool BasicArray:: ArrayIteratorImpl::equal_to( const IArrayConstIteratorImpl& other ) const { const ArrayConstIteratorImpl *p = dynamic_cast(&other); return p != NULL && _p_array == p->_p_array && _offset == p->_offset; } /** * @brief 判断只读数组的迭代器与数组的迭代器是否相同 * * @param [in] other : const IArrayIteratroImpl& * @return bool * @retval * @see * @author liaoshangbin * @data 2010/08/12 16:28:37 **/ template inline bool BasicArray:: ArrayConstIteratorImpl::equal_to( const IArrayIteratorImpl& other ) const { const ArrayIteratorImpl *p = dynamic_cast(&other); return p != NULL && _p_array == p->_p_array && _offset == p->_offset; } /** * @brief 判断两个只读数组的迭代器是否相同 * * @param [in] other : const IArrayConstIteratroImpl& * @return bool * @retval * @see * @author liaoshangbin * @data 2010/08/12 16:29:20 **/ template inline bool BasicArray:: ArrayConstIteratorImpl:: equal_to( const IArrayConstIteratorImpl& other ) const { const ArrayConstIteratorImpl *p = dynamic_cast(&other); return p != NULL && _p_array == p->_p_array && _offset == p->_offset; } }} //namespace bsl::var #endif //__BSL_VAR_ARRAY_H__ /* vim: set ts=4 sw=4 sts=4 tw=100 */