#include <builtinfuncs.h>

#include <algorithm>
#include <functional>
#include <vector>
#include <cassert>

/// delete された回数を数える int ラッパ
class DeleteCountInt {
public:
    DeleteCountInt(int val) : _val(val) {}
    operator int () { return _val; }
    ~DeleteCountInt() { i++; }
    int _val;
    static int i;
};
int DeleteCountInt::i = 0;

int main() {
    // New and Delete
    {
	std::vector<int*> ints;
	std::vector<DeleteCountInt*> dcis;

	ints.resize(2);
	std::generate(ints.begin(), ints.end(), New<int>());
	deleteClear(ints);

	ints.push_back(new int(1));
	ints.push_back(new int(2));

	std::transform(ints.begin(), ints.end(), std::back_inserter(dcis),
		       NewCopy<DeleteCountInt, int*>());

	assert(1 == *dcis.front());
	assert(2 == *dcis.back());

	deleteClear(ints);

	std::for_each(dcis.begin(), dcis.end(), Delete<DeleteCountInt>());
	assert(DeleteCountInt::i == 2);
	// delete した後 0 をセットしているので OK
	std::for_each(dcis.begin(), dcis.end(), Delete<DeleteCountInt>());
	assert(DeleteCountInt::i == 2);
    }

    // Casts
    {
	std::vector<const int*> cints;
	std::vector<int*> ints;

	cints.push_back(new int(1));
	cints.push_back(new int(2));

	std::transform(cints.begin(), cints.end(), std::back_inserter(ints),
		       ConstCast<int*, const int*>());

	deleteClear(ints);
    }

    return 0;
}

