// TestProject.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//

#include "stdafx.h"
#include "AutoLockInc.h"
#include "CriticalSectionInc.h"
#include "SRWLockInc.h"

#include <list>
#include <algorithm>

class CData
{
public:
        CData(VOID)
        {
        }
        
        ~CData(VOID)
        {
        }
};

#define THREAD_SAFE_CODE(THREAD_SAFE, SAFE_CODE, CODE) \
        if (THREAD_SAFE) \
        { SAFE_CODE CODE }\
        else \
        { CODE }

template <bool THREAD_SAFE = true>
class CDataMgr
{
public:
        CDataMgr(VOID)
        {
        }

        ~CDataMgr(VOID)
        {
        }

        BOOL InsertData(CData* data)
        {
                THREAD_SAFE_CODE(THREAD_SAFE, 
                BaseLib::CSRWWriteLock WriteLock(mLock);
                BaseLib::CAutoLock Lock(WriteLock);
                ,

                mDataList.push_back(data);
                return TRUE;

                )
        }

        BOOL DeleteData(CData* data)
        {
                THREAD_SAFE_CODE(THREAD_SAFE, 
                BaseLib::CSRWWriteLock WriteLock(mLock);
                BaseLib::CAutoLock Lock(WriteLock);
                ,

                std::list<CData*>::iterator iter
                        = std::find(mDataList.begin(), mDataList.end(), data);
                if (iter == mDataList.end())
                        return FALSE;

                delete *iter;
                mDataList.erase(iter);

                )
        }

        struct IDataReader
        {
                IDataReader(VOID) {}
                virtual ~IDataReader(VOID) {}
                virtual BOOL Read(CData* data) = 0;
        };

        BOOL ReadData(CData* data, IDataReader& dataReader)
        {
                THREAD_SAFE_CODE(THREAD_SAFE, 
                BaseLib::CSRWReadLock ReadLock(mLock);
                BaseLib::CAutoLock Lock(ReadLock);


                CData* Data = Find(data);
                if (!Data)
                        return FALSE;

                return dataReader.Read(data);

                )
        }

private:
        CData* Find(CData* data)
        {
                std::list<CData*>::iterator iter
                        = std::find(mDataList.begin(), mDataList.end(), data);
                if (iter == mDataList.end())
                        return NULL;
                return *iter;
        }

private:
        std::list<CData*> mDataList;
        BaseLib::CSRWLock mLock;
};


int _tmain(int argc, _TCHAR* argv[])
{
        CData* data = new CData;

        CDataMgr<true> DataMgr;

        DataMgr.InsertData(data);

        struct CDataReader : public CDataMgr<true>::IDataReader
        {
                virtual BOOL Read(CData* data)
                {
                        return TRUE;
                }
        } DataReader;

        DataMgr.ReadData(data, DataReader);

        return 0;
}


매크로 인자안에 코드가 들어가 있어서 디버깅이 불편...

좋은 방법 없을까여