- 浏览: 261634 次
- 性别:
- 来自: 武汉
文章分类
最新评论
-
daknife:
谢谢你的这篇文章,让我大概了解了select的一部分底层原理。 ...
Linux-2.6.25 select系统调用源码分析 -
gjlzjb:
非常有用,谢谢哈。另外问下,您是否用过Pheonix Syst ...
Why Map/Reduce? -
zhangyafei_kimi:
canbo 写道请问,我怎么生成安装包,提供给其它用户安装呢? ...
下载最新的Google Chrome源码并编译 -
canbo:
请问,我怎么生成安装包,提供给其它用户安装呢?
下载最新的Google Chrome源码并编译
#ifndef __KIMI_BOOST_ARRAY2
#define __KIMI_BOOST_ARRAY2
#pragma once
#include <cstddef> //size_t
#include <exception>//exception
#include <iterator>//random_access_iterator_tag,reverse_iterator
namespace kimi_boost
{
template <class T> class array2;//forward declaration
//iterator for class array2
template <class T,class Ref,class Ptr>
struct __M_array2_iterator
{
typedef std::random_access_iterator_tag iterator_category;
typedef T value_type;
typedef std::ptrdiff_t difference_type;
typedef Ptr pointer;
typedef Ref reference;
typedef __M_array2_iterator self;
std::size_t m;//index1
std::size_t n;//index2
array2<T>* m_pArray;//pointer to current array2 object
__M_array2_iterator():m(0),n(0),m_pArray(0){}
__M_array2_iterator(std::size_t m1, std::size_t n1, array2<T>* pArray)
:m(m1),n(n1),m_pArray(pArray){}
__M_array2_iterator(const __M_array2_iterator& y)
:m(y.m),n(y.n),m_pArray(y.m_pArray){}
reference operator*()const{return m_pArray->at(m,n);}
pointer operator->()const{return &(this->operator *());}
//necessary operators for a bidirectional iterator
self& operator++()
{
if(n < m_pArray->size2()-1) ++n;
else if (n == m_pArray->size2()-1 && m < m_pArray->size1()-1){n=0;++m;}
else n=m_pArray->size2();//pass the last element : end
return *this;
}
self operator++(int)
{
self temp=*this;
++*this;
return temp;
}
self& operator--()
{
if(n > 0) --n;
else if (n == 0 && m > 0){n=m_pArray->size2()-1;--m;}
return *this;
}
self operator--(int)
{
self temp=*this;
--*this;
return temp;
}
bool operator==(const self& x)const
{
return m_pArray==x.m_pArray && m==x.m && n==x.n;
}
bool operator!=(const self& x)const
{
return !operator ==(x);
}
//necessary operators for a random access iterator
difference_type operator-(const self& x)const
{
return difference_type( (m-x.m)*m_pArray->size2() + n-x.n );
}
self& operator += (difference_type x)
{
difference_type size2=m_pArray->size2();
difference_type total = n+x;
difference_type new_m = static_cast<difference_type>(m) + total/size2;
difference_type new_n = total%size2;
if( new_m >= static_cast<difference_type>(m_pArray->size1()) )//pass end(),and restrict to end()
{
m=m_pArray->size1()-1;
n=m_pArray->size2();
}
else if(new_m <0)//precede begin(),and restrict to begin()
{
m=0;
n=0;
}
else
{
m = new_m;
n = new_n;
}
return *this;
}
self operator + (difference_type n)const
{
self temp = *this;
return temp += n;
}
self& operator -= (difference_type n)
{
return *this += -n;
}
self& operator - (difference_type n)
{
self temp = *this;
return temp -= n;
}
bool operator<(const self& x)const
{
if(m<x.m) return true;
else if(m==x.m && n<x.n) return true;
else return false;
}
};
//a 2-dimension array
template <class T>
class array2
{
public:
typedef T value_type;
typedef __M_array2_iterator<T,T&,T*> iterator;
typedef __M_array2_iterator<T,const T&,const T*> const_iterator;
typedef T& reference;
typedef const T& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
private:
//Array Index Out Of Bounds Exception
struct ArrayIndexOutOfBoundsException : public std::exception
{
ArrayIndexOutOfBoundsException(const char *const& what):exception(what){}
};
//a proxy class that represents a 1-dimension array
class array1
{
public:
array1():m_ptr(0) , m_size(0){}
~array1()
{
if(m_ptr)
{
delete[] m_ptr;
m_ptr=0;
}
}
//initialize
void init(size_type N)
{
//delete []m_ptr;
m_ptr = new T[N];
m_size = N;
}
array1(const array1&);//ban copy ctor
array1& operator=(const array1&);//ban assignment
reference operator [](size_type N){return m_ptr[N];}
const_reference operator [](size_type N) const{return m_ptr[N];}
size_type size() const{return m_size;}
private:
T* m_ptr;
size_type m_size;
};
private:
array1* m_pCon;
size_type m_size;
//bounds check
void _M_init_proxys(size_type M,size_type N)
{
for(size_type i=0 ; i<M ; ++i)
m_pCon[i].init(N);
}
void _M_bounds_check(size_type M,size_type N) const
{
if(M >= m_size && N>=m_pCon[0].size())
throw ArrayIndexOutOfBoundsException("Array Index Out Of Bounds");
}
public:
array2():m_pCon(0),m_size(0){}
array2(size_type M, size_type N):m_pCon(new array1[M]) , m_size(M)
{
_M_init_proxys(M,N);
}
~array2()
{
if(m_pCon && m_size)
{
delete[] m_pCon;
m_pCon=0;
}
}
array2(size_type M , size_type N , array2<T>& a):m_pCon(new array1[M]) , m_size(M)
{
_M_init_proxys(M,N);
difference_type num2 = a.size();
difference_type num1 = M*N;
std::copy(a.begin(), (num1>=num2)?a.end():(a.begin()+num1) ,begin());
}
array2(size_type M , size_type N , iterator f , iterator l):m_pCon(new array1[M]) , m_size(M)
{
_M_init_proxys(M,N);
difference_type num2 = std::distance(f,l);
difference_type num1 = M*N;
std::copy(f, (num1>=num2)?l:(f+num1) ,begin());
}
array2(const array2<T>& a)
{
m_pCon = new array1[a.m_size];
for(size_type i=0 ; i<a.size1() ; ++i)
{
m_pCon[i].init(a.m_pCon[0].size());
for(size_type j=0 ; j<a.size2() ; ++j)
m_pCon[i][j]=a[i][j];
}
m_size=a.m_size;
}
array2<T>& operator = (const array2<T>& a)
{
if(&a != this)
{
delete []m_pCon;
m_pCon = new array1[a.m_size];
for(size_type i=0 ; i<a.size1() ; ++i)
{
m_pCon[i].init(a.m_pCon[0].size());
for(size_type j=0 ; j<a.size2() ; ++j)
m_pCon[i][j]=a[i][j];
}
m_size=a.m_size;
}
return *this;
}
//retrieve the total size
size_type size()const
{return size1()*size2();}
//retrieve the first dimension's size
size_type size1()const
{return m_size;}
//retrieve the second dimension's size
size_type size2()const
{return m_pCon[0].size();}
//resize the array and keep the previous content in the array
void resize(size_type m,size_type n)
{
array1* newPlace=new array1[m];
for(size_type i=0 ; i<m ; ++i)
newPlace[i].init(n);
for(size_type i=0 ; i<std::min(m,m_size) ; ++i)
for(size_type j=0 ; j<std::min(n,m_pCon[0].size()) ; ++j)
newPlace[i][j] = m_pCon[i][j];
delete [] m_pCon;
m_pCon = newPlace;
m_size = m;
}
array1& operator [] (size_type m){return m_pCon[m];}
const array1& operator [] (size_type m) const{return m_pCon[m];}
reference at(size_type m,size_type n) { _M_bounds_check(m,n); return m_pCon[m][n]; }
const_reference at(size_type m,size_type n) const { _M_bounds_check(m,n); return m_pCon[m][n]; }
void assign (const_reference value)
{
std::fill_n(begin(),size(),value);
}
void swap(array2<T>& y)
{
std::swap(m_pCon , y.m_pCon);
std::swap(m_size , y.m_size);
}
iterator begin() { return iterator(0,0,this); }
const_iterator begin() const { return const_iterator(0,0,this); }
iterator end() { return iterator(size1()-1,size2(),this); }
const_iterator end() const { return const_iterator(size1()-1,size2(),this); }
reverse_iterator rbegin() { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const {return const_reverse_iterator(end());}
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const {return const_reverse_iterator(begin());}
reference front() { return at(0,0); }
const_reference front() const {return at(0,0);}
reference back() { return at(size1()-1,size2()-1); }
const_reference back() const { return at(size1()-1,size2()-1); }
//member templates
template <class T2>
array2(const array2<T2>& a)
{
m_pCon = new array1[a.size1()];
for(size_type i=0 ; i<a.size1() ; ++i)
{
m_pCon[i].init(a.size2());
for(size_type j=0 ; j<a.size2() ; ++j)
m_pCon[i][j]=static_cast<T>(a[i][j]);
}
m_size=a.size1();
}
template <class T2>
array2<T>& operator = (const array2<T2>& a)
{
delete []m_pCon;
m_pCon = new array1[a.size1()];
for(size_type i=0 ; i<a.size1() ; ++i)
{
m_pCon[i].init(a.size2());
for(size_type j=0 ; j<a.size2() ; ++j)
m_pCon[i][j]=static_cast<T>(a[i][j]);
}
m_size=a.size1();
return *this;
}
template <class T2>
void swap(array2<T2>& y)
{
//unfinished
}
template<class InputIterator>
array2(size_type M , size_type N , InputIterator f , InputIterator l):m_pCon(new array1[M]) , m_size(M)
{
_M_init_proxys(M,N);
difference_type num2 = std::distance(f,l);
difference_type num1 = M*N;
std::copy(f, (num1>=num2)?l:(f+num1) ,begin());
}
};
//relative global comparison functiaon
template<class T>
bool operator== (const array2<T>& x, const array2<T>& y)
{
if(x.size1() != y.size1() || x.size2() != y.size2() ) return false;
array2<T>* px = const_cast< array2<T>* >(&x);
array2<T>* py = const_cast< array2<T>* >(&y);
return std::equal (px->begin(), px->end(), py->begin());
}
template<class T>
bool operator< (const array2<T>& x, const array2<T>& y)
{
array2<T>* px = const_cast< array2<T>* >(&x);
array2<T>* py = const_cast< array2<T>* >(&y);
return std::lexicographical_compare(px->begin(),px->end(),py->begin(),py->end());
}
template<class T>
bool operator!= (const array2<T>& x, const array2<T>& y) {return !(x==y);}
template<class T>
bool operator> (const array2<T>& x, const array2<T>& y) {return y<x;}
template<class T>
bool operator<= (const array2<T>& x, const array2<T>& y) {return !(y<x);}
template<class T>
bool operator>= (const array2<T>& x, const array2<T>& y) {return !(x<y);}
// global swap()
template<class T>
inline void swap (array2<T>& x, array2<T>& y) {x.swap(y);}
}//end of namespace kimi_boost
#endif//__KIMI_BOOST_ARRAY2
接下来是例子程序
void array2_test()
{
kimi_boost::array2<float> f3(2,3);
kimi_boost::array2<float> f4(3,4);
f3[0][0]=456.3f;
f3[0][1]=46.9f;
f3[0][2]=45.9f;
f3[1][0]=-17.5f;
f3[1][1]=0.0f;
f3[1][2]=1.0f;
kimi_boost::array2<float> f10(3,2,f3.begin(),f3.end());
std::copy(f10.begin(),f10.end(),std::ostream_iterator<float>(std::cout," "));
std::cout<<"\r\n";
kimi_boost::array2<float> f11(3,5,f3);
std::copy(f11.begin(),f11.end(),std::ostream_iterator<float>(std::cout," "));
std::cout<<"\r\n";
//f3[1] = f3[0]; //error
kimi_boost::array2<float> f1(f3);
kimi_boost::array2<float> f2;
f2=f3;
f4.assign(9.0f);
f3.swap(f4);
f3.swap(f4);
std::copy(f3.begin(),f3.end(),std::ostream_iterator<float>(std::cout," "));
std::cout<<"\r\n";
std::sort(f3.begin(),f3.end());
std::copy(f3.begin(),f3.end(),std::ostream_iterator<float>(std::cout," "));
std::cout<<"\r\n";
std::copy(f3.rbegin(),f3.rend(),std::ostream_iterator<float>(std::cout," "));
std::cout<<"\r\n";
kimi_boost::array2<float> f6(f3);
std::cout<< (f6==f3) <<"\r\n";
std::cout<< (f6<f3) <<"\r\n";
f6[0][0]=666.666f;
std::cout<< (f6==f3) <<"\r\n";
std::cout<< (f3<f6) <<"\r\n";
vector<int> vi;
vi.assign(10,666);
kimi_boost::array2<int> ai(2,5,vi.begin(),vi.end());
std::copy(ai.begin(),ai.end(),std::ostream_iterator<int>(std::cout," "));
std::cout<<"\r\n";
}
不足之处多多
欢迎拍砖
发表评论
-
The Elements of Programing Style
2009-08-09 18:26 1235把代码写清楚,别耍小聪明。 想干什么,讲的简单点、直接点。 只 ... -
6个变态的C语言Hello World程序
2009-06-01 09:37 807转载自:http://cocre.com/?p=914 下面 ... -
在VS2005中使用IBM Purify的注意事项
2009-05-12 12:24 3929Rational Purify 使用及分析实例可以见这里htt ... -
boost.pool源码整理和使用说明
2007-07-22 13:49 270Source #ifndef __KIMI_BOOST_PO ... -
boost.any源码整理和使用说明
2007-08-24 22:44 1994Source #include <algorithm& ... -
boost.array源码整理和使用说明
2007-08-24 22:45 1217Source #include <cstddef> ... -
boost.BOOST_STATIC_ASSERT源码整理和使用说明
2007-08-24 22:49 1307Source #include <boost/conf ... -
boost.shared_ptr源码整理和使用说明
2007-08-24 22:51 4145Source #pragma once //share ... -
boost.lexical_cast源码整理和使用说明
2007-08-24 22:55 1477Source #include <cstddef> ... -
编译期判断类的继承性
2007-08-24 23:00 1069介绍一个雕虫小技:编译期判断类的继承性。具体来说就是类型U是否 ... -
boost.type_traits源码整理和使用说明(1)
2007-08-28 01:35 2028Introduction The Boost type-tr ... -
泛型快速排序
2007-08-28 03:20 903Source #ifndef kimi_quicksort ... -
C++ Meta Programming 和 Boost MPL(1)
2007-08-30 23:01 1559本系列全部转载自kuibyshev.bokee.com ... -
C++ Meta Programming 和 Boost MPL(2)
2007-08-30 23:02 1485本系列全部转载自kuibyshev.bokee.com ... -
C++ Meta Programming 和 Boost MPL(3)
2007-08-30 23:06 1458本系列全部转载自kuibyshev.bokee.com ... -
C++ Meta Programming 和 Boost MPL(4)
2007-08-30 23:07 1632本系列全部转载自kuibyshev.bokee.com ... -
泛型归并排序
2007-09-18 00:23 1181#define SENTINEL_CARD (-1) # ... -
泛型插入排序
2007-09-18 00:25 1171#pragma once #include <iter ... -
boost.tuple源码整理和使用说明
2007-10-07 23:13 1536Introduction A tuple (or n-tup ... -
才发现VC中也可以检测内存泄漏
2009-03-30 14:54 1339#include <stdio.h> ...
相关推荐
例如,在 C++ 的标准模板库 (STL) 中,std::vector 是一个一维动态数组。 但是,你可以使用这些一维的 Vector 来创建二维数组或更高维度的数据结构。下面我将介绍如何使用一维 Vector(以 C++ 的 std::vector 为例...
21.12 最后一个子序列搜索find_end 301 21.13 本章小结 303 第22章 变易算法 304 22.1 元素复制copy 304 22.2 反向复制copy_backward 305 22.3 元素交换swap 306 22.4 迭代器交换iter_swap 307 22.5 ...
leetcode二维数组搜索算法 JavaScript/TypeScript 的快速算法库。 问题 参加leetcode等在线算法竞赛或编码算法题时,可以选择c++,java,python。 因为他们有像 STL 这样的内置库,包含优先队列、顺序集等。 安装 npm ...
这里说的动态数组是可以根据需要动态增长占用内存的数组,比如程序初始分配了100个元素,可是运行了一段时间后区区100个空间不能满足了,现在需要400个,怎么办呢;那肯定需要再额外分配300个。 C语言有realloc()...
三种动态对象数组的使用和对比(Tlist类、DynamicArray、STL中的vector容器)。
3D-numpy-stl.zip,简单的库,使处理stl文件(和一般的3d对象)快速和容易。,3D建模使用专门的软件来创建物理对象的数字模型。它是3D计算机图形的一个方面,用于视频游戏,3D打印和VR,以及其他应用程序。
ACM专用模板,包括数据结构,图论,字符串,数论,几何计算,KD树,ST表,二叉搜索树,二维ST表(任意矩形,正方形),二维树状数组模板,分块,权值线段树 区间最早出现问题,树状数组模板,线段树模板,线段树扫描...
stl模型数据在三维场景渲染显示stl模型数据在三维场景渲染显示stl模型数据在三维场景渲染显示stl模型数据在三维场景渲染显示stl模型数据在三维场景渲染显示stl模型数据在三维场景渲染显示stl模型数据在三维场景渲染...
将stl三维格式导入MATLAB程序,即可看到三维图像。
用三维CAD软件画了一个轮胎的三维模型,并生成了STL文件,已包含在文件夹中了。当然,你也可以重新画三维模型,替换这个STL文件,同样要显示在本程序中。
三维模型转换器,通过国际标准三维模型文件stl导入,分步骤处理,先对数据导入分层,求轮廓线,求填充线,导出cli欧洲标准3D模型,供快速成型机处理生成模型 此版本不含三维图像动态演示,后面我把增强版本放上去...
现将此版本含三维图像动态演示源码上传,代码里包含一个半球ast模型,由于鼠标和维纳斯头像模型数据较大,无法上传,需要的可联系我softlxf@163.com 使用方法很简单,菜单功能都可以通过下面按钮实现,首先设置好...
cpp代码-C++ STL之vector动态数组
11库,它定义了一个通用的n维数组类,该类能够处理Matlab的mxArray (可变或不可变)和标准C ++分配(静态和动态)。 它旨在提供最少(但有用)的功能,并且可以轻松扩展/构建用于任何类型的应用程序。 文献资料 该...
面向对象方法(STL_analysis)of_Iterator迭代器,这个文档对这进行了详细介绍,供参考!
就是只支持动态数组,对静态和动态数组没有一个统一的非GP的接口,因此我着重于这方 面的改进, [简介] 该组类有以下几个类模板组成 1. template <;typename T, size_t DimNum>; class ...
The tree.hh library for C++ provides an STL-like container class for n-ary trees, templated over the data stored at the nodes. Various types of iterators are provided (post-order, pre-order, and ...
学习STL MAP, STL SET之数据结构基础