/*

oess_1: Object Entity Serialization & Stability
Yauheni A. Akhotnikau (C) 2002-2006
eao197@yahoo.com
-------------------------------------------------

Permission is granted to anyone to use this software for any purpose on any
computer system, and to redistribute it freely, subject to the following
restrictions:

1. This software is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

2. The origin of this software must not be misrepresented, either by
   explicit claim or by omission.

3. Altered versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

-------------------------------------------------

*/

/*
 * Проверка корректности сохранения контейнеров с объектом, который
 * поддерживает ручную сериализацию, в двоичном потоке.
 */

#undef NDEBUG

#include <string>
#include <cassert>

#include <oess_1/io/h/mem_buf.hpp>

#include <oess_1/io/custom/stl/h/list.hpp>
#include <oess_1/io/custom/stl/h/vector.hpp>
#include <oess_1/io/custom/stl/h/deque.hpp>
#include <oess_1/io/custom/stl/h/set.hpp>
#include <oess_1/io/custom/stl/h/map.hpp>

template< class C >
void
pack_and_unpack_container( const C & from, C & to )
	{
		oess_1::io::mem_buf_t b;
		b << from;
		b.set_pos( 0 );
		b >> to;
	}

void
test_list()
	{
		typedef std::list< oess_1::int_t > list_t;

		{
			list_t empty_list_from, to;
			pack_and_unpack_container( empty_list_from, to );

			assert( empty_list_from == to );
		}

		{
			list_t full_list_from, to;
			full_list_from.push_back( 4 );
			full_list_from.push_back( 3 );
			full_list_from.push_back( 1 );
			full_list_from.push_back( 7 );
			pack_and_unpack_container( full_list_from, to );

			assert( full_list_from == to );
		}
	}

void
test_vector()
	{
		typedef std::vector< oess_1::int_t > vector_t;

		{
			vector_t empty_vector_from, to;
			pack_and_unpack_container( empty_vector_from, to );

			assert( empty_vector_from == to );
		}

		{
			vector_t full_vector_from, to;
			full_vector_from.push_back( 4 );
			full_vector_from.push_back( 3 );
			full_vector_from.push_back( 1 );
			full_vector_from.push_back( 7 );
			pack_and_unpack_container( full_vector_from, to );

			assert( full_vector_from == to );
		}
	}

void
test_deque()
	{
		typedef std::deque< oess_1::int_t > deque_t;

		{
			deque_t empty_deque_from, to;
			pack_and_unpack_container( empty_deque_from, to );

			assert( empty_deque_from == to );
		}

		{
			deque_t full_deque_from, to;
			full_deque_from.push_back( 4 );
			full_deque_from.push_back( 3 );
			full_deque_from.push_back( 1 );
			full_deque_from.push_back( 7 );
			pack_and_unpack_container( full_deque_from, to );

			assert( full_deque_from == to );
		}
	}

void
test_set()
	{
		typedef std::set< oess_1::int_t > set_t;

		{
			set_t empty_set_from, to;
			pack_and_unpack_container( empty_set_from, to );

			assert( empty_set_from == to );
		}

		{
			set_t full_set_from, to;
			full_set_from.insert( 4 );
			full_set_from.insert( 3 );
			full_set_from.insert( 1 );
			full_set_from.insert( 7 );
			pack_and_unpack_container( full_set_from, to );

			assert( full_set_from == to );
		}
	}

void
test_multiset()
	{
		typedef std::multiset< oess_1::int_t > multiset_t;

		{
			multiset_t empty_multiset_from, to;
			pack_and_unpack_container( empty_multiset_from, to );

			assert( empty_multiset_from == to );
		}

		{
			multiset_t full_multiset_from, to;
			full_multiset_from.insert( 4 );
			full_multiset_from.insert( 3 );
			full_multiset_from.insert( 1 );
			full_multiset_from.insert( 7 );
			full_multiset_from.insert( 3 );
			full_multiset_from.insert( 7 );
			pack_and_unpack_container( full_multiset_from, to );

			assert( full_multiset_from == to );
		}
	}

void
test_map()
	{
		typedef std::map< std::string, oess_1::int_t > map_t;

		{
			map_t empty_map_from, to;
			pack_and_unpack_container( empty_map_from, to );

			assert( empty_map_from == to );
		}

		{
			map_t full_map_from, to;
			full_map_from.insert( map_t::value_type( "forth", 4 ) );
			full_map_from.insert( map_t::value_type( "third", 3 ) );
			full_map_from.insert( map_t::value_type( "first", 1 ) );
			full_map_from.insert( map_t::value_type( "seventh", 7 ) );
			pack_and_unpack_container( full_map_from, to );

			assert( full_map_from == to );
		}
	}

void
test_multimap()
	{
		typedef std::multimap< std::string, oess_1::int_t > multimap_t;

		{
			multimap_t empty_multimap_from, to;
			pack_and_unpack_container( empty_multimap_from, to );

			assert( empty_multimap_from == to );
		}

		{
			multimap_t full_multimap_from, to;
			full_multimap_from.insert( multimap_t::value_type( "forth", 4 ) );
			full_multimap_from.insert( multimap_t::value_type( "third", 3 ) );
			full_multimap_from.insert( multimap_t::value_type( "first", 1 ) );
			full_multimap_from.insert( multimap_t::value_type( "forth", 5 ) );
			full_multimap_from.insert( multimap_t::value_type( "seventh", 7 ) );
			full_multimap_from.insert( multimap_t::value_type( "third", 2 ) );
			pack_and_unpack_container( full_multimap_from, to );

			assert( full_multimap_from == to );
		}
	}

int
main()
	{
		test_list();
		test_vector();
		test_deque();
		test_set();
		test_multiset();
		test_map();
		test_multimap();
	}

