boost.multi_array学习-子视图用法(3)

//made by davidsu33
//2014-9-14 11:51

#include "stdafx.h"
#include 
#include 
#include 

#include 
#include 

#include 

#include 
#include 
#include 

#include 
#include 
#include 
#include 

using namespace std;

typedef boost::fast_pool_allocator FastPoolAllocator;
typedef boost::multi_array Multi3Array;

void mult_array_access(Multi3Array &mult3);
void show_dims(Multi3Array& mult3);
void sub_view(Multi3Array &mult3);

template
bool check_ptr(T& v1, T& v2);

void test_multi_array()
{
	//using namespace boost;

	//还可以设置维度的存储顺序
	//Multi3Array mult3Array(boost::multi_array_types::extent_gen::extents()[3][4][5]);
	//Multi3Array mult3Array(boost::extents[3][4][5]); //Right Usage

	//为什么不能直接写
	boost::detail::multi_array::extent_gen<3> extentgen3 = boost::detail::multi_array::extent_gen<0>()[3][4][5];
	//Multi3Array mult3Array(extentgen3); //Right Usage

	//???
	//因为操作符顺序的关系不能写成,因为()的操作符顺序高,所以导致
	//boost::detail::multi_array::extent_gen<0>()[..],[..]没有先解析
	//Multi3Array mult3Array(boost::detail::multi_array::extent_gen<0>()[3][4][5]); //Error Usage

	Multi3Array mult3Array((boost::detail::multi_array::extent_gen<0>()[3][4][5])); //Right Usage

	int nDims = mult3Array.num_dimensions();

	assert((mult3Array.num_dimensions() == 3));
	assert((mult3Array.num_elements() == 3*4*5));

	int sz = mult3Array.size();

	//可以通过ListExtend来扩展
	boost::array dimArray = {3, 4, 5};
	Multi3Array mutl3Array2(dimArray);

	assert(mutl3Array2.num_elements() == mult3Array.num_elements());
	mult_array_access(mult3Array);
	show_dims(mult3Array);
	sub_view(mult3Array);
}

void mult_array_access(Multi3Array &mult3)
{
	boost::array idx = {0, 0, 0};
	assert(mult3[0][0][0] == mult3(idx));

	mult3[0][0][0] = 100;
	assert(mult3(idx) == 100);

	int i=0;
	double *pData = mult3.data();
	std::for_each(pData, pData+mult3.num_elements(), boost::lambda::_1 = boost::lambda::var(i)++);

	i=0; //reset i=0;
	boost::array idx3;
	assert(mult3[0][0][0] == 0);
	for (int x=0; x<3; ++x)
	{
		for (int y=0; y<4; ++y)
		{
			for(int z=0; z<5; ++z)
			{
				idx3 = boost::assign::list_of(x)(y)(z);
				assert(mult3(idx3) == i++);
			}
		}
	}

	cout<<"test passed"<::type ArrayView##x;
	
	SUB_ARRAYVIEW(3);
	SUB_ARRAYVIEW(2);
	SUB_ARRAYVIEW(1);

	//IndexRange的三种写法
	typedef Multi3Array::index_range IndexRange;
	typedef boost::multi_array_types::index_range IndexRangeType;
	typedef boost::detail::multi_array::index_range IndexRangeType2;

	//bool isOK = MIsSame::value;
	MSTATIC_ASSERT_MARCO((MIsSame::value));
	//MSTATIC_ASSERT_MARCO((MIsSame::value)); //编译不过
	MSTATIC_ASSERT_MARCO((MIsSame::value));
	//MSTATIC_ASSERT_MARCO((MIsSame::value)); //编译不过

	typedef Multi3Array::size_type MSizeType;
	vector v(mult3.num_dimensions(), 0);
	copy(mult3.shape(), mult3.shape()+mult3.num_dimensions(), v.begin());
	copy(v.begin(), v.end(), std::ostream_iterator(cout, ";"));
	cout<(std::cout));
	cout<(std::cout));
	cout< idx3 = {0, 0, 0};
	boost::array idx32 = {0, 1, 3};
	aview3(idx3) = 10;
	assert(mult3(idx32) == 10);
	mult3(idx32) = 1000;
	assert(aview3(idx3) == 1000);

	//获取2D视图,相当于第一位的索引始终是0
	ArrayView2 aview21 = mult3[boost::indices[0][IndexRange(1,2)][IndexRange(3, 5)]];
	ArrayView2 aview22 = mult3[boost::indices[1][IndexRange(1,2)][IndexRange(3, 5)]];
	ArrayView2 aview23 = mult3[boost::indices[2][IndexRange(1,2)][IndexRange(3, 5)]];

	assert(2 == aview21.num_dimensions());
	assert(2 == aview22.num_dimensions());
	assert(2 == aview23.num_dimensions());

	//2 == 2 is bool
	//2 == (true/false)导致错误
	//assert(2 == 2 == 2 == 2); //must be false

	int xoffset = 1, yoffset = 3;
	boost::array idx2 = {0, 0};
	boost::array idx21 = {0, 0+xoffset, 0+yoffset};
	boost::array idx22 = {1, 0+xoffset, 0+yoffset};
	boost::array idx23 = {2, 0+xoffset, 0+yoffset};
	
	check_ptr(aview21(idx2), mult3(idx21));
	check_ptr(aview22(idx2), mult3(idx22));
	check_ptr(aview23(idx2), mult3(idx23));

	cout<<"sub-view test all passed"<
bool check_ptr(T& v1, T& v2)
{
	assert(v1 == v2);
	return (&v1 == &v2);
}

//multi_array_ref的用法
//可以和一维数组进行相互转换使用
//具备multi_array的大部分功能,除了resize
//multi_array是从multi_array_ref派生过来
void multi_array_ref_usage()
{
	boost::array dArray;
	for (unsigned i=0; i MultiArray3DimsRef;
	typedef MultiArray3DimsRef::size_type MDimRefSizeType;
	typedef boost::array BArray3;

	MultiArray3DimsRef ref(&dArray[0], boost::multi_array_types::extent_gen()[2][3][4]);
	MultiArray3DimsRef ref2(&dArray[0], boost::extents[2][3][4]);

	BArray3 bArray3 = {2, 3, 4};
	MultiArray3DimsRef ref3(&dArray[0], bArray3);

	assert(ref[0][0][0] == 1);
	assert(ref2[0][0][0] == 1);
	assert(ref3[0][0][0] == 1);

	typedef boost::array BArray2;
	BArray3 idx = {0, 0, 0};

	ref(idx) = 100;
	assert(ref2(idx) == 100);
	assert(ref3(idx) == 100);

	//sub-view
	typedef boost::multi_array_types::index_range IndexRange;
	BOOST_AUTO(subview1 ,ref[boost::indices[0][IndexRange(2,3)][IndexRange(2,4)]]);
	MultiArray3DimsRef::array_view<2>::type subview2 = ref[boost::indices[0][IndexRange(2,3)][IndexRange(2,4)]];
	assert(subview2 == subview1);

	assert(subview1[0][0] == ref[0][2][2]);
	cout<<"multi_array_ref test all passed!"<> MultiArrayFastAlloc;
	typedef MultiArrayFastAlloc::extent_range Range;
	typedef boost::multi_array_types::extent_range MRange;
	typedef MultiArrayFastAlloc::size_type MArraySizeType;

	//extents[extent_range | const_int]
	//extent_range可以设置变基址
	//const_int可以指定索引范围大小,索引从0开始

	MultiArrayFastAlloc mafa(boost::extents[MRange(1,5)][4][MRange(-3, 6)]);
	mafa[1][0][-3] = 100; //变索引

	boost::array idx = {1, 0, -3};
	assert(mafa(idx) == 100);

	const MArraySizeType *shapeList = mafa.shape();
	const MArraySizeType extens[3] = {(5-1), 4, (6-(-3))};

	assert(std::equal(shapeList, shapeList+nDim, extens));

	typedef boost::multi_array_types::index Index;
	const  Index*bases = mafa.index_bases();
	boost::array aindex = {1, 0, -3};
	assert(std::equal(bases, bases+mafa.num_dimensions(), &aindex[0]));
}

//灵活的子视图,可以通过逻辑表达式来控制范围
void flexible_sub_view()
{
	const unsigned nDims = 3;
	typedef boost::multi_array MultiArray3Dims;
	MultiArray3Dims ma(boost::multi_array_types::extent_gen::extents()[7][8][9]);
	typedef boost::multi_array_types::index_range IndexRange;

	BOOST_AUTO(indice, boost::indices[IndexRange()<4][2<=IndexRange()<=6][3::type sb2 = ma[indice];
	assert(sb2 == subview);

	const boost::multi_array_types::index * bases = sb2.index_bases();
	boost::array a3 = {0, 2, 4};
	std::equal(bases, bases+sb2.num_dimensions(), &a3[0]);
}

int _tmain(int argc, _TCHAR* argv[])
{
	test_multi_array();  
	multi_array_ref_usage();
	reIndex_multi_array();
	flexible_sub_view();

	getchar();
	return 0;
}

你可能感兴趣的:(boost)