/*-------------------------------------------------------------------------
 * drawElements Quality Program Tester Core
 * ----------------------------------------
 *
 * Copyright 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Template class that is either type of Left or Right.
 *//*--------------------------------------------------------------------*/

#include "tcuEither.hpp"

namespace tcu
{
namespace
{

enum
{
	COPYCHECK_VALUE = 1637423219
};

class TestClassWithConstructor
{
public:
	TestClassWithConstructor (int i)
		: m_i			(i)
		, m_copyCheck	(COPYCHECK_VALUE)
	{
	}

	~TestClassWithConstructor (void)
	{
		TCU_CHECK(m_copyCheck == COPYCHECK_VALUE);
	}

	TestClassWithConstructor (const TestClassWithConstructor& other)
		: m_i			(other.m_i)
		, m_copyCheck	(other.m_copyCheck)
	{
	}

	TestClassWithConstructor& operator= (const TestClassWithConstructor& other)
	{
		TCU_CHECK(m_copyCheck == COPYCHECK_VALUE);

		if (this == &other)
			return *this;

		m_i = other.m_i;
		m_copyCheck = other.m_copyCheck;

		TCU_CHECK(m_copyCheck == COPYCHECK_VALUE);

		return *this;
	}

	int getValue (void) const
	{
		TCU_CHECK(m_copyCheck == COPYCHECK_VALUE);

		return m_i;
	}

private:
	int m_i;
	int m_copyCheck;
};

} // anonymous

void Either_selfTest (void)
{
	// Simple test for first
	{
		const int					intValue	= 1503457782;
		const Either<int, float>	either		(intValue);

		TCU_CHECK(either.isFirst());
		TCU_CHECK(!either.isSecond());

		TCU_CHECK(either.is<int>());
		TCU_CHECK(!either.is<float>());

		TCU_CHECK(either.getFirst() == intValue);
		TCU_CHECK(either.get<int>() == intValue);
	}

	// Simple test for second
	{
		const float					floatValue	= 0.43223332995f;
		const Either<int, float>	either		(floatValue);

		TCU_CHECK(!either.isFirst());
		TCU_CHECK(either.isSecond());

		TCU_CHECK(!either.is<int>());
		TCU_CHECK(either.is<float>());

		TCU_CHECK(either.getSecond() == floatValue);
		TCU_CHECK(either.get<float>() == floatValue);
	}

	// Assign first value
	{
		const int			intValue	= 1942092699;
		const float			floatValue	= 0.43223332995f;
		Either<int, float>	either		(floatValue);

		either = intValue;

		TCU_CHECK(either.isFirst());
		TCU_CHECK(!either.isSecond());

		TCU_CHECK(either.is<int>());
		TCU_CHECK(!either.is<float>());

		TCU_CHECK(either.getFirst() == intValue);
		TCU_CHECK(either.get<int>() == intValue);
	}

	// Assign second value
	{
		const int			intValue	= 1942092699;
		const float			floatValue	= 0.43223332995f;
		Either<int, float>	either		(intValue);

		either = floatValue;

		TCU_CHECK(!either.isFirst());
		TCU_CHECK(either.isSecond());

		TCU_CHECK(!either.is<int>());
		TCU_CHECK(either.is<float>());

		TCU_CHECK(either.getSecond() == floatValue);
		TCU_CHECK(either.get<float>() == floatValue);
	}

	// Assign first either value
	{
		const int					intValue	= 1942092699;
		const float					floatValue	= 0.43223332995f;
		Either<int, float>			either		(floatValue);
		const Either<int, float>	otherEither	(intValue);

		either = otherEither;

		TCU_CHECK(either.isFirst());
		TCU_CHECK(!either.isSecond());

		TCU_CHECK(either.is<int>());
		TCU_CHECK(!either.is<float>());

		TCU_CHECK(either.getFirst() == intValue);
		TCU_CHECK(either.get<int>() == intValue);
	}

	// Assign second either value
	{
		const int					intValue	= 1942092699;
		const float					floatValue	= 0.43223332995f;
		Either<int, float>			either		(intValue);
		const Either<int, float>	otherEither	(floatValue);

		either = otherEither;

		TCU_CHECK(!either.isFirst());
		TCU_CHECK(either.isSecond());

		TCU_CHECK(!either.is<int>());
		TCU_CHECK(either.is<float>());

		TCU_CHECK(either.getSecond() == floatValue);
		TCU_CHECK(either.get<float>() == floatValue);
	}

	// Simple test for first with constructor
	{
		const TestClassWithConstructor				testObject	(171899615);
		const Either<TestClassWithConstructor, int>	either		(testObject);

		TCU_CHECK(either.isFirst());
		TCU_CHECK(!either.isSecond());

		TCU_CHECK(either.is<TestClassWithConstructor>());
		TCU_CHECK(!either.is<int>());

		TCU_CHECK(either.getFirst().getValue() == testObject.getValue());
		TCU_CHECK(either.get<TestClassWithConstructor>().getValue() == testObject.getValue());
	}

	// Simple test for second with constructor
	{
		const TestClassWithConstructor				testObject	(171899615);
		const Either<int, TestClassWithConstructor>	either		(testObject);

		TCU_CHECK(!either.isFirst());
		TCU_CHECK(either.isSecond());

		TCU_CHECK(either.is<TestClassWithConstructor>());
		TCU_CHECK(!either.is<int>());

		TCU_CHECK(either.getSecond().getValue() == testObject.getValue());
		TCU_CHECK(either.get<TestClassWithConstructor>().getValue() == testObject.getValue());
	}

	// Assign first with constructor
	{
		const int								intValue	= 1942092699;
		const TestClassWithConstructor			testObject	(171899615);
		Either<TestClassWithConstructor, int>	either		(intValue);

		either = testObject;

		TCU_CHECK(either.isFirst());
		TCU_CHECK(!either.isSecond());

		TCU_CHECK(either.is<TestClassWithConstructor>());
		TCU_CHECK(!either.is<int>());

		TCU_CHECK(either.getFirst().getValue() == testObject.getValue());
		TCU_CHECK(either.get<TestClassWithConstructor>().getValue() == testObject.getValue());
	}

	// Assign second with constructor
	{
		const int								intValue	= 1942092699;
		const TestClassWithConstructor			testObject	(171899615);
		Either<int, TestClassWithConstructor>	either		(intValue);

		either = testObject;

		TCU_CHECK(!either.isFirst());
		TCU_CHECK(either.isSecond());

		TCU_CHECK(either.is<TestClassWithConstructor>());
		TCU_CHECK(!either.is<int>());

		TCU_CHECK(either.getSecond().getValue() == testObject.getValue());
		TCU_CHECK(either.get<TestClassWithConstructor>().getValue() == testObject.getValue());
	}

	// Assign first either with constructor
	{
		const int									intValue	= 1942092699;
		const TestClassWithConstructor				testObject	(171899615);
		Either<TestClassWithConstructor, int>		either		(intValue);
		const Either<TestClassWithConstructor, int>	otherEither	(testObject);

		either = otherEither;

		TCU_CHECK(either.isFirst());
		TCU_CHECK(!either.isSecond());

		TCU_CHECK(either.is<TestClassWithConstructor>());
		TCU_CHECK(!either.is<int>());

		TCU_CHECK(either.getFirst().getValue() == testObject.getValue());
		TCU_CHECK(either.get<TestClassWithConstructor>().getValue() == testObject.getValue());
	}

	// Assign second either with constructor
	{
		const int									intValue	= 1942092699;
		const TestClassWithConstructor				testObject	(171899615);
		Either<int, TestClassWithConstructor>		either		(intValue);
		const Either<int, TestClassWithConstructor>	otherEither	(testObject);

		either = otherEither;

		TCU_CHECK(!either.isFirst());
		TCU_CHECK(either.isSecond());

		TCU_CHECK(either.is<TestClassWithConstructor>());
		TCU_CHECK(!either.is<int>());

		TCU_CHECK(either.getSecond().getValue() == testObject.getValue());
		TCU_CHECK(either.get<TestClassWithConstructor>().getValue() == testObject.getValue());
	}
}

} // tcu
