#include <psemek/test/test.hpp>

#include <psemek/sir/memory.hpp>

#include <algorithm>
#include <vector>
#include <set>
#include <map>

using namespace psemek;

namespace
{

	template <typename C1, typename C2>
	void read_write(C1 const & c1, C2 & c2)
	{
		using std::size;

		char buffer[1024];

		{
			io::memory_ostream s{buffer, buffer + size(buffer)};
			sir::ostream os{s};
			write(os, c1);
		}

		{
			io::memory_istream s{buffer, buffer + size(buffer)};
			sir::memory_istream is{s};
			read(is, c2);
		}
	}

}

test_case(sir_memory_vector)
{
	std::vector<std::uint32_t> c1{ 15, 16, 18, 2, 65535, 14, 5, 8, 42, 555, 18, 729, 76 };
	sir::vector<std::uint32_t> c2;

	read_write(c1, c2);

	expect_equal(c1.size(), c2.size());

	for (std::size_t i = 0; i < c1.size(); ++i)
		expect_equal(c1[i], c2[i]);
}

test_case(sir_memory_set)
{
	std::set<std::uint32_t> c1{ 15, 16, 18, 2, 65535, 14, 5, 8, 42, 555, 18, 729, 76 };
	sir::set<std::uint32_t> c2;

	read_write(c1, c2);

	expect_equal(c1.size(), c2.size());
	expect(std::is_sorted(c2.begin(), c2.end()));

	auto i1 = c1.begin();
	auto i2 = c2.begin();

	for (; i1 != c1.end(); ++i1, ++i2)
		expect_equal(*i1, *i2);
}

test_case(sir_memory_map)
{
	std::map<std::uint32_t, float> c1 { {10, 3.1415f}, {15, 6.7123f}, {1, -24.444f} };
	sir::map<std::uint32_t, float> c2;

	read_write(c1, c2);

	expect_equal(c1.size(), c2.size());

	auto i1 = c1.begin();
	auto i2 = c2.begin();

	for (; i1 != c1.end(); ++i1, ++i2)
	{
		expect_equal(i1->first, i2->first);
		expect_equal(i1->second, i2->second);
	}
}
