[ create a new paste ] login | about

Link: http://codepad.org/enAH4P4O    [ raw code | output | fork ]

C++, pasted on Sep 11:
#ifdef ___POOL___
#define ___POOL___
#include"type.hpp"
#include<vector>
#include<cstdlib>

/*
 * 上限値を定めて値を取り出する
 * 渡された値が上限値以上なら、上限値にまるめる。
 *
 * value	任意の値
 * limit	valueの上限値
 */
inline size_t ClipValue(size_t value,size_t limit)
{
	return value<limit?value:limit;
}

/*
 * 高速伸張配列
 * 値を追加しても無駄にコピーを
 * 行わず比較的高速に伸びる配列
 */
class BinalyPool
{
	typedef Type::narrow Byte;

	typedef std::vector<Byte> Cache;
	Cache cache;
	size_t 
		length,		//この配列全体の長さ
		pool_offset,	//次に書込を開始する位置
		signal;		//状態値(bit Flag)

	enum{Update=1};		//更新を示す(Bit Flag)

	/*
	 *リスト型格納領域
	 */
	struct Buffer
	{
		enum{length=0x100};

		Byte array[length];
		Buffer *next;

	};
	Buffer top,*current;

	/*
	 *書込領域を更新する。
	 *既存の領域があればそれを利用する
	 */
	void NextBuffer(size_t write_length)
	{
		if(Buffer::length>write_length)
		{
			pool_offset+=write_length;

			if(Buffer::length>pool_offset) return;
		}

		if(!current->next)
	       	{
			current->next = new Buffer;
			current->next->next=0;
		}
		current=current->next;
	}
public:
	typedef Byte *iterator;
	typedef const Byte *const_iterator;
	BinalyPool(void):
		signal(0),
		length(0),
		pool_offset(0),
		current(&top)
	{
		top.next=0;
	}
	virtual ~BinalyPool(void)
	{
		FullClear();
	}
	size_t size(void)const
	{
		return length;
	}

	/*
	 * 先頭から書き込めるようにする
	 * 見かけだけの解除だが書込速度が最速になるので
	 * 通常はこちらを使う。
	 */
	BinalyPool &Clear(void)
	{
		signal^=signal&Update;

		length=0;
		pool_offset=0;
		current = &top;
		cache.resize(0);

		return *this;
	}

	/*
	 * 完全に情報を領域ごと削除する。
	 * 格納領域を再度構築するため遅くなる。
	 * 容量的にまずい場合のみ使う
	 */
	BinalyPool &FullClear(void)
	{
		Buffer *i = top.next,*garbage;

		Clear();
		cache=Cache();

		while(i)
		{
			garbage=i;
			i=i->next;
			delete garbage;
		}
		top.next = 0;

		return *this;
	}

	/*
	 * 引数に指定した配列を追記する。
	 *
	 * value_array	配列
	 * length	配列長
	 */
	virtual BinalyPool &Append(const void *value_array,size_t length)
	{
		const Byte *array=static_cast<const Byte*>(value_array);

		signal|=Update;

		//直列バッファへ格納
		if(size()<cache.capacity())
		{
			//空き容量と配列長のうち空き容量を上限に格納する
			size_t
				cache_blank=cache.capacity()-size(),
				write_length=ClipValue(length,cache_blank);

			for(size_t i=0;i<write_length;++i)
			{
				cache.push_back(array[i]);
			}

			length-=write_length;
			array+=write_length;
			this->length=cache.size();
		}

		//
		this->length+=length;

		if(0>=length)return *this;

		//位置を調整してリストバッファに格納
		if(0<pool_offset&&pool_offset<Buffer::length)
		{
			//空き容量と配列長のうち空き容量を上限に格納する
			size_t capacity=ClipValue(length,Buffer::length-pool_offset);

			//前回書き込んだ次の位置から配列を書き込む
			std::memcpy
			(
			 	pool_offset+current->array,
				array,
				capacity
			);

			array+=capacity;
			if(capacity<=length)length-=capacity;
			NextBuffer(capacity);
		}
		
		//Buffer::length以上引数の配列要素がある場合はここで処理する
		while(Buffer::length<=length)
		{
			std::memcpy
			(
			 	current->array,
				array,
				Buffer::length
			);
			
			array+=Buffer::length;
			if(Buffer::length<=length)length-=Buffer::length;
			NextBuffer(Buffer::length);
		}

		//Buffer::lengthで割りきれず最終的に残った配列要素をここで書き込む
		if(0<length)
		{
			std::memcpy
			(
			 	current->array,
				array,
				length
			);
			pool_offset=length;
		}

		return *this;
	}

	/*
	 *
	 *
	 */
	iterator begin(void)
	{
		if(signal)
		{
			size_t length=size()-cache.size();
			const Buffer *buffer=&top;
			
			current = &top;
			cache.reserve(size());

			while(Buffer::length<length)
			{
				for(size_t i=0;Buffer::length>i;++i)
				{
					cache.push_back(buffer->array[i]);
				}
				buffer=buffer->next;
				length-=Buffer::length<length?Buffer::length:0;
			}

			for(size_t i=0;i<length&&buffer;++i)
			{
				cache.push_back(buffer->array[i]);
			}
			pool_offset=0;

			signal^=signal&Update;
		}

		return &cache.front();
	}
	iterator end(void)
	{
		return begin()+size();
	}
	const_iterator begin(void)const
	{
		return begin();
	}
	const_iterator end(void)const
	{
		return end();
	}
};
#endif


Output:
1
2
In function `_start':
undefined reference to `main'


Create a new paste based on this one


Comments: