
// stdafx.h : 標準のシステム インクルード ファイルのインクルード ファイル、または
// 参照回数が多く、かつあまり変更されない、プロジェクト専用のインクルード ファイル
// を記述します。

#pragma once

#include "../stdafx.h"
#include <afxwin.h>

struct CRString
{
	static boost::optional<int> ToInt(LPCWSTR src)
		{
			int val;
			return ::swscanf_s(src,L"%d",&val)==1 ? boost::optional<int>(val) : boost::none;
		}
	static boost::optional<int> ToInt(LPCSTR src)
		{
			int val;
			return ::sscanf_s(src,"%d",&val)==1 ?  boost::optional<int>(val) : boost::none;
		}

	// Fomrat	///////////////////////////////////////////
	static CStringW Format(LPCWSTR lpszFormat,...)
		{
			va_list argList;
			va_start(argList,lpszFormat);
			CStringW s;
			s.FormatV(lpszFormat,argList);
			va_end(argList);
			return s;
		}
	static CStringA Format(LPCSTR lpszFormat,...)
		{
			va_list argList;
			va_start(argList,lpszFormat);
			CStringA s;
			s.FormatV(lpszFormat,argList);
			va_end(argList);
			return s;
		}
};


// グローバル一意識別子(ID)クラス
class CRUid
{
	template <class> friend class CRUidT;		// friend は CastFrom だけでよいんだけど書き方がわからん
	boost::uuids::uuid	m_id;

	CRUid(const boost::uuids::uuid &id)
		:m_id(id)
		{
		}
public:
	CRUid()
		:m_id(boost::uuids::nil_uuid())	// null
		{}
	CRUid(const CRUid &s)
		{
			*this = s;
		}
	bool operator==(const CRUid &s)const
		{
			return m_id == s.m_id;
		}
	bool operator!=(const CRUid &s)const
		{
			return !((*this)==s);
		}
	bool operator<(const CRUid &s)const
		{
			return m_id < s.m_id;
		}
	bool operator>(const CRUid &s)const
		{
			return m_id > s.m_id;
		}
	bool IsEmpty()const
		{
			return *this == CRUid();
		}
	operator bool()const
		{
			return !IsEmpty();
		}

	static CRUid RandomGenerator()
		{
#if 0
			return CRUid(boost::uuids::random_generator()());
#else
			GUID g;	// boost::uuids::random_generator() が凄く遅いので
			::CoCreateGuid(&g);
			boost::uuids::uuid id;
			::memcpy( id.data, &g, sizeof(id) ); 
			return CRUid(id);
#endif
		}

	std::string GetText()const
		{
			const std::string s = boost::lexical_cast<std::string>(m_id);
			return s;
		}
};

