#include <catch2/catch.hpp>

#include <alib/range>
#include <alib/vector>
#include <alib/list>

TEST_CASE ( "Range", "[unit][std][bits]" ) {
	SECTION ( "Constructor" ) {
		ext::vector < int > v1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

		ext::iterator_range < ext::vector < int >::iterator > rv1 ( v1.begin ( ), v1.end ( ) );

		auto rv2 = ext::range ( v1 );

		CHECK ( ( std::equal ( rv1.begin ( ), rv1.end ( ), rv2.begin ( ), rv2.end ( ) ) ) );
	}

	SECTION ( "Size" ) {
		ext::vector < int > v1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

		ext::iterator_range < ext::vector < int >::iterator > rv1 ( v1.begin ( ), v1.end ( ) );

		CHECK ( rv1.size ( ) == 10 );

		ext::list < int > l1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

		ext::iterator_range < ext::list < int >::iterator > rl1 ( l1.begin ( ), l1.end ( ) );

		CHECK ( rl1.size ( ) == 10 );
	}

	SECTION ( "Split" ) {
		ext::vector < int > v1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

		auto r1 = ext::range ( v1 );

		ext::vector < int > v2 = { 0, 1, 2 };

		auto r2 = ext::range ( v2 );

		ext::vector < int > v3 = { 3, 4, 5, 6, 7, 8, 9 };

		auto r3 = ext::range ( v3 );

		auto splitted = r1.split ( 3 );

		CHECK ( ( std::equal ( splitted.first.begin ( ), splitted.first.end ( ), r2.begin ( ), r2.end ( ) ) ) );
		CHECK ( ( std::equal ( splitted.second.begin ( ), splitted.second.end ( ), r3.begin ( ), r3.end ( ) ) ) );
	}

	SECTION ( "Slice" ) {
		ext::vector < int > v1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

		auto r1 = ext::range ( v1 );

		ext::vector < int > v2 = { 4, 5, 6 };

		auto r2 = ext::range ( v2 );

		auto sliced = r1.slice ( 4, -3 );

		CHECK ( ( std::equal ( sliced.begin ( ), sliced.end ( ), r2.begin ( ), r2.end ( ) ) ) );
	}
}
