Newer
Older
snipet / libscpp / trunk / src / scpp_assert.cpp
/* =============================================================================
 *  scpp_assert.cpp
 *  Copyright (c)  2003 - 2011  Nomura Kei
 *  LICENSE :
 *  LGPL (GNU Lesser General General Public License - Version 3,29 June 2007)
 *  http://www.gnu.org/copyleft/lesser.html
 * =============================================================================
 *
 * アサーションモジュール.
 * アサーション関数が失敗するとき, AssertError を throw します.
 */
#include <iostream>
#include <sstream>
#include <string>

#include <scpp_assert.hpp>
#undef assertEquals
#undef assertTrue
#undef assertFalse
#undef assertNull
#undef assertNotNull
#undef fail


namespace scpp
{


////////////////////////////////////////////////////////////////////////////////
//
// Error
//

/**
 * 最後に発生した errno に対応するメッセージをもつ Exception を構築します.
 * エラーメッセージを取得できない場合, 空文字がメッセージに設定されます.
 */
AssertError::AssertError() throw()
	: Error(), fileName("Unknown"), lineNumber(0), functionName("Unknown")
{
	// NOP
}


/**
 * コピーコンストラクタ.
 *
 * @param t コピー元
 */
AssertError::AssertError(const AssertError& t) throw()
	: Error(t), fileName(t.fileName), lineNumber(t.lineNumber), functionName(t.functionName)
{
	// NOP
}


/**
 * 指定されたメッセージを持つ Exception を構築します.
 *
 * @param msg メッセージ
 */
AssertError::AssertError(const std::string& msg) throw()
	: Error(msg), fileName("Unknown"), lineNumber(0), functionName("Unknown")
{
	// NOP
}


/**
 * 指定されたメッセージを持つ Exception を構築します.
 *
 * @param msg メッセージ
 * @param file AssertError 発生ソースファイル名
 * @param line AssertError 発生ソース行番号
 * @param func AssertError 発生関数名
 */
AssertError::AssertError(const std::string& msg, const char* file, int line, const char* func) throw()
	: Error(msg), fileName(file), lineNumber(line), functionName(func)
{
	// NOP
}


/**
 * デストラクタ.
 */
AssertError::~AssertError() throw()
{
	// NOP
}


/**
 * AssertError が throw されたファイル名を取得します.
 *
 * @return ファイル名
 */
const std::string& AssertError::getFileName() const throw()
{
	return fileName;
}


/**
 * AssertError が throw された行番号を取得します.
 *
 * @return 行番号
 */
int AssertError::getLineNumber() const throw()
{
	return lineNumber;
}


/**
 * AssertError が throw された関数名を取得します.
 *
 * @return 関数名
 */
const std::string& AssertError::getFunctionName() const throw()
{
	return functionName;
}




namespace Assertion
{


/**
 * bool 型の値比較.
 * 通常, 本メソッドを直接使用せず, assertEquals(expected, actual) マクロを使用してください.
 * 指定された excepted と actual が同じか否かを判定し, 不一致の場合 AssertError を throw します.
 *
 * @param expected 比較対象1
 * @param actual   比較対象2
 * @param file     ファイル
 * @param line     行番号
 * @param func     関数
 */
void assertEquals(bool expected, bool actual, const char* file, int line, const char* func) throw(AssertError)
{
	if (expected != actual)
	{
		if (expected)
		{
			throw AssertError("expected:<true> but was:<false>", file, line, func);
		}
		else
		{
			throw AssertError("expected:<true> but was:<false>", file, line, func);
		}
	}
}


/**
 * char 型の値比較.
 * 通常, 本メソッドを直接使用せず, assertEquals(expected, actual) マクロを使用してください.
 * 指定された excepted と actual が同じか否かを判定し, 不一致の場合 AssertError を throw します.
 *
 * @param expected 比較対象1
 * @param actual   比較対象2
 * @param file     ファイル
 * @param line     行番号
 * @param func     関数
 */
void assertEquals(char expected, char actual, const char* file, int line, const char* func) throw(AssertError)
{
	if (expected != actual)
	{
		std::ostringstream msg;
		msg << "expected <" << expected << "> but was:<" << actual << ">";
		throw AssertError(msg.str(), file, line, func);
	}
}


/**
 * double 型の値比較.
 * 通常, 本メソッドを直接使用せず, assertEquals(expected, actual) マクロを使用してください.
 * 指定された excepted と actual が同じか否かを判定し, 不一致の場合 AssertError を throw します.
 *
 * @param expected 比較対象1
 * @param actual   比較対象2
 * @param file     ファイル
 * @param line     行番号
 * @param func     関数
 */
void assertEquals(double expected, double actual, const char* file, int line, const char* func) throw(AssertError)
{
	if (expected != actual)
	{
		std::ostringstream msg;
		msg << "expected <" << expected << "> but was:<" << actual << ">";
		throw AssertError(msg.str(), file, line, func);
	}
}


/**
 * float 型の値比較.
 * 通常, 本メソッドを直接使用せず, assertEquals(expected, actual) マクロを使用してください.
 * 指定された excepted と actual が同じか否かを判定し, 不一致の場合 AssertError を throw します.
 *
 * @param expected 比較対象1
 * @param actual   比較対象2
 * @param file     ファイル
 * @param line     行番号
 * @param func     関数
 */
void assertEquals(float expected, float actual, const char* file, int line, const char* func) throw(AssertError)
{
	if (expected != actual)
	{
		std::ostringstream msg;
		msg << "expected <" << expected << "> but was:<" << actual << ">";
		throw AssertError(msg.str(), file, line, func);
	}
}


/**
 * int 型の値比較.
 * 通常, 本メソッドを直接使用せず, assertEquals(expected, actual) マクロを使用してください.
 * 指定された excepted と actual が同じか否かを判定し, 不一致の場合 AssertError を throw します.
 *
 * @param expected 比較対象1
 * @param actual   比較対象2
 * @param file     ファイル
 * @param line     行番号
 * @param func     関数
 */
void assertEquals(int expected, int actual, const char* file, int line, const char* func) throw(AssertError)
{
	if (expected != actual)
	{
		std::ostringstream msg;
		msg << "expected <" << expected << "> but was:<" << actual << ">";
		throw AssertError(msg.str(), file, line, func);
	}
}



/**
 * long 型の値比較.
 * 通常, 本メソッドを直接使用せず, assertEquals(expected, actual) マクロを使用してください.
 * 指定された excepted と actual が同じか否かを判定し, 不一致の場合 AssertError を throw します.
 *
 * @param expected 比較対象1
 * @param actual   比較対象2
 * @param file     ファイル
 * @param line     行番号
 * @param func     関数
 */
void assertEquals(long expected, long actual, const char* file, int line, const char* func) throw(AssertError)
{
	if (expected != actual)
	{
		std::ostringstream msg;
		msg << "expected <" << expected << "> but was:<" << actual << ">";
		throw AssertError(msg.str(), file, line, func);
	}
}


/**
 * 文字列 (string) 型の値比較.
 * 通常, 本メソッドを直接使用せず, assertEquals(expected, actual) マクロを使用してください.
 * 指定された excepted と actual が同じか否かを判定し, 不一致の場合 AssertError を throw します.
 *
 * @param expected 比較対象1
 * @param actual   比較対象2
 * @param file     ファイル
 * @param line     行番号
 * @param func     関数
 */
void assertEquals(const std::string& expected, const std::string& actual, const char* file, int line, const char* func) throw(AssertError)
{
	if (expected != actual)
	{
		std::ostringstream msg;
		msg << "expected <" << expected << "> but was:<" << actual << ">";
		throw AssertError(msg.str(), file, line, func);
	}
}


/**
 * 文字列型 (const char*) の値比較.
 * 通常, 本メソッドを直接使用せず, assertEquals(expected, actual) マクロを使用してください.
 * 指定された excepted と actual が同じか否かを判定し, 不一致の場合 AssertError を throw します.
 *
 * @param expected 比較対象1
 * @param actual   比較対象2
 * @param file     ファイル
 * @param line     行番号
 * @param func     関数
 */
void assertEquals(const char* expected, const char* actual, const char* file, int line, const char* func) throw(AssertError)
{
	std::string expectedStr = expected;
	std::string actualStr   = actual;
	assertEquals(expectedStr, actualStr, file, line, func);
}


/**
 * 文字列型 (const char*, string) の値比較.
 * 通常, 本メソッドを直接使用せず, assertEquals(expected, actual) マクロを使用してください.
 * 指定された excepted と actual が同じか否かを判定し, 不一致の場合 AssertError を throw します.
 *
 * @param expected 比較対象1
 * @param actual   比較対象2
 * @param file     ファイル
 * @param line     行番号
 * @param func     関数
 */
void assertEquals(const char* expected, const std::string& actual, const char* file, int line, const char* func) throw(AssertError)
{
	std::string expectedStr = expected;
	assertEquals(expectedStr, actual, file, line, func);
}


/**
 * 文字列型 (string, const char*) の値比較.
 * 通常, 本メソッドを直接使用せず, assertEquals(expected, actual) マクロを使用してください.
 * 指定された excepted と actual が同じか否かを判定し, 不一致の場合 AssertError を throw します.
 *
 * @param expected 比較対象1
 * @param actual   比較対象2
 * @param file     ファイル
 * @param line     行番号
 * @param func     関数
 */
void assertEquals(const std::string& expected, const char* actual, const char* file, int line, const char* func) throw(AssertError)
{
	std::string actualStr = actual;
	assertEquals(expected, actualStr, file, line, func);
}


/**
 * 指定された値 condition が true であるか判定し, true でない場合 AssertError を throw します.
 * 通常, 本メソッドを直接使用せず, assertTrue(condition) マクロを使用してください.
 *
 * @param condition 判定する bool
 * @param file      ファイル
 * @param line      行番号
 * @param func      関数
 */
void assertTrue(bool condition, const char* file, int line, const char* func) throw(AssertError)
{
	if (!condition)
	{
		throw AssertError("", file, line, func);
	}
}


/**
 * 指定された値 condition が false であるか判定し, false でない場合 AssertError を throw します.
 * 通常, 本メソッドを直接使用せず, assertFalse(condition) マクロを使用してください.
 *
 * @param condition 判定する bool
 * @param file      ファイル
 * @param line      行番号
 * @param func      関数
 */
void assertFalse(bool condition, const char* file, int line, const char* func) throw(AssertError)
{
	if (condition)
	{
		throw AssertError("", file, line, func);
	}
}


/**
 * 指定された値 condition が null であるか判定し, null でない場合 AssertError を throw します.
 * 通常, 本メソッドを直接使用せず, assertNull(obj) マクロを使用してください.
 *
 * @param obj  null か否か判定するオブジェクト
 * @param file ファイル
 * @param line 行番号
 * @param func 関数
 */
void assertNull(void* obj, const char* file, int line, const char* func) throw(AssertError)
{
	if (obj != 0)
	{
		throw AssertError("", file, line, func);
	}
}


/**
 * 指定された値 condition が null でないか判定し, null の場合 AssertError を throw します.
 * 通常, 本メソッドを直接使用せず, assertNotNull(obj) マクロを使用してください.
 *
 * @param obj nullでないか確認するオブジェクト
 * @param file ファイル
 * @param line 行番号
 * @param func 関数
 */
void assertNotNull(void* obj, const char* file, int line, const char* func) throw(AssertError)
{
	if (obj == 0)
	{
		throw AssertError("", file, line, func);
	}
}


/**
 * AssertError を throw します.
 * 通常, 本メソッドを直接使用せず, fail() マクロを使用してください.
 *
 * @param file ファイル
 * @param line 行番号
 * @param func 関数
 */
void fail(const char* file, int line, const char* func) throw(AssertError)
{
	throw AssertError("", file, line, func);
}


}	// namespace Assertion
}	// namespace scpp