#include <memory>
#include <j/lang/object.hpp>
#include <j/lang/string.hpp>
namespace j
{
namespace lang
{
/**
* Object を構築します。
*/
Object::Object() noexcept { /* NOP */ }
/**
* Object のコピーコンストラクタ。
*
* @param obj コピー元オブジェクト
*/
Object::Object(const Object &) noexcept { /* NOP */ }
/**
* Object のムーブコンストラクタ。
*
* @param obj ムーブ元オブジェクト
*/
Object::Object(Object &&) noexcept { /* NOP */ }
// デストラクタ
// virtual Object::~Object() noexcept = default;
/**
* コピー代入演算子。
* コピーして代入します。
*
* @param obj コピー元オブジェクト
* @return 本オブジェクトへの参照
*/
Object &Object::operator=(const Object &) noexcept
{ // 特にコピーする要素はない。
return *this;
}
/**
* ムーブ代入演算子。
*
* @param obj ムーブ元オブジェクト
* @return 本オブジェクトへの参照
*/
Object &Object::operator=(Object &&) noexcept
{ // 特に移すものはない。
return *this;
}
/**
* 比較演算子。
*
* @param obj 比較するオブジェクト
* @return true/false (合致/不一致)
*/
bool Object::operator==(const Object &obj) const noexcept
{
return equals(obj);
}
/**
* 比較演算子。
*
* @param obj 比較するオブジェクト
* @return true/false (合致/不一致)
*/
bool Object::operator!=(const Object &obj) const noexcept
{
return !equals(obj);
}
/**
* クラス名を取得します。
*
* @return クラス名
*/
String Object::getClassName() const noexcept
{
return String(typeid(*this).name());
}
/**
* 本オブジェクトの文字列表現を返します。
*
* @return 本オブジェクトの文字列表現
*/
String Object::toString() const noexcept
{
// String str(getClassName() + "@" + std::to_string(reinterpret_cast<std::uintptr_t>(this)));
return getClassName();
}
/**
* 指定されたオブジェクトが同じクラスか否かを返します。
*
* @param obj オブジェクト
* @return true/false (同じクラス/異なるクラス)
*/
bool Object::isSameClass(const Object &obj) const noexcept
{
return (typeid(*this) == typeid(obj));
}
/**
* 指定されたオブジェクトと合致するか否かを返します。
*
* @param obj 比較するオブジェクト
* @return true/false (合致する/しない)
*/
bool Object::equals(const Object &obj) const noexcept
{
if (isSameClass(obj))
{ // 同じクラス
int ownHash = hashCode();
int objHash = obj.hashCode();
if (ownHash == objHash)
{ // ハッシュコードが一緒
String ownStr = toString();
String objStr = obj.toString();
return ownStr.equals(objStr);
}
}
return false;
}
/**
* ハッシュコードを取得します。
*
* @return ハッシュコード
*/
int Object::hashCode() const noexcept
{
return (reinterpret_cast<std::intptr_t>(this));
}
/**
* 待機中のスレッドを再開します。
*/
void Object::notify()
{
std::lock_guard<std::mutex> lock(mtx);
cv.notify_one();
}
/**
* 待機中のすべてのスレッドを再開します。
*/
void Object::notifyAll()
{
std::lock_guard<std::mutex> lock(mtx);
cv.notify_all();
}
/**
* 現在のスレッドを待機させます。
*/
void Object::wait()
{
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock);
}
/**
* 現在のスレッドを待機させます。
*/
void Object::wait(int msec)
{
std::unique_lock<std::mutex> lock(mtx);
cv.wait_for(lock, std::chrono::milliseconds(msec));
}
/**
* 本オブジェクトの複製を取得します。
*
* [備考]
* 派生クラスが、ポリモーフィズムをサポートするために、
* unique_ptr<Object> を返すようにしています。
*
* @return 本オブジェクトの複製
*/
std::unique_ptr<Object> Object::clone() const noexcept
{
return std::make_unique<Object>(*this);
}
/**
* 出力用
*
* @param os output stream
* @param obj オブジェクト
*/
std::ostream &operator<<(std::ostream &os, const Object &obj)
{
return operator<<(os, obj.toString());
}
} // namespace lang
} // namespace j