/// 組み込み関数を片っ端から関数オブジェクト化

#ifndef __BUILTINFUNCS_H__
#define __BUILTINFUNCS_H__

#include <functional>

template <class _New>
class New {
public:
    _New* operator () () {
	return new _New;
    }
};

/// NewCopy
/**
 * NewCopy は第二テンプレート引数として、
 * コンストラクタの引数をとる。
 * この第二テンプレート引数がポインタの時は
 * *from を使ってコンストラクタを呼び出す。
 * また VC などのテンプレート特別バージョンを
 * サポートしていないコンパイラでは、
 * NewCopyPtr がこの役目を果たす。
 */
template <class _New, class _From>
class NewCopy : public std::unary_function<_From, _New*> {
public:
    _New* operator () (const _From& from) {
	return new _New(from);
    }
};

// VC などテンプレート特別バージョンをサポートしてない
// コンパイラだと動きません
#ifndef __DONT_HAVE_TEMP_CLASS_SPEC__
template <class _New, class _From>
class NewCopy<_New, _From*> :
    public std::unary_function<_From*, _New*> {
public:
    _New* operator () (const _From* from) {
	return new _New(*from);
    }
};
#else
template <class _New, class _From =_New*>
class NewCopyFromPtr :
    public std::unary_function<_From, _New*> {
public:
    _New* operator () (const _From from) {
	return new _New(*from);
    }
};
#endif // ! __TEMP_CLASS_SPEC__

template <class _Target>
class Delete : public std::unary_function<_Target, void> {
public:
    void operator () (_Target*& target) {
		delete target;
		target = 0;
    }
};

template <class _Casted, class _From>
class DynamicCast : public std::unary_function<_From, _Casted> {
public:
    _Casted operator () (_From from) {
	return dynamic_cast<_Casted>(from);
    }
};

template <class _Casted, class _From>
class StaticCast : public std::unary_function<_From, _Casted> {
public:
    _Casted operator () (_From from) {
	return static_cast<_Casted>(from);
    }
};

template <class _Casted, class _From>
class ReinterpretCast : public std::unary_function<_From, _Casted> {
public:
    _Casted operator () (_From from) {
	return reinterpret_cast<_Casted>(from);
    }
};

template <class _Casted, class _From>
class ConstCast : public std::unary_function<_From, _Casted> {
public:
    _Casted operator () (_From from) {
	return const_cast<_Casted>(from);
    }
};

#include <algorithm>

/// STL コンパチなコンテナの内容を全て解放し、空にする
template <class _Container>
void deleteClear(_Container& cont) {
    for (typename _Container::iterator ite = cont.begin();
	 ite != cont.end(); ite++) {
	delete *ite;
    }
    cont.clear();
}

/// 関数オブジェクト版
template <class _Container>
class DeleteClear : public std::unary_function<_Container, void> {
public:
    void operator () (_Container& cont) {
	deleteClear(cont);
    }
};

#endif // ! __BUILTINFUNCS_H__

