ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/s10k/CommonLibs/plog/Util.h
(Generate patch)

Comparing s10k/CommonLibs/plog/Util.h (file contents):
Revision 1073 by s10k, Thu Oct 5 17:48:32 2017 UTC vs.
Revision 1096 by s10k, Sat Dec 30 14:40:33 2017 UTC

# Line 1 | Line 1
1 < #pragma once
2 < #include <cassert>
3 < #include <cstring>
4 < #include <cstdio>
5 < #include <sstream>
6 < #include <fcntl.h>
7 < #include <sys/stat.h>
8 <
9 < #ifndef PLOG_ENABLE_WCHAR_INPUT
10 < #   ifdef _WIN32
11 < #       define PLOG_ENABLE_WCHAR_INPUT 1
12 < #   else
13 < #       define PLOG_ENABLE_WCHAR_INPUT 0
14 < #   endif
15 < #endif
16 <
17 < #ifdef _WIN32
18 < #   include <plog/WinApi.h>
19 < #   include <time.h>
20 < #   include <sys/timeb.h>
21 < #   include <io.h>
22 < #   include <share.h>
23 < #else
24 < #   include <unistd.h>
25 < #   include <sys/syscall.h>
26 < #   include <sys/time.h>
27 < #   include <pthread.h>
28 < #   if PLOG_ENABLE_WCHAR_INPUT
29 < #       include <iconv.h>
30 < #   endif
31 < #endif
32 <
33 < #ifdef _WIN32
34 < #   define _PLOG_NSTR(x)   L##x
35 < #   define PLOG_NSTR(x)    _PLOG_NSTR(x)
36 < #else
37 < #   define PLOG_NSTR(x)    x
38 < #endif
39 <
40 < namespace plog
41 < {
42 <    namespace util
43 <    {
44 < #ifdef _WIN32
45 <        typedef std::wstring nstring;
46 <        typedef std::wstringstream nstringstream;
47 <        typedef wchar_t nchar;
48 < #else
49 <        typedef std::string nstring;
50 <        typedef std::stringstream nstringstream;
51 <        typedef char nchar;
52 < #endif
53 <
54 <        inline void localtime_s(struct tm* t, const time_t* time)
55 <        {
56 < #if defined(_WIN32) && defined(__BORLANDC__)
57 <            ::localtime_s(time, t);
58 < #elif defined(_WIN32) && defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
59 <            *t = *::localtime(time);
60 < #elif defined(_WIN32)
61 <            ::localtime_s(t, time);
62 < #else
63 <            ::localtime_r(time, t);
64 < #endif
65 <        }
66 <
67 < #ifdef _WIN32
68 <        typedef timeb Time;
69 <
70 <        inline void ftime(Time* t)
71 <        {
72 <            ::ftime(t);
73 <        }
74 < #else
75 <        struct Time
76 <        {
77 <            time_t time;
78 <            unsigned short millitm;
79 <        };
80 <
81 <        inline void ftime(Time* t)
82 <        {
83 <            timeval tv;
84 <            ::gettimeofday(&tv, NULL);
85 <
86 <            t->time = tv.tv_sec;
87 <            t->millitm = static_cast<unsigned short>(tv.tv_usec / 1000);
88 <        }
89 < #endif
90 <
91 <        inline unsigned int gettid()
92 <        {
93 < #ifdef _WIN32
94 <            return GetCurrentThreadId();
95 < #elif defined(__unix__)
96 <            return static_cast<unsigned int>(::syscall(__NR_gettid));
97 < #elif defined(__APPLE__)
98 <            uint64_t tid64;
99 <            pthread_threadid_np(NULL, &tid64);
100 <            return static_cast<unsigned int>(tid64);
101 < #endif
102 <        }
103 <
104 < #if PLOG_ENABLE_WCHAR_INPUT && !defined(_WIN32)
105 <        inline std::string toNarrow(const wchar_t* wstr)
106 <        {
107 <            size_t wlen = ::wcslen(wstr);
108 <            std::string str(wlen * sizeof(wchar_t), 0);
109 <
110 <            if (!str.empty())
111 <            {
112 <                const char* in = reinterpret_cast<const char*>(&wstr[0]);
113 <                char* out = &str[0];
114 <                size_t inBytes = wlen * sizeof(wchar_t);
115 <                size_t outBytes = str.size();
116 <
117 <                iconv_t cd = ::iconv_open("UTF-8", "WCHAR_T");
118 <                ::iconv(cd, const_cast<char**>(&in), &inBytes, &out, &outBytes);
119 <                ::iconv_close(cd);
120 <
121 <                str.resize(str.size() - outBytes);
122 <            }
123 <
124 <            return str;
125 <        }
126 < #endif
127 <
128 < #ifdef _WIN32
129 <        inline std::wstring toWide(const char* str)
130 <        {
131 <            size_t len = ::strlen(str);
132 <            std::wstring wstr(len, 0);
133 <
134 <            if (!wstr.empty())
135 <            {
136 <                int wlen = MultiByteToWideChar(codePage::kActive, 0, str, static_cast<int>(len), &wstr[0], static_cast<int>(wstr.size()));
137 <                wstr.resize(wlen);
138 <            }
139 <
140 <            return wstr;
141 <        }
142 <
143 <        inline std::string toUTF8(const std::wstring& wstr)
144 <        {
145 <            std::string str(wstr.size() * sizeof(wchar_t), 0);
146 <
147 <            if (!str.empty())
148 <            {
149 <                int len = WideCharToMultiByte(codePage::kUTF8, 0, wstr.c_str(), static_cast<int>(wstr.size()), &str[0], static_cast<int>(str.size()), 0, 0);
150 <                str.resize(len);
151 <            }
152 <
153 <            return str;
154 <        }
155 < #endif
156 <
157 <        inline std::string processFuncName(const char* func)
158 <        {
159 < #if (defined(_WIN32) && !defined(__MINGW32__)) || defined(__OBJC__)
160 <            return std::string(func);
161 < #else
162 <            const char* funcBegin = func;
163 <            const char* funcEnd = ::strchr(funcBegin, '(');
164 <
165 <            if (!funcEnd)
166 <            {
167 <                return std::string(func);
168 <            }
169 <
170 <            for (const char* i = funcEnd - 1; i >= funcBegin; --i) // search backwards for the first space char
171 <            {
172 <                if (*i == ' ')
173 <                {
174 <                    funcBegin = i + 1;
175 <                    break;
176 <                }
177 <            }
178 <
179 <            return std::string(funcBegin, funcEnd);
180 < #endif
181 <        }
182 <
183 <        inline const nchar* findExtensionDot(const nchar* fileName)
184 <        {
185 < #ifdef _WIN32
186 <            return std::wcsrchr(fileName, L'.');
187 < #else
188 <            return std::strrchr(fileName, '.');
189 < #endif
190 <        }
191 <
192 <        inline void splitFileName(const nchar* fileName, nstring& fileNameNoExt, nstring& fileExt)
193 <        {
194 <            const nchar* dot = findExtensionDot(fileName);
195 <
196 <            if (dot)
197 <            {
198 <                fileNameNoExt.assign(fileName, dot);
199 <                fileExt.assign(dot + 1);
200 <            }
201 <            else
202 <            {
203 <                fileNameNoExt.assign(fileName);
204 <                fileExt.clear();
205 <            }
206 <        }
207 <
208 <        class NonCopyable
209 <        {
210 <        protected:
211 <            NonCopyable()
212 <            {
213 <            }
214 <
215 <        private:
216 <            NonCopyable(const NonCopyable&);
217 <            NonCopyable& operator=(const NonCopyable&);
218 <        };
219 <
220 <        class File : NonCopyable
221 <        {
222 <        public:
223 <            File() : m_file(-1)
224 <            {
225 <            }
226 <
227 <            File(const nchar* fileName) : m_file(-1)
228 <            {
229 <                open(fileName);
230 <            }
231 <
232 <            ~File()
233 <            {
234 <                close();
235 <            }
236 <
237 <            off_t open(const nchar* fileName)
238 <            {
239 < #if defined(_WIN32) && (defined(__BORLANDC__) || defined(__MINGW32__))
240 <                m_file = ::_wsopen(fileName, _O_CREAT | _O_WRONLY | _O_BINARY, SH_DENYWR, _S_IREAD | _S_IWRITE);
241 < #elif defined(_WIN32)
242 <                ::_wsopen_s(&m_file, fileName, _O_CREAT | _O_WRONLY | _O_BINARY, _SH_DENYWR, _S_IREAD | _S_IWRITE);
243 < #else
244 <                m_file = ::open(fileName, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
245 < #endif
246 <                return seek(0, SEEK_END);
247 <            }
248 <
249 <            int write(const void* buf, size_t count)
250 <            {
251 < #ifdef _WIN32
252 <                return m_file != -1 ? ::_write(m_file, buf, static_cast<unsigned int>(count)) : -1;
253 < #else
254 <                return m_file != -1 ? static_cast<int>(::write(m_file, buf, count)) : -1;
255 < #endif
256 <            }
257 <
258 <            template<class CharType>
259 <            int write(const std::basic_string<CharType>& str)
260 <            {
261 <                return write(str.data(), str.size() * sizeof(CharType));
262 <            }
263 <
264 <            off_t seek(off_t offset, int whence)
265 <            {
266 < #ifdef _WIN32
267 <                return m_file != -1 ? ::_lseek(m_file, offset, whence) : -1;
268 < #else
269 <                return m_file != -1 ? ::lseek(m_file, offset, whence) : -1;
270 < #endif
271 <            }
272 <
273 <            void close()
274 <            {
275 <                if (m_file != -1)
276 <                {
277 < #ifdef _WIN32
278 <                    ::_close(m_file);
279 < #else
280 <                    ::close(m_file);
281 < #endif
282 <                    m_file = -1;
283 <                }
284 <            }
285 <
286 <            static int unlink(const nchar* fileName)
287 <            {
288 < #ifdef _WIN32
289 <                return ::_wunlink(fileName);
290 < #else
291 <                return ::unlink(fileName);
292 < #endif
293 <            }
294 <
295 <            static int rename(const nchar* oldFilename, const nchar* newFilename)
296 <            {
297 < #ifdef _WIN32
298 <                return MoveFileW(oldFilename, newFilename);
299 < #else
300 <                return ::rename(oldFilename, newFilename);
301 < #endif
302 <            }
303 <
304 <        private:
305 <            int m_file;
306 <        };
307 <
308 <        class Mutex : NonCopyable
309 <        {
310 <        public:
311 <            Mutex()
312 <            {
313 < #ifdef _WIN32
314 <                InitializeCriticalSection(&m_sync);
315 < #else
316 <                ::pthread_mutex_init(&m_sync, 0);
317 < #endif
318 <            }
319 <
320 <            ~Mutex()
321 <            {
322 < #ifdef _WIN32
323 <                DeleteCriticalSection(&m_sync);
324 < #else
325 <                ::pthread_mutex_destroy(&m_sync);
326 < #endif
327 <            }
328 <
329 <            friend class MutexLock;
330 <
331 <        private:
332 <            void lock()
333 <            {
334 < #ifdef _WIN32
335 <                EnterCriticalSection(&m_sync);
336 < #else
337 <                ::pthread_mutex_lock(&m_sync);
338 < #endif
339 <            }
340 <
341 <            void unlock()
342 <            {
343 < #ifdef _WIN32
344 <                LeaveCriticalSection(&m_sync);
345 < #else
346 <                ::pthread_mutex_unlock(&m_sync);
347 < #endif
348 <            }
349 <
350 <        private:
351 < #ifdef _WIN32
352 <            CRITICAL_SECTION m_sync;
353 < #else
354 <            pthread_mutex_t m_sync;
355 < #endif
356 <        };
357 <
358 <        class MutexLock : NonCopyable
359 <        {
360 <        public:
361 <            MutexLock(Mutex& mutex) : m_mutex(mutex)
362 <            {
363 <                m_mutex.lock();
364 <            }
365 <
366 <            ~MutexLock()
367 <            {
368 <                m_mutex.unlock();
369 <            }
370 <
371 <        private:
372 <            Mutex& m_mutex;
373 <        };
374 <
375 <        template<class T>
376 <        class Singleton : NonCopyable
377 <        {
378 <        public:
379 <            Singleton()
380 <            {
381 <                assert(!m_instance);
382 <                m_instance = static_cast<T*>(this);
383 <            }
384 <
385 <            ~Singleton()
386 <            {
387 <                assert(m_instance);
388 <                m_instance = 0;
389 <            }
390 <
391 <            static T* getInstance()
392 <            {
393 <                return m_instance;
394 <            }
395 <
396 <        private:
397 <            static T* m_instance;
398 <        };
399 <
400 <        template<class T>
401 <        T* Singleton<T>::m_instance = NULL;
402 <    }
403 < }
1 > #pragma once
2 > #include <cassert>
3 > #include <cstring>
4 > #include <cstdio>
5 > #include <sstream>
6 > #include <fcntl.h>
7 > #include <sys/stat.h>
8 >
9 > #ifndef PLOG_ENABLE_WCHAR_INPUT
10 > #   ifdef _WIN32
11 > #       define PLOG_ENABLE_WCHAR_INPUT 1
12 > #   else
13 > #       define PLOG_ENABLE_WCHAR_INPUT 0
14 > #   endif
15 > #endif
16 >
17 > #ifdef _WIN32
18 > #   include <plog/WinApi.h>
19 > #   include <time.h>
20 > #   include <sys/timeb.h>
21 > #   include <io.h>
22 > #   include <share.h>
23 > #else
24 > #   include <unistd.h>
25 > #   include <sys/syscall.h>
26 > #   include <sys/time.h>
27 > #   include <pthread.h>
28 > #   if PLOG_ENABLE_WCHAR_INPUT
29 > #       include <iconv.h>
30 > #   endif
31 > #endif
32 >
33 > #ifdef _WIN32
34 > #   define _PLOG_NSTR(x)   L##x
35 > #   define PLOG_NSTR(x)    _PLOG_NSTR(x)
36 > #else
37 > #   define PLOG_NSTR(x)    x
38 > #endif
39 >
40 > namespace plog
41 > {
42 >    namespace util
43 >    {
44 > #ifdef _WIN32
45 >        typedef std::wstring nstring;
46 >        typedef std::wstringstream nstringstream;
47 >        typedef wchar_t nchar;
48 > #else
49 >        typedef std::string nstring;
50 >        typedef std::stringstream nstringstream;
51 >        typedef char nchar;
52 > #endif
53 >
54 >        inline void localtime_s(struct tm* t, const time_t* time)
55 >        {
56 > #if defined(_WIN32) && defined(__BORLANDC__)
57 >            ::localtime_s(time, t);
58 > #elif defined(_WIN32) && defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
59 >            *t = *::localtime(time);
60 > #elif defined(_WIN32)
61 >            ::localtime_s(t, time);
62 > #else
63 >            ::localtime_r(time, t);
64 > #endif
65 >        }
66 >
67 > #ifdef _WIN32
68 >        typedef timeb Time;
69 >
70 >        inline void ftime(Time* t)
71 >        {
72 >            ::ftime(t);
73 >        }
74 > #else
75 >        struct Time
76 >        {
77 >            time_t time;
78 >            unsigned short millitm;
79 >        };
80 >
81 >        inline void ftime(Time* t)
82 >        {
83 >            timeval tv;
84 >            ::gettimeofday(&tv, NULL);
85 >
86 >            t->time = tv.tv_sec;
87 >            t->millitm = static_cast<unsigned short>(tv.tv_usec / 1000);
88 >        }
89 > #endif
90 >
91 >        inline unsigned int gettid()
92 >        {
93 > #ifdef _WIN32
94 >            return GetCurrentThreadId();
95 > #elif defined(__unix__)
96 >            return static_cast<unsigned int>(::syscall(__NR_gettid));
97 > #elif defined(__APPLE__)
98 >            uint64_t tid64;
99 >            pthread_threadid_np(NULL, &tid64);
100 >            return static_cast<unsigned int>(tid64);
101 > #endif
102 >        }
103 >
104 > #if PLOG_ENABLE_WCHAR_INPUT && !defined(_WIN32)
105 >        inline std::string toNarrow(const wchar_t* wstr)
106 >        {
107 >            size_t wlen = ::wcslen(wstr);
108 >            std::string str(wlen * sizeof(wchar_t), 0);
109 >
110 >            if (!str.empty())
111 >            {
112 >                const char* in = reinterpret_cast<const char*>(&wstr[0]);
113 >                char* out = &str[0];
114 >                size_t inBytes = wlen * sizeof(wchar_t);
115 >                size_t outBytes = str.size();
116 >
117 >                iconv_t cd = ::iconv_open("UTF-8", "WCHAR_T");
118 >                ::iconv(cd, const_cast<char**>(&in), &inBytes, &out, &outBytes);
119 >                ::iconv_close(cd);
120 >
121 >                str.resize(str.size() - outBytes);
122 >            }
123 >
124 >            return str;
125 >        }
126 > #endif
127 >
128 > #ifdef _WIN32
129 >        inline std::wstring toWide(const char* str)
130 >        {
131 >            size_t len = ::strlen(str);
132 >            std::wstring wstr(len, 0);
133 >
134 >            if (!wstr.empty())
135 >            {
136 >                int wlen = MultiByteToWideChar(codePage::kActive, 0, str, static_cast<int>(len), &wstr[0], static_cast<int>(wstr.size()));
137 >                wstr.resize(wlen);
138 >            }
139 >
140 >            return wstr;
141 >        }
142 >
143 >        inline std::string toUTF8(const std::wstring& wstr)
144 >        {
145 >            std::string str(wstr.size() * sizeof(wchar_t), 0);
146 >
147 >            if (!str.empty())
148 >            {
149 >                int len = WideCharToMultiByte(codePage::kUTF8, 0, wstr.c_str(), static_cast<int>(wstr.size()), &str[0], static_cast<int>(str.size()), 0, 0);
150 >                str.resize(len);
151 >            }
152 >
153 >            return str;
154 >        }
155 > #endif
156 >
157 >        inline std::string processFuncName(const char* func)
158 >        {
159 > #if (defined(_WIN32) && !defined(__MINGW32__)) || defined(__OBJC__)
160 >            return std::string(func);
161 > #else
162 >            const char* funcBegin = func;
163 >            const char* funcEnd = ::strchr(funcBegin, '(');
164 >
165 >            if (!funcEnd)
166 >            {
167 >                return std::string(func);
168 >            }
169 >
170 >            for (const char* i = funcEnd - 1; i >= funcBegin; --i) // search backwards for the first space char
171 >            {
172 >                if (*i == ' ')
173 >                {
174 >                    funcBegin = i + 1;
175 >                    break;
176 >                }
177 >            }
178 >
179 >            return std::string(funcBegin, funcEnd);
180 > #endif
181 >        }
182 >
183 >        inline const nchar* findExtensionDot(const nchar* fileName)
184 >        {
185 > #ifdef _WIN32
186 >            return std::wcsrchr(fileName, L'.');
187 > #else
188 >            return std::strrchr(fileName, '.');
189 > #endif
190 >        }
191 >
192 >        inline void splitFileName(const nchar* fileName, nstring& fileNameNoExt, nstring& fileExt)
193 >        {
194 >            const nchar* dot = findExtensionDot(fileName);
195 >
196 >            if (dot)
197 >            {
198 >                fileNameNoExt.assign(fileName, dot);
199 >                fileExt.assign(dot + 1);
200 >            }
201 >            else
202 >            {
203 >                fileNameNoExt.assign(fileName);
204 >                fileExt.clear();
205 >            }
206 >        }
207 >
208 >        class NonCopyable
209 >        {
210 >        protected:
211 >            NonCopyable()
212 >            {
213 >            }
214 >
215 >        private:
216 >            NonCopyable(const NonCopyable&);
217 >            NonCopyable& operator=(const NonCopyable&);
218 >        };
219 >
220 >        class File : NonCopyable
221 >        {
222 >        public:
223 >            File() : m_file(-1)
224 >            {
225 >            }
226 >
227 >            File(const nchar* fileName) : m_file(-1)
228 >            {
229 >                open(fileName);
230 >            }
231 >
232 >            ~File()
233 >            {
234 >                close();
235 >            }
236 >
237 >            off_t open(const nchar* fileName)
238 >            {
239 > #if defined(_WIN32) && (defined(__BORLANDC__) || defined(__MINGW32__))
240 >                m_file = ::_wsopen(fileName, _O_CREAT | _O_WRONLY | _O_BINARY, SH_DENYWR, _S_IREAD | _S_IWRITE);
241 > #elif defined(_WIN32)
242 >                ::_wsopen_s(&m_file, fileName, _O_CREAT | _O_WRONLY | _O_BINARY, _SH_DENYWR, _S_IREAD | _S_IWRITE);
243 > #else
244 >                m_file = ::open(fileName, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
245 > #endif
246 >                return seek(0, SEEK_END);
247 >            }
248 >
249 >            int write(const void* buf, size_t count)
250 >            {
251 > #ifdef _WIN32
252 >                return m_file != -1 ? ::_write(m_file, buf, static_cast<unsigned int>(count)) : -1;
253 > #else
254 >                return m_file != -1 ? static_cast<int>(::write(m_file, buf, count)) : -1;
255 > #endif
256 >            }
257 >
258 >            template<class CharType>
259 >            int write(const std::basic_string<CharType>& str)
260 >            {
261 >                return write(str.data(), str.size() * sizeof(CharType));
262 >            }
263 >
264 >            off_t seek(off_t offset, int whence)
265 >            {
266 > #ifdef _WIN32
267 >                return m_file != -1 ? ::_lseek(m_file, offset, whence) : -1;
268 > #else
269 >                return m_file != -1 ? ::lseek(m_file, offset, whence) : -1;
270 > #endif
271 >            }
272 >
273 >            void close()
274 >            {
275 >                if (m_file != -1)
276 >                {
277 > #ifdef _WIN32
278 >                    ::_close(m_file);
279 > #else
280 >                    ::close(m_file);
281 > #endif
282 >                    m_file = -1;
283 >                }
284 >            }
285 >
286 >            static int unlink(const nchar* fileName)
287 >            {
288 > #ifdef _WIN32
289 >                return ::_wunlink(fileName);
290 > #else
291 >                return ::unlink(fileName);
292 > #endif
293 >            }
294 >
295 >            static int rename(const nchar* oldFilename, const nchar* newFilename)
296 >            {
297 > #ifdef _WIN32
298 >                return MoveFileW(oldFilename, newFilename);
299 > #else
300 >                return ::rename(oldFilename, newFilename);
301 > #endif
302 >            }
303 >
304 >        private:
305 >            int m_file;
306 >        };
307 >
308 >        class Mutex : NonCopyable
309 >        {
310 >        public:
311 >            Mutex()
312 >            {
313 > #ifdef _WIN32
314 >                InitializeCriticalSection(&m_sync);
315 > #else
316 >                ::pthread_mutex_init(&m_sync, 0);
317 > #endif
318 >            }
319 >
320 >            ~Mutex()
321 >            {
322 > #ifdef _WIN32
323 >                DeleteCriticalSection(&m_sync);
324 > #else
325 >                ::pthread_mutex_destroy(&m_sync);
326 > #endif
327 >            }
328 >
329 >            friend class MutexLock;
330 >
331 >        private:
332 >            void lock()
333 >            {
334 > #ifdef _WIN32
335 >                EnterCriticalSection(&m_sync);
336 > #else
337 >                ::pthread_mutex_lock(&m_sync);
338 > #endif
339 >            }
340 >
341 >            void unlock()
342 >            {
343 > #ifdef _WIN32
344 >                LeaveCriticalSection(&m_sync);
345 > #else
346 >                ::pthread_mutex_unlock(&m_sync);
347 > #endif
348 >            }
349 >
350 >        private:
351 > #ifdef _WIN32
352 >            CRITICAL_SECTION m_sync;
353 > #else
354 >            pthread_mutex_t m_sync;
355 > #endif
356 >        };
357 >
358 >        class MutexLock : NonCopyable
359 >        {
360 >        public:
361 >            MutexLock(Mutex& mutex) : m_mutex(mutex)
362 >            {
363 >                m_mutex.lock();
364 >            }
365 >
366 >            ~MutexLock()
367 >            {
368 >                m_mutex.unlock();
369 >            }
370 >
371 >        private:
372 >            Mutex& m_mutex;
373 >        };
374 >
375 >        template<class T>
376 >        class Singleton : NonCopyable
377 >        {
378 >        public:
379 >            Singleton()
380 >            {
381 >                assert(!m_instance);
382 >                m_instance = static_cast<T*>(this);
383 >            }
384 >
385 >            ~Singleton()
386 >            {
387 >                assert(m_instance);
388 >                m_instance = 0;
389 >            }
390 >
391 >            static T* getInstance()
392 >            {
393 >                return m_instance;
394 >            }
395 >
396 >        private:
397 >            static T* m_instance;
398 >        };
399 >
400 >        template<class T>
401 >        T* Singleton<T>::m_instance = NULL;
402 >    }
403 > }

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)