/* =============================================================================
 *  scpp_assert.hpp
 *  Copyright (c) 2003 - 2013  Nomura Kei
 * =============================================================================
 */
#ifndef SCPP_ASSERT_HPP
#define SCPP_ASSERT_HPP
#ifdef __plusplus

#ifndef SCPP_EXCEPTION_HPP
#include <scpp_exception.hpp>
#endif


/**
 * アサーションに失敗した際に throw される Error です.
 */
class AssertError : public Error
{
	public:
		AssertError() NO_THROW();
		AssertError(const AssertError& t) NO_THROW();
		AssertError(const std::string& msg) NO_THROW();
		AssertError(const std::string& msg, const char* file, int line, const char* func) NO_THROW();
		virtual ~AssertError() NO_THROW();
		const std::string& getFileName() const NO_THROW();
		int                getLineNumber() const NO_THROW();
		const std::string& getFunctionName() const NO_THROW();
	private:
		std::string fileName;
		int         lineNumber;
		std::string functionName;
};


/**
 * アサーション名前空間.
 * assertEquals, assertFalse, assertTrue, fail 等の
 * アサーションを扱います.
 */
namespace Assertion
{

void assertEquals (bool               expected, bool               actual, const char* file, int line, const char* func) throw(AssertError);
void assertEquals (char               expected, char               actual, const char* file, int line, const char* func) throw(AssertError);
void assertEquals (double             expected, double             actual, const char* file, int line, const char* func) throw(AssertError);
void assertEquals (float              expected, float              actual, const char* file, int line, const char* func) throw(AssertError);
void assertEquals (int                expected, int                actual, const char* file, int line, const char* func) throw(AssertError);
void assertEquals (long               expected, long               actual, const char* file, int line, const char* func) throw(AssertError);
void assertEquals (const std::string& expected, const std::string& actual, const char* file, int line, const char* func) throw(AssertError);
void assertEquals (const char*        expected, const char*        actual, const char* file, int line, const char* func) throw(AssertError);
void assertEquals (const char*        expected, const std::string& actual, const char* file, int line, const char* func) throw(AssertError);
void assertEquals (const std::string& expected, const char*        actual, const char* file, int line, const char* func) throw(AssertError);
void assertTrue   (bool condition                                        , const char* file, int line, const char* func) throw(AssertError);
void assertFalse  (bool condition                                        , const char* file, int line, const char* func) throw(AssertError);
void assertNull   (void* obj                                             , const char* file, int line, const char* func) throw(AssertError);
void assertNotNull(void* obj                                             , const char* file, int line, const char* func) throw(AssertError);
void fail(                                                                 const char* file, int line, const char* func) throw(AssertError);


}	// namespace Assertion
}	// namespace scpp


/**
 * 指定された actual が, expected と同一でない場合, AssertError を throw します.
 *
 * @param expected 期待する値
 * @param actual   比較する値
 */
#define assertEquals(expected, actual)  assertEquals(expected, actual, __FILE__, __LINE__, __PRETTY_FUNCTION__)


/**
 * 指定された condition が true でない場合, AssertError を throw します.
 *
 * @param condition 比較する値
 */
#define assertTrue(condition)           assertTrue(condition         , __FILE__, __LINE__, __PRETTY_FUNCTION__)


/**
 * 指定された condition が false でない場合, AssertError を throw します.
 *
 * @param condition 比較する値
 */
#define assertFalse(condition)          assertFalse(condition        , __FILE__, __LINE__, __PRETTY_FUNCTION__)


/**
 * 指定された obj が 0 (null) でない場合, AssertError を throw します.
 *
 * @param obj null か否か確認する値
 */
#define assertNull(obj)                 assertNull(obj               , __FILE__, __LINE__, __PRETTY_FUNCTION__)


/**
 * 指定された obj が 0 (null) の場合, AssertError を throw します.
 *
 * @param obj null か否か確認する値
 */
#define assertNotNull(obj)              assertNotNull(obj            , __FILE__, __LINE__, __PRETTY_FUNCTION__)


/**
 * 常に AssertError を throw します.
 */
#define fail()                          fail(                          __FILE__, __LINE__, __PRETTY_FUNCTION__)


#endif	/* __plusplus		*/
#endif	/* SCPP_ASSERT_HPP	*/

