summaryrefslogtreecommitdiff
path: root/shared
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:10:11 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:10:11 +0200
commitc0cdb2ad99a1e2a6ade5ce76c91177a79258e669 (patch)
tree4701a015385d9a6a5a4ba99a8f1f5d400fff26b1 /shared
parent3.13 (diff)
downloadFreeFileSync-c0cdb2ad99a1e2a6ade5ce76c91177a79258e669.tar.gz
FreeFileSync-c0cdb2ad99a1e2a6ade5ce76c91177a79258e669.tar.bz2
FreeFileSync-c0cdb2ad99a1e2a6ade5ce76c91177a79258e669.zip
3.14
Diffstat (limited to 'shared')
-rw-r--r--shared/IFileOperation/dll_main.cpp10
-rw-r--r--shared/IFileOperation/file_op.cpp32
-rw-r--r--shared/IFileOperation/file_op.h14
-rw-r--r--shared/ShadowCopy/dll_main.cpp10
-rw-r--r--shared/ShadowCopy/shadow.h13
-rw-r--r--shared/Taskbar_Seven/dll_main.cpp10
-rw-r--r--shared/Taskbar_Seven/taskbar.cpp38
-rw-r--r--shared/Taskbar_Seven/taskbar.h14
-rw-r--r--shared/assert_static.h4
-rw-r--r--shared/c_dll.h4
-rw-r--r--shared/com_error.h6
-rw-r--r--shared/com_ptr.h6
-rw-r--r--shared/custom_button.cpp2
-rw-r--r--shared/custom_button.h2
-rw-r--r--shared/custom_combo_box.cpp8
-rw-r--r--shared/dir_name.cpp4
-rw-r--r--shared/dst_hack.cpp63
-rw-r--r--shared/file_handling.cpp406
-rw-r--r--shared/file_id.cpp13
-rw-r--r--shared/file_io.cpp26
-rw-r--r--shared/file_traverser.cpp116
-rw-r--r--shared/global_func.cpp5
-rw-r--r--shared/global_func.h13
-rw-r--r--shared/inotify/inotify-cxx.cpp1020
-rw-r--r--shared/inotify/inotify-cxx.h1375
-rw-r--r--shared/localization.cpp573
-rw-r--r--shared/localization.h4
-rw-r--r--shared/loki/AbstractFactory.h216
-rw-r--r--shared/loki/Allocator.h32
-rw-r--r--shared/loki/AssocVector.h548
-rw-r--r--shared/loki/CachedFactory.h2002
-rw-r--r--shared/loki/CheckReturn.h108
-rw-r--r--shared/loki/Checker.h46
-rw-r--r--shared/loki/ConstPolicy.h30
-rw-r--r--shared/loki/DataGenerators.h96
-rw-r--r--shared/loki/EmptyType.h46
-rw-r--r--shared/loki/Factory.h1828
-rw-r--r--shared/loki/Function.h598
-rw-r--r--shared/loki/Functor.h2813
-rw-r--r--shared/loki/HierarchyGenerators.h374
-rw-r--r--shared/loki/Key.h1442
-rw-r--r--shared/loki/LevelMutex.h204
-rw-r--r--shared/loki/LockingPtr.h156
-rw-r--r--shared/loki/LokiExport.h18
-rw-r--r--shared/loki/LokiTypeInfo.h142
-rw-r--r--shared/loki/MultiMethods.h586
-rw-r--r--shared/loki/NullType.h18
-rw-r--r--shared/loki/OrderedStatic.h376
-rw-r--r--shared/loki/Pimpl.h288
-rw-r--r--shared/loki/RefToValue.h96
-rw-r--r--shared/loki/Register.h170
-rw-r--r--shared/loki/SPCachedFactory.h292
-rw-r--r--shared/loki/SafeBits.h128
-rw-r--r--shared/loki/SafeFormat.h1022
-rw-r--r--shared/loki/ScopeGuard.h1220
-rw-r--r--shared/loki/Sequence.h54
-rw-r--r--shared/loki/Singleton.h1426
-rw-r--r--shared/loki/SmallObj.cpp582
-rw-r--r--shared/loki/SmallObj.h1106
-rw-r--r--shared/loki/SmartPtr.h2276
-rw-r--r--shared/loki/StrongPtr.h816
-rw-r--r--shared/loki/Threads.h486
-rw-r--r--shared/loki/Tuple.h14
-rw-r--r--shared/loki/TypeManip.h244
-rw-r--r--shared/loki/TypeTraits.h4238
-rw-r--r--shared/loki/Typelist.h580
-rw-r--r--shared/loki/TypelistMacros.h14
-rw-r--r--shared/loki/Visitor.h314
-rw-r--r--shared/loki/static_check.h18
-rw-r--r--shared/long_path_prefix.cpp10
-rw-r--r--shared/mouse_move_dlg.cpp54
-rw-r--r--shared/mouse_move_dlg.h40
-rw-r--r--shared/perf.h44
-rw-r--r--shared/privilege.cpp48
-rw-r--r--shared/recycler.cpp8
-rw-r--r--shared/shadow.cpp18
-rw-r--r--shared/symlink_target.h9
-rw-r--r--shared/taskbar.cpp30
-rw-r--r--shared/tinyxml/tinystr.cpp6
-rw-r--r--shared/tinyxml/tinystr.h460
-rw-r--r--shared/tinyxml/tinyxml.cpp56
-rw-r--r--shared/tinyxml/tinyxml.h2631
-rw-r--r--shared/tinyxml/tinyxmlparser.cpp252
-rw-r--r--shared/tinyxml/xmltest.cpp2595
-rw-r--r--shared/util.cpp18
-rw-r--r--shared/xml_base.cpp36
-rw-r--r--shared/zbase.h4
-rw-r--r--shared/zstring.cpp46
88 files changed, 18886 insertions, 18333 deletions
diff --git a/shared/IFileOperation/dll_main.cpp b/shared/IFileOperation/dll_main.cpp
index d23e5c48..ab387012 100644
--- a/shared/IFileOperation/dll_main.cpp
+++ b/shared/IFileOperation/dll_main.cpp
@@ -15,11 +15,11 @@ BOOL APIENTRY DllMain(HINSTANCE hinstDLL,
{
switch (fdwReason)
{
- case DLL_PROCESS_ATTACH:
- case DLL_PROCESS_DETACH:
- case DLL_THREAD_ATTACH:
- case DLL_THREAD_DETACH:
- break;
+ case DLL_PROCESS_ATTACH:
+ case DLL_PROCESS_DETACH:
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ break;
}
return TRUE;
}
diff --git a/shared/IFileOperation/file_op.cpp b/shared/IFileOperation/file_op.cpp
index b1b7f4cd..fc942f44 100644
--- a/shared/IFileOperation/file_op.cpp
+++ b/shared/IFileOperation/file_op.cpp
@@ -36,10 +36,10 @@ bool fileop::moveToRecycleBin(const wchar_t* fileNames[],
// Create the IFileOperation interface
ComPtr<IFileOperation> fileOp;
- hr = CoCreateInstance(CLSID_FileOperation,
- NULL,
- CLSCTX_ALL,
- IID_PPV_ARGS(fileOp.init()));
+ hr = ::CoCreateInstance(CLSID_FileOperation,
+ NULL,
+ CLSCTX_ALL,
+ IID_PPV_ARGS(fileOp.init()));
if (FAILED(hr))
{
lastErrorMessage = generateErrorMsg(L"Error calling \"CoCreateInstance\".", hr);
@@ -70,6 +70,10 @@ bool fileop::moveToRecycleBin(const wchar_t* fileNames[],
IID_PPV_ARGS(psiFile.init()));
if (FAILED(hr))
{
+ if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) || //file not existing anymore
+ hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND))
+ continue;
+
std::wstring message(L"Error calling \"SHCreateItemFromParsingName\" for file:\n");
message += std::wstring(L"\"") + fileNames[i] + L"\".";
@@ -122,10 +126,10 @@ bool fileop::copyFile(const wchar_t* sourceFile,
// Create the IFileOperation interface
ComPtr<IFileOperation> fileOp;
- hr = CoCreateInstance(CLSID_FileOperation,
- NULL,
- CLSCTX_ALL,
- IID_PPV_ARGS(fileOp.init()));
+ hr = ::CoCreateInstance(CLSID_FileOperation,
+ NULL,
+ CLSCTX_ALL,
+ IID_PPV_ARGS(fileOp.init()));
if (FAILED(hr))
{
lastErrorMessage = generateErrorMsg(L"Error calling \"CoCreateInstance\".", hr);
@@ -148,9 +152,9 @@ bool fileop::copyFile(const wchar_t* sourceFile,
//create source object
ComPtr<IShellItem> psiSourceFile;
- hr = SHCreateItemFromParsingName(sourceFile,
- NULL,
- IID_PPV_ARGS(psiSourceFile.init()));
+ hr = ::SHCreateItemFromParsingName(sourceFile,
+ NULL,
+ IID_PPV_ARGS(psiSourceFile.init()));
if (FAILED(hr))
{
std::wstring message(L"Error calling \"SHCreateItemFromParsingName\" for file:\n");
@@ -171,9 +175,9 @@ bool fileop::copyFile(const wchar_t* sourceFile,
//create target folder object
ComPtr<IShellItem> psiTargetFolder;
- hr = SHCreateItemFromParsingName(targetFolder.c_str(),
- NULL,
- IID_PPV_ARGS(psiTargetFolder.init()));
+ hr = ::SHCreateItemFromParsingName(targetFolder.c_str(),
+ NULL,
+ IID_PPV_ARGS(psiTargetFolder.init()));
if (FAILED(hr))
{
std::wstring message(L"Error calling \"SHCreateItemFromParsingName\" for folder:\n");
diff --git a/shared/IFileOperation/file_op.h b/shared/IFileOperation/file_op.h
index 9842f0d6..a7b0434f 100644
--- a/shared/IFileOperation/file_op.h
+++ b/shared/IFileOperation/file_op.h
@@ -16,6 +16,10 @@
namespace fileop
{
+/*--------------
+ |declarations|
+ --------------*/
+
//COM needs to be initialized before calling any of these functions! CoInitializeEx/CoUninitialize
FILE_OP_DLL_API
@@ -30,13 +34,17 @@ bool copyFile(const wchar_t* sourceFile,
FILE_OP_DLL_API
void getLastError(wchar_t* errorMessage, size_t errorBufferLen);
-
-//function typedefs
+/*----------
+ |typedefs|
+ ----------*/
typedef bool (*MoveToRecycleBinFct)(const wchar_t* fileNames[], size_t fileNo);
typedef bool (*CopyFileFct)(const wchar_t* sourceFile, const wchar_t* targetFile);
typedef void (*GetLastErrorFct)(wchar_t* errorMessage, size_t errorBufferLen);
-//function names (use const pointers to ensure internal linkage)
+/*--------------
+ |symbol names|
+ --------------*/
+//(use const pointers to ensure internal linkage)
const char* const moveToRecycleBinFctName = "moveToRecycleBin";
const char* const copyFileFctName = "copyFile";
const char* const getLastErrorFctName = "getLastError";
diff --git a/shared/ShadowCopy/dll_main.cpp b/shared/ShadowCopy/dll_main.cpp
index d23e5c48..ab387012 100644
--- a/shared/ShadowCopy/dll_main.cpp
+++ b/shared/ShadowCopy/dll_main.cpp
@@ -15,11 +15,11 @@ BOOL APIENTRY DllMain(HINSTANCE hinstDLL,
{
switch (fdwReason)
{
- case DLL_PROCESS_ATTACH:
- case DLL_PROCESS_DETACH:
- case DLL_THREAD_ATTACH:
- case DLL_THREAD_DETACH:
- break;
+ case DLL_PROCESS_ATTACH:
+ case DLL_PROCESS_DETACH:
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ break;
}
return TRUE;
}
diff --git a/shared/ShadowCopy/shadow.h b/shared/ShadowCopy/shadow.h
index 683a4e16..5495633d 100644
--- a/shared/ShadowCopy/shadow.h
+++ b/shared/ShadowCopy/shadow.h
@@ -16,6 +16,10 @@
namespace shadow
{
+/*--------------
+ |declarations|
+ --------------*/
+
//COM needs to be initialized before calling any of these functions! CoInitializeEx/CoUninitialize
typedef size_t ShadowHandle;
@@ -38,7 +42,9 @@ void releaseShadowCopy(ShadowHandle handle);
//##########################################################################################
-//function typedefs
+/*----------
+ |typedefs|
+ ----------*/
typedef bool (*CreateShadowCopyFct)(const wchar_t* volumeName,
wchar_t* shadowVolName,
unsigned int shadowBufferLen,
@@ -48,7 +54,10 @@ typedef bool (*CreateShadowCopyFct)(const wchar_t* volumeName,
typedef void (*ReleaseShadowCopyFct)(ShadowHandle handle);
-//function names
+/*--------------
+ |symbol names|
+ --------------*/
+//(use const pointers to ensure internal linkage)
const char* const createShadowCopyFctName = "createShadowCopy";
const char* const releaseShadowCopyFctName = "releaseShadowCopy";
}
diff --git a/shared/Taskbar_Seven/dll_main.cpp b/shared/Taskbar_Seven/dll_main.cpp
index d23e5c48..ab387012 100644
--- a/shared/Taskbar_Seven/dll_main.cpp
+++ b/shared/Taskbar_Seven/dll_main.cpp
@@ -15,11 +15,11 @@ BOOL APIENTRY DllMain(HINSTANCE hinstDLL,
{
switch (fdwReason)
{
- case DLL_PROCESS_ATTACH:
- case DLL_PROCESS_DETACH:
- case DLL_THREAD_ATTACH:
- case DLL_THREAD_DETACH:
- break;
+ case DLL_PROCESS_ATTACH:
+ case DLL_PROCESS_DETACH:
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ break;
}
return TRUE;
}
diff --git a/shared/Taskbar_Seven/taskbar.cpp b/shared/Taskbar_Seven/taskbar.cpp
index c853eb5d..297a0739 100644
--- a/shared/Taskbar_Seven/taskbar.cpp
+++ b/shared/Taskbar_Seven/taskbar.cpp
@@ -46,26 +46,26 @@ ComPtr<ITaskbarList3> getInstance()
bool tbseven::setStatus(void* hwnd, //HWND: window assciated to the taskbar icon
- TaskBarStatus status)
+ TaskBarStatus status)
{
TBPFLAG flag = TBPF_NORMAL;
switch (status)
{
- case STATUS_NOPROGRESS:
- flag = TBPF_NOPROGRESS;
- break;
- case STATUS_INDETERMINATE:
- flag = TBPF_INDETERMINATE;
- break;
- case STATUS_NORMAL:
- flag = TBPF_NORMAL;
- break;
- case STATUS_ERROR:
- flag = TBPF_ERROR;
- break;
- case STATUS_PAUSED:
- flag = TBPF_PAUSED;
- break;
+ case STATUS_NOPROGRESS:
+ flag = TBPF_NOPROGRESS;
+ break;
+ case STATUS_INDETERMINATE:
+ flag = TBPF_INDETERMINATE;
+ break;
+ case STATUS_NORMAL:
+ flag = TBPF_NORMAL;
+ break;
+ case STATUS_ERROR:
+ flag = TBPF_ERROR;
+ break;
+ case STATUS_PAUSED:
+ flag = TBPF_PAUSED;
+ break;
}
ComPtr<ITaskbarList3> taskbarlist = getInstance();
@@ -73,7 +73,7 @@ bool tbseven::setStatus(void* hwnd, //HWND: window assciated to the taskbar icon
return false;
HRESULT hr = taskbarlist->SetProgressState(static_cast<HWND>(hwnd), //[in] HWND hwnd,
- flag); //[in] TBPFLAG tbpFlags
+ flag); //[in] TBPFLAG tbpFlags
if (FAILED(hr))
{
lastErrorMessage = generateErrorMsg(L"Error calling \"SetProgressState\".", hr);
@@ -85,8 +85,8 @@ bool tbseven::setStatus(void* hwnd, //HWND: window assciated to the taskbar icon
bool tbseven::setProgress(void* hwnd, //HWND: window assciated to the taskbar icon
- size_t current,
- size_t total)
+ size_t current,
+ size_t total)
{
ComPtr<ITaskbarList3> taskbarlist = getInstance();
if (!taskbarlist) //error msg already set
diff --git a/shared/Taskbar_Seven/taskbar.h b/shared/Taskbar_Seven/taskbar.h
index 295cdbcd..7b6efbb5 100644
--- a/shared/Taskbar_Seven/taskbar.h
+++ b/shared/Taskbar_Seven/taskbar.h
@@ -16,6 +16,10 @@
namespace tbseven
{
+/*--------------
+ |declarations|
+ --------------*/
+
enum TaskBarStatus
{
STATUS_NOPROGRESS,
@@ -42,13 +46,17 @@ bool setProgress(void* hwnd, //HWND: window assciated to the taskbar icon
DLL_FUNCTION_DECLARATION
void getLastError(wchar_t* errorMessage, size_t errorBufferLen);
-
-//function typedefs
+/*----------
+ |typedefs|
+ ----------*/
typedef bool (*SetStatusFct)(void* hwnd, TaskBarStatus status);
typedef bool (*SetProgressFct)(void* hwnd, size_t current, size_t total);
typedef void (*GetLastErrorFct)(wchar_t* errorMessage, size_t errorBufferLen);
-//function names (use const pointers to ensure internal linkage)
+/*--------------
+ |symbol names|
+ --------------*/
+//(use const pointers to ensure internal linkage)
const char* const setStatusFctName = "setStatus";
const char* const setProgressFctName = "setProgress";
const char* const getLastErrorFctName = "getLastError";
diff --git a/shared/assert_static.h b/shared/assert_static.h
index d2bd0a3a..198943cf 100644
--- a/shared/assert_static.h
+++ b/shared/assert_static.h
@@ -27,10 +27,10 @@ struct CompileTimeError<true> {};
#define LOKI_CONCAT_SUB( X, Y ) X##Y
#define assert_static(expr) \
- enum { LOKI_CONCAT(loki_enum_dummy_value, __LINE__) = sizeof(StaticCheckImpl::CompileTimeError<static_cast<bool>(expr) >) }
+ enum { LOKI_CONCAT(loki_enum_dummy_value, __LINE__) = sizeof(StaticCheckImpl::CompileTimeError<static_cast<bool>(expr) >) }
/*#define assert_static(expr) \
- { Loki::CompileTimeError<((expr) != 0)> Static_Assert_Has_Failed; (void)Static_Assert_Has_Failed; } */
+{ Loki::CompileTimeError<((expr) != 0)> Static_Assert_Has_Failed; (void)Static_Assert_Has_Failed; } */
#endif
diff --git a/shared/c_dll.h b/shared/c_dll.h
index 3941cc0e..a80c419e 100644
--- a/shared/c_dll.h
+++ b/shared/c_dll.h
@@ -29,11 +29,11 @@ public:
T& retrieve(S handle); //return default-constructed object if not found
private:
- HandleProvider() {}
+ HandleProvider() {}
HandleProvider(const HandleProvider&);
HandleProvider& operator=(const HandleProvider&);
S generate();
-
+
std::map<S, T> handleMap;
};
/*
diff --git a/shared/com_error.h b/shared/com_error.h
index 30c7904f..c3f7745b 100644
--- a/shared/com_error.h
+++ b/shared/com_error.h
@@ -28,13 +28,13 @@ public:
}
private:
- ComException(const ComException&);
- ComException& operator=(const ComException&);
+ ComException(const ComException&);
+ ComException& operator=(const ComException&);
const std::wstring message_;
const HRESULT hr_;
};
-
+
diff --git a/shared/com_ptr.h b/shared/com_ptr.h
index f8331220..6c7a62ab 100644
--- a/shared/com_ptr.h
+++ b/shared/com_ptr.h
@@ -46,13 +46,13 @@ public:
private:
T* ptr;
- struct ConversionToBool
+ struct ConversionToBool
{
int dummy;
};
public:
- operator int ConversionToBool::*() const; //use member pointer as implicit conversion to bool (C++ Templates - Vandevoorde/Josuttis; chapter 20)
+ operator int ConversionToBool::* () const; //use member pointer as implicit conversion to bool (C++ Templates - Vandevoorde/Josuttis; chapter 20)
};
@@ -181,7 +181,7 @@ ComPtr<T>::operator bool() const
template <class T>
inline
-ComPtr<T>::operator int ComPtr<T>::ConversionToBool::*() const
+ComPtr<T>::operator int ComPtr<T>::ConversionToBool::* () const
{
return ptr != NULL ? &ConversionToBool::dummy : NULL;
}
diff --git a/shared/custom_button.cpp b/shared/custom_button.cpp
index ea473fc2..de057dc5 100644
--- a/shared/custom_button.cpp
+++ b/shared/custom_button.cpp
@@ -10,7 +10,7 @@
#include <algorithm>
-wxButtonWithImage::wxButtonWithImage(wxWindow *parent,
+wxButtonWithImage::wxButtonWithImage(wxWindow* parent,
wxWindowID id,
const wxString& label,
const wxPoint& pos,
diff --git a/shared/custom_button.h b/shared/custom_button.h
index 63875e42..4ebff73c 100644
--- a/shared/custom_button.h
+++ b/shared/custom_button.h
@@ -14,7 +14,7 @@
class wxButtonWithImage : public wxBitmapButton
{
public:
- wxButtonWithImage(wxWindow *parent,
+ wxButtonWithImage(wxWindow* parent,
wxWindowID id,
const wxString& label,
const wxPoint& pos = wxDefaultPosition,
diff --git a/shared/custom_combo_box.cpp b/shared/custom_combo_box.cpp
index a1f28b5c..f6084fdf 100644
--- a/shared/custom_combo_box.cpp
+++ b/shared/custom_combo_box.cpp
@@ -57,11 +57,11 @@ void CustomComboBox::OnKeyEvent(wxKeyEvent& event)
const int selectedItem = this->GetCurrentSelection();
if (0 <= selectedItem && selectedItem < static_cast<int>(this->GetCount()) &&
#if wxCHECK_VERSION(2, 9, 1)
- dropDownShown)
+ dropDownShown)
#else
- //what a mess...:
- (GetValue() != GetString(selectedItem) || //avoid problems when a character shall be deleted instead of list item
- GetValue() == wxEmptyString)) //exception: always allow removing empty entry
+ //what a mess...:
+ (GetValue() != GetString(selectedItem) || //avoid problems when a character shall be deleted instead of list item
+ GetValue() == wxEmptyString)) //exception: always allow removing empty entry
#endif
{
//save old (selected) value: deletion seems to have influence on this
diff --git a/shared/dir_name.cpp b/shared/dir_name.cpp
index 4ae3ef2f..5fd4eab2 100644
--- a/shared/dir_name.cpp
+++ b/shared/dir_name.cpp
@@ -164,8 +164,8 @@ void DirectoryNameMainDlg::OnFilesDropped(FFSFileDropEvent& event)
if (event.filesDropped_.empty())
return;
- if ( this->dropWindow1_ == event.dropWindow_ || //file may be dropped on window 1 or 2
- this->dropWindow2_ == event.dropWindow_)
+ if (this->dropWindow1_ == event.dropWindow_ || //file may be dropped on window 1 or 2
+ this->dropWindow2_ == event.dropWindow_)
{
if (AcceptDrop(event.filesDropped_))
{
diff --git a/shared/dst_hack.cpp b/shared/dst_hack.cpp
index 87ed6c2f..a2841ce0 100644
--- a/shared/dst_hack.cpp
+++ b/shared/dst_hack.cpp
@@ -18,22 +18,43 @@ bool dst::isFatDrive(const Zstring& fileName) //throw()
const size_t BUFFER_SIZE = MAX_PATH + 1;
wchar_t buffer[BUFFER_SIZE];
-//this call is expensive: ~1.5 ms!
-// if (!::GetVolumePathName(applyLongPathPrefix(fileName).c_str(), //__in LPCTSTR lpszFileName,
-// buffer, //__out LPTSTR lpszVolumePathName,
-// BUFFER_SIZE)) //__in DWORD cchBufferLength
-// ...
-// Zstring volumePath = buffer;
-// if (!volumePath.EndsWith(common::FILE_NAME_SEPARATOR)) //a trailing backslash is required
-// volumePath += common::FILE_NAME_SEPARATOR;
+ //this call is expensive: ~1.5 ms!
+ // if (!::GetVolumePathName(applyLongPathPrefix(fileName).c_str(), //__in LPCTSTR lpszFileName,
+ // buffer, //__out LPTSTR lpszVolumePathName,
+ // BUFFER_SIZE)) //__in DWORD cchBufferLength
+ // ...
+ // Zstring volumePath = buffer;
+ // if (!volumePath.EndsWith(common::FILE_NAME_SEPARATOR)) //a trailing backslash is required
+ // volumePath += common::FILE_NAME_SEPARATOR;
//fast ::GetVolumePathName() clone: let's hope it's not too simple (doesn't honor mount points)
- const Zstring nameFmt = removeLongPathPrefix(fileName); //throw()
- const size_t pos = nameFmt.find(Zstr(":\\"));
- if (pos != 1) //expect single letter volume
- return false;
- const Zstring volumePath(nameFmt.c_str(), 3);
-
+ Zstring volumePath;
+ {
+ Zstring nameFmt = removeLongPathPrefix(fileName); //throw()
+ if (!nameFmt.EndsWith(Zstr("\\")))
+ nameFmt += Zstr("\\"); //GetVolumeInformation expects trailing backslash
+
+ if (nameFmt.StartsWith(Zstr("\\\\"))) //UNC path: "\\ComputerName\SharedFolder\"
+ {
+ size_t nameSize = nameFmt.size();
+ const size_t posFirstSlash = nameFmt.find(Zstr("\\"), 2);
+ if (posFirstSlash != Zstring::npos)
+ {
+ nameSize = posFirstSlash + 1;
+ const size_t posSecondSlash = nameFmt.find(Zstr("\\"), posFirstSlash + 1);
+ if (posSecondSlash != Zstring::npos)
+ nameSize = posSecondSlash + 1;
+ }
+ volumePath = Zstring(nameFmt.c_str(), nameSize); //include trailing backslash!
+ }
+ else //local path: "C:\Folder\"
+ {
+ const size_t pos = nameFmt.find(Zstr(":\\"));
+ if (pos != 1) //expect single letter volume
+ return false;
+ volumePath = Zstring(nameFmt.c_str(), 3);
+ }
+ }
//suprisingly fast: ca. 0.03 ms per call!
if (!::GetVolumeInformation(volumePath.c_str(), //__in_opt LPCTSTR lpRootPathName,
NULL, //__out LPTSTR lpVolumeNameBuffer,
@@ -62,8 +83,8 @@ FILETIME utcToLocal(const FILETIME& utcTime) //throw (std::runtime_error)
//treat binary local time representation (which is invariant under DST time zone shift) as logical UTC:
FILETIME localTime = {};
if (!::FileTimeToLocalFileTime(
- &utcTime, //__in const FILETIME *lpFileTime,
- &localTime)) //__out LPFILETIME lpLocalFileTime
+ &utcTime, //__in const FILETIME *lpFileTime,
+ &localTime)) //__out LPFILETIME lpLocalFileTime
{
const wxString errorMessage = wxString(_("Conversion error:")) + wxT(" FILETIME -> local FILETIME: ") +
wxT("(") + wxULongLong(utcTime.dwHighDateTime, utcTime.dwLowDateTime).ToString() + wxT(") ") + wxT("\n\n") + ffs3::getLastErrorFormatted();
@@ -78,8 +99,8 @@ FILETIME localToUtc(const FILETIME& localTime) //throw (std::runtime_error)
//treat binary local time representation (which is invariant under DST time zone shift) as logical UTC:
FILETIME utcTime = {};
if (!::LocalFileTimeToFileTime(
- &localTime, //__in const FILETIME *lpLocalFileTime,
- &utcTime)) //__out LPFILETIME lpFileTime
+ &localTime, //__in const FILETIME *lpLocalFileTime,
+ &utcTime)) //__out LPFILETIME lpFileTime
{
const wxString errorMessage = wxString(_("Conversion error:")) + wxT(" local FILETIME -> FILETIME: ") +
wxT("(") + wxULongLong(localTime.dwHighDateTime, localTime.dwLowDateTime).ToString() + wxT(") ") + wxT("\n\n") + ffs3::getLastErrorFormatted();
@@ -224,7 +245,7 @@ std::bitset<UTC_LOCAL_OFFSET_BITS> getUtcLocalShift()
const int absValue = common::abs(timeShiftQuarter); //MSVC C++0x bug: std::bitset<>(unsigned long) is ambiguous
if (std::bitset<UTC_LOCAL_OFFSET_BITS - 1>(absValue).to_ulong() != static_cast<unsigned long>(absValue) || //time shifts that big shouldn't be possible!
- timeShiftSec % (60 * 15) != 0) //all known time shift have at least 15 minute granularity!
+ timeShiftSec % (60 * 15) != 0) //all known time shift have at least 15 minute granularity!
{
const wxString errorMessage = wxString(_("Conversion error:")) + wxT(" Unexpected UTC <-> local time shift: ") +
wxT("(") + wxLongLong(timeShiftSec).ToString() + wxT(") ") + wxT("\n\n") + ffs3::getLastErrorFormatted();
@@ -254,8 +275,8 @@ int convertUtcLocalShift(std::bitset<UTC_LOCAL_OFFSET_BITS> rawShift)
bool dst::fatHasUtcEncoded(const RawTime& rawTime) //"createTimeRaw" as retrieved by ::FindFirstFile() and ::GetFileAttributesEx(); throw (std::runtime_error)
{
- if ( cmpFileTime(rawTime.createTimeRaw, FAT_MIN_TIME) < 0 ||
- cmpFileTime(FAT_MAX_TIME, rawTime.createTimeRaw) < 0)
+ if (cmpFileTime(rawTime.createTimeRaw, FAT_MIN_TIME) < 0 ||
+ cmpFileTime(FAT_MAX_TIME, rawTime.createTimeRaw) < 0)
{
assert(false); //shouldn't be possible according to FAT specification
return false;
diff --git a/shared/file_handling.cpp b/shared/file_handling.cpp
index 10cab5ef..14a4b84c 100644
--- a/shared/file_handling.cpp
+++ b/shared/file_handling.cpp
@@ -16,7 +16,6 @@
#include "string_conv.h"
#include <wx/utils.h>
#include <boost/scoped_array.hpp>
-#include <boost/shared_ptr.hpp>
#include <stdexcept>
#include "loki/TypeManip.h"
#include "loki/ScopeGuard.h"
@@ -128,9 +127,9 @@ bool replaceMacro(wxString& macro) //macro without %-characters, return true if
macro.Trim(false); //
//remove leading, trailing double-quotes
- if ( macro.StartsWith(wxT("\"")) &&
- macro.EndsWith(wxT("\"")) &&
- macro.length() >= 2)
+ if (macro.StartsWith(wxT("\"")) &&
+ macro.EndsWith(wxT("\"")) &&
+ macro.length() >= 2)
macro = wxString(macro.c_str() + 1, macro.length() - 2);
return true;
}
@@ -219,7 +218,7 @@ bool ffs3::fileExists(const Zstring& filename)
#endif
}
-#include <wx/msgdlg.h>
+
bool ffs3::dirExists(const Zstring& dirname)
{
//symbolic links (broken or not) are also treated as existing directories!
@@ -278,7 +277,8 @@ wxULongLong getFileSizeSymlink(const Zstring& linkName) //throw (FileError)
NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
- boost::shared_ptr<void> dummy(hFile, ::CloseHandle);
+ Loki::ScopeGuard dummy = Loki::MakeGuard(::CloseHandle, hFile);
+ (void)dummy; //silence warning "unused variable"
BY_HANDLE_FILE_INFORMATION fileInfoByHandle;
if (::GetFileInformationByHandle(hFile, &fileInfoByHandle))
@@ -480,12 +480,12 @@ void renameFileInternal(const Zstring& oldName, const Zstring& newName) //throw
}
else
{
- const DWORD errorCode = ::GetLastError();
+ Loki::ScopeGuard dummy = Loki::MakeGuard(::SetLastError, ::GetLastError()); //use error code from ::MoveFileEx()
+ (void)dummy;
+
//cleanup: (try to) restore file attributes: assume oldName is still existing
::SetFileAttributes(oldNameFmt.c_str(),
oldNameAttrib);
-
- ::SetLastError(errorCode); //set error code from ::MoveFileEx()
}
}
}
@@ -514,16 +514,6 @@ void renameFileInternal(const Zstring& oldName, const Zstring& newName) //throw
}
-void renameFileInternalNoThrow(const Zstring& oldName, const Zstring& newName) //throw ()
-{
- try
- {
- ::renameFileInternal(oldName, newName);
- }
- catch (...) {}
-}
-
-
#ifdef FFS_WIN
/*small wrapper around
::GetShortPathName()
@@ -584,10 +574,10 @@ bool fix8Dot3NameClash(const Zstring& oldName, const Zstring& newName) //throw
const Zstring fileNameShort = getFilenameFmt(newName, ::GetShortPathName).AfterLast(common::FILE_NAME_SEPARATOR); //throw() returns empty string on error
const Zstring fileNameLong = getFilenameFmt(newName, ::GetLongPathName).AfterLast(common::FILE_NAME_SEPARATOR); //throw() returns empty string on error
- if ( !fileNameShort.empty() &&
- !fileNameLong.empty() &&
- EqualFilename()(fileNameOrig, fileNameShort) &&
- !EqualFilename()(fileNameShort, fileNameLong))
+ if (!fileNameShort.empty() &&
+ !fileNameLong.empty() &&
+ EqualFilename()(fileNameOrig, fileNameShort) &&
+ !EqualFilename()(fileNameShort, fileNameLong))
{
//we detected an event where newName is in shortname format (although it is intended to be a long name) and
//writing target file failed because another unrelated file happens to have the same short name
@@ -603,7 +593,7 @@ bool fix8Dot3NameClash(const Zstring& oldName, const Zstring& newName) //throw
//DON'T call ffs3::renameFile() to avoid reentrance!
//schedule cleanup; the file system should assign this unrelated file a new (unique) short name
- Loki::ScopeGuard guard = Loki::MakeGuard(renameFileInternalNoThrow, parkedTarget, unrelatedPathLong);//equivalent to Boost.ScopeExit in this case
+ Loki::ScopeGuard guard = Loki::MakeGuard(renameFileInternal, parkedTarget, unrelatedPathLong);//equivalent to Boost.ScopeExit in this case
(void)guard; //silence warning "unused variable"
renameFileInternal(oldName, newName); //the short filename name clash is solved, this should work now
@@ -645,11 +635,11 @@ public:
{
switch (moveCallback.requestUiRefresh(sourceFile_))
{
- case MoveFileCallback::CONTINUE:
- return CopyFileCallback::CONTINUE;
+ case MoveFileCallback::CONTINUE:
+ return CopyFileCallback::CONTINUE;
- case MoveFileCallback::CANCEL:
- return CopyFileCallback::CANCEL;
+ case MoveFileCallback::CANCEL:
+ return CopyFileCallback::CANCEL;
}
return CopyFileCallback::CONTINUE; //dummy return value
}
@@ -666,11 +656,11 @@ void ffs3::moveFile(const Zstring& sourceFile, const Zstring& targetFile, MoveFi
if (callback)
switch (callback->requestUiRefresh(sourceFile))
{
- case MoveFileCallback::CONTINUE:
- break;
- case MoveFileCallback::CANCEL: //a user aborted operation IS an error condition!
- throw FileError(wxString(_("Error moving file:")) + wxT("\n\"") + zToWx(sourceFile) + wxT("\" ->\n\"") + zToWx(targetFile) + wxT("\"") +
- wxT("\n\n") + _("Operation aborted!"));
+ case MoveFileCallback::CONTINUE:
+ break;
+ case MoveFileCallback::CANCEL: //a user aborted operation IS an error condition!
+ throw FileError(wxString(_("Error moving file:")) + wxT("\n\"") + zToWx(sourceFile) + wxT("\" ->\n\"") + zToWx(targetFile) + wxT("\"") +
+ wxT("\n\n") + _("Operation aborted!"));
}
//support case-sensitive renaming
@@ -762,11 +752,11 @@ struct RemoveCallbackImpl : public ffs3::RemoveDirCallback
{
switch (moveCallback_.requestUiRefresh(sourceDir_))
{
- case MoveFileCallback::CONTINUE:
- break;
- case MoveFileCallback::CANCEL: //a user aborted operation IS an error condition!
- throw ffs3::FileError(wxString(_("Error moving directory:")) + wxT("\n\"") + ffs3::zToWx(sourceDir_) + wxT("\" ->\n\"") +
- ffs3::zToWx(targetDir_) + wxT("\"") + wxT("\n\n") + _("Operation aborted!"));
+ case MoveFileCallback::CONTINUE:
+ break;
+ case MoveFileCallback::CANCEL: //a user aborted operation IS an error condition!
+ throw ffs3::FileError(wxString(_("Error moving directory:")) + wxT("\n\"") + ffs3::zToWx(sourceDir_) + wxT("\" ->\n\"") +
+ ffs3::zToWx(targetDir_) + wxT("\"") + wxT("\n\n") + _("Operation aborted!"));
}
}
@@ -786,11 +776,11 @@ void moveDirectoryImpl(const Zstring& sourceDir, const Zstring& targetDir, bool
if (callback)
switch (callback->requestUiRefresh(sourceDir))
{
- case MoveFileCallback::CONTINUE:
- break;
- case MoveFileCallback::CANCEL: //a user aborted operation IS an error condition!
- throw FileError(wxString(_("Error moving directory:")) + wxT("\n\"") + zToWx(sourceDir) + wxT("\" ->\n\"") +
- zToWx(targetDir) + wxT("\"") + wxT("\n\n") + _("Operation aborted!"));
+ case MoveFileCallback::CONTINUE:
+ break;
+ case MoveFileCallback::CANCEL: //a user aborted operation IS an error condition!
+ throw FileError(wxString(_("Error moving directory:")) + wxT("\n\"") + zToWx(sourceDir) + wxT("\" ->\n\"") +
+ zToWx(targetDir) + wxT("\"") + wxT("\n\n") + _("Operation aborted!"));
}
//handle symbolic links
@@ -915,9 +905,9 @@ void ffs3::removeDirectory(const Zstring& directory, RemoveDirCallback* callback
const Zstring directoryFmt = applyLongPathPrefix(directory); //support for \\?\-prefix
//initialize file attributes
- if (!::SetFileAttributes( // initialize file attributes: actually NEEDED for symbolic links also!
- directoryFmt.c_str(), // address of directory name
- FILE_ATTRIBUTE_NORMAL)) // attributes to set
+ if (!::SetFileAttributes( // initialize file attributes: actually NEEDED for symbolic links also!
+ directoryFmt.c_str(), // address of directory name
+ FILE_ATTRIBUTE_NORMAL)) // attributes to set
{
wxString errorMessage = wxString(_("Error deleting directory:")) + wxT("\n\"") + directory.c_str() + wxT("\"");
throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
@@ -1010,7 +1000,9 @@ void ffs3::copyFileTimes(const Zstring& sourceObj, const Zstring& targetObj, boo
const wxString errorMessage = wxString(_("Error reading file attributes:")) + wxT("\n\"") + zToWx(sourceObj) + wxT("\"");
throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
}
- boost::shared_ptr<void> dummy(hSource, ::CloseHandle);
+
+ Loki::ScopeGuard dummy = Loki::MakeGuard(::CloseHandle, hSource);
+ (void)dummy; //silence warning "unused variable"
if (!::GetFileTime(hSource, //__in HANDLE hFile,
&creationTime, //__out_opt LPFILETIME lpCreationTime,
@@ -1028,7 +1020,7 @@ void ffs3::copyFileTimes(const Zstring& sourceObj, const Zstring& targetObj, boo
lastWriteTime = sourceAttr.ftLastWriteTime;
}
-//####################################### DST hack ###########################################
+ //####################################### DST hack ###########################################
if (!isDirectory) //dst hack not (yet) required for directories (symlinks implicitly checked by isFatDrive())
{
if (dst::isFatDrive(sourceObj)) //throw()
@@ -1048,7 +1040,7 @@ void ffs3::copyFileTimes(const Zstring& sourceObj, const Zstring& targetObj, boo
lastWriteTime = encodedTime.writeTimeRaw;
}
}
-//####################################### DST hack ###########################################
+ //####################################### DST hack ###########################################
}
@@ -1068,7 +1060,8 @@ void ffs3::copyFileTimes(const Zstring& sourceObj, const Zstring& targetObj, boo
wxString errorMessage = wxString(_("Error changing modification time:")) + wxT("\n\"") + zToWx(targetObj) + wxT("\"");
throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
}
- boost::shared_ptr<void> dummy(hTarget, ::CloseHandle);
+ Loki::ScopeGuard dummy = Loki::MakeGuard(::CloseHandle, hTarget);
+ (void)dummy; //silence warning "unused variable"
if (!::SetFileTime(hTarget,
&creationTime,
@@ -1141,6 +1134,28 @@ void ffs3::copyFileTimes(const Zstring& sourceObj, const Zstring& targetObj, boo
namespace
{
+struct TryCleanUp
+{
+ static void tryDeleteDir(const Zstring& dirname) //throw ()
+ {
+ try
+ {
+ ffs3::removeDirectory(dirname, NULL);
+ }
+ catch (...) {}
+ }
+
+ static void tryDeleteFile(const Zstring& filename) //throw ()
+ {
+ try
+ {
+ ffs3::removeFile(filename);
+ }
+ catch (...) {}
+ }
+};
+
+
#ifdef FFS_WIN
Zstring resolveDirectorySymlink(const Zstring& dirLinkName) //get full target path of symbolic link to a directory; throw (FileError)
{
@@ -1158,7 +1173,8 @@ Zstring resolveDirectorySymlink(const Zstring& dirLinkName) //get full target pa
throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
}
- boost::shared_ptr<void> dummy(hDir, ::CloseHandle);
+ Loki::ScopeGuard dummy = Loki::MakeGuard(::CloseHandle, hDir);
+ (void)dummy; //silence warning "unused variable"
const size_t BUFFER_SIZE = 10000;
TCHAR targetPath[BUFFER_SIZE];
@@ -1189,13 +1205,39 @@ Zstring resolveDirectorySymlink(const Zstring& dirLinkName) //get full target pa
return targetPath;
}
+#endif
-
-#elif defined FFS_LINUX
-void copySymlinkInternal(const Zstring& sourceLink, const Zstring& targetLink, bool copyFilePermissions) //throw (FileError)
+enum SymlinkType
+{
+ SYMLINK_TYPE_FILE,
+ SYMLINK_TYPE_DIR
+};
+void copySymlinkInternal(const Zstring& sourceLink, const Zstring& targetLink, SymlinkType type, bool copyFilePermissions) //throw (FileError)
{
using namespace ffs3;
+#ifdef FFS_WIN
+ const Zstring linkPath = getSymlinkRawTargetString(sourceLink); //accept broken symlinks; throw (FileError)
+
+ //dynamically load windows API function
+ typedef BOOLEAN (WINAPI *CreateSymbolicLinkFunc)(
+ LPCTSTR lpSymlinkFileName,
+ LPCTSTR lpTargetFileName,
+ DWORD dwFlags);
+ static const CreateSymbolicLinkFunc createSymbolicLink = util::getDllFun<CreateSymbolicLinkFunc>(L"kernel32.dll", "CreateSymbolicLinkW");
+ if (createSymbolicLink == NULL)
+ throw FileError(wxString(_("Error loading library function:")) + wxT("\n\"") + wxT("CreateSymbolicLinkW") + wxT("\""));
+
+ if (!createSymbolicLink( //seems no long path prefix is required...
+ targetLink.c_str(), //__in LPTSTR lpSymlinkFileName,
+ linkPath.c_str(), //__in LPTSTR lpTargetFileName,
+ (type == SYMLINK_TYPE_DIR ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0))) //__in DWORD dwFlags
+ {
+ const wxString errorMessage = wxString(_("Error copying symbolic link:")) + wxT("\n\"") + zToWx(sourceLink) + wxT("\" ->\n\"") + zToWx(targetLink) + wxT("\"");
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
+ }
+
+#elif defined FFS_LINUX
//copy symbolic link
const int BUFFER_SIZE = 10000;
char buffer[BUFFER_SIZE];
@@ -1214,18 +1256,20 @@ void copySymlinkInternal(const Zstring& sourceLink, const Zstring& targetLink, b
const wxString errorMessage = wxString(_("Error copying symbolic link:")) + wxT("\n\"") + zToWx(sourceLink) + wxT("\" ->\n\"") + zToWx(targetLink) + wxT("\"");
throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
}
+#endif
//allow only consistent objects to be created -> don't place before ::symlink, targetLink may already exist
- Loki::ScopeGuard guardTargetLink = Loki::MakeGuard(::unlink, targetLink);
+ Loki::ScopeGuard guardNewDir = type == SYMLINK_TYPE_DIR ?
+ Loki::MakeGuard(&TryCleanUp::tryDeleteDir, targetLink) :
+ Loki::MakeGuard(&TryCleanUp::tryDeleteFile, targetLink);
copyFileTimes(sourceLink, targetLink, false); //throw (FileError)
if (copyFilePermissions)
copyObjectPermissions(sourceLink, targetLink, false); //throw FileError()
- guardTargetLink.Dismiss();
+ guardNewDir.Dismiss(); //target has been created successfully!
}
-#endif
}
@@ -1241,14 +1285,15 @@ void copySecurityContext(const Zstring& source, const Zstring& target, bool dere
::lgetfilecon(source.c_str(), &contextSource);
if (rv < 0)
{
- if ( errno == ENODATA || //no security context (allegedly) is not an error condition on SELinux
- errno == EOPNOTSUPP) //extended attributes are not supported by the filesystem
+ if (errno == ENODATA || //no security context (allegedly) is not an error condition on SELinux
+ errno == EOPNOTSUPP) //extended attributes are not supported by the filesystem
return;
wxString errorMessage = wxString(_("Error reading security context:")) + wxT("\n\"") + zToWx(source) + wxT("\"");
throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
}
- boost::shared_ptr<char> dummy1(contextSource, ::freecon);
+ Loki::ScopeGuard dummy1 = Loki::MakeGuard(::freecon, contextSource);
+ (void)dummy1; //silence warning "unused variable"
{
security_context_t contextTarget = NULL;
@@ -1263,7 +1308,9 @@ void copySecurityContext(const Zstring& source, const Zstring& target, bool dere
}
else
{
- boost::shared_ptr<char> dummy2(contextTarget, ::freecon);
+ Loki::ScopeGuard dummy2 = Loki::MakeGuard(::freecon, contextTarget);
+ (void)dummy2; //silence warning "unused variable"
+
if (::strcmp(contextSource, contextTarget) == 0) //nothing to do
return;
}
@@ -1281,8 +1328,8 @@ void copySecurityContext(const Zstring& source, const Zstring& target, bool dere
#endif //HAVE_SELINUX
-//copy permissions for files, directories or symbolic links:
-void ffs3::copyObjectPermissions(const Zstring& source, const Zstring& target, bool derefSymlinks) //throw FileError(); probably requires admin rights
+//copy permissions for files, directories or symbolic links: requires admin rights
+void ffs3::copyObjectPermissions(const Zstring& source, const Zstring& target, bool derefSymlinks) //throw FileError();
{
#ifdef FFS_WIN
//setting privileges requires admin rights!
@@ -1315,9 +1362,10 @@ void ffs3::copyObjectPermissions(const Zstring& source, const Zstring& target, b
const wxString errorMessage = wxString(_("Error copying file permissions:")) + wxT("\n\"") + zToWx(source) + wxT("\" ->\n\"") + zToWx(target) + wxT("\"") + wxT("\n\n");
throw FileError(errorMessage + ffs3::getLastErrorFormatted() + wxT(" (OR)"));
}
- boost::shared_ptr<void> dummy(hSource, ::CloseHandle);
+ Loki::ScopeGuard dummy = Loki::MakeGuard(::CloseHandle, hSource);
+ (void)dummy; //silence warning "unused variable"
-// DWORD rc = ::GetNamedSecurityInfo(const_cast<WCHAR*>(applyLongPathPrefix(source).c_str()), -> does NOT dereference symlinks!
+ // DWORD rc = ::GetNamedSecurityInfo(const_cast<WCHAR*>(applyLongPathPrefix(source).c_str()), -> does NOT dereference symlinks!
DWORD rc = ::GetSecurityInfo(
hSource, //__in LPTSTR pObjectName,
SE_FILE_OBJECT, //__in SE_OBJECT_TYPE ObjectType,
@@ -1332,7 +1380,9 @@ void ffs3::copyObjectPermissions(const Zstring& source, const Zstring& target, b
const wxString errorMessage = wxString(_("Error copying file permissions:")) + wxT("\n\"") + zToWx(source) + wxT("\" ->\n\"") + zToWx(target) + wxT("\"") + wxT("\n\n");
throw FileError(errorMessage + ffs3::getLastErrorFormatted(rc) + wxT(" (R)"));
}
- boost::shared_ptr<void> dummy2(buffer, ::LocalFree);
+
+ Loki::ScopeGuard dummy4 = Loki::MakeGuard(::LocalFree, buffer);
+ (void)dummy4; //silence warning "unused variable"
const Zstring targetFmt = ffs3::applyLongPathPrefix(target);
@@ -1340,8 +1390,8 @@ void ffs3::copyObjectPermissions(const Zstring& source, const Zstring& target, b
//read-only file attribute may cause trouble: temporarily reset it
const DWORD targetAttr = ::GetFileAttributes(targetFmt.c_str());
Loki::ScopeGuard resetAttributes = Loki::MakeGuard(::SetFileAttributes, targetFmt, targetAttr);
- if ( targetAttr != INVALID_FILE_ATTRIBUTES &&
- (targetAttr & FILE_ATTRIBUTE_READONLY))
+ if (targetAttr != INVALID_FILE_ATTRIBUTES &&
+ (targetAttr & FILE_ATTRIBUTE_READONLY))
::SetFileAttributes(targetFmt.c_str(), targetAttr & (~FILE_ATTRIBUTE_READONLY)); //try to...
else
resetAttributes.Dismiss();
@@ -1359,9 +1409,10 @@ void ffs3::copyObjectPermissions(const Zstring& source, const Zstring& target, b
const wxString errorMessage = wxString(_("Error copying file permissions:")) + wxT("\n\"") + zToWx(source) + wxT("\" ->\n\"") + zToWx(target) + wxT("\"") + wxT("\n\n");
throw FileError(errorMessage + ffs3::getLastErrorFormatted() + wxT(" (OW)"));
}
- boost::shared_ptr<void> dummy3(hTarget, ::CloseHandle);
+ Loki::ScopeGuard dummy2 = Loki::MakeGuard(::CloseHandle, hTarget);
+ (void)dummy2; //silence warning "unused variable"
-// rc = ::SetNamedSecurityInfo(const_cast<WCHAR*>(applyLongPathPrefix(target).c_str()), //__in LPTSTR pObjectName, -> does NOT dereference symlinks!
+ // rc = ::SetNamedSecurityInfo(const_cast<WCHAR*>(applyLongPathPrefix(target).c_str()), //__in LPTSTR pObjectName, -> does NOT dereference symlinks!
rc = ::SetSecurityInfo(
hTarget, //__in LPTSTR pObjectName,
SE_FILE_OBJECT, //__in SE_OBJECT_TYPE ObjectType,
@@ -1386,9 +1437,9 @@ void ffs3::copyObjectPermissions(const Zstring& source, const Zstring& target, b
if (derefSymlinks)
{
struct stat fileInfo;
- if ( ::stat(source.c_str(), &fileInfo) != 0 ||
- ::chown(target.c_str(), fileInfo.st_uid, fileInfo.st_gid) != 0 || // may require admin rights!
- ::chmod(target.c_str(), fileInfo.st_mode) != 0)
+ if (::stat(source.c_str(), &fileInfo) != 0 ||
+ ::chown(target.c_str(), fileInfo.st_uid, fileInfo.st_gid) != 0 || // may require admin rights!
+ ::chmod(target.c_str(), fileInfo.st_mode) != 0)
{
const wxString errorMessage = wxString(_("Error copying file permissions:")) + wxT("\n\"") + zToWx(source) + wxT("\" ->\n\"") + zToWx(target) + wxT("\"") + wxT("\n\n");
throw FileError(errorMessage + ffs3::getLastErrorFormatted() + wxT(" (R)"));
@@ -1397,9 +1448,9 @@ void ffs3::copyObjectPermissions(const Zstring& source, const Zstring& target, b
else
{
struct stat fileInfo;
- if ( ::lstat(source.c_str(), &fileInfo) != 0 ||
- ::lchown(target.c_str(), fileInfo.st_uid, fileInfo.st_gid) != 0 || // may require admin rights!
- (!symlinkExists(target) && ::chmod(target.c_str(), fileInfo.st_mode) != 0)) //setting access permissions doesn't make sense for symlinks on Linux: there is no lchmod()
+ if (::lstat(source.c_str(), &fileInfo) != 0 ||
+ ::lchown(target.c_str(), fileInfo.st_uid, fileInfo.st_gid) != 0 || // may require admin rights!
+ (!symlinkExists(target) && ::chmod(target.c_str(), fileInfo.st_mode) != 0)) //setting access permissions doesn't make sense for symlinks on Linux: there is no lchmod()
{
const wxString errorMessage = wxString(_("Error copying file permissions:")) + wxT("\n\"") + zToWx(source) + wxT("\" ->\n\"") + zToWx(target) + wxT("\"") + wxT("\n\n");
throw FileError(errorMessage + ffs3::getLastErrorFormatted() + wxT(" (W)"));
@@ -1428,40 +1479,31 @@ void createDirectoryRecursively(const Zstring& directory, const Zstring& templat
createDirectoryRecursively(dirParent, templateParent, false, copyFilePermissions, level + 1); //don't create symbolic links in recursion!
}
- struct TryCleanUp
- {
- static void tryDeleteDir(const Zstring& dirname) //throw ()
- {
- try
- {
- removeDirectory(dirname, NULL);
- }
- catch (...) {}
- }
- };
-
//now creation should be possible
-#ifdef FFS_WIN
- const DWORD templateAttr = templateDir.empty() ? INVALID_FILE_ATTRIBUTES :
- ::GetFileAttributes(applyLongPathPrefix(templateDir).c_str()); //returns successful for broken symlinks
- if (templateAttr == INVALID_FILE_ATTRIBUTES) //fallback
+
+ if (templateDir.empty() || !somethingExists(templateDir))
{
- if (!::CreateDirectory(applyLongPathPrefixCreateDir(directory).c_str(), // pointer to a directory path string
- NULL))
+ //default directory creation
+#ifdef FFS_WIN
+ if (!::CreateDirectory(applyLongPathPrefixCreateDir(directory).c_str(), NULL))// pointer to a directory path string
+#elif defined FFS_LINUX
+ if (::mkdir(directory.c_str(), 0755) != 0)
+#endif
{
if (level != 0) return;
- const wxString errorMessage = wxString(_("Error creating directory:")) + wxT("\n\"") + directory.c_str() + wxT("\"");
+ wxString errorMessage = wxString(_("Error creating directory:")) + wxT("\n\"") + zToWx(directory) + wxT("\"");
throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
}
}
else
{
- const bool isSymlink = (templateAttr & FILE_ATTRIBUTE_REPARSE_POINT) != 0; //syntax required to shut MSVC up
-
+#ifdef FFS_WIN
//symbolic link handling
- if (isSymlink)
+ if (symlinkExists(templateDir))
{
- if (!copyDirectorySymLinks) //create directory based on target of symbolic link
+ if (copyDirectorySymLinks)
+ return copySymlinkInternal(templateDir, directory, SYMLINK_TYPE_DIR, copyFilePermissions); //throw (FileError)
+ else //create directory based on target of symbolic link
{
//get target directory of symbolic link
Zstring linkPath;
@@ -1482,48 +1524,25 @@ void createDirectoryRecursively(const Zstring& directory, const Zstring& templat
return;
}
- if (!::CreateDirectoryEx( // this function automatically copies symbolic links if encountered
- applyLongPathPrefix(linkPath).c_str(), // pointer to path string of template directory
- applyLongPathPrefixCreateDir(directory).c_str(), // pointer to a directory path string
- NULL))
+ if (!::CreateDirectoryEx( // this function automatically copies symbolic links if encountered
+ applyLongPathPrefix(linkPath).c_str(), // pointer to path string of template directory
+ applyLongPathPrefixCreateDir(directory).c_str(), // pointer to a directory path string
+ NULL))
{
if (level != 0) return;
const wxString errorMessage = wxString(_("Error creating directory:")) + wxT("\n\"") + directory.c_str() + wxT("\"");
throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
}
}
- else //copy symbolic link
- {
- const Zstring linkPath = getSymlinkRawTargetString(templateDir); //accept broken symlinks; throw (FileError)
-
- //dynamically load windows API function
- typedef BOOLEAN (WINAPI *CreateSymbolicLinkFunc)(
- LPCTSTR lpSymlinkFileName,
- LPCTSTR lpTargetFileName,
- DWORD dwFlags);
- static const CreateSymbolicLinkFunc createSymbolicLink = util::getDllFun<CreateSymbolicLinkFunc>(L"kernel32.dll", "CreateSymbolicLinkW");
- if (createSymbolicLink == NULL)
- throw FileError(wxString(_("Error loading library function:")) + wxT("\n\"") + wxT("CreateSymbolicLinkW") + wxT("\""));
-
- if (!createSymbolicLink( //seems no long path prefix is required...
- directory.c_str(), //__in LPTSTR lpSymlinkFileName,
- linkPath.c_str(), //__in LPTSTR lpTargetFileName,
- SYMBOLIC_LINK_FLAG_DIRECTORY)) //__in DWORD dwFlags
- {
- //if (level != 0) return;
- const wxString errorMessage = wxString(_("Error copying symbolic link:")) + wxT("\n\"") + templateDir.c_str() + wxT("\" ->\n\"") + directory.c_str() + wxT("\"");
- throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
- }
- }
}
else //no symbolic link
{
//automatically copies symbolic links if encountered: unfortunately it doesn't copy symlinks over network shares but silently creates empty folders instead (on XP)!
//also it isn't able to copy most junctions because of missing permissions (although target path can be retrieved!)
if (!::CreateDirectoryEx(
- applyLongPathPrefix(templateDir).c_str(), // pointer to path string of template directory
- applyLongPathPrefixCreateDir(directory).c_str(), // pointer to a directory path string
- NULL))
+ applyLongPathPrefix(templateDir).c_str(), // pointer to path string of template directory
+ applyLongPathPrefixCreateDir(directory).c_str(), // pointer to a directory path string
+ NULL))
{
if (level != 0) return;
const wxString errorMessage = wxString(_("Error creating directory:")) + wxT("\n\"") + directory.c_str() + wxT("\"");
@@ -1531,42 +1550,30 @@ void createDirectoryRecursively(const Zstring& directory, const Zstring& templat
}
}
- //ensure cleanup:
- Loki::ScopeGuard guardNewDir = Loki::MakeGuard(&TryCleanUp::tryDeleteDir, directory);
+#elif defined FFS_LINUX
+ //symbolic link handling
+ if (copyDirectorySymLinks &&
+ symlinkExists(templateDir))
+ //there is no directory-type symlink in Linux! => just copy as file
+ return copySymlinkInternal(templateDir, directory, SYMLINK_TYPE_DIR, copyFilePermissions); //throw (FileError)
+
+ //default directory creation
+ if (::mkdir(directory.c_str(), 0755) != 0)
+ {
+ if (level != 0) return;
+ wxString errorMessage = wxString(_("Error creating directory:")) + wxT("\n\"") + zToWx(directory) + wxT("\"");
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
+ }
+#endif
+ Loki::ScopeGuard guardNewDir = Loki::MakeGuard(&TryCleanUp::tryDeleteDir, directory); //ensure cleanup:
- if (copyDirectorySymLinks && isSymlink) //we need to copy the Symbolic Link's change date manually
- copyFileTimes(templateDir, directory, false); //throw (FileError)
+ copyFileTimes(templateDir, directory, !copyDirectorySymLinks); //throw (FileError)
if (copyFilePermissions)
copyObjectPermissions(templateDir, directory, !copyDirectorySymLinks); //throw FileError()
guardNewDir.Dismiss(); //target has been created successfully!
}
-
-#elif defined FFS_LINUX
- //symbolic link handling
- if ( copyDirectorySymLinks &&
- !templateDir.empty() &&
- symlinkExists(templateDir))
- //there is no directory-type symlink in Linux! => just copy as file
- return copySymlinkInternal(templateDir, directory, copyFilePermissions); //throw (FileError)
-
- //default directory creation
- if (::mkdir(directory.c_str(), 0755) != 0)
- {
- if (level != 0) return;
- wxString errorMessage = wxString(_("Error creating directory:")) + wxT("\n\"") + zToWx(directory) + wxT("\"");
- throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
- }
-
- //ensure cleanup:
- Loki::ScopeGuard guardNewDir = Loki::MakeGuard(&TryCleanUp::tryDeleteDir, directory);
-
- if (!templateDir.empty() && copyFilePermissions)
- copyObjectPermissions(templateDir, directory, true); //throw FileError()
-
- guardNewDir.Dismiss(); //target has been created successfully!
-#endif
}
@@ -1644,10 +1651,10 @@ DWORD CALLBACK copyCallbackInternal(
{
switch (callback->updateCopyStatus(wxULongLong(totalBytesTransferred.HighPart, totalBytesTransferred.LowPart)))
{
- case CopyFileCallback::CONTINUE:
- break;
- case CopyFileCallback::CANCEL:
- return PROGRESS_CANCEL;
+ case CopyFileCallback::CONTINUE:
+ break;
+ case CopyFileCallback::CANCEL:
+ return PROGRESS_CANCEL;
}
}
catch (...)
@@ -1719,27 +1726,16 @@ void ffs3::copyFile(const Zstring& sourceFile,
const Zstring temporary = createTempName(targetFile); //use temporary file until a correct date has been set
- struct TryCleanUp //ensure cleanup if working with temporary failed!
- {
- static void tryDeleteFile(const Zstring& filename) //throw ()
- {
- try
- {
- removeFile(filename);
- }
- catch (...) {}
- }
- };
- Loki::ScopeGuard guardTempFile = Loki::MakeGuard(&TryCleanUp::tryDeleteFile, temporary);
+ Loki::ScopeGuard guardTempFile = Loki::MakeGuard(&ffs3::removeFile, temporary);
if (!::CopyFileEx( //same performance as CopyFile()
- applyLongPathPrefix(sourceFile).c_str(),
- applyLongPathPrefix(temporary).c_str(),
- callback != NULL ? copyCallbackInternal : NULL,
- callback,
- NULL,
- copyFlags))
+ applyLongPathPrefix(sourceFile).c_str(),
+ applyLongPathPrefix(temporary).c_str(),
+ callback != NULL ? copyCallbackInternal : NULL,
+ callback,
+ NULL,
+ copyFlags))
{
const DWORD lastError = ::GetLastError();
@@ -1747,8 +1743,8 @@ void ffs3::copyFile(const Zstring& sourceFile,
//if file is locked (try to) use Windows Volume Shadow Copy Service
if (shadowCopyHandler != NULL &&
- (lastError == ERROR_SHARING_VIOLATION ||
- lastError == ERROR_LOCK_VIOLATION))
+ (lastError == ERROR_SHARING_VIOLATION ||
+ lastError == ERROR_LOCK_VIOLATION))
{
//shadowFilename already contains prefix: E.g. "\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Program Files\FFS\sample.dat"
@@ -1772,9 +1768,22 @@ void ffs3::copyFile(const Zstring& sourceFile,
NULL,
callback);
}
+
//assemble error message...
- const wxString errorMessage = wxString(_("Error copying file:")) + wxT("\n\"") + sourceFile.c_str() + wxT("\" ->\n\"") + targetFile.c_str() + wxT("\"") + wxT("\n\n");
- throw FileError(errorMessage + ffs3::getLastErrorFormatted(lastError));
+ wxString errorMessage = wxString(_("Error copying file:")) + wxT("\n\"") + sourceFile.c_str() + wxT("\" ->\n\"") + targetFile.c_str() + wxT("\"") +
+ wxT("\n\n") + ffs3::getLastErrorFormatted(lastError);
+
+ try //add more meaningful message
+ {
+ //trying to copy > 4GB file to FAT/FAT32 volume gives obscure ERROR_INVALID_PARAMETER (FAT can indeed handle files up to 4 Gig, tested!)
+ if (lastError == ERROR_INVALID_PARAMETER &&
+ dst::isFatDrive(targetFile) &&
+ getFilesize(sourceFile) >= (wxULongLong(1024 * 1024 * 1024)*=4)) //throw (FileError)
+ errorMessage += wxT("\nFAT volume cannot store file larger than 4 gigabyte!");
+ }
+ catch(...) {}
+
+ throw FileError(errorMessage);
}
//rename temporary file: do not add anything else here (note specific error handing)
@@ -1782,14 +1791,14 @@ void ffs3::copyFile(const Zstring& sourceFile,
guardTempFile.Dismiss(); //no need to delete temp file anymore
- Loki::ScopeGuard guardTargetFile = Loki::MakeGuard(&TryCleanUp::tryDeleteFile, targetFile);
-
- if (copyFilePermissions)
- copyObjectPermissions(sourceFile, targetFile, !copyFileSymLinks); //throw FileError()
+ Loki::ScopeGuard guardTargetFile = Loki::MakeGuard(&ffs3::removeFile, targetFile);
//copy creation date (last modification date is REDUNDANTLY written, too, even for symlinks)
copyFileTimes(sourceFile, targetFile, !copyFileSymLinks); //throw (FileError)
+ if (copyFilePermissions)
+ copyObjectPermissions(sourceFile, targetFile, !copyFileSymLinks); //throw FileError()
+
guardTargetFile.Dismiss();
}
@@ -1804,10 +1813,10 @@ void ffs3::copyFile(const Zstring& sourceFile,
using ffs3::CopyFileCallback;
//symbolic link handling
- if ( copyFileSymLinks &&
- symlinkExists(sourceFile))
+ if (copyFileSymLinks &&
+ symlinkExists(sourceFile))
{
- return copySymlinkInternal(sourceFile, targetFile, copyFilePermissions); //throw (FileError)
+ return copySymlinkInternal(sourceFile, targetFile, SYMLINK_TYPE_FILE, copyFilePermissions); //throw (FileError)
}
//begin of regular file copy
@@ -1825,7 +1834,8 @@ void ffs3::copyFile(const Zstring& sourceFile,
const Zstring temporary = createTempName(targetFile); //use temporary file until a correct date has been set
//ensure cleanup (e.g. network drop): call BEFORE creating fileOut object!
- Loki::ScopeGuard guardTempFile = Loki::MakeGuard(::unlink, temporary);
+ Loki::ScopeGuard guardTempFile = Loki::MakeGuard(&ffs3::removeFile, temporary);
+
FileOutput fileOut(temporary); //throw FileError()
@@ -1846,12 +1856,12 @@ void ffs3::copyFile(const Zstring& sourceFile,
if (callback != NULL)
switch (callback->updateCopyStatus(totalBytesTransferred))
{
- case CopyFileCallback::CONTINUE:
- break;
+ case CopyFileCallback::CONTINUE:
+ break;
- case CopyFileCallback::CANCEL: //a user aborted operation IS an error condition!
- throw FileError(wxString(_("Error copying file:")) + wxT("\n\"") + zToWx(sourceFile) + wxT("\" ->\n\"") +
- zToWx(targetFile) + wxT("\"\n\n") + _("Operation aborted!"));
+ case CopyFileCallback::CANCEL: //a user aborted operation IS an error condition!
+ throw FileError(wxString(_("Error copying file:")) + wxT("\n\"") + zToWx(sourceFile) + wxT("\" ->\n\"") +
+ zToWx(targetFile) + wxT("\"\n\n") + _("Operation aborted!"));
}
}
while (!fileIn.eof());
@@ -1864,7 +1874,7 @@ void ffs3::copyFile(const Zstring& sourceFile,
guardTempFile.Dismiss();
//ensure cleanup:
- Loki::ScopeGuard guardTargetFile = Loki::MakeGuard(::unlink, targetFile.c_str());
+ Loki::ScopeGuard guardTargetFile = Loki::MakeGuard(&ffs3::removeFile, targetFile);
//adapt file modification time:
copyFileTimes(sourceFile, targetFile, true); //throw (FileError)
diff --git a/shared/file_id.cpp b/shared/file_id.cpp
index 7b091201..eb3be8d6 100644
--- a/shared/file_id.cpp
+++ b/shared/file_id.cpp
@@ -9,7 +9,7 @@
#ifdef FFS_WIN
#include <wx/msw/wrapwin.h> //includes "windows.h"
#include "long_path_prefix.h"
-#include <boost/shared_ptr.hpp>
+#include "loki/ScopeGuard.h"
#elif defined FFS_LINUX
#include <sys/stat.h>
@@ -33,12 +33,12 @@ std::string util::retrieveFileID(const Zstring& filename)
std::string fileID;
#ifdef FFS_WIN
-//WARNING: CreateFile() is SLOW, while GetFileInformationByHandle() is cheap!
-//http://msdn.microsoft.com/en-us/library/aa363788(VS.85).aspx
+ //WARNING: CreateFile() is SLOW, while GetFileInformationByHandle() is cheap!
+ //http://msdn.microsoft.com/en-us/library/aa363788(VS.85).aspx
- //privilege SE_BACKUP_NAME doesn't seem to be required here at all
- //note: setting privileges requires admin rights!
+ //privilege SE_BACKUP_NAME doesn't seem to be required here at all
+ //note: setting privileges requires admin rights!
const HANDLE hFile = ::CreateFile(ffs3::applyLongPathPrefix(filename).c_str(),
0,
@@ -49,7 +49,8 @@ std::string util::retrieveFileID(const Zstring& filename)
NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
- boost::shared_ptr<void> dummy(hFile, ::CloseHandle);
+ Loki::ScopeGuard dummy = Loki::MakeGuard(::CloseHandle, hFile);
+ (void)dummy; //silence warning "unused variable"
BY_HANDLE_FILE_INFORMATION fileInfo = {};
if (::GetFileInformationByHandle(hFile, &fileInfo))
diff --git a/shared/file_io.cpp b/shared/file_io.cpp
index b75b8a13..e6de77bb 100644
--- a/shared/file_io.cpp
+++ b/shared/file_io.cpp
@@ -61,7 +61,7 @@ FileInput::FileInput(const Zstring& filename) : //throw FileError()
const DWORD lastError = ::GetLastError();
const wxString& errorMessage = wxString(_("Error opening file:")) + wxT("\n\"") + zToWx(filename_) + wxT("\"") + wxT("\n\n") + ffs3::getLastErrorFormatted(lastError);
if (lastError == ERROR_FILE_NOT_FOUND ||
- lastError == ERROR_PATH_NOT_FOUND)
+ lastError == ERROR_PATH_NOT_FOUND)
throw ErrorNotExisting(errorMessage);
else
throw FileError(errorMessage);
@@ -97,12 +97,12 @@ size_t FileInput::read(void* buffer, size_t bytesToRead) //returns actual number
DWORD bytesRead = 0;
if (!::ReadFile(
- fileHandle, //__in HANDLE hFile,
- buffer, //__out LPVOID lpBuffer,
- static_cast<DWORD>(bytesToRead), //__in DWORD nNumberOfBytesToRead,
- &bytesRead, //__out_opt LPDWORD lpNumberOfBytesRead,
- NULL) //__inout_opt LPOVERLAPPED lpOverlapped
- || bytesRead > bytesToRead) //must be fulfilled
+ fileHandle, //__in HANDLE hFile,
+ buffer, //__out LPVOID lpBuffer,
+ static_cast<DWORD>(bytesToRead), //__in DWORD nNumberOfBytesToRead,
+ &bytesRead, //__out_opt LPDWORD lpNumberOfBytesRead,
+ NULL) //__inout_opt LPOVERLAPPED lpOverlapped
+ || bytesRead > bytesToRead) //must be fulfilled
throw FileError(wxString(_("Error reading file:")) + wxT("\n\"") + zToWx(filename_) + wxT("\"") +
wxT("\n\n") + ffs3::getLastErrorFormatted());
@@ -165,12 +165,12 @@ void FileOutput::write(const void* buffer, size_t bytesToWrite) //throw FileErro
DWORD bytesWritten = 0;
if (!::WriteFile(
- fileHandle, //__in HANDLE hFile,
- buffer, //__out LPVOID lpBuffer,
- static_cast<DWORD>(bytesToWrite), //__in DWORD nNumberOfBytesToRead,
- &bytesWritten, //__out_opt LPDWORD lpNumberOfBytesWritten,
- NULL) //__inout_opt LPOVERLAPPED lpOverlapped
- || bytesWritten != bytesToWrite) //must be fulfilled for synchronous writes!
+ fileHandle, //__in HANDLE hFile,
+ buffer, //__out LPVOID lpBuffer,
+ static_cast<DWORD>(bytesToWrite), //__in DWORD nNumberOfBytesToRead,
+ &bytesWritten, //__out_opt LPDWORD lpNumberOfBytesWritten,
+ NULL) //__inout_opt LPOVERLAPPED lpOverlapped
+ || bytesWritten != bytesToWrite) //must be fulfilled for synchronous writes!
throw FileError(wxString(_("Error writing file:")) + wxT("\n\"") + zToWx(filename_) + wxT("\"") +
wxT("\n\n") + ffs3::getLastErrorFormatted() + wxT(" (w)")); //w -> distinguish from fopen error message!
#elif defined FFS_LINUX
diff --git a/shared/file_traverser.cpp b/shared/file_traverser.cpp
index 66242fa2..f0777898 100644
--- a/shared/file_traverser.cpp
+++ b/shared/file_traverser.cpp
@@ -66,7 +66,8 @@ bool setWin32FileInformationFromSymlink(const Zstring& linkName, ffs3::TraverseC
if (hFile == INVALID_HANDLE_VALUE)
return false;
- boost::shared_ptr<void> dummy(hFile, ::CloseHandle);
+ Loki::ScopeGuard dummy = Loki::MakeGuard(::CloseHandle, hFile);
+ (void)dummy; //silence warning "unused variable"
BY_HANDLE_FILE_INFORMATION fileInfoByHandle;
if (!::GetFileInformationByHandle(hFile, &fileInfoByHandle))
@@ -129,7 +130,7 @@ private:
directory :
directory + common::FILE_NAME_SEPARATOR;
- WIN32_FIND_DATA fileMetaData;
+ WIN32_FIND_DATA fileMetaData = {};
HANDLE searchHandle = ::FindFirstFile(applyLongPathPrefix(directoryFormatted + Zchar('*')).c_str(), //__in LPCTSTR lpFileName
&fileMetaData); //__out LPWIN32_FIND_DATA lpFindFileData
//no noticable performance difference compared to FindFirstFileEx with FindExInfoBasic, FIND_FIRST_EX_CASE_SENSITIVE and/or FIND_FIRST_EX_LARGE_FETCH
@@ -148,15 +149,16 @@ private:
return;
}
- boost::shared_ptr<void> dummy(searchHandle, ::FindClose);
+ Loki::ScopeGuard dummy = Loki::MakeGuard(::FindClose, searchHandle);
+ (void)dummy; //silence warning "unused variable"
do
{
//don't return "." and ".."
const Zchar* const shortName = fileMetaData.cFileName;
- if ( shortName[0] == Zstr('.') &&
- ((shortName[1] == Zstr('.') && shortName[2] == Zstr('\0')) ||
- shortName[1] == Zstr('\0')))
+ if ( shortName[0] == Zstr('.') &&
+ ((shortName[1] == Zstr('.') && shortName[2] == Zstr('\0')) ||
+ shortName[1] == Zstr('\0')))
continue;
const Zstring& fullName = directoryFormatted + shortName;
@@ -172,7 +174,7 @@ private:
}
catch (FileError& e)
{
- (void)e;
+ (void)e;
#ifndef NDEBUG //show broken symlink / access errors in debug build!
sink.onError(e.msg());
#endif
@@ -187,12 +189,12 @@ private:
const TraverseCallback::ReturnValDir rv = sink.onDir(shortName, fullName);
switch (rv.returnCode)
{
- case TraverseCallback::ReturnValDir::TRAVERSING_DIR_IGNORE:
- break;
+ case TraverseCallback::ReturnValDir::TRAVERSING_DIR_IGNORE:
+ break;
- case TraverseCallback::ReturnValDir::TRAVERSING_DIR_CONTINUE:
- traverse<followSymlinks>(fullName, *rv.subDirCb, level + 1);
- break;
+ case TraverseCallback::ReturnValDir::TRAVERSING_DIR_CONTINUE:
+ traverse<followSymlinks>(fullName, *rv.subDirCb, level + 1);
+ break;
}
}
else //a file or symlink that is followed...
@@ -210,7 +212,7 @@ private:
}
else
{
-//####################################### DST hack ###########################################
+ //####################################### DST hack ###########################################
if (isFatFileSystem)
{
const dst::RawTime rawTime(fileMetaData.ftCreationTime, fileMetaData.ftLastWriteTime);
@@ -220,7 +222,7 @@ private:
else
markForDstHack.push_back(std::make_pair(fullName, fileMetaData.ftLastWriteTime));
}
-//####################################### DST hack ###########################################
+ //####################################### DST hack ###########################################
setWin32FileInformation(fileMetaData.ftLastWriteTime, fileMetaData.nFileSizeHigh, fileMetaData.nFileSizeLow, details);
}
@@ -247,7 +249,8 @@ private:
return;
}
- boost::shared_ptr<DIR> dummy(dirObj, &::closedir); //never close NULL handles! -> crash
+ Loki::ScopeGuard dummy = Loki::MakeGuard(::closedir, dirObj); //never close NULL handles! -> crash
+ (void)dummy; //silence warning "unused variable"
while (true)
{
@@ -266,9 +269,9 @@ private:
//don't return "." and ".."
const Zchar* const shortName = dirEntry->d_name;
- if ( shortName[0] == Zstr('.') &&
- ((shortName[1] == Zstr('.') && shortName[2] == Zstr('\0')) ||
- shortName[1] == Zstr('\0')))
+ if ( shortName[0] == Zstr('.') &&
+ ((shortName[1] == Zstr('.') && shortName[2] == Zstr('\0')) ||
+ shortName[1] == Zstr('\0')))
continue;
const Zstring& fullName = directory.EndsWith(common::FILE_NAME_SEPARATOR) ? //e.g. "/"
@@ -327,12 +330,12 @@ private:
const TraverseCallback::ReturnValDir rv = sink.onDir(shortName, fullName);
switch (rv.returnCode)
{
- case TraverseCallback::ReturnValDir::TRAVERSING_DIR_IGNORE:
- break;
+ case TraverseCallback::ReturnValDir::TRAVERSING_DIR_IGNORE:
+ break;
- case TraverseCallback::ReturnValDir::TRAVERSING_DIR_CONTINUE:
- traverse<followSymlinks>(fullName, *rv.subDirCb, level + 1);
- break;
+ case TraverseCallback::ReturnValDir::TRAVERSING_DIR_CONTINUE:
+ traverse<followSymlinks>(fullName, *rv.subDirCb, level + 1);
+ break;
}
}
else //a file... (or symlink; pathological!)
@@ -349,43 +352,66 @@ private:
#ifdef FFS_WIN
-//####################################### DST hack ###########################################
+ //####################################### DST hack ###########################################
void applyDstHack(ffs3::DstHackCallback& dstCallback)
{
+ int failedAttempts = 0;
+ int filesToValidate = 50; //don't let data verification become a performance issue
+
for (FilenameTimeList::const_iterator i = markForDstHack.begin(); i != markForDstHack.end(); ++i)
{
+ if (failedAttempts >= 10) //some cloud storages don't support changing creation/modification times => don't waste (a lot of) time trying to
+ return;
+
dstCallback.requestUiRefresh(i->first);
- HANDLE hTarget = ::CreateFile(ffs3::applyLongPathPrefix(i->first).c_str(),
- FILE_WRITE_ATTRIBUTES,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL,
- OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS,
- NULL);
- if (hTarget == INVALID_HANDLE_VALUE)
- assert(false); //don't throw exceptions due to dst hack here
- else
+ const dst::RawTime encodedTime = dst::fatEncodeUtcTime(i->second); //throw (std::runtime_error)
{
- boost::shared_ptr<void> dummy2(hTarget, ::CloseHandle);
-
- const dst::RawTime encodedTime = dst::fatEncodeUtcTime(i->second); //throw (std::runtime_error)
+ HANDLE hTarget = ::CreateFile(ffs3::applyLongPathPrefix(i->first).c_str(),
+ FILE_WRITE_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL);
+ if (hTarget == INVALID_HANDLE_VALUE)
+ {
+ ++failedAttempts;
+ assert(false); //don't throw exceptions due to dst hack here
+ continue;
+ }
+ Loki::ScopeGuard dummy = Loki::MakeGuard(::CloseHandle, hTarget);
+ (void)dummy; //silence warning "unused variable"
if (!::SetFileTime(hTarget,
&encodedTime.createTimeRaw,
NULL,
&encodedTime.writeTimeRaw))
+ {
+ ++failedAttempts;
assert(false); //don't throw exceptions due to dst hack here
+ continue;
+ }
+ }
-#ifndef NDEBUG //dst hack: verify data written; attention: this check may fail for "sync.ffs_lock"
+ //even at this point it's not sure whether data was written correctly, again cloud storages tend to lie about success status
+ if (filesToValidate > 0)
+ {
+ --filesToValidate; //don't change during check!
+
+ //dst hack: verify data written; attention: this check may fail for "sync.ffs_lock"
WIN32_FILE_ATTRIBUTE_DATA debugeAttr = {};
- assert(::GetFileAttributesEx(ffs3::applyLongPathPrefix(i->first).c_str(), //__in LPCTSTR lpFileName,
- GetFileExInfoStandard, //__in GET_FILEEX_INFO_LEVELS fInfoLevelId,
- &debugeAttr)); //__out LPVOID lpFileInformation
+ ::GetFileAttributesEx(ffs3::applyLongPathPrefix(i->first).c_str(), //__in LPCTSTR lpFileName,
+ GetFileExInfoStandard, //__in GET_FILEEX_INFO_LEVELS fInfoLevelId,
+ &debugeAttr); //__out LPVOID lpFileInformation
- assert(::CompareFileTime(&debugeAttr.ftCreationTime, &encodedTime.createTimeRaw) == 0);
- assert(::CompareFileTime(&debugeAttr.ftLastWriteTime, &encodedTime.writeTimeRaw) == 0);
-#endif
+ if (::CompareFileTime(&debugeAttr.ftCreationTime, &encodedTime.createTimeRaw) != 0 ||
+ ::CompareFileTime(&debugeAttr.ftLastWriteTime, &encodedTime.writeTimeRaw) != 0)
+ {
+ ++failedAttempts;
+ assert(false); //don't throw exceptions due to dst hack here
+ continue;
+ }
}
}
}
@@ -393,7 +419,7 @@ private:
const bool isFatFileSystem;
typedef std::vector<std::pair<Zstring, FILETIME> > FilenameTimeList;
FilenameTimeList markForDstHack;
-//####################################### DST hack ###########################################
+ //####################################### DST hack ###########################################
#endif
};
diff --git a/shared/global_func.cpp b/shared/global_func.cpp
index fe741b22..07a68187 100644
--- a/shared/global_func.cpp
+++ b/shared/global_func.cpp
@@ -17,7 +17,8 @@ size_t common::getDigitCount(size_t number) //count number of digits
}
//############################################################################
-DebugLog::DebugLog() :
+DebugLog::DebugLog(const wxString& filePrefix) :
+ prefix(filePrefix),
lineCount(0),
logFile(NULL)
{
@@ -37,7 +38,7 @@ wxString DebugLog::assembleFileName()
{
wxString tmp = wxDateTime::Now().FormatISOTime();
tmp.Replace(wxT(":"), wxEmptyString);
- return wxString(wxT("DEBUG_")) + wxDateTime::Now().FormatISODate() + wxChar('_') + tmp + wxT(".log");
+ return prefix + wxString(wxT("DEBUG_")) + wxDateTime::Now().FormatISODate() + wxChar('_') + tmp + wxT(".log");
}
diff --git a/shared/global_func.h b/shared/global_func.h
index 169ad611..e0f5434a 100644
--- a/shared/global_func.h
+++ b/shared/global_func.h
@@ -38,14 +38,14 @@ T abs(const T& d) //absolute value
}
-//number conversion C++ ANSI/wide char versions
+//formatted number conversion C++ ANSI/wide char versions
template <class CharType, class T>
std::basic_string<CharType> numberToString(const T& number); //convert number to string the C++ way
template <class T, class CharType>
T stringToNumber(const std::basic_string<CharType>& input); //convert number to string the C++ way
-//number conversion wxWidgets
+//formatted number conversion wxWidgets
template <class T> wxString numberToString(const T& number);
template <class T> T stringToNumber(const wxString& input);
@@ -78,13 +78,15 @@ class wxFile;
class DebugLog
{
public:
- wxDEPRECATED(DebugLog());
+ wxDEPRECATED(DebugLog(const wxString& filePrefix = wxString()));
~DebugLog();
void write(const wxString& logText);
private:
wxString assembleFileName();
+
wxString logfileName;
+ wxString prefix;
int lineCount;
wxFile* logFile; //logFile.close(); <- not needed
};
@@ -130,9 +132,8 @@ template <class T, class CharType>
inline
T common::stringToNumber(const std::basic_string<CharType>& input) //convert number to string the C++ way
{
- std::basic_istringstream<CharType> ss(input);
- T number;
- ss >> number;
+ T number = 0;
+ std::basic_istringstream<CharType>(input) >> number;
return number;
}
diff --git a/shared/inotify/inotify-cxx.cpp b/shared/inotify/inotify-cxx.cpp
index 689612ac..5a460ec7 100644
--- a/shared/inotify/inotify-cxx.cpp
+++ b/shared/inotify/inotify-cxx.cpp
@@ -2,11 +2,11 @@
/// inotify C++ interface implementation
/**
* \file inotify-cxx.cpp
- *
+ *
* inotify C++ interface
- *
+ *
* Copyright (C) 2006, 2007, 2009 Lukas Jelinek <lukas@aiken.cz>
- *
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of one of the following licenses:
*
@@ -19,9 +19,9 @@
*
* Credits:
* Mike Frysinger (cleanup of includes)
- *
+ *
*/
-
+
#include <errno.h>
#include <unistd.h>
@@ -52,590 +52,658 @@
int32_t InotifyEvent::GetDescriptor() const
{
- return m_pWatch != NULL // if watch exists
- ? m_pWatch->GetDescriptor() // return its descriptor
- : -1; // else return -1
+ return m_pWatch != NULL // if watch exists
+ ? m_pWatch->GetDescriptor() // return its descriptor
+ : -1; // else return -1
}
uint32_t InotifyEvent::GetMaskByName(const std::string& rName)
{
- if (rName == "IN_ACCESS")
- return IN_ACCESS;
- else if (rName == "IN_MODIFY")
- return IN_MODIFY;
- else if (rName == "IN_ATTRIB")
- return IN_ATTRIB;
- else if (rName == "IN_CLOSE_WRITE")
- return IN_CLOSE_WRITE;
- else if (rName == "IN_CLOSE_NOWRITE")
- return IN_CLOSE_NOWRITE;
- else if (rName == "IN_OPEN")
- return IN_OPEN;
- else if (rName == "IN_MOVED_FROM")
- return IN_MOVED_FROM;
- else if (rName == "IN_MOVED_TO")
- return IN_MOVED_TO;
- else if (rName == "IN_CREATE")
- return IN_CREATE;
- else if (rName == "IN_DELETE")
- return IN_DELETE;
- else if (rName == "IN_DELETE_SELF")
- return IN_DELETE_SELF;
- else if (rName == "IN_UNMOUNT")
- return IN_UNMOUNT;
- else if (rName == "IN_Q_OVERFLOW")
- return IN_Q_OVERFLOW;
- else if (rName == "IN_IGNORED")
- return IN_IGNORED;
- else if (rName == "IN_CLOSE")
- return IN_CLOSE;
- else if (rName == "IN_MOVE")
- return IN_MOVE;
- else if (rName == "IN_ISDIR")
- return IN_ISDIR;
- else if (rName == "IN_ONESHOT")
- return IN_ONESHOT;
- else if (rName == "IN_ALL_EVENTS")
- return IN_ALL_EVENTS;
-
+ if (rName == "IN_ACCESS")
+ return IN_ACCESS;
+ else if (rName == "IN_MODIFY")
+ return IN_MODIFY;
+ else if (rName == "IN_ATTRIB")
+ return IN_ATTRIB;
+ else if (rName == "IN_CLOSE_WRITE")
+ return IN_CLOSE_WRITE;
+ else if (rName == "IN_CLOSE_NOWRITE")
+ return IN_CLOSE_NOWRITE;
+ else if (rName == "IN_OPEN")
+ return IN_OPEN;
+ else if (rName == "IN_MOVED_FROM")
+ return IN_MOVED_FROM;
+ else if (rName == "IN_MOVED_TO")
+ return IN_MOVED_TO;
+ else if (rName == "IN_CREATE")
+ return IN_CREATE;
+ else if (rName == "IN_DELETE")
+ return IN_DELETE;
+ else if (rName == "IN_DELETE_SELF")
+ return IN_DELETE_SELF;
+ else if (rName == "IN_UNMOUNT")
+ return IN_UNMOUNT;
+ else if (rName == "IN_Q_OVERFLOW")
+ return IN_Q_OVERFLOW;
+ else if (rName == "IN_IGNORED")
+ return IN_IGNORED;
+ else if (rName == "IN_CLOSE")
+ return IN_CLOSE;
+ else if (rName == "IN_MOVE")
+ return IN_MOVE;
+ else if (rName == "IN_ISDIR")
+ return IN_ISDIR;
+ else if (rName == "IN_ONESHOT")
+ return IN_ONESHOT;
+ else if (rName == "IN_ALL_EVENTS")
+ return IN_ALL_EVENTS;
+
#ifdef IN_DONT_FOLLOW
- else if (rName == "IN_DONT_FOLLOW")
- return IN_DONT_FOLLOW;
+ else if (rName == "IN_DONT_FOLLOW")
+ return IN_DONT_FOLLOW;
#endif // IN_DONT_FOLLOW
#ifdef IN_ONLYDIR
- else if (rName == "IN_ONLYDIR")
- return IN_ONLYDIR;
+ else if (rName == "IN_ONLYDIR")
+ return IN_ONLYDIR;
#endif // IN_ONLYDIR
#ifdef IN_MOVE_SELF
- else if (rName == "IN_MOVE_SELF")
- return IN_MOVE_SELF;
+ else if (rName == "IN_MOVE_SELF")
+ return IN_MOVE_SELF;
#endif // IN_MOVE_SELF
-
- return (uint32_t) 0;
+
+ return (uint32_t) 0;
}
void InotifyEvent::DumpTypes(uint32_t uValue, std::string& rStr)
{
- rStr = "";
-
- if (IsType(uValue, IN_ALL_EVENTS)) {
- rStr.append("IN_ALL_EVENTS");
- }
- else {
- if (IsType(uValue, IN_ACCESS)) {
- DUMP_SEP;
- rStr.append("IN_ACCESS");
- }
- if (IsType(uValue, IN_MODIFY)) {
- DUMP_SEP;
- rStr.append("IN_MODIFY");
- }
- if (IsType(uValue, IN_ATTRIB)) {
- DUMP_SEP;
- rStr.append("IN_ATTRIB");
- }
- if (IsType(uValue, IN_CREATE)) {
- DUMP_SEP;
- rStr.append("IN_CREATE");
- }
- if (IsType(uValue, IN_DELETE)) {
- DUMP_SEP;
- rStr.append("IN_DELETE");
- }
- if (IsType(uValue, IN_DELETE_SELF)) {
- DUMP_SEP;
- rStr.append("IN_DELETE_SELF");
- }
- if (IsType(uValue, IN_OPEN)) {
- DUMP_SEP;
- rStr.append("IN_OPEN");
- }
- if (IsType(uValue, IN_CLOSE)) {
- DUMP_SEP;
- rStr.append("IN_CLOSE");
+ rStr = "";
+
+ if (IsType(uValue, IN_ALL_EVENTS))
+ {
+ rStr.append("IN_ALL_EVENTS");
}
+ else
+ {
+ if (IsType(uValue, IN_ACCESS))
+ {
+ DUMP_SEP;
+ rStr.append("IN_ACCESS");
+ }
+ if (IsType(uValue, IN_MODIFY))
+ {
+ DUMP_SEP;
+ rStr.append("IN_MODIFY");
+ }
+ if (IsType(uValue, IN_ATTRIB))
+ {
+ DUMP_SEP;
+ rStr.append("IN_ATTRIB");
+ }
+ if (IsType(uValue, IN_CREATE))
+ {
+ DUMP_SEP;
+ rStr.append("IN_CREATE");
+ }
+ if (IsType(uValue, IN_DELETE))
+ {
+ DUMP_SEP;
+ rStr.append("IN_DELETE");
+ }
+ if (IsType(uValue, IN_DELETE_SELF))
+ {
+ DUMP_SEP;
+ rStr.append("IN_DELETE_SELF");
+ }
+ if (IsType(uValue, IN_OPEN))
+ {
+ DUMP_SEP;
+ rStr.append("IN_OPEN");
+ }
+ if (IsType(uValue, IN_CLOSE))
+ {
+ DUMP_SEP;
+ rStr.append("IN_CLOSE");
+ }
#ifdef IN_MOVE_SELF
- if (IsType(uValue, IN_MOVE_SELF)) {
- DUMP_SEP;
- rStr.append("IN_MOVE_SELF");
- }
+ if (IsType(uValue, IN_MOVE_SELF))
+ {
+ DUMP_SEP;
+ rStr.append("IN_MOVE_SELF");
+ }
#endif // IN_MOVE_SELF
-
- else {
- if (IsType(uValue, IN_CLOSE_WRITE)) {
+
+ else
+ {
+ if (IsType(uValue, IN_CLOSE_WRITE))
+ {
+ DUMP_SEP;
+ rStr.append("IN_CLOSE_WRITE");
+ }
+ if (IsType(uValue, IN_CLOSE_NOWRITE))
+ {
+ DUMP_SEP;
+ rStr.append("IN_CLOSE_NOWRITE");
+ }
+ }
+ if (IsType(uValue, IN_MOVE))
+ {
+ DUMP_SEP;
+ rStr.append("IN_MOVE");
+ }
+ else
+ {
+ if (IsType(uValue, IN_MOVED_FROM))
+ {
+ DUMP_SEP;
+ rStr.append("IN_MOVED_FROM");
+ }
+ if (IsType(uValue, IN_MOVED_TO))
+ {
+ DUMP_SEP;
+ rStr.append("IN_MOVED_TO");
+ }
+ }
+ }
+ if (IsType(uValue, IN_UNMOUNT))
+ {
DUMP_SEP;
- rStr.append("IN_CLOSE_WRITE");
- }
- if (IsType(uValue, IN_CLOSE_NOWRITE)) {
+ rStr.append("IN_UNMOUNT");
+ }
+ if (IsType(uValue, IN_Q_OVERFLOW))
+ {
DUMP_SEP;
- rStr.append("IN_CLOSE_NOWRITE");
- }
+ rStr.append("IN_Q_OVERFLOW");
}
- if (IsType(uValue, IN_MOVE)) {
- DUMP_SEP;
- rStr.append("IN_MOVE");
+ if (IsType(uValue, IN_IGNORED))
+ {
+ DUMP_SEP;
+ rStr.append("IN_IGNORED");
}
- else {
- if (IsType(uValue, IN_MOVED_FROM)) {
+ if (IsType(uValue, IN_ISDIR))
+ {
DUMP_SEP;
- rStr.append("IN_MOVED_FROM");
- }
- if (IsType(uValue, IN_MOVED_TO)) {
+ rStr.append("IN_ISDIR");
+ }
+ if (IsType(uValue, IN_ONESHOT))
+ {
DUMP_SEP;
- rStr.append("IN_MOVED_TO");
- }
- }
- }
- if (IsType(uValue, IN_UNMOUNT)) {
- DUMP_SEP;
- rStr.append("IN_UNMOUNT");
- }
- if (IsType(uValue, IN_Q_OVERFLOW)) {
- DUMP_SEP;
- rStr.append("IN_Q_OVERFLOW");
- }
- if (IsType(uValue, IN_IGNORED)) {
- DUMP_SEP;
- rStr.append("IN_IGNORED");
- }
- if (IsType(uValue, IN_ISDIR)) {
- DUMP_SEP;
- rStr.append("IN_ISDIR");
- }
- if (IsType(uValue, IN_ONESHOT)) {
- DUMP_SEP;
- rStr.append("IN_ONESHOT");
- }
-
+ rStr.append("IN_ONESHOT");
+ }
+
#ifdef IN_DONT_FOLLOW
- if (IsType(uValue, IN_DONT_FOLLOW)) {
- DUMP_SEP;
- rStr.append("IN_DONT_FOLLOW");
- }
+ if (IsType(uValue, IN_DONT_FOLLOW))
+ {
+ DUMP_SEP;
+ rStr.append("IN_DONT_FOLLOW");
+ }
#endif // IN_DONT_FOLLOW
-
+
#ifdef IN_ONLYDIR
- if (IsType(uValue, IN_ONLYDIR)) {
- DUMP_SEP;
- rStr.append("IN_ONLYDIR");
- }
+ if (IsType(uValue, IN_ONLYDIR))
+ {
+ DUMP_SEP;
+ rStr.append("IN_ONLYDIR");
+ }
#endif // IN_ONLYDIR
}
void InotifyEvent::DumpTypes(std::string& rStr) const
{
- DumpTypes(m_uMask, rStr);
+ DumpTypes(m_uMask, rStr);
}
void InotifyWatch::SetMask(uint32_t uMask) throw (InotifyException)
{
- IN_WRITE_BEGIN
-
- if (m_wd != -1) {
- int wd = inotify_add_watch(m_pInotify->GetDescriptor(), m_path.c_str(), uMask);
- if (wd != m_wd) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("changing mask failed"), wd == -1 ? errno : EINVAL, this);
- }
- }
-
- m_uMask = uMask;
-
- IN_WRITE_END
+ IN_WRITE_BEGIN
+
+ if (m_wd != -1)
+ {
+ int wd = inotify_add_watch(m_pInotify->GetDescriptor(), m_path.c_str(), uMask);
+ if (wd != m_wd)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("changing mask failed"), wd == -1 ? errno : EINVAL, this);
+ }
+ }
+
+ m_uMask = uMask;
+
+ IN_WRITE_END
}
void InotifyWatch::SetEnabled(bool fEnabled) throw (InotifyException)
{
- IN_WRITE_BEGIN
-
- if (fEnabled == m_fEnabled) {
- IN_WRITE_END_NOTHROW
- return;
- }
-
- if (m_pInotify != NULL) {
- if (fEnabled) {
- m_wd = inotify_add_watch(m_pInotify->GetDescriptor(), m_path.c_str(), m_uMask);
- if (m_wd == -1) {
+ IN_WRITE_BEGIN
+
+ if (fEnabled == m_fEnabled)
+ {
IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("enabling watch failed"), errno, this);
- }
- m_pInotify->m_watches.insert(IN_WATCH_MAP::value_type(m_wd, this));
+ return;
}
- else {
- if (inotify_rm_watch(m_pInotify->GetDescriptor(), m_wd) != 0) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("disabling watch failed"), errno, this);
- }
- m_pInotify->m_watches.erase(m_wd);
- m_wd = -1;
- }
- }
-
- m_fEnabled = fEnabled;
-
- IN_WRITE_END
+
+ if (m_pInotify != NULL)
+ {
+ if (fEnabled)
+ {
+ m_wd = inotify_add_watch(m_pInotify->GetDescriptor(), m_path.c_str(), m_uMask);
+ if (m_wd == -1)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("enabling watch failed"), errno, this);
+ }
+ m_pInotify->m_watches.insert(IN_WATCH_MAP::value_type(m_wd, this));
+ }
+ else
+ {
+ if (inotify_rm_watch(m_pInotify->GetDescriptor(), m_wd) != 0)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("disabling watch failed"), errno, this);
+ }
+ m_pInotify->m_watches.erase(m_wd);
+ m_wd = -1;
+ }
+ }
+
+ m_fEnabled = fEnabled;
+
+ IN_WRITE_END
}
void InotifyWatch::__Disable()
{
- IN_WRITE_BEGIN
-
- if (!m_fEnabled) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("event cannot occur on disabled watch"), EINVAL, this);
- }
-
- if (m_pInotify != NULL) {
- m_pInotify->m_watches.erase(m_wd);
- m_wd = -1;
- }
-
- m_fEnabled = false;
-
- IN_WRITE_END
+ IN_WRITE_BEGIN
+
+ if (!m_fEnabled)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("event cannot occur on disabled watch"), EINVAL, this);
+ }
+
+ if (m_pInotify != NULL)
+ {
+ m_pInotify->m_watches.erase(m_wd);
+ m_wd = -1;
+ }
+
+ m_fEnabled = false;
+
+ IN_WRITE_END
}
Inotify::Inotify() throw (InotifyException)
{
- IN_LOCK_INIT
-
- m_fd = inotify_init();
- if (m_fd == -1) {
- IN_LOCK_DONE
- throw InotifyException(IN_EXC_MSG("inotify init failed"), errno, NULL);
- }
+ IN_LOCK_INIT
+
+ m_fd = inotify_init();
+ if (m_fd == -1)
+ {
+ IN_LOCK_DONE
+ throw InotifyException(IN_EXC_MSG("inotify init failed"), errno, NULL);
+ }
}
-
+
Inotify::~Inotify()
{
- Close();
-
- IN_LOCK_DONE
+ Close();
+
+ IN_LOCK_DONE
}
void Inotify::Close()
{
- IN_WRITE_BEGIN
-
- if (m_fd != -1) {
- RemoveAll();
- close(m_fd);
- m_fd = -1;
- }
-
- IN_WRITE_END
+ IN_WRITE_BEGIN
+
+ if (m_fd != -1)
+ {
+ RemoveAll();
+ close(m_fd);
+ m_fd = -1;
+ }
+
+ IN_WRITE_END
}
void Inotify::Add(InotifyWatch* pWatch) throw (InotifyException)
{
- IN_WRITE_BEGIN
-
- // invalid descriptor - this case shouldn't occur - go away
- if (m_fd == -1) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
- }
-
- // this path already watched - go away
- if (FindWatch(pWatch->GetPath()) != NULL) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("path already watched"), EBUSY, this);
- }
-
- // for enabled watch
- if (pWatch->IsEnabled()) {
-
- // try to add watch to kernel
- int wd = inotify_add_watch(m_fd, pWatch->GetPath().c_str(), pWatch->GetMask());
-
- // adding failed - go away
- if (wd == -1) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("adding watch failed"), errno, this);
- }
-
- // this path already watched (but defined another way)
- InotifyWatch* pW = FindWatch(wd);
- if (pW != NULL) {
-
- // try to recover old watch because it may be modified - then go away
- if (inotify_add_watch(m_fd, pW->GetPath().c_str(), pW->GetMask()) < 0) {
+ IN_WRITE_BEGIN
+
+ // invalid descriptor - this case shouldn't occur - go away
+ if (m_fd == -1)
+ {
IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("watch collision detected and recovery failed"), errno, this);
- }
- else {
- // recovery failed - go away
+ throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
+ }
+
+ // this path already watched - go away
+ if (FindWatch(pWatch->GetPath()) != NULL)
+ {
IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("path already watched (but defined another way)"), EBUSY, this);
- }
- }
-
- pWatch->m_wd = wd;
- m_watches.insert(IN_WATCH_MAP::value_type(pWatch->m_wd, pWatch));
- }
-
- m_paths.insert(IN_WP_MAP::value_type(pWatch->m_path, pWatch));
- pWatch->m_pInotify = this;
-
- IN_WRITE_END
+ throw InotifyException(IN_EXC_MSG("path already watched"), EBUSY, this);
+ }
+
+ // for enabled watch
+ if (pWatch->IsEnabled())
+ {
+
+ // try to add watch to kernel
+ int wd = inotify_add_watch(m_fd, pWatch->GetPath().c_str(), pWatch->GetMask());
+
+ // adding failed - go away
+ if (wd == -1)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("adding watch failed"), errno, this);
+ }
+
+ // this path already watched (but defined another way)
+ InotifyWatch* pW = FindWatch(wd);
+ if (pW != NULL)
+ {
+
+ // try to recover old watch because it may be modified - then go away
+ if (inotify_add_watch(m_fd, pW->GetPath().c_str(), pW->GetMask()) < 0)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("watch collision detected and recovery failed"), errno, this);
+ }
+ else
+ {
+ // recovery failed - go away
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("path already watched (but defined another way)"), EBUSY, this);
+ }
+ }
+
+ pWatch->m_wd = wd;
+ m_watches.insert(IN_WATCH_MAP::value_type(pWatch->m_wd, pWatch));
+ }
+
+ m_paths.insert(IN_WP_MAP::value_type(pWatch->m_path, pWatch));
+ pWatch->m_pInotify = this;
+
+ IN_WRITE_END
}
void Inotify::Remove(InotifyWatch* pWatch) throw (InotifyException)
{
- IN_WRITE_BEGIN
-
- // invalid descriptor - this case shouldn't occur - go away
- if (m_fd == -1) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
- }
-
- // for enabled watch
- if (pWatch->m_wd != -1) {
-
- // removing watch failed - go away
- if (inotify_rm_watch(m_fd, pWatch->m_wd) == -1) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("removing watch failed"), errno, this);
- }
- m_watches.erase(pWatch->m_wd);
- pWatch->m_wd = -1;
- }
-
- m_paths.erase(pWatch->m_path);
- pWatch->m_pInotify = NULL;
-
- IN_WRITE_END
+ IN_WRITE_BEGIN
+
+ // invalid descriptor - this case shouldn't occur - go away
+ if (m_fd == -1)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
+ }
+
+ // for enabled watch
+ if (pWatch->m_wd != -1)
+ {
+
+ // removing watch failed - go away
+ if (inotify_rm_watch(m_fd, pWatch->m_wd) == -1)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("removing watch failed"), errno, this);
+ }
+ m_watches.erase(pWatch->m_wd);
+ pWatch->m_wd = -1;
+ }
+
+ m_paths.erase(pWatch->m_path);
+ pWatch->m_pInotify = NULL;
+
+ IN_WRITE_END
}
void Inotify::RemoveAll()
{
- IN_WRITE_BEGIN
-
- IN_WP_MAP::iterator it = m_paths.begin();
- while (it != m_paths.end()) {
- InotifyWatch* pW = (*it).second;
- if (pW->m_wd != -1) {
- inotify_rm_watch(m_fd, pW->m_wd);
- pW->m_wd = -1;
- }
- pW->m_pInotify = NULL;
- it++;
- }
-
- m_watches.clear();
- m_paths.clear();
-
- IN_WRITE_END
+ IN_WRITE_BEGIN
+
+ IN_WP_MAP::iterator it = m_paths.begin();
+ while (it != m_paths.end())
+ {
+ InotifyWatch* pW = (*it).second;
+ if (pW->m_wd != -1)
+ {
+ inotify_rm_watch(m_fd, pW->m_wd);
+ pW->m_wd = -1;
+ }
+ pW->m_pInotify = NULL;
+ it++;
+ }
+
+ m_watches.clear();
+ m_paths.clear();
+
+ IN_WRITE_END
}
void Inotify::WaitForEvents(bool fNoIntr) throw (InotifyException)
{
- ssize_t len = 0;
-
- do {
- len = read(m_fd, m_buf, INOTIFY_BUFLEN);
- } while (fNoIntr && len == -1 && errno == EINTR);
-
- if (len == -1 && !(errno == EWOULDBLOCK || errno == EINTR))
- throw InotifyException(IN_EXC_MSG("reading events failed"), errno, this);
-
- if (len == -1)
- return;
-
- IN_WRITE_BEGIN
-
- ssize_t i = 0;
- while (i < len) {
- struct inotify_event* pEvt = (struct inotify_event*) &m_buf[i];
- InotifyWatch* pW = FindWatch(pEvt->wd);
- if (pW != NULL) {
- InotifyEvent evt(pEvt, pW);
- if ( InotifyEvent::IsType(pW->GetMask(), IN_ONESHOT)
- || InotifyEvent::IsType(evt.GetMask(), IN_IGNORED))
- pW->__Disable();
- m_events.push_back(evt);
- }
- i += INOTIFY_EVENT_SIZE + (ssize_t) pEvt->len;
- }
-
- IN_WRITE_END
+ ssize_t len = 0;
+
+ do
+ {
+ len = read(m_fd, m_buf, INOTIFY_BUFLEN);
+ }
+ while (fNoIntr && len == -1 && errno == EINTR);
+
+ if (len == -1 && !(errno == EWOULDBLOCK || errno == EINTR))
+ throw InotifyException(IN_EXC_MSG("reading events failed"), errno, this);
+
+ if (len == -1)
+ return;
+
+ IN_WRITE_BEGIN
+
+ ssize_t i = 0;
+ while (i < len)
+ {
+ struct inotify_event* pEvt = (struct inotify_event*) &m_buf[i];
+ InotifyWatch* pW = FindWatch(pEvt->wd);
+ if (pW != NULL)
+ {
+ InotifyEvent evt(pEvt, pW);
+ if ( InotifyEvent::IsType(pW->GetMask(), IN_ONESHOT)
+ || InotifyEvent::IsType(evt.GetMask(), IN_IGNORED))
+ pW->__Disable();
+ m_events.push_back(evt);
+ }
+ i += INOTIFY_EVENT_SIZE + (ssize_t) pEvt->len;
+ }
+
+ IN_WRITE_END
}
-
+
bool Inotify::GetEvent(InotifyEvent* pEvt) throw (InotifyException)
{
- if (pEvt == NULL)
- throw InotifyException(IN_EXC_MSG("null pointer to event"), EINVAL, this);
-
- IN_WRITE_BEGIN
-
- bool b = !m_events.empty();
- if (b) {
- *pEvt = m_events.front();
- m_events.pop_front();
- }
-
- IN_WRITE_END
-
- return b;
+ if (pEvt == NULL)
+ throw InotifyException(IN_EXC_MSG("null pointer to event"), EINVAL, this);
+
+ IN_WRITE_BEGIN
+
+ bool b = !m_events.empty();
+ if (b)
+ {
+ *pEvt = m_events.front();
+ m_events.pop_front();
+ }
+
+ IN_WRITE_END
+
+ return b;
}
-
+
bool Inotify::PeekEvent(InotifyEvent* pEvt) throw (InotifyException)
{
- if (pEvt == NULL)
- throw InotifyException(IN_EXC_MSG("null pointer to event"), EINVAL, this);
-
- IN_READ_BEGIN
-
- bool b = !m_events.empty();
- if (b) {
- *pEvt = m_events.front();
- }
-
- IN_READ_END
-
- return b;
+ if (pEvt == NULL)
+ throw InotifyException(IN_EXC_MSG("null pointer to event"), EINVAL, this);
+
+ IN_READ_BEGIN
+
+ bool b = !m_events.empty();
+ if (b)
+ {
+ *pEvt = m_events.front();
+ }
+
+ IN_READ_END
+
+ return b;
}
InotifyWatch* Inotify::FindWatch(int iDescriptor)
{
- IN_READ_BEGIN
-
- IN_WATCH_MAP::iterator it = m_watches.find(iDescriptor);
- InotifyWatch* pW = it == m_watches.end() ? NULL : (*it).second;
-
- IN_READ_END
-
- return pW;
+ IN_READ_BEGIN
+
+ IN_WATCH_MAP::iterator it = m_watches.find(iDescriptor);
+ InotifyWatch* pW = it == m_watches.end() ? NULL : (*it).second;
+
+ IN_READ_END
+
+ return pW;
}
InotifyWatch* Inotify::FindWatch(const std::string& rPath)
{
- IN_READ_BEGIN
-
- IN_WP_MAP::iterator it = m_paths.find(rPath);
- InotifyWatch* pW = it == m_paths.end() ? NULL : (*it).second;
-
- IN_READ_END
-
- return pW;
+ IN_READ_BEGIN
+
+ IN_WP_MAP::iterator it = m_paths.find(rPath);
+ InotifyWatch* pW = it == m_paths.end() ? NULL : (*it).second;
+
+ IN_READ_END
+
+ return pW;
}
-
+
void Inotify::SetNonBlock(bool fNonBlock) throw (InotifyException)
{
- IN_WRITE_BEGIN
-
- if (m_fd == -1) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
- }
-
- int res = fcntl(m_fd, F_GETFL);
- if (res == -1) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("cannot get inotify flags"), errno, this);
- }
-
- if (fNonBlock) {
- res |= O_NONBLOCK;
- }
- else {
- res &= ~O_NONBLOCK;
- }
-
- if (fcntl(m_fd, F_SETFL, res) == -1) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("cannot set inotify flags"), errno, this);
- }
-
- IN_WRITE_END
+ IN_WRITE_BEGIN
+
+ if (m_fd == -1)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
+ }
+
+ int res = fcntl(m_fd, F_GETFL);
+ if (res == -1)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("cannot get inotify flags"), errno, this);
+ }
+
+ if (fNonBlock)
+ {
+ res |= O_NONBLOCK;
+ }
+ else
+ {
+ res &= ~O_NONBLOCK;
+ }
+
+ if (fcntl(m_fd, F_SETFL, res) == -1)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("cannot set inotify flags"), errno, this);
+ }
+
+ IN_WRITE_END
}
void Inotify::SetCloseOnExec(bool fClOnEx) throw (InotifyException)
{
- IN_WRITE_BEGIN
-
- if (m_fd == -1) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
- }
-
- int res = fcntl(m_fd, F_GETFD);
- if (res == -1) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("cannot get inotify flags"), errno, this);
- }
-
- if (fClOnEx) {
- res |= FD_CLOEXEC;
- }
- else {
- res &= ~FD_CLOEXEC;
- }
-
- if (fcntl(m_fd, F_SETFD, res) == -1) {
- IN_WRITE_END_NOTHROW
- throw InotifyException(IN_EXC_MSG("cannot set inotify flags"), errno, this);
- }
-
- IN_WRITE_END
+ IN_WRITE_BEGIN
+
+ if (m_fd == -1)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("invalid file descriptor"), EBUSY, this);
+ }
+
+ int res = fcntl(m_fd, F_GETFD);
+ if (res == -1)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("cannot get inotify flags"), errno, this);
+ }
+
+ if (fClOnEx)
+ {
+ res |= FD_CLOEXEC;
+ }
+ else
+ {
+ res &= ~FD_CLOEXEC;
+ }
+
+ if (fcntl(m_fd, F_SETFD, res) == -1)
+ {
+ IN_WRITE_END_NOTHROW
+ throw InotifyException(IN_EXC_MSG("cannot set inotify flags"), errno, this);
+ }
+
+ IN_WRITE_END
}
uint32_t Inotify::GetCapability(InotifyCapability_t cap) throw (InotifyException)
{
- FILE* f = fopen(GetCapabilityPath(cap).c_str(), "r");
- if (f == NULL)
- throw InotifyException(IN_EXC_MSG("cannot get capability"), errno, NULL);
-
- unsigned int val = 0;
- if (fscanf(f, "%u", &val) != 1) {
+ FILE* f = fopen(GetCapabilityPath(cap).c_str(), "r");
+ if (f == NULL)
+ throw InotifyException(IN_EXC_MSG("cannot get capability"), errno, NULL);
+
+ unsigned int val = 0;
+ if (fscanf(f, "%u", &val) != 1)
+ {
+ fclose(f);
+ throw InotifyException(IN_EXC_MSG("cannot get capability"), EIO, NULL);
+ }
+
fclose(f);
- throw InotifyException(IN_EXC_MSG("cannot get capability"), EIO, NULL);
- }
-
- fclose(f);
-
- return (uint32_t) val;
+
+ return (uint32_t) val;
}
void Inotify::SetCapability(InotifyCapability_t cap, uint32_t val) throw (InotifyException)
{
- FILE* f = fopen(GetCapabilityPath(cap).c_str(), "w");
- if (f == NULL)
- throw InotifyException(IN_EXC_MSG("cannot set capability"), errno, NULL);
-
- if (fprintf(f, "%u", (unsigned int) val) <= 0) {
+ FILE* f = fopen(GetCapabilityPath(cap).c_str(), "w");
+ if (f == NULL)
+ throw InotifyException(IN_EXC_MSG("cannot set capability"), errno, NULL);
+
+ if (fprintf(f, "%u", (unsigned int) val) <= 0)
+ {
+ fclose(f);
+ throw InotifyException(IN_EXC_MSG("cannot set capability"), EIO, NULL);
+ }
+
fclose(f);
- throw InotifyException(IN_EXC_MSG("cannot set capability"), EIO, NULL);
- }
-
- fclose(f);
}
std::string Inotify::GetCapabilityPath(InotifyCapability_t cap) throw (InotifyException)
{
- std::string path(PROCFS_INOTIFY_BASE);
-
- switch (cap) {
- case IN_MAX_EVENTS:
- path.append("max_queued_events");
- break;
- case IN_MAX_INSTANCES:
- path.append("max_user_instances");
- break;
- case IN_MAX_WATCHES:
- path.append("max_user_watches");
- break;
- default:
- throw InotifyException(IN_EXC_MSG("unknown capability type"), EINVAL, NULL);
- }
-
- return path;
+ std::string path(PROCFS_INOTIFY_BASE);
+
+ switch (cap)
+ {
+ case IN_MAX_EVENTS:
+ path.append("max_queued_events");
+ break;
+ case IN_MAX_INSTANCES:
+ path.append("max_user_instances");
+ break;
+ case IN_MAX_WATCHES:
+ path.append("max_user_watches");
+ break;
+ default:
+ throw InotifyException(IN_EXC_MSG("unknown capability type"), EINVAL, NULL);
+ }
+
+ return path;
}
diff --git a/shared/inotify/inotify-cxx.h b/shared/inotify/inotify-cxx.h
index 34ae2212..2fb00fc8 100644
--- a/shared/inotify/inotify-cxx.h
+++ b/shared/inotify/inotify-cxx.h
@@ -2,11 +2,11 @@
/// inotify C++ interface header
/**
* \file inotify-cxx.h
- *
+ *
* inotify C++ interface
- *
+ *
* Copyright (C) 2006, 2007, 2009 Lukas Jelinek, <lukas@aiken.cz>
- *
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of one of the following licenses:
*
@@ -50,12 +50,12 @@
*/
#define IN_EXC_MSG(msg) (std::string(__PRETTY_FUNCTION__) + ": " + msg)
-/// inotify capability/limit identifiers
+/// inotify capability/limit identifiers
typedef enum
{
- IN_MAX_EVENTS = 0, ///< max. events in the kernel queue
- IN_MAX_INSTANCES = 1, ///< max. inotify file descriptors per process
- IN_MAX_WATCHES = 2 ///< max. watches per file descriptor
+ IN_MAX_EVENTS = 0, ///< max. events in the kernel queue
+ IN_MAX_INSTANCES = 1, ///< max. inotify file descriptors per process
+ IN_MAX_WATCHES = 2 ///< max. watches per file descriptor
} InotifyCapability_t;
/// inotify-cxx thread safety
@@ -63,16 +63,16 @@ typedef enum
* If this symbol is defined you can use this interface safely
* threaded applications. Remember that it slightly degrades
* performance.
- *
+ *
* Even if INOTIFY_THREAD_SAFE is defined some classes stay
* unsafe. If you must use them (must you?) in more than one
* thread concurrently you need to implement explicite locking.
- *
+ *
* You need not to define INOTIFY_THREAD_SAFE in that cases
* where the application is multithreaded but all the inotify
* infrastructure will be managed only in one thread. This is
* the recommended way.
- *
+ *
* Locking may fail (it is very rare but not impossible). In this
* case an exception is thrown. But if unlocking fails in case
* of an error it does nothing (this failure is ignored).
@@ -95,7 +95,7 @@ typedef enum
throw InotifyException(IN_EXC_MSG("cannot initialize lock"), res, this); \
pthread_rwlockattr_destroy(&attr); \
}
-
+
#define IN_LOCK_DONE pthread_rwlock_destroy(&__m_lock);
#define IN_READ_BEGIN \
@@ -104,23 +104,23 @@ typedef enum
if (res != 0) \
throw InotifyException(IN_EXC_MSG("locking for reading failed"), res, (void*) this); \
}
-
+
#define IN_READ_END \
{ \
int res = pthread_rwlock_unlock(&__m_lock); \
if (res != 0) \
throw InotifyException(IN_EXC_MSG("unlocking failed"), res, (void*) this); \
}
-
+
#define IN_READ_END_NOTHROW pthread_rwlock_unlock(&__m_lock);
-
+
#define IN_WRITE_BEGIN \
{ \
int res = pthread_rwlock_wrlock(&__m_lock); \
if (res != 0) \
throw InotifyException(IN_EXC_MSG("locking for writing failed"), res, (void*) this); \
}
-
+
#define IN_WRITE_END IN_READ_END
#define IN_WRITE_END_NOTHROW IN_READ_END_NOTHROW
@@ -151,59 +151,59 @@ class Inotify;
* This class allows to acquire information about exceptional
* events. It makes easier to log or display error messages
* and to identify problematic code locations.
- *
+ *
* Although this class is basically thread-safe it is not intended
* to be shared between threads.
*/
class InotifyException
{
public:
- /// Constructor
- /**
- * \param[in] rMsg message
- * \param[in] iErr error number (see errno.h)
- * \param[in] pSrc source
- */
- InotifyException(const std::string& rMsg = "", int iErr = 0, void* pSrc = NULL)
- : m_msg(rMsg),
- m_err(iErr)
- {
- m_pSrc = pSrc;
- }
-
- /// Returns the exception message.
- /**
- * \return message
- */
- inline const std::string& GetMessage() const
- {
- return m_msg;
- }
-
- /// Returns the exception error number.
- /**
- * If not applicable this value is 0 (zero).
- *
- * \return error number (standardized; see errno.h)
- */
- inline int GetErrorNumber() const
- {
- return m_err;
- }
-
- /// Returns the exception source.
- /**
- * \return source
- */
- inline void* GetSource() const
- {
- return m_pSrc;
- }
+ /// Constructor
+ /**
+ * \param[in] rMsg message
+ * \param[in] iErr error number (see errno.h)
+ * \param[in] pSrc source
+ */
+ InotifyException(const std::string& rMsg = "", int iErr = 0, void* pSrc = NULL)
+ : m_msg(rMsg),
+ m_err(iErr)
+ {
+ m_pSrc = pSrc;
+ }
+
+ /// Returns the exception message.
+ /**
+ * \return message
+ */
+ inline const std::string& GetMessage() const
+ {
+ return m_msg;
+ }
+
+ /// Returns the exception error number.
+ /**
+ * If not applicable this value is 0 (zero).
+ *
+ * \return error number (standardized; see errno.h)
+ */
+ inline int GetErrorNumber() const
+ {
+ return m_err;
+ }
+
+ /// Returns the exception source.
+ /**
+ * \return source
+ */
+ inline void* GetSource() const
+ {
+ return m_pSrc;
+ }
protected:
- std::string m_msg; ///< message
- int m_err; ///< error number
- mutable void* m_pSrc; ///< source
+ std::string m_msg; ///< message
+ int m_err; ///< error number
+ mutable void* m_pSrc; ///< source
};
@@ -211,7 +211,7 @@ protected:
/**
* It holds all information about inotify event and provides
* access to its particular values.
- *
+ *
* This class is not (and is not intended to be) thread-safe
* and therefore it must not be used concurrently in multiple
* threads.
@@ -219,157 +219,160 @@ protected:
class InotifyEvent
{
public:
- /// Constructor.
- /**
- * Creates a plain event.
- */
- InotifyEvent()
- : m_uMask(0),
- m_uCookie(0)
- {
- m_pWatch = NULL;
- }
-
- /// Constructor.
- /**
- * Creates an event based on inotify event data.
- * For NULL pointers it works the same way as InotifyEvent().
- *
- * \param[in] pEvt event data
- * \param[in] pWatch inotify watch
- */
- InotifyEvent(const struct inotify_event* pEvt, InotifyWatch* pWatch)
- : m_uMask(0),
- m_uCookie(0)
- {
- if (pEvt != NULL) {
- m_uMask = (uint32_t) pEvt->mask;
- m_uCookie = (uint32_t) pEvt->cookie;
- if (pEvt->name != NULL) {
- m_name = pEvt->len > 0
- ? pEvt->name
- : "";
- }
- m_pWatch = pWatch;
- }
- else {
- m_pWatch = NULL;
+ /// Constructor.
+ /**
+ * Creates a plain event.
+ */
+ InotifyEvent()
+ : m_uMask(0),
+ m_uCookie(0)
+ {
+ m_pWatch = NULL;
}
- }
-
- /// Destructor.
- ~InotifyEvent() {}
-
- /// Returns the event watch descriptor.
- /**
- * \return watch descriptor
- *
- * \sa InotifyWatch::GetDescriptor()
- */
- int32_t GetDescriptor() const;
-
- /// Returns the event mask.
- /**
- * \return event mask
- *
- * \sa InotifyWatch::GetMask()
- */
- inline uint32_t GetMask() const
- {
- return m_uMask;
- }
-
- /// Checks a value for the event type.
- /**
- * \param[in] uValue checked value
- * \param[in] uType type which is checked for
- * \return true = the value contains the given type, false = otherwise
- */
- inline static bool IsType(uint32_t uValue, uint32_t uType)
- {
- return ((uValue & uType) != 0) && ((~uValue & uType) == 0);
- }
-
- /// Checks for the event type.
- /**
- * \param[in] uType type which is checked for
- * \return true = event mask contains the given type, false = otherwise
- */
- inline bool IsType(uint32_t uType) const
- {
- return IsType(m_uMask, uType);
- }
-
- /// Returns the event cookie.
- /**
- * \return event cookie
- */
- inline uint32_t GetCookie() const
- {
- return m_uCookie;
- }
-
- /// Returns the event name length.
- /**
- * \return event name length
- */
- inline uint32_t GetLength() const
- {
- return (uint32_t) m_name.length();
- }
-
- /// Returns the event name.
- /**
- * \return event name
- */
- inline const std::string& GetName() const
- {
- return m_name;
- }
-
- /// Extracts the event name.
- /**
- * \param[out] rName event name
- */
- inline void GetName(std::string& rName) const
- {
- rName = GetName();
- }
-
- /// Returns the source watch.
- /**
- * \return source watch
- */
- inline InotifyWatch* GetWatch()
- {
- return m_pWatch;
- }
-
- /// Finds the appropriate mask for a name.
- /**
- * \param[in] rName mask name
- * \return mask for name; 0 on failure
- */
- static uint32_t GetMaskByName(const std::string& rName);
-
- /// Fills the string with all types contained in an event mask value.
- /**
- * \param[in] uValue event mask value
- * \param[out] rStr dumped event types
- */
- static void DumpTypes(uint32_t uValue, std::string& rStr);
-
- /// Fills the string with all types contained in the event mask.
- /**
- * \param[out] rStr dumped event types
- */
- void DumpTypes(std::string& rStr) const;
-
+
+ /// Constructor.
+ /**
+ * Creates an event based on inotify event data.
+ * For NULL pointers it works the same way as InotifyEvent().
+ *
+ * \param[in] pEvt event data
+ * \param[in] pWatch inotify watch
+ */
+ InotifyEvent(const struct inotify_event* pEvt, InotifyWatch* pWatch)
+ : m_uMask(0),
+ m_uCookie(0)
+ {
+ if (pEvt != NULL)
+ {
+ m_uMask = (uint32_t) pEvt->mask;
+ m_uCookie = (uint32_t) pEvt->cookie;
+ if (pEvt->name != NULL)
+ {
+ m_name = pEvt->len > 0
+ ? pEvt->name
+ : "";
+ }
+ m_pWatch = pWatch;
+ }
+ else
+ {
+ m_pWatch = NULL;
+ }
+ }
+
+ /// Destructor.
+ ~InotifyEvent() {}
+
+ /// Returns the event watch descriptor.
+ /**
+ * \return watch descriptor
+ *
+ * \sa InotifyWatch::GetDescriptor()
+ */
+ int32_t GetDescriptor() const;
+
+ /// Returns the event mask.
+ /**
+ * \return event mask
+ *
+ * \sa InotifyWatch::GetMask()
+ */
+ inline uint32_t GetMask() const
+ {
+ return m_uMask;
+ }
+
+ /// Checks a value for the event type.
+ /**
+ * \param[in] uValue checked value
+ * \param[in] uType type which is checked for
+ * \return true = the value contains the given type, false = otherwise
+ */
+ inline static bool IsType(uint32_t uValue, uint32_t uType)
+ {
+ return ((uValue & uType) != 0) && ((~uValue & uType) == 0);
+ }
+
+ /// Checks for the event type.
+ /**
+ * \param[in] uType type which is checked for
+ * \return true = event mask contains the given type, false = otherwise
+ */
+ inline bool IsType(uint32_t uType) const
+ {
+ return IsType(m_uMask, uType);
+ }
+
+ /// Returns the event cookie.
+ /**
+ * \return event cookie
+ */
+ inline uint32_t GetCookie() const
+ {
+ return m_uCookie;
+ }
+
+ /// Returns the event name length.
+ /**
+ * \return event name length
+ */
+ inline uint32_t GetLength() const
+ {
+ return (uint32_t) m_name.length();
+ }
+
+ /// Returns the event name.
+ /**
+ * \return event name
+ */
+ inline const std::string& GetName() const
+ {
+ return m_name;
+ }
+
+ /// Extracts the event name.
+ /**
+ * \param[out] rName event name
+ */
+ inline void GetName(std::string& rName) const
+ {
+ rName = GetName();
+ }
+
+ /// Returns the source watch.
+ /**
+ * \return source watch
+ */
+ inline InotifyWatch* GetWatch()
+ {
+ return m_pWatch;
+ }
+
+ /// Finds the appropriate mask for a name.
+ /**
+ * \param[in] rName mask name
+ * \return mask for name; 0 on failure
+ */
+ static uint32_t GetMaskByName(const std::string& rName);
+
+ /// Fills the string with all types contained in an event mask value.
+ /**
+ * \param[in] uValue event mask value
+ * \param[out] rStr dumped event types
+ */
+ static void DumpTypes(uint32_t uValue, std::string& rStr);
+
+ /// Fills the string with all types contained in the event mask.
+ /**
+ * \param[out] rStr dumped event types
+ */
+ void DumpTypes(std::string& rStr) const;
+
private:
- uint32_t m_uMask; ///< mask
- uint32_t m_uCookie; ///< cookie
- std::string m_name; ///< name
- InotifyWatch* m_pWatch; ///< source watch
+ uint32_t m_uMask; ///< mask
+ uint32_t m_uCookie; ///< cookie
+ std::string m_name; ///< name
+ InotifyWatch* m_pWatch; ///< source watch
};
@@ -378,140 +381,140 @@ private:
/**
* It holds information about the inotify watch on a particular
* inode.
- *
+ *
* If the INOTIFY_THREAD_SAFE is defined this class is thread-safe.
*/
class InotifyWatch
{
public:
- /// Constructor.
- /**
- * Creates an inotify watch. Because this watch is
- * inactive it has an invalid descriptor (-1).
- *
- * \param[in] rPath watched file path
- * \param[in] uMask mask for events
- * \param[in] fEnabled events enabled yes/no
- */
- InotifyWatch(const std::string& rPath, int32_t uMask, bool fEnabled = true)
- : m_path(rPath),
- m_uMask(uMask),
- m_wd((int32_t) -1),
- m_fEnabled(fEnabled)
- {
- IN_LOCK_INIT
- }
-
- /// Destructor.
- ~InotifyWatch()
- {
- IN_LOCK_DONE
- }
-
- /// Returns the watch descriptor.
- /**
- * \return watch descriptor; -1 for inactive watch
- */
- inline int32_t GetDescriptor() const
- {
- return m_wd;
- }
-
- /// Returns the watched file path.
- /**
- * \return file path
- */
- inline const std::string& GetPath() const
- {
- return m_path;
- }
-
- /// Returns the watch event mask.
- /**
- * \return event mask
- */
- inline uint32_t GetMask() const
- {
- return (uint32_t) m_uMask;
- }
-
- /// Sets the watch event mask.
- /**
- * If the watch is active (added to an instance of Inotify)
- * this method may fail due to unsuccessful re-setting
- * the watch in the kernel.
- *
- * \param[in] uMask event mask
- *
- * \throw InotifyException thrown if changing fails
- */
- void SetMask(uint32_t uMask) throw (InotifyException);
-
- /// Returns the appropriate inotify class instance.
- /**
- * \return inotify instance
- */
- inline Inotify* GetInotify()
- {
- return m_pInotify;
- }
-
- /// Enables/disables the watch.
- /**
- * If the watch is active (added to an instance of Inotify)
- * this method may fail due to unsuccessful re-setting
- * the watch in the kernel.
- *
- * Re-setting the current state has no effect.
- *
- * \param[in] fEnabled set enabled yes/no
- *
- * \throw InotifyException thrown if enabling/disabling fails
- */
- void SetEnabled(bool fEnabled) throw (InotifyException);
-
- /// Checks whether the watch is enabled.
- /**
- * \return true = enables, false = disabled
- */
- inline bool IsEnabled() const
- {
- return m_fEnabled;
- }
-
- /// Checks whether the watch is recursive.
- /**
- * A recursive watch monitors a directory itself and all
- * its subdirectories. This watch is a logical object
- * which may have many underlying kernel watches.
- *
- * \return currently always false (recursive watches not yet supported)
- * \attention Recursive watches are currently NOT supported.
- * They are planned for future versions.
- */
- inline bool IsRecursive() const
- {
- return false;
- }
-
+ /// Constructor.
+ /**
+ * Creates an inotify watch. Because this watch is
+ * inactive it has an invalid descriptor (-1).
+ *
+ * \param[in] rPath watched file path
+ * \param[in] uMask mask for events
+ * \param[in] fEnabled events enabled yes/no
+ */
+ InotifyWatch(const std::string& rPath, int32_t uMask, bool fEnabled = true)
+ : m_path(rPath),
+ m_uMask(uMask),
+ m_wd((int32_t) -1),
+ m_fEnabled(fEnabled)
+ {
+ IN_LOCK_INIT
+ }
+
+ /// Destructor.
+ ~InotifyWatch()
+ {
+ IN_LOCK_DONE
+ }
+
+ /// Returns the watch descriptor.
+ /**
+ * \return watch descriptor; -1 for inactive watch
+ */
+ inline int32_t GetDescriptor() const
+ {
+ return m_wd;
+ }
+
+ /// Returns the watched file path.
+ /**
+ * \return file path
+ */
+ inline const std::string& GetPath() const
+ {
+ return m_path;
+ }
+
+ /// Returns the watch event mask.
+ /**
+ * \return event mask
+ */
+ inline uint32_t GetMask() const
+ {
+ return (uint32_t) m_uMask;
+ }
+
+ /// Sets the watch event mask.
+ /**
+ * If the watch is active (added to an instance of Inotify)
+ * this method may fail due to unsuccessful re-setting
+ * the watch in the kernel.
+ *
+ * \param[in] uMask event mask
+ *
+ * \throw InotifyException thrown if changing fails
+ */
+ void SetMask(uint32_t uMask) throw (InotifyException);
+
+ /// Returns the appropriate inotify class instance.
+ /**
+ * \return inotify instance
+ */
+ inline Inotify* GetInotify()
+ {
+ return m_pInotify;
+ }
+
+ /// Enables/disables the watch.
+ /**
+ * If the watch is active (added to an instance of Inotify)
+ * this method may fail due to unsuccessful re-setting
+ * the watch in the kernel.
+ *
+ * Re-setting the current state has no effect.
+ *
+ * \param[in] fEnabled set enabled yes/no
+ *
+ * \throw InotifyException thrown if enabling/disabling fails
+ */
+ void SetEnabled(bool fEnabled) throw (InotifyException);
+
+ /// Checks whether the watch is enabled.
+ /**
+ * \return true = enables, false = disabled
+ */
+ inline bool IsEnabled() const
+ {
+ return m_fEnabled;
+ }
+
+ /// Checks whether the watch is recursive.
+ /**
+ * A recursive watch monitors a directory itself and all
+ * its subdirectories. This watch is a logical object
+ * which may have many underlying kernel watches.
+ *
+ * \return currently always false (recursive watches not yet supported)
+ * \attention Recursive watches are currently NOT supported.
+ * They are planned for future versions.
+ */
+ inline bool IsRecursive() const
+ {
+ return false;
+ }
+
private:
- friend class Inotify;
-
- std::string m_path; ///< watched file path
- uint32_t m_uMask; ///< event mask
- int32_t m_wd; ///< watch descriptor
- Inotify* m_pInotify; ///< inotify object
- bool m_fEnabled; ///< events enabled yes/no
-
- IN_LOCK_DECL
-
- /// Disables the watch (due to removing by the kernel).
- /**
- * This method must be called after receiving an event.
- * It ensures the watch object is consistent with the kernel
- * data.
- */
- void __Disable();
+ friend class Inotify;
+
+ std::string m_path; ///< watched file path
+ uint32_t m_uMask; ///< event mask
+ int32_t m_wd; ///< watch descriptor
+ Inotify* m_pInotify; ///< inotify object
+ bool m_fEnabled; ///< events enabled yes/no
+
+ IN_LOCK_DECL
+
+ /// Disables the watch (due to removing by the kernel).
+ /**
+ * This method must be called after receiving an event.
+ * It ensures the watch object is consistent with the kernel
+ * data.
+ */
+ void __Disable();
};
@@ -526,360 +529,360 @@ typedef std::map<std::string, InotifyWatch*> IN_WP_MAP;
/**
* It holds information about the inotify device descriptor
* and manages the event queue.
- *
+ *
* If the INOTIFY_THREAD_SAFE is defined this class is thread-safe.
*/
class Inotify
{
public:
- /// Constructor.
- /**
- * Creates and initializes an instance of inotify communication
- * object (opens the inotify device).
- *
- * \throw InotifyException thrown if inotify isn't available
- */
- Inotify() throw (InotifyException);
-
- /// Destructor.
- /**
- * Calls Close() due to clean-up.
- */
- ~Inotify();
-
- /// Removes all watches and closes the inotify device.
- void Close();
-
- /// Adds a new watch.
- /**
- * \param[in] pWatch inotify watch
- *
- * \throw InotifyException thrown if adding failed
- */
- void Add(InotifyWatch* pWatch) throw (InotifyException);
-
- /// Adds a new watch.
- /**
- * \param[in] rWatch inotify watch
- *
- * \throw InotifyException thrown if adding failed
- */
- inline void Add(InotifyWatch& rWatch) throw (InotifyException)
- {
- Add(&rWatch);
- }
-
- /// Removes a watch.
- /**
- * If the given watch is not present it does nothing.
- *
- * \param[in] pWatch inotify watch
- *
- * \throw InotifyException thrown if removing failed
- */
- void Remove(InotifyWatch* pWatch) throw (InotifyException);
-
- /// Removes a watch.
- /**
- * If the given watch is not present it does nothing.
- *
- * \param[in] rWatch inotify watch
- *
- * \throw InotifyException thrown if removing failed
- */
- inline void Remove(InotifyWatch& rWatch) throw (InotifyException)
- {
- Remove(&rWatch);
- }
-
- /// Removes all watches.
- void RemoveAll();
-
- /// Returns the count of watches.
- /**
- * This is the total count of all watches (regardless whether
- * enabled or not).
- *
- * \return count of watches
- *
- * \sa GetEnabledCount()
- */
- inline size_t GetWatchCount() const
- {
- IN_READ_BEGIN
- size_t n = (size_t) m_paths.size();
- IN_READ_END
- return n;
- }
-
- /// Returns the count of enabled watches.
- /**
- * \return count of enabled watches
- *
- * \sa GetWatchCount()
- */
- inline size_t GetEnabledCount() const
- {
- IN_READ_BEGIN
- size_t n = (size_t) m_watches.size();
- IN_READ_END
- return n;
- }
-
- /// Waits for inotify events.
- /**
- * It waits until one or more events occur. When called
- * in nonblocking mode it only retrieves occurred events
- * to the internal queue and exits.
- *
- * \param[in] fNoIntr if true it re-calls the system call after a handled signal
- *
- * \throw InotifyException thrown if reading events failed
- *
- * \sa SetNonBlock()
- */
- void WaitForEvents(bool fNoIntr = false) throw (InotifyException);
-
- /// Returns the count of received and queued events.
- /**
- * This number is related to the events in the queue inside
- * this object, not to the events pending in the kernel.
- *
- * \return count of events
- */
- inline size_t GetEventCount()
- {
- IN_READ_BEGIN
- size_t n = (size_t) m_events.size();
- IN_READ_END
- return n;
- }
-
- /// Extracts a queued inotify event.
- /**
- * The extracted event is removed from the queue.
- * If the pointer is NULL it does nothing.
- *
- * \param[in,out] pEvt event object
- *
- * \throw InotifyException thrown if the provided pointer is NULL
- */
- bool GetEvent(InotifyEvent* pEvt) throw (InotifyException);
-
- /// Extracts a queued inotify event.
- /**
- * The extracted event is removed from the queue.
- *
- * \param[in,out] rEvt event object
- *
- * \throw InotifyException thrown only in very anomalous cases
- */
- bool GetEvent(InotifyEvent& rEvt) throw (InotifyException)
- {
- return GetEvent(&rEvt);
- }
-
- /// Extracts a queued inotify event (without removing).
- /**
- * The extracted event stays in the queue.
- * If the pointer is NULL it does nothing.
- *
- * \param[in,out] pEvt event object
- *
- * \throw InotifyException thrown if the provided pointer is NULL
- */
- bool PeekEvent(InotifyEvent* pEvt) throw (InotifyException);
-
- /// Extracts a queued inotify event (without removing).
- /**
- * The extracted event stays in the queue.
- *
- * \param[in,out] rEvt event object
- *
- * \throw InotifyException thrown only in very anomalous cases
- */
- bool PeekEvent(InotifyEvent& rEvt) throw (InotifyException)
- {
- return PeekEvent(&rEvt);
- }
-
- /// Searches for a watch by a watch descriptor.
- /**
- * It tries to find a watch by the given descriptor.
- *
- * \param[in] iDescriptor watch descriptor
- * \return pointer to a watch; NULL if no such watch exists
- */
- InotifyWatch* FindWatch(int iDescriptor);
-
- /// Searches for a watch by a filesystem path.
- /**
- * It tries to find a watch by the given filesystem path.
- *
- * \param[in] rPath filesystem path
- * \return pointer to a watch; NULL if no such watch exists
- *
- * \attention The path must be exactly identical to the one
- * used for the searched watch. Be careful about
- * absolute/relative and case-insensitive paths.
- */
- InotifyWatch* FindWatch(const std::string& rPath);
-
- /// Returns the file descriptor.
- /**
- * The descriptor can be used in standard low-level file
- * functions (poll(), select(), fcntl() etc.).
- *
- * \return valid file descriptor or -1 for inactive object
- *
- * \sa SetNonBlock()
- */
- inline int GetDescriptor() const
- {
- return m_fd;
- }
-
- /// Enables/disables non-blocking mode.
- /**
- * Use this mode if you want to monitor the descriptor
- * (acquired thru GetDescriptor()) in functions such as
- * poll(), select() etc.
- *
- * Non-blocking mode is disabled by default.
- *
- * \param[in] fNonBlock enable/disable non-blocking mode
- *
- * \throw InotifyException thrown if setting mode failed
- *
- * \sa GetDescriptor(), SetCloseOnExec()
- */
- void SetNonBlock(bool fNonBlock) throw (InotifyException);
-
- /// Enables/disables closing on exec.
- /**
- * Enable this if you want to close the descriptor when
- * executing another program. Otherwise, the descriptor
- * will be inherited.
- *
- * Closing on exec is disabled by default.
- *
- * \param[in] fClOnEx enable/disable closing on exec
- *
- * \throw InotifyException thrown if setting failed
- *
- * \sa GetDescriptor(), SetNonBlock()
- */
- void SetCloseOnExec(bool fClOnEx) throw (InotifyException);
-
- /// Acquires a particular inotify capability/limit.
- /**
- * \param[in] cap capability/limit identifier
- * \return capability/limit value
- * \throw InotifyException thrown if the given value cannot be acquired
- */
- static uint32_t GetCapability(InotifyCapability_t cap) throw (InotifyException);
-
- /// Modifies a particular inotify capability/limit.
- /**
- * \param[in] cap capability/limit identifier
- * \param[in] val new capability/limit value
- * \throw InotifyException thrown if the given value cannot be set
- * \attention Using this function requires root privileges.
- * Beware of setting extensive values - it may seriously
- * affect system performance and/or stability.
- */
- static void SetCapability(InotifyCapability_t cap, uint32_t val) throw (InotifyException);
-
- /// Returns the maximum number of events in the kernel queue.
- /**
- * \return maximum number of events in the kernel queue
- * \throw InotifyException thrown if the given value cannot be acquired
- */
- inline static uint32_t GetMaxEvents() throw (InotifyException)
- {
- return GetCapability(IN_MAX_EVENTS);
- }
-
- /// Sets the maximum number of events in the kernel queue.
- /**
- * \param[in] val new value
- * \throw InotifyException thrown if the given value cannot be set
- * \attention Using this function requires root privileges.
- * Beware of setting extensive values - the greater value
- * is set here the more physical memory may be used for the inotify
- * infrastructure.
- */
- inline static void SetMaxEvents(uint32_t val) throw (InotifyException)
- {
- SetCapability(IN_MAX_EVENTS, val);
- }
-
- /// Returns the maximum number of inotify instances per process.
- /**
- * It means the maximum number of open inotify file descriptors
- * per running process.
- *
- * \return maximum number of inotify instances
- * \throw InotifyException thrown if the given value cannot be acquired
- */
- inline static uint32_t GetMaxInstances() throw (InotifyException)
- {
- return GetCapability(IN_MAX_INSTANCES);
- }
-
- /// Sets the maximum number of inotify instances per process.
- /**
- * \param[in] val new value
- * \throw InotifyException thrown if the given value cannot be set
- * \attention Using this function requires root privileges.
- * Beware of setting extensive values - the greater value
- * is set here the more physical memory may be used for the inotify
- * infrastructure.
- */
- inline static void SetMaxInstances(uint32_t val) throw (InotifyException)
- {
- SetCapability(IN_MAX_INSTANCES, val);
- }
-
- /// Returns the maximum number of inotify watches per instance.
- /**
- * It means the maximum number of inotify watches per inotify
- * file descriptor.
- *
- * \return maximum number of inotify watches
- * \throw InotifyException thrown if the given value cannot be acquired
- */
- inline static uint32_t GetMaxWatches() throw (InotifyException)
- {
- return GetCapability(IN_MAX_WATCHES);
- }
-
- /// Sets the maximum number of inotify watches per instance.
- /**
- * \param[in] val new value
- * \throw InotifyException thrown if the given value cannot be set
- * \attention Using this function requires root privileges.
- * Beware of setting extensive values - the greater value
- * is set here the more physical memory may be used for the inotify
- * infrastructure.
- */
- inline static void SetMaxWatches(uint32_t val) throw (InotifyException)
- {
- SetCapability(IN_MAX_WATCHES, val);
- }
+ /// Constructor.
+ /**
+ * Creates and initializes an instance of inotify communication
+ * object (opens the inotify device).
+ *
+ * \throw InotifyException thrown if inotify isn't available
+ */
+ Inotify() throw (InotifyException);
+
+ /// Destructor.
+ /**
+ * Calls Close() due to clean-up.
+ */
+ ~Inotify();
+
+ /// Removes all watches and closes the inotify device.
+ void Close();
+
+ /// Adds a new watch.
+ /**
+ * \param[in] pWatch inotify watch
+ *
+ * \throw InotifyException thrown if adding failed
+ */
+ void Add(InotifyWatch* pWatch) throw (InotifyException);
+
+ /// Adds a new watch.
+ /**
+ * \param[in] rWatch inotify watch
+ *
+ * \throw InotifyException thrown if adding failed
+ */
+ inline void Add(InotifyWatch& rWatch) throw (InotifyException)
+ {
+ Add(&rWatch);
+ }
+
+ /// Removes a watch.
+ /**
+ * If the given watch is not present it does nothing.
+ *
+ * \param[in] pWatch inotify watch
+ *
+ * \throw InotifyException thrown if removing failed
+ */
+ void Remove(InotifyWatch* pWatch) throw (InotifyException);
+
+ /// Removes a watch.
+ /**
+ * If the given watch is not present it does nothing.
+ *
+ * \param[in] rWatch inotify watch
+ *
+ * \throw InotifyException thrown if removing failed
+ */
+ inline void Remove(InotifyWatch& rWatch) throw (InotifyException)
+ {
+ Remove(&rWatch);
+ }
+
+ /// Removes all watches.
+ void RemoveAll();
+
+ /// Returns the count of watches.
+ /**
+ * This is the total count of all watches (regardless whether
+ * enabled or not).
+ *
+ * \return count of watches
+ *
+ * \sa GetEnabledCount()
+ */
+ inline size_t GetWatchCount() const
+ {
+ IN_READ_BEGIN
+ size_t n = (size_t) m_paths.size();
+ IN_READ_END
+ return n;
+ }
+
+ /// Returns the count of enabled watches.
+ /**
+ * \return count of enabled watches
+ *
+ * \sa GetWatchCount()
+ */
+ inline size_t GetEnabledCount() const
+ {
+ IN_READ_BEGIN
+ size_t n = (size_t) m_watches.size();
+ IN_READ_END
+ return n;
+ }
+
+ /// Waits for inotify events.
+ /**
+ * It waits until one or more events occur. When called
+ * in nonblocking mode it only retrieves occurred events
+ * to the internal queue and exits.
+ *
+ * \param[in] fNoIntr if true it re-calls the system call after a handled signal
+ *
+ * \throw InotifyException thrown if reading events failed
+ *
+ * \sa SetNonBlock()
+ */
+ void WaitForEvents(bool fNoIntr = false) throw (InotifyException);
+
+ /// Returns the count of received and queued events.
+ /**
+ * This number is related to the events in the queue inside
+ * this object, not to the events pending in the kernel.
+ *
+ * \return count of events
+ */
+ inline size_t GetEventCount()
+ {
+ IN_READ_BEGIN
+ size_t n = (size_t) m_events.size();
+ IN_READ_END
+ return n;
+ }
+
+ /// Extracts a queued inotify event.
+ /**
+ * The extracted event is removed from the queue.
+ * If the pointer is NULL it does nothing.
+ *
+ * \param[in,out] pEvt event object
+ *
+ * \throw InotifyException thrown if the provided pointer is NULL
+ */
+ bool GetEvent(InotifyEvent* pEvt) throw (InotifyException);
+
+ /// Extracts a queued inotify event.
+ /**
+ * The extracted event is removed from the queue.
+ *
+ * \param[in,out] rEvt event object
+ *
+ * \throw InotifyException thrown only in very anomalous cases
+ */
+ bool GetEvent(InotifyEvent& rEvt) throw (InotifyException)
+ {
+ return GetEvent(&rEvt);
+ }
+
+ /// Extracts a queued inotify event (without removing).
+ /**
+ * The extracted event stays in the queue.
+ * If the pointer is NULL it does nothing.
+ *
+ * \param[in,out] pEvt event object
+ *
+ * \throw InotifyException thrown if the provided pointer is NULL
+ */
+ bool PeekEvent(InotifyEvent* pEvt) throw (InotifyException);
+
+ /// Extracts a queued inotify event (without removing).
+ /**
+ * The extracted event stays in the queue.
+ *
+ * \param[in,out] rEvt event object
+ *
+ * \throw InotifyException thrown only in very anomalous cases
+ */
+ bool PeekEvent(InotifyEvent& rEvt) throw (InotifyException)
+ {
+ return PeekEvent(&rEvt);
+ }
+
+ /// Searches for a watch by a watch descriptor.
+ /**
+ * It tries to find a watch by the given descriptor.
+ *
+ * \param[in] iDescriptor watch descriptor
+ * \return pointer to a watch; NULL if no such watch exists
+ */
+ InotifyWatch* FindWatch(int iDescriptor);
+
+ /// Searches for a watch by a filesystem path.
+ /**
+ * It tries to find a watch by the given filesystem path.
+ *
+ * \param[in] rPath filesystem path
+ * \return pointer to a watch; NULL if no such watch exists
+ *
+ * \attention The path must be exactly identical to the one
+ * used for the searched watch. Be careful about
+ * absolute/relative and case-insensitive paths.
+ */
+ InotifyWatch* FindWatch(const std::string& rPath);
+
+ /// Returns the file descriptor.
+ /**
+ * The descriptor can be used in standard low-level file
+ * functions (poll(), select(), fcntl() etc.).
+ *
+ * \return valid file descriptor or -1 for inactive object
+ *
+ * \sa SetNonBlock()
+ */
+ inline int GetDescriptor() const
+ {
+ return m_fd;
+ }
+
+ /// Enables/disables non-blocking mode.
+ /**
+ * Use this mode if you want to monitor the descriptor
+ * (acquired thru GetDescriptor()) in functions such as
+ * poll(), select() etc.
+ *
+ * Non-blocking mode is disabled by default.
+ *
+ * \param[in] fNonBlock enable/disable non-blocking mode
+ *
+ * \throw InotifyException thrown if setting mode failed
+ *
+ * \sa GetDescriptor(), SetCloseOnExec()
+ */
+ void SetNonBlock(bool fNonBlock) throw (InotifyException);
+
+ /// Enables/disables closing on exec.
+ /**
+ * Enable this if you want to close the descriptor when
+ * executing another program. Otherwise, the descriptor
+ * will be inherited.
+ *
+ * Closing on exec is disabled by default.
+ *
+ * \param[in] fClOnEx enable/disable closing on exec
+ *
+ * \throw InotifyException thrown if setting failed
+ *
+ * \sa GetDescriptor(), SetNonBlock()
+ */
+ void SetCloseOnExec(bool fClOnEx) throw (InotifyException);
+
+ /// Acquires a particular inotify capability/limit.
+ /**
+ * \param[in] cap capability/limit identifier
+ * \return capability/limit value
+ * \throw InotifyException thrown if the given value cannot be acquired
+ */
+ static uint32_t GetCapability(InotifyCapability_t cap) throw (InotifyException);
+
+ /// Modifies a particular inotify capability/limit.
+ /**
+ * \param[in] cap capability/limit identifier
+ * \param[in] val new capability/limit value
+ * \throw InotifyException thrown if the given value cannot be set
+ * \attention Using this function requires root privileges.
+ * Beware of setting extensive values - it may seriously
+ * affect system performance and/or stability.
+ */
+ static void SetCapability(InotifyCapability_t cap, uint32_t val) throw (InotifyException);
+
+ /// Returns the maximum number of events in the kernel queue.
+ /**
+ * \return maximum number of events in the kernel queue
+ * \throw InotifyException thrown if the given value cannot be acquired
+ */
+ inline static uint32_t GetMaxEvents() throw (InotifyException)
+ {
+ return GetCapability(IN_MAX_EVENTS);
+ }
+
+ /// Sets the maximum number of events in the kernel queue.
+ /**
+ * \param[in] val new value
+ * \throw InotifyException thrown if the given value cannot be set
+ * \attention Using this function requires root privileges.
+ * Beware of setting extensive values - the greater value
+ * is set here the more physical memory may be used for the inotify
+ * infrastructure.
+ */
+ inline static void SetMaxEvents(uint32_t val) throw (InotifyException)
+ {
+ SetCapability(IN_MAX_EVENTS, val);
+ }
+
+ /// Returns the maximum number of inotify instances per process.
+ /**
+ * It means the maximum number of open inotify file descriptors
+ * per running process.
+ *
+ * \return maximum number of inotify instances
+ * \throw InotifyException thrown if the given value cannot be acquired
+ */
+ inline static uint32_t GetMaxInstances() throw (InotifyException)
+ {
+ return GetCapability(IN_MAX_INSTANCES);
+ }
+
+ /// Sets the maximum number of inotify instances per process.
+ /**
+ * \param[in] val new value
+ * \throw InotifyException thrown if the given value cannot be set
+ * \attention Using this function requires root privileges.
+ * Beware of setting extensive values - the greater value
+ * is set here the more physical memory may be used for the inotify
+ * infrastructure.
+ */
+ inline static void SetMaxInstances(uint32_t val) throw (InotifyException)
+ {
+ SetCapability(IN_MAX_INSTANCES, val);
+ }
+
+ /// Returns the maximum number of inotify watches per instance.
+ /**
+ * It means the maximum number of inotify watches per inotify
+ * file descriptor.
+ *
+ * \return maximum number of inotify watches
+ * \throw InotifyException thrown if the given value cannot be acquired
+ */
+ inline static uint32_t GetMaxWatches() throw (InotifyException)
+ {
+ return GetCapability(IN_MAX_WATCHES);
+ }
+
+ /// Sets the maximum number of inotify watches per instance.
+ /**
+ * \param[in] val new value
+ * \throw InotifyException thrown if the given value cannot be set
+ * \attention Using this function requires root privileges.
+ * Beware of setting extensive values - the greater value
+ * is set here the more physical memory may be used for the inotify
+ * infrastructure.
+ */
+ inline static void SetMaxWatches(uint32_t val) throw (InotifyException)
+ {
+ SetCapability(IN_MAX_WATCHES, val);
+ }
+
+private:
+ int m_fd; ///< file descriptor
+ IN_WATCH_MAP m_watches; ///< watches (by descriptors)
+ IN_WP_MAP m_paths; ///< watches (by paths)
+ unsigned char m_buf[INOTIFY_BUFLEN]; ///< buffer for events
+ std::deque<InotifyEvent> m_events; ///< event queue
+
+ IN_LOCK_DECL
+
+ friend class InotifyWatch;
-private:
- int m_fd; ///< file descriptor
- IN_WATCH_MAP m_watches; ///< watches (by descriptors)
- IN_WP_MAP m_paths; ///< watches (by paths)
- unsigned char m_buf[INOTIFY_BUFLEN]; ///< buffer for events
- std::deque<InotifyEvent> m_events; ///< event queue
-
- IN_LOCK_DECL
-
- friend class InotifyWatch;
-
- static std::string GetCapabilityPath(InotifyCapability_t cap) throw (InotifyException);
+ static std::string GetCapabilityPath(InotifyCapability_t cap) throw (InotifyException);
};
diff --git a/shared/localization.cpp b/shared/localization.cpp
index 678767b9..a412df1e 100644
--- a/shared/localization.cpp
+++ b/shared/localization.cpp
@@ -13,6 +13,12 @@
#include <map>
#include <wx/ffile.h>
+#if wxCHECK_VERSION(2, 9, 1)
+#include <boost/cstdint.hpp>
+#include <wx/translation.h>
+#include <cstdlib>
+#endif
+
using ffs3::CustomLocale;
using ffs3::LocalizationInfo;
@@ -132,13 +138,6 @@ LocalizationInfo::LocalizationInfo()
newEntry.languageFlag = wxT("holland.png");
locMapping.push_back(newEntry);
- newEntry.languageID = wxLANGUAGE_RUSSIAN;
- newEntry.languageName = wxT("PуÑÑкий");
- newEntry.languageFile = wxT("russian.lng");
- newEntry.translatorName = wxT("Fayzullin T.N. aka Svobodniy");
- newEntry.languageFlag = wxT("russia.png");
- locMapping.push_back(newEntry);
-
newEntry.languageID = wxLANGUAGE_POLISH;
newEntry.languageName = wxT("Polski");
newEntry.languageFile = wxT("polish.lng");
@@ -160,6 +159,13 @@ LocalizationInfo::LocalizationInfo()
newEntry.languageFlag = wxT("brazil.png");
locMapping.push_back(newEntry);
+ newEntry.languageID = wxLANGUAGE_RUSSIAN;
+ newEntry.languageName = wxT("PуÑÑкий");
+ newEntry.languageFile = wxT("russian.lng");
+ newEntry.translatorName = wxT("Fayzullin T.N. aka Svobodniy");
+ newEntry.languageFlag = wxT("russia.png");
+ locMapping.push_back(newEntry);
+
newEntry.languageID = wxLANGUAGE_ROMANIAN;
newEntry.languageName = wxT("Română");
newEntry.languageFile = wxT("romanian.lng");
@@ -195,19 +201,19 @@ LocalizationInfo::LocalizationInfo()
newEntry.languageFlag = wxT("turkey.png");
locMapping.push_back(newEntry);
-// newEntry.languageID = wxLANGUAGE_HEBREW;
-// newEntry.languageName = wxT("עִבְרִית");
-// newEntry.languageFile = wxT("hebrew.lng");
-// newEntry.translatorName = wxT("Moshe Olshevsky");
-// newEntry.languageFlag = wxT("isreal.png");
-// locMapping.push_back(newEntry);
+ // newEntry.languageID = wxLANGUAGE_HEBREW;
+ // newEntry.languageName = wxT("עִבְרִית");
+ // newEntry.languageFile = wxT("hebrew.lng");
+ // newEntry.translatorName = wxT("Moshe Olshevsky");
+ // newEntry.languageFlag = wxT("isreal.png");
+ // locMapping.push_back(newEntry);
-// newEntry.languageID = wxLANGUAGE_ARABIC;
-// newEntry.languageName = wxT("العربية");
-// newEntry.languageFile = wxT("arabic.lng");
-// newEntry.translatorName = wxT("Yousef Shamshoum");
-// newEntry.languageFlag = wxT("arabic-language.png");
-// locMapping.push_back(newEntry);
+ // newEntry.languageID = wxLANGUAGE_ARABIC;
+ // newEntry.languageName = wxT("العربية");
+ // newEntry.languageFile = wxT("arabic.lng");
+ // newEntry.translatorName = wxT("Yousef Shamshoum");
+ // newEntry.languageFlag = wxT("arabic-language.png");
+ // locMapping.push_back(newEntry);
newEntry.languageID = wxLANGUAGE_JAPANESE;
newEntry.languageName = wxT("日本語");
@@ -230,163 +236,140 @@ LocalizationInfo::LocalizationInfo()
newEntry.languageFlag = wxT("china.png");
locMapping.push_back(newEntry);
+ newEntry.languageID = wxLANGUAGE_KOREAN;
+ newEntry.languageName = wxT("한국어");
+ newEntry.languageFile = wxT("korean.lng");
+ newEntry.translatorName = wxT("Simon Park");
+ newEntry.languageFlag = wxT("south_korea.png");
+ locMapping.push_back(newEntry);
+
//std::sort(locMapping.begin(), locMapping.end(), CompareByName());
}
-int mapLanguageDialect(const int language)
+namespace
+{
+int mapLanguageDialect(int language)
{
switch (language) //map language dialects
{
- //variants of wxLANGUAGE_GERMAN
- case wxLANGUAGE_GERMAN_AUSTRIAN:
- case wxLANGUAGE_GERMAN_BELGIUM:
- case wxLANGUAGE_GERMAN_LIECHTENSTEIN:
- case wxLANGUAGE_GERMAN_LUXEMBOURG:
- case wxLANGUAGE_GERMAN_SWISS:
- return wxLANGUAGE_GERMAN;
-
- //variants of wxLANGUAGE_FRENCH
- case wxLANGUAGE_FRENCH_BELGIAN:
- case wxLANGUAGE_FRENCH_CANADIAN:
- case wxLANGUAGE_FRENCH_LUXEMBOURG:
- case wxLANGUAGE_FRENCH_MONACO:
- case wxLANGUAGE_FRENCH_SWISS:
- return wxLANGUAGE_FRENCH;
-
- //variants of wxLANGUAGE_DUTCH
- case wxLANGUAGE_DUTCH_BELGIAN:
- return wxLANGUAGE_DUTCH;
-
- //variants of wxLANGUAGE_ITALIAN
- case wxLANGUAGE_ITALIAN_SWISS:
- return wxLANGUAGE_ITALIAN;
-
- //variants of wxLANGUAGE_CHINESE_SIMPLIFIED
- case wxLANGUAGE_CHINESE:
- case wxLANGUAGE_CHINESE_SINGAPORE:
- return wxLANGUAGE_CHINESE_SIMPLIFIED;
-
- //variants of wxLANGUAGE_CHINESE_TRADITIONAL
- case wxLANGUAGE_CHINESE_TAIWAN:
- case wxLANGUAGE_CHINESE_HONGKONG:
- case wxLANGUAGE_CHINESE_MACAU:
- return wxLANGUAGE_CHINESE_TRADITIONAL;
-
- //variants of wxLANGUAGE_RUSSIAN
- case wxLANGUAGE_RUSSIAN_UKRAINE:
- return wxLANGUAGE_RUSSIAN;
-
- //variants of wxLANGUAGE_SPANISH
- case wxLANGUAGE_SPANISH_ARGENTINA:
- case wxLANGUAGE_SPANISH_BOLIVIA:
- case wxLANGUAGE_SPANISH_CHILE:
- case wxLANGUAGE_SPANISH_COLOMBIA:
- case wxLANGUAGE_SPANISH_COSTA_RICA:
- case wxLANGUAGE_SPANISH_DOMINICAN_REPUBLIC:
- case wxLANGUAGE_SPANISH_ECUADOR:
- case wxLANGUAGE_SPANISH_EL_SALVADOR:
- case wxLANGUAGE_SPANISH_GUATEMALA:
- case wxLANGUAGE_SPANISH_HONDURAS:
- case wxLANGUAGE_SPANISH_MEXICAN:
- case wxLANGUAGE_SPANISH_MODERN:
- case wxLANGUAGE_SPANISH_NICARAGUA:
- case wxLANGUAGE_SPANISH_PANAMA:
- case wxLANGUAGE_SPANISH_PARAGUAY:
- case wxLANGUAGE_SPANISH_PERU:
- case wxLANGUAGE_SPANISH_PUERTO_RICO:
- case wxLANGUAGE_SPANISH_URUGUAY:
- case wxLANGUAGE_SPANISH_US:
- case wxLANGUAGE_SPANISH_VENEZUELA:
- return wxLANGUAGE_SPANISH;
-
- //variants of wxLANGUAGE_SWEDISH
- case wxLANGUAGE_SWEDISH_FINLAND:
- return wxLANGUAGE_SWEDISH;
-
- //case wxLANGUAGE_CZECH:
- //case wxLANGUAGE_FINNISH:
- //case wxLANGUAGE_GREEK:
- //case wxLANGUAGE_JAPANESE:
- //case wxLANGUAGE_POLISH:
- //case wxLANGUAGE_SLOVENIAN:
- //case wxLANGUAGE_HUNGARIAN:
- //case wxLANGUAGE_PORTUGUESE:
- //case wxLANGUAGE_PORTUGUESE_BRAZILIAN:
-
- //variants of wxLANGUAGE_ARABIC (also needed to detect RTL languages)
- case wxLANGUAGE_ARABIC_ALGERIA:
- case wxLANGUAGE_ARABIC_BAHRAIN:
- case wxLANGUAGE_ARABIC_EGYPT:
- case wxLANGUAGE_ARABIC_IRAQ:
- case wxLANGUAGE_ARABIC_JORDAN:
- case wxLANGUAGE_ARABIC_KUWAIT:
- case wxLANGUAGE_ARABIC_LEBANON:
- case wxLANGUAGE_ARABIC_LIBYA:
- case wxLANGUAGE_ARABIC_MOROCCO:
- case wxLANGUAGE_ARABIC_OMAN:
- case wxLANGUAGE_ARABIC_QATAR:
- case wxLANGUAGE_ARABIC_SAUDI_ARABIA:
- case wxLANGUAGE_ARABIC_SUDAN:
- case wxLANGUAGE_ARABIC_SYRIA:
- case wxLANGUAGE_ARABIC_TUNISIA:
- case wxLANGUAGE_ARABIC_UAE:
- case wxLANGUAGE_ARABIC_YEMEN:
- return wxLANGUAGE_ARABIC;
-
- //variants of wxLANGUAGE_ENGLISH_UK
- case wxLANGUAGE_ENGLISH_AUSTRALIA:
- case wxLANGUAGE_ENGLISH_NEW_ZEALAND:
- case wxLANGUAGE_ENGLISH_TRINIDAD:
- case wxLANGUAGE_ENGLISH_CARIBBEAN:
- case wxLANGUAGE_ENGLISH_JAMAICA:
- case wxLANGUAGE_ENGLISH_BELIZE:
- case wxLANGUAGE_ENGLISH_EIRE:
- case wxLANGUAGE_ENGLISH_SOUTH_AFRICA:
- case wxLANGUAGE_ENGLISH_ZIMBABWE:
- case wxLANGUAGE_ENGLISH_BOTSWANA:
- case wxLANGUAGE_ENGLISH_DENMARK:
- return wxLANGUAGE_ENGLISH_UK;
-
- default:
- return language;
+ //variants of wxLANGUAGE_GERMAN
+ case wxLANGUAGE_GERMAN_AUSTRIAN:
+ case wxLANGUAGE_GERMAN_BELGIUM:
+ case wxLANGUAGE_GERMAN_LIECHTENSTEIN:
+ case wxLANGUAGE_GERMAN_LUXEMBOURG:
+ case wxLANGUAGE_GERMAN_SWISS:
+ return wxLANGUAGE_GERMAN;
+
+ //variants of wxLANGUAGE_FRENCH
+ case wxLANGUAGE_FRENCH_BELGIAN:
+ case wxLANGUAGE_FRENCH_CANADIAN:
+ case wxLANGUAGE_FRENCH_LUXEMBOURG:
+ case wxLANGUAGE_FRENCH_MONACO:
+ case wxLANGUAGE_FRENCH_SWISS:
+ return wxLANGUAGE_FRENCH;
+
+ //variants of wxLANGUAGE_DUTCH
+ case wxLANGUAGE_DUTCH_BELGIAN:
+ return wxLANGUAGE_DUTCH;
+
+ //variants of wxLANGUAGE_ITALIAN
+ case wxLANGUAGE_ITALIAN_SWISS:
+ return wxLANGUAGE_ITALIAN;
+
+ //variants of wxLANGUAGE_CHINESE_SIMPLIFIED
+ case wxLANGUAGE_CHINESE:
+ case wxLANGUAGE_CHINESE_SINGAPORE:
+ return wxLANGUAGE_CHINESE_SIMPLIFIED;
+
+ //variants of wxLANGUAGE_CHINESE_TRADITIONAL
+ case wxLANGUAGE_CHINESE_TAIWAN:
+ case wxLANGUAGE_CHINESE_HONGKONG:
+ case wxLANGUAGE_CHINESE_MACAU:
+ return wxLANGUAGE_CHINESE_TRADITIONAL;
+
+ //variants of wxLANGUAGE_RUSSIAN
+ case wxLANGUAGE_RUSSIAN_UKRAINE:
+ return wxLANGUAGE_RUSSIAN;
+
+ //variants of wxLANGUAGE_SPANISH
+ case wxLANGUAGE_SPANISH_ARGENTINA:
+ case wxLANGUAGE_SPANISH_BOLIVIA:
+ case wxLANGUAGE_SPANISH_CHILE:
+ case wxLANGUAGE_SPANISH_COLOMBIA:
+ case wxLANGUAGE_SPANISH_COSTA_RICA:
+ case wxLANGUAGE_SPANISH_DOMINICAN_REPUBLIC:
+ case wxLANGUAGE_SPANISH_ECUADOR:
+ case wxLANGUAGE_SPANISH_EL_SALVADOR:
+ case wxLANGUAGE_SPANISH_GUATEMALA:
+ case wxLANGUAGE_SPANISH_HONDURAS:
+ case wxLANGUAGE_SPANISH_MEXICAN:
+ case wxLANGUAGE_SPANISH_MODERN:
+ case wxLANGUAGE_SPANISH_NICARAGUA:
+ case wxLANGUAGE_SPANISH_PANAMA:
+ case wxLANGUAGE_SPANISH_PARAGUAY:
+ case wxLANGUAGE_SPANISH_PERU:
+ case wxLANGUAGE_SPANISH_PUERTO_RICO:
+ case wxLANGUAGE_SPANISH_URUGUAY:
+ case wxLANGUAGE_SPANISH_US:
+ case wxLANGUAGE_SPANISH_VENEZUELA:
+ return wxLANGUAGE_SPANISH;
+
+ //variants of wxLANGUAGE_SWEDISH
+ case wxLANGUAGE_SWEDISH_FINLAND:
+ return wxLANGUAGE_SWEDISH;
+
+ //case wxLANGUAGE_CZECH:
+ //case wxLANGUAGE_FINNISH:
+ //case wxLANGUAGE_GREEK:
+ //case wxLANGUAGE_JAPANESE:
+ //case wxLANGUAGE_POLISH:
+ //case wxLANGUAGE_SLOVENIAN:
+ //case wxLANGUAGE_HUNGARIAN:
+ //case wxLANGUAGE_PORTUGUESE:
+ //case wxLANGUAGE_PORTUGUESE_BRAZILIAN:
+ //case wxLANGUAGE_KOREAN:
+
+ //variants of wxLANGUAGE_ARABIC (also needed to detect RTL languages)
+ case wxLANGUAGE_ARABIC_ALGERIA:
+ case wxLANGUAGE_ARABIC_BAHRAIN:
+ case wxLANGUAGE_ARABIC_EGYPT:
+ case wxLANGUAGE_ARABIC_IRAQ:
+ case wxLANGUAGE_ARABIC_JORDAN:
+ case wxLANGUAGE_ARABIC_KUWAIT:
+ case wxLANGUAGE_ARABIC_LEBANON:
+ case wxLANGUAGE_ARABIC_LIBYA:
+ case wxLANGUAGE_ARABIC_MOROCCO:
+ case wxLANGUAGE_ARABIC_OMAN:
+ case wxLANGUAGE_ARABIC_QATAR:
+ case wxLANGUAGE_ARABIC_SAUDI_ARABIA:
+ case wxLANGUAGE_ARABIC_SUDAN:
+ case wxLANGUAGE_ARABIC_SYRIA:
+ case wxLANGUAGE_ARABIC_TUNISIA:
+ case wxLANGUAGE_ARABIC_UAE:
+ case wxLANGUAGE_ARABIC_YEMEN:
+ return wxLANGUAGE_ARABIC;
+
+ //variants of wxLANGUAGE_ENGLISH_UK
+ case wxLANGUAGE_ENGLISH_AUSTRALIA:
+ case wxLANGUAGE_ENGLISH_NEW_ZEALAND:
+ case wxLANGUAGE_ENGLISH_TRINIDAD:
+ case wxLANGUAGE_ENGLISH_CARIBBEAN:
+ case wxLANGUAGE_ENGLISH_JAMAICA:
+ case wxLANGUAGE_ENGLISH_BELIZE:
+ case wxLANGUAGE_ENGLISH_EIRE:
+ case wxLANGUAGE_ENGLISH_SOUTH_AFRICA:
+ case wxLANGUAGE_ENGLISH_ZIMBABWE:
+ case wxLANGUAGE_ENGLISH_BOTSWANA:
+ case wxLANGUAGE_ENGLISH_DENMARK:
+ return wxLANGUAGE_ENGLISH_UK;
+
+ default:
+ return language;
}
}
-typedef wxString TextOriginal;
-typedef wxString TextTranslation;
-
-class Translation : public std::map<TextOriginal, TextTranslation> {};
-
-
-CustomLocale& CustomLocale::getInstance()
-{
- static CustomLocale instance;
- return instance;
-}
-
-
-CustomLocale::CustomLocale() :
- translationDB(new Translation),
- currentLanguage(wxLANGUAGE_ENGLISH)
-{
- Init(wxLANGUAGE_DEFAULT); //setting a different language needn't be supported on all systems!
-
- //actually these two parameters are language dependent, but we take system setting to handle all kinds of language derivations
- const lconv* localInfo = localeconv();
- THOUSANDS_SEPARATOR = wxString::FromUTF8(localInfo->thousands_sep);
- DECIMAL_POINT = wxString::FromUTF8(localInfo->decimal_point);
-
- // why not working?
- // THOUSANDS_SEPARATOR = std::use_facet<std::numpunct<wchar_t> >(std::locale("")).thousands_sep();
- // DECIMAL_POINT = std::use_facet<std::numpunct<wchar_t> >(std::locale("")).decimal_point();
-}
-
-
-CustomLocale::~CustomLocale() {} //non-inline destructor for std::auto_ptr to work with forward declaration
-
-
inline
void exchangeEscapeChars(wxString& data)
{
@@ -407,20 +390,20 @@ void exchangeEscapeChars(wxString& data)
switch (value)
{
- case wxChar('\\'):
- output += wxChar('\\');
- break;
- case wxChar('n'):
- output += wxChar('\n');
- break;
- case wxChar('t'):
- output += wxChar('\t');
- break;
- case wxChar('\"'):
- output += wxChar('\"');
- break;
- default:
- output += value;
+ case wxChar('\\'):
+ output += wxChar('\\');
+ break;
+ case wxChar('n'):
+ output += wxChar('\n');
+ break;
+ case wxChar('t'):
+ output += wxChar('\t');
+ break;
+ case wxChar('\"'):
+ output += wxChar('\"');
+ break;
+ default:
+ output += value;
}
}
else
@@ -432,13 +415,13 @@ void exchangeEscapeChars(wxString& data)
}
+//workaround to get a FILE* from a unicode filename in a portable way
class UnicodeFileReader
{
public:
UnicodeFileReader(const wxString& filename) :
inputFile(NULL)
{
- //workaround to get a FILE* from a unicode filename
wxFFile dummyFile(filename, wxT("rb"));
if (dummyFile.IsOpened())
{
@@ -489,9 +472,182 @@ private:
};
+typedef std::map<wxString, wxString> TranslationMap; //map original text |-> translation
+
+void loadTranslation(const wxString& filename, TranslationMap& trans) //empty translation on error
+{
+ trans.clear();
+
+ UnicodeFileReader langFile(ffs3::getResourceDir() + wxT("Languages") + ffs3::zToWx(common::FILE_NAME_SEPARATOR) + filename);
+ if (langFile.isOkay())
+ {
+ //save encoding info: required by mo file generator
+ trans.insert(std::make_pair(wxEmptyString, wxT("Content-Type: text/plain; charset=UTF-8\n")));
+
+ int rowNumber = 0;
+ wxString original;
+ wxString tmpString;
+ while (langFile.getNextLine(tmpString))
+ {
+ exchangeEscapeChars(tmpString);
+
+ if (rowNumber++ % 2 == 0)
+ original = tmpString;
+ else
+ {
+ const wxString& translation = tmpString;
+
+ if (!original.empty() && !translation.empty())
+ trans.insert(std::make_pair(original, translation));
+ }
+ }
+ }
+}
+}
+
+
+#if wxCHECK_VERSION(2, 9, 1)
+//this whole abomination is required to support language formats other than "mo" in wxWidgets v2.9
+class FFSTranslationLoader : public wxTranslationsLoader
+{
+public:
+ static const wxString domainName()
+ {
+ return wxT("FFS");
+ }
+
+ FFSTranslationLoader(const TranslationMap& trans, wxLanguage langId) : langId_(langId)
+ {
+ //generate mo file: http://www.gnu.org/software/hello/manual/gettext/MO-Files.html
+
+ std::string binaryStream;
+
+ const size_t offsetTableOrig = sizeof(wxMsgCatalogHeader);
+ const size_t offsetTableTrans = offsetTableOrig + trans.size() * sizeof(wxMsgTableEntry);
+ const size_t offsetTableString = offsetTableTrans + trans.size() * sizeof(wxMsgTableEntry);
+
+ wxMsgCatalogHeader header =
+ {
+ 0x950412de, //magic number (save in this machine's byte order)
+ 0, //revision
+ trans.size(), //numStrings
+ offsetTableOrig, //ofsOrigTable
+ offsetTableTrans, //ofsTransTable
+ 0, //nHashSize
+ 0, //ofsHashTable
+ };
+ writeCobject(binaryStream, header);
+
+ std::string tableOrig;
+ std::string tableTrans;
+ std::string stringsList;
+ for (TranslationMap::const_iterator i = trans.begin(); i != trans.end(); ++i)
+ {
+
+#ifndef _MSC_VER
+#warning redundant UTF8 conversion!!!
+#endif
+ std::string origString = i->first.ToUTF8();
+ const wxMsgTableEntry origEntry = {origString.length(), offsetTableString + stringsList.size()};
+ writeCobject(tableOrig, origEntry);
+ stringsList.append(origString.c_str(), origString.length() + 1); //include NULL-termination
+
+#ifndef _MSC_VER
+#warning redundant UTF8 conversion!!!
+#endif
+ std::string transString = i->second.ToUTF8();
+ const wxMsgTableEntry transEntry = {transString.length(), offsetTableString + stringsList.size()};
+ writeCobject(tableTrans, transEntry);
+ stringsList.append(transString.c_str(), transString.length() + 1); //include NULL-termination
+ }
+ binaryStream += tableOrig;
+ binaryStream += tableTrans;
+ binaryStream += stringsList;
+
+ buffer = wxScopedCharBuffer::CreateOwned(static_cast<char*>(::malloc(binaryStream.size())), binaryStream.size()); //takes buffer ownership, calls ::free()
+ std::copy(binaryStream.begin(), binaryStream.end(), buffer.data());
+ }
+
+ virtual wxMsgCatalog* LoadCatalog(const wxString& domain, const wxString& lang)
+ {
+ if (domain != domainName() || lang != wxLocale::GetLanguageCanonicalName(langId_)) //avoid superfluous calls by wxWidgets framework
+ return NULL;
+
+ return wxMsgCatalog::CreateFromData(buffer, domain);
+ }
+
+ virtual wxArrayString GetAvailableTranslations(const wxString& domain) const
+ {
+ wxArrayString output;
+ if (domain == domainName())
+ output.Add(wxLocale::GetLanguageCanonicalName(langId_));
+ return output;
+ }
+
+private:
+ struct wxMsgTableEntry
+ {
+ boost::uint32_t nLen, // length of the string
+ ofsString; // pointer to the string
+ };
+
+ // header of a .mo file
+ struct wxMsgCatalogHeader
+ {
+ boost::uint32_t magic, // offset +00: magic id
+ revision, // +04: revision
+ numStrings, // +08: number of strings in the file
+ ofsOrigTable, // +0C: start of original string table
+ ofsTransTable, // +10: start of translated string table
+ nHashSize, // +14: hash table size
+ ofsHashTable; // +18: offset of hash table start
+ };
+
+ template <class T>
+ void writeCobject(std::string& str, T obj)
+ {
+ str.append(reinterpret_cast<const char*>(&obj), sizeof(obj));
+ }
+
+ wxScopedCharBuffer buffer; //raw data in mo file format
+ const wxLanguage langId_;
+};
+#endif
+
+
+CustomLocale& CustomLocale::getInstance()
+{
+ static CustomLocale instance;
+ return instance;
+}
+
+
+class Translation : public TranslationMap {};
+
+
+CustomLocale::CustomLocale() :
+ translationDB(new Translation),
+ currentLanguage(wxLANGUAGE_ENGLISH)
+{
+ Init(wxLANGUAGE_DEFAULT); //setting a different language needn't be supported on all systems!
+
+ //actually these two parameters are language dependent, but we take system setting to handle all kinds of language derivations
+ const lconv* localInfo = localeconv();
+ THOUSANDS_SEPARATOR = wxString::FromUTF8(localInfo->thousands_sep);
+ DECIMAL_POINT = wxString::FromUTF8(localInfo->decimal_point);
+
+ // why not working?
+ // THOUSANDS_SEPARATOR = std::use_facet<std::numpunct<wchar_t> >(std::locale("")).thousands_sep();
+ // DECIMAL_POINT = std::use_facet<std::numpunct<wchar_t> >(std::locale("")).decimal_point();
+}
+
+
+CustomLocale::~CustomLocale() {} //non-inline destructor for std::auto_ptr to work with forward declaration
+
+
void CustomLocale::setLanguage(int language)
{
- currentLanguage = language;
+ currentLanguage = static_cast<wxLanguage>(language);
//default: english
wxString languageFile;
@@ -509,29 +665,8 @@ void CustomLocale::setLanguage(int language)
translationDB->clear();
if (!languageFile.empty())
{
- UnicodeFileReader langFile(ffs3::getResourceDir() + wxT("Languages") +
- zToWx(common::FILE_NAME_SEPARATOR) + languageFile);
- if (langFile.isOkay())
- {
- int rowNumber = 0;
- wxString original;
- wxString tmpString;
- while (langFile.getNextLine(tmpString))
- {
- exchangeEscapeChars(tmpString);
-
- if (rowNumber++ % 2 == 0)
- original = tmpString;
- else
- {
- const wxString& translation = tmpString;
-
- if (!translation.empty())
- translationDB->insert(std::make_pair(original, translation));
- }
- }
- }
- else
+ loadTranslation(languageFile, *translationDB); //empty translation on error
+ if (translationDB->empty())
{
wxMessageBox(wxString(_("Error reading file:")) + wxT(" \"") + languageFile + wxT("\""), _("Error"), wxOK | wxICON_ERROR);
currentLanguage = wxLANGUAGE_ENGLISH; //reset to english language to show this error just once
@@ -539,6 +674,16 @@ void CustomLocale::setLanguage(int language)
}
else
; //if languageFile is empty texts will be english per default
+
+
+
+#if wxCHECK_VERSION(2, 9, 1)
+ wxTranslations::Set(new wxTranslations);
+ wxTranslations::Get()->SetLoader(new FFSTranslationLoader(*translationDB, currentLanguage)); //ownership passed
+ wxTranslations::Get()->SetLanguage(currentLanguage);
+ wxTranslations::Get()->AddCatalog(FFSTranslationLoader::domainName(), wxLANGUAGE_ENGLISH_US);
+ //... a little over design going on?!?
+#endif
}
@@ -553,23 +698,3 @@ const wxChar* CustomLocale::GetString(const wxChar* szOrigString, const wxChar*
return szOrigString;
}
-
-
-/*
-
-wxWidgets 2.9.1:
-
-class CustomTranslation : public wxTranslations
-{
- virtual const wxString& GetString(const wxString& origString,
- const wxString& domain = wxEmptyString) const
- {
- static const wxString blah = "map origString to translation by some arbitrary means";
- return blah;
- }
-
- wxTranslations::Set(new CustomTranslation);
-
-};
-
-*/
diff --git a/shared/localization.h b/shared/localization.h
index 40d71423..3ce7bf24 100644
--- a/shared/localization.h
+++ b/shared/localization.h
@@ -23,7 +23,7 @@ wxString getDecimalPoint();
struct LocInfoLine
{
- int languageID;
+ wxLanguage languageID;
wxString languageName;
wxString languageFile;
wxString translatorName;
@@ -63,7 +63,7 @@ private:
~CustomLocale(); //non-inline destructor for std::auto_ptr to work with forward declaration -> superfluous in this case: singleton pattern!
std::auto_ptr<Translation> translationDB; //careful with forward-declarations and auto_ptr! save in this case, 'cause full class info available
- int currentLanguage;
+ wxLanguage currentLanguage;
};
}
diff --git a/shared/loki/AbstractFactory.h b/shared/loki/AbstractFactory.h
index 8ff518dc..9a30583b 100644
--- a/shared/loki/AbstractFactory.h
+++ b/shared/loki/AbstractFactory.h
@@ -2,14 +2,14 @@
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
-// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author or Addison-Wesley Longman make no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author or Addison-Wesley Longman make no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_ABSTRACTFACTORY_INC_
@@ -31,7 +31,7 @@
* \ingroup FactoriesGroup
* \brief Implements an abstract object factory.
*/
-
+
/**
* \class AbstractFactory
* \ingroup AbstractFactoryGroup
@@ -46,137 +46,137 @@ namespace Loki
// The building block of an Abstract Factory
////////////////////////////////////////////////////////////////////////////////
- template <class T>
- class AbstractFactoryUnit
- {
- public:
- virtual T* DoCreate(Type2Type<T>) = 0;
- virtual ~AbstractFactoryUnit() {}
- };
+template <class T>
+class AbstractFactoryUnit
+{
+public:
+ virtual T* DoCreate(Type2Type<T>) = 0;
+ virtual ~AbstractFactoryUnit() {}
+};
////////////////////////////////////////////////////////////////////////////////
// class template AbstractFactory
// Defines an Abstract Factory interface starting from a typelist
////////////////////////////////////////////////////////////////////////////////
- template
- <
- class TList,
- template <class> class Unit = AbstractFactoryUnit
- >
- class AbstractFactory : public GenScatterHierarchy<TList, Unit>
+template
+<
+class TList,
+ template <class> class Unit = AbstractFactoryUnit
+ >
+class AbstractFactory : public GenScatterHierarchy<TList, Unit>
+{
+public:
+ typedef TList ProductList;
+
+ template <class T> T* Create()
{
- public:
- typedef TList ProductList;
-
- template <class T> T* Create()
- {
- Unit<T>& unit = *this;
- return unit.DoCreate(Type2Type<T>());
- }
- };
-
+ Unit<T>& unit = *this;
+ return unit.DoCreate(Type2Type<T>());
+ }
+};
+
////////////////////////////////////////////////////////////////////////////////
// class template OpNewFactoryUnit
// Creates an object by invoking the new operator
////////////////////////////////////////////////////////////////////////////////
- template <class ConcreteProduct, class Base>
- class OpNewFactoryUnit : public Base
+template <class ConcreteProduct, class Base>
+class OpNewFactoryUnit : public Base
+{
+ typedef typename Base::ProductList BaseProductList;
+
+protected:
+ typedef typename BaseProductList::Tail ProductList;
+
+public:
+ typedef typename BaseProductList::Head AbstractProduct;
+ ConcreteProduct* DoCreate(Type2Type<AbstractProduct>)
{
- typedef typename Base::ProductList BaseProductList;
-
- protected:
- typedef typename BaseProductList::Tail ProductList;
-
- public:
- typedef typename BaseProductList::Head AbstractProduct;
- ConcreteProduct* DoCreate(Type2Type<AbstractProduct>)
- {
- return new ConcreteProduct;
- }
- };
+ return new ConcreteProduct;
+ }
+};
////////////////////////////////////////////////////////////////////////////////
// class template PrototypeFactoryUnit
// Creates an object by cloning a prototype
// There is a difference between the implementation herein and the one described
-// in the book: GetPrototype and SetPrototype use the helper friend
+// in the book: GetPrototype and SetPrototype use the helper friend
// functions DoGetPrototype and DoSetPrototype. The friend functions avoid
// name hiding issues. Plus, GetPrototype takes a reference to pointer
// instead of returning the pointer by value.
////////////////////////////////////////////////////////////////////////////////
- template <class ConcreteProduct, class Base>
- class PrototypeFactoryUnit : public Base
+template <class ConcreteProduct, class Base>
+class PrototypeFactoryUnit : public Base
+{
+ typedef typename Base::ProductList BaseProductList;
+
+protected:
+ typedef typename BaseProductList::Tail ProductList;
+
+public:
+ typedef typename BaseProductList::Head AbstractProduct;
+
+ PrototypeFactoryUnit(AbstractProduct* p = 0)
+ : pPrototype_(p)
+ {}
+
+ template <class CP, class Base1>
+ friend void DoGetPrototype(const PrototypeFactoryUnit<CP, Base1>& me,
+ typename Base1::ProductList::Head*& pPrototype);
+
+ template <class CP, class Base1>
+ friend void DoSetPrototype(PrototypeFactoryUnit<CP, Base1>& me,
+ typename Base1::ProductList::Head* pObj);
+
+ template <class U>
+ void GetPrototype(U*& p)
+ { return DoGetPrototype(*this, p); }
+
+ template <class U>
+ void SetPrototype(U* pObj)
+ { DoSetPrototype(*this, pObj); }
+
+ AbstractProduct* DoCreate(Type2Type<AbstractProduct>)
{
- typedef typename Base::ProductList BaseProductList;
-
- protected:
- typedef typename BaseProductList::Tail ProductList;
-
- public:
- typedef typename BaseProductList::Head AbstractProduct;
-
- PrototypeFactoryUnit(AbstractProduct* p = 0)
- : pPrototype_(p)
- {}
-
- template <class CP, class Base1>
- friend void DoGetPrototype(const PrototypeFactoryUnit<CP, Base1>& me,
- typename Base1::ProductList::Head*& pPrototype);
-
- template <class CP, class Base1>
- friend void DoSetPrototype(PrototypeFactoryUnit<CP, Base1>& me,
- typename Base1::ProductList::Head* pObj);
-
- template <class U>
- void GetPrototype(U*& p)
- { return DoGetPrototype(*this, p); }
-
- template <class U>
- void SetPrototype(U* pObj)
- { DoSetPrototype(*this, pObj); }
-
- AbstractProduct* DoCreate(Type2Type<AbstractProduct>)
- {
- assert(pPrototype_);
- return pPrototype_->Clone();
- }
-
- private:
- AbstractProduct* pPrototype_;
- };
-
- template <class CP, class Base>
- inline void DoGetPrototype(const PrototypeFactoryUnit<CP, Base>& me,
- typename Base::ProductList::Head*& pPrototype)
- { pPrototype = me.pPrototype_; }
-
- template <class CP, class Base>
- inline void DoSetPrototype(PrototypeFactoryUnit<CP, Base>& me,
- typename Base::ProductList::Head* pObj)
- { me.pPrototype_ = pObj; }
+ assert(pPrototype_);
+ return pPrototype_->Clone();
+ }
+
+private:
+ AbstractProduct* pPrototype_;
+};
+
+template <class CP, class Base>
+inline void DoGetPrototype(const PrototypeFactoryUnit<CP, Base>& me,
+ typename Base::ProductList::Head*& pPrototype)
+{ pPrototype = me.pPrototype_; }
+
+template <class CP, class Base>
+inline void DoSetPrototype(PrototypeFactoryUnit<CP, Base>& me,
+ typename Base::ProductList::Head* pObj)
+{ me.pPrototype_ = pObj; }
////////////////////////////////////////////////////////////////////////////////
// class template ConcreteFactory
// Implements an AbstractFactory interface
////////////////////////////////////////////////////////////////////////////////
- template
- <
- class AbstractFact,
- template <class, class> class Creator = OpNewFactoryUnit,
- class TList = typename AbstractFact::ProductList
- >
- class ConcreteFactory
- : public GenLinearHierarchy<
- typename TL::Reverse<TList>::Result, Creator, AbstractFact>
- {
- public:
- typedef typename AbstractFact::ProductList ProductList;
- typedef TList ConcreteProductList;
- };
+template
+<
+class AbstractFact,
+ template <class, class> class Creator = OpNewFactoryUnit,
+ class TList = typename AbstractFact::ProductList
+ >
+class ConcreteFactory
+ : public GenLinearHierarchy<
+ typename TL::Reverse<TList>::Result, Creator, AbstractFact>
+{
+public:
+ typedef typename AbstractFact::ProductList ProductList;
+ typedef TList ConcreteProductList;
+};
} // namespace Loki
diff --git a/shared/loki/Allocator.h b/shared/loki/Allocator.h
index a79ee061..39b63912 100644
--- a/shared/loki/Allocator.h
+++ b/shared/loki/Allocator.h
@@ -2,12 +2,12 @@
// The Loki Library
// Copyright (c) 2008 by Rich Sposato
//
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author makes no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author makes no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
@@ -35,26 +35,26 @@ namespace Loki
*/
template
<
- typename Type,
- typename AllocT = Loki::AllocatorSingleton<>
->
+typename Type,
+ typename AllocT = Loki::AllocatorSingleton<>
+ >
class LokiAllocator
{
public:
typedef ::std::size_t size_type;
typedef ::std::ptrdiff_t difference_type;
- typedef Type * pointer;
- typedef const Type * const_pointer;
- typedef Type & reference;
- typedef const Type & const_reference;
+ typedef Type* pointer;
+ typedef const Type* const_pointer;
+ typedef Type& reference;
+ typedef const Type& const_reference;
typedef Type value_type;
/// Default constructor does nothing.
inline LokiAllocator( void ) throw() { }
/// Copy constructor does nothing.
- inline LokiAllocator( const LokiAllocator & ) throw() { }
+ inline LokiAllocator( const LokiAllocator& ) throw() { }
/// Type converting allocator constructor does nothing.
template < typename Type1 >
@@ -84,10 +84,10 @@ public:
@param hint Place where caller thinks allocation should occur.
@return Pointer to block of memory.
*/
- pointer allocate( size_type count, const void * hint = 0 )
+ pointer allocate( size_type count, const void* hint = 0 )
{
(void)hint; // Ignore the hint.
- void * p = AllocT::Instance().Allocate( count * sizeof( Type ), true );
+ void* p = AllocT::Instance().Allocate( count * sizeof( Type ), true );
return reinterpret_cast< pointer >( p );
}
@@ -108,7 +108,7 @@ public:
}
/// Construct an element at the pointer.
- void construct( pointer p, const Type & value )
+ void construct( pointer p, const Type& value )
{
// A call to global placement new forces a call to copy constructor.
::new( p ) Type( value );
diff --git a/shared/loki/AssocVector.h b/shared/loki/AssocVector.h
index 905e0963..ad43d152 100644
--- a/shared/loki/AssocVector.h
+++ b/shared/loki/AssocVector.h
@@ -2,14 +2,14 @@
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
-// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author or Addison-Wesley Longman make no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author or Addison-Wesley Longman make no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_ASSOCVECTOR_INC_
@@ -30,38 +30,38 @@ namespace Loki
// Used by AssocVector
////////////////////////////////////////////////////////////////////////////////
- namespace Private
- {
- template <class Value, class C>
- class AssocVectorCompare : public C
- {
- typedef std::pair<typename C::first_argument_type, Value>
- Data;
- typedef typename C::first_argument_type first_argument_type;
-
- public:
- AssocVectorCompare()
- {}
-
- AssocVectorCompare(const C& src) : C(src)
- {}
-
- bool operator()(const first_argument_type& lhs,
- const first_argument_type& rhs) const
- { return C::operator()(lhs, rhs); }
-
- bool operator()(const Data& lhs, const Data& rhs) const
- { return operator()(lhs.first, rhs.first); }
-
- bool operator()(const Data& lhs,
- const first_argument_type& rhs) const
- { return operator()(lhs.first, rhs); }
-
- bool operator()(const first_argument_type& lhs,
- const Data& rhs) const
- { return operator()(lhs, rhs.first); }
- };
- }
+namespace Private
+{
+template <class Value, class C>
+class AssocVectorCompare : public C
+{
+ typedef std::pair<typename C::first_argument_type, Value>
+ Data;
+ typedef typename C::first_argument_type first_argument_type;
+
+public:
+ AssocVectorCompare()
+ {}
+
+ AssocVectorCompare(const C& src) : C(src)
+ {}
+
+ bool operator()(const first_argument_type& lhs,
+ const first_argument_type& rhs) const
+ { return C::operator()(lhs, rhs); }
+
+ bool operator()(const Data& lhs, const Data& rhs) const
+ { return operator()(lhs.first, rhs.first); }
+
+ bool operator()(const Data& lhs,
+ const first_argument_type& rhs) const
+ { return operator()(lhs.first, rhs); }
+
+ bool operator()(const first_argument_type& lhs,
+ const Data& rhs) const
+ { return operator()(lhs, rhs.first); }
+};
+}
////////////////////////////////////////////////////////////////////////////////
// class template AssocVector
@@ -75,283 +75,283 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
- template
- <
- class K,
- class V,
- class C = std::less<K>,
- class A = std::allocator< std::pair<K, V> >
- >
- class AssocVector
- : private std::vector< std::pair<K, V>, A >
- , private Private::AssocVectorCompare<V, C>
+template
+<
+class K,
+ class V,
+ class C = std::less<K>,
+ class A = std::allocator< std::pair<K, V> >
+ >
+class AssocVector
+ : private std::vector< std::pair<K, V>, A >
+ , private Private::AssocVectorCompare<V, C>
+{
+ typedef std::vector<std::pair<K, V>, A> Base;
+ typedef Private::AssocVectorCompare<V, C> MyCompare;
+
+public:
+ typedef K key_type;
+ typedef V mapped_type;
+ typedef typename Base::value_type value_type;
+
+ typedef C key_compare;
+ typedef A allocator_type;
+ typedef typename A::reference reference;
+ typedef typename A::const_reference const_reference;
+ typedef typename Base::iterator iterator;
+ typedef typename Base::const_iterator const_iterator;
+ typedef typename Base::size_type size_type;
+ typedef typename Base::difference_type difference_type;
+ typedef typename A::pointer pointer;
+ typedef typename A::const_pointer const_pointer;
+ typedef typename Base::reverse_iterator reverse_iterator;
+ typedef typename Base::const_reverse_iterator const_reverse_iterator;
+
+ class value_compare
+ : public std::binary_function<value_type, value_type, bool>
+ , private key_compare
{
- typedef std::vector<std::pair<K, V>, A> Base;
- typedef Private::AssocVectorCompare<V, C> MyCompare;
+ friend class AssocVector;
+
+ protected:
+ value_compare(key_compare pred) : key_compare(pred)
+ {}
public:
- typedef K key_type;
- typedef V mapped_type;
- typedef typename Base::value_type value_type;
-
- typedef C key_compare;
- typedef A allocator_type;
- typedef typename A::reference reference;
- typedef typename A::const_reference const_reference;
- typedef typename Base::iterator iterator;
- typedef typename Base::const_iterator const_iterator;
- typedef typename Base::size_type size_type;
- typedef typename Base::difference_type difference_type;
- typedef typename A::pointer pointer;
- typedef typename A::const_pointer const_pointer;
- typedef typename Base::reverse_iterator reverse_iterator;
- typedef typename Base::const_reverse_iterator const_reverse_iterator;
-
- class value_compare
- : public std::binary_function<value_type, value_type, bool>
- , private key_compare
- {
- friend class AssocVector;
-
- protected:
- value_compare(key_compare pred) : key_compare(pred)
- {}
-
- public:
- bool operator()(const value_type& lhs, const value_type& rhs) const
- { return key_compare::operator()(lhs.first, rhs.first); }
- };
-
- // 23.3.1.1 construct/copy/destroy
-
- explicit AssocVector(const key_compare& comp = key_compare(),
- const A& alloc = A())
+ bool operator()(const value_type& lhs, const value_type& rhs) const
+ { return key_compare::operator()(lhs.first, rhs.first); }
+ };
+
+ // 23.3.1.1 construct/copy/destroy
+
+ explicit AssocVector(const key_compare& comp = key_compare(),
+ const A& alloc = A())
: Base(alloc), MyCompare(comp)
- {}
-
- template <class InputIterator>
- AssocVector(InputIterator first, InputIterator last,
- const key_compare& comp = key_compare(),
- const A& alloc = A())
+ {}
+
+ template <class InputIterator>
+ AssocVector(InputIterator first, InputIterator last,
+ const key_compare& comp = key_compare(),
+ const A& alloc = A())
: Base(first, last, alloc), MyCompare(comp)
- {
- MyCompare& me = *this;
- std::sort(begin(), end(), me);
- }
-
- AssocVector& operator=(const AssocVector& rhs)
- {
- AssocVector(rhs).swap(*this);
- return *this;
- }
+ {
+ MyCompare& me = *this;
+ std::sort(begin(), end(), me);
+ }
- // iterators:
- // The following are here because MWCW gets 'using' wrong
- iterator begin() { return Base::begin(); }
- const_iterator begin() const { return Base::begin(); }
- iterator end() { return Base::end(); }
- const_iterator end() const { return Base::end(); }
- reverse_iterator rbegin() { return Base::rbegin(); }
- const_reverse_iterator rbegin() const { return Base::rbegin(); }
- reverse_iterator rend() { return Base::rend(); }
- const_reverse_iterator rend() const { return Base::rend(); }
-
- // capacity:
- bool empty() const { return Base::empty(); }
- size_type size() const { return Base::size(); }
- size_type max_size() { return Base::max_size(); }
-
- // 23.3.1.2 element access:
- mapped_type& operator[](const key_type& key)
- { return insert(value_type(key, mapped_type())).first->second; }
-
- // modifiers:
- std::pair<iterator, bool> insert(const value_type& val)
- {
- bool found(true);
- iterator i(lower_bound(val.first));
-
- if (i == end() || this->operator()(val.first, i->first))
- {
- i = Base::insert(i, val);
- found = false;
- }
- return std::make_pair(i, !found);
- }
- //Section [23.1.2], Table 69
- //http://developer.apple.com/documentation/DeveloperTools/gcc-3.3/libstdc++/23_containers/howto.html#4
- iterator insert(iterator pos, const value_type& val)
+ AssocVector& operator=(const AssocVector& rhs)
+ {
+ AssocVector(rhs).swap(*this);
+ return *this;
+ }
+
+ // iterators:
+ // The following are here because MWCW gets 'using' wrong
+ iterator begin() { return Base::begin(); }
+ const_iterator begin() const { return Base::begin(); }
+ iterator end() { return Base::end(); }
+ const_iterator end() const { return Base::end(); }
+ reverse_iterator rbegin() { return Base::rbegin(); }
+ const_reverse_iterator rbegin() const { return Base::rbegin(); }
+ reverse_iterator rend() { return Base::rend(); }
+ const_reverse_iterator rend() const { return Base::rend(); }
+
+ // capacity:
+ bool empty() const { return Base::empty(); }
+ size_type size() const { return Base::size(); }
+ size_type max_size() { return Base::max_size(); }
+
+ // 23.3.1.2 element access:
+ mapped_type& operator[](const key_type& key)
+ { return insert(value_type(key, mapped_type())).first->second; }
+
+ // modifiers:
+ std::pair<iterator, bool> insert(const value_type& val)
+ {
+ bool found(true);
+ iterator i(lower_bound(val.first));
+
+ if (i == end() || this->operator()(val.first, i->first))
{
- if( (pos == begin() || this->operator()(*(pos-1),val)) &&
- (pos == end() || this->operator()(val, *pos)) )
- {
- return Base::insert(pos, val);
- }
- return insert(val).first;
+ i = Base::insert(i, val);
+ found = false;
}
-
- template <class InputIterator>
- void insert(InputIterator first, InputIterator last)
- { for (; first != last; ++first) insert(*first); }
-
- void erase(iterator pos)
- { Base::erase(pos); }
-
- size_type erase(const key_type& k)
+ return std::make_pair(i, !found);
+ }
+ //Section [23.1.2], Table 69
+ //http://developer.apple.com/documentation/DeveloperTools/gcc-3.3/libstdc++/23_containers/howto.html#4
+ iterator insert(iterator pos, const value_type& val)
+ {
+ if( (pos == begin() || this->operator()(*(pos-1),val)) &&
+ (pos == end() || this->operator()(val, *pos)) )
{
- iterator i(find(k));
- if (i == end()) return 0;
- erase(i);
- return 1;
+ return Base::insert(pos, val);
}
+ return insert(val).first;
+ }
- void erase(iterator first, iterator last)
- { Base::erase(first, last); }
+ template <class InputIterator>
+ void insert(InputIterator first, InputIterator last)
+ { for (; first != last; ++first) insert(*first); }
- void swap(AssocVector& other)
- {
- Base::swap(other);
- MyCompare& me = *this;
- MyCompare& rhs = other;
- std::swap(me, rhs);
- }
-
- void clear()
- { Base::clear(); }
+ void erase(iterator pos)
+ { Base::erase(pos); }
- // observers:
- key_compare key_comp() const
- { return *this; }
+ size_type erase(const key_type& k)
+ {
+ iterator i(find(k));
+ if (i == end()) return 0;
+ erase(i);
+ return 1;
+ }
- value_compare value_comp() const
- {
- const key_compare& comp = *this;
- return value_compare(comp);
- }
+ void erase(iterator first, iterator last)
+ { Base::erase(first, last); }
- // 23.3.1.3 map operations:
- iterator find(const key_type& k)
- {
- iterator i(lower_bound(k));
- if (i != end() && this->operator()(k, i->first))
- {
- i = end();
- }
- return i;
- }
+ void swap(AssocVector& other)
+ {
+ Base::swap(other);
+ MyCompare& me = *this;
+ MyCompare& rhs = other;
+ std::swap(me, rhs);
+ }
- const_iterator find(const key_type& k) const
- {
- const_iterator i(lower_bound(k));
- if (i != end() && this->operator()(k, i->first))
- {
- i = end();
- }
- return i;
- }
+ void clear()
+ { Base::clear(); }
- size_type count(const key_type& k) const
- { return find(k) != end(); }
+ // observers:
+ key_compare key_comp() const
+ { return *this; }
- iterator lower_bound(const key_type& k)
- {
- MyCompare& me = *this;
- return std::lower_bound(begin(), end(), k, me);
- }
-
- const_iterator lower_bound(const key_type& k) const
- {
- const MyCompare& me = *this;
- return std::lower_bound(begin(), end(), k, me);
- }
+ value_compare value_comp() const
+ {
+ const key_compare& comp = *this;
+ return value_compare(comp);
+ }
- iterator upper_bound(const key_type& k)
+ // 23.3.1.3 map operations:
+ iterator find(const key_type& k)
+ {
+ iterator i(lower_bound(k));
+ if (i != end() && this->operator()(k, i->first))
{
- MyCompare& me = *this;
- return std::upper_bound(begin(), end(), k, me);
+ i = end();
}
+ return i;
+ }
- const_iterator upper_bound(const key_type& k) const
+ const_iterator find(const key_type& k) const
+ {
+ const_iterator i(lower_bound(k));
+ if (i != end() && this->operator()(k, i->first))
{
- const MyCompare& me = *this;
- return std::upper_bound(begin(), end(), k, me);
+ i = end();
}
+ return i;
+ }
- std::pair<iterator, iterator> equal_range(const key_type& k)
- {
- MyCompare& me = *this;
- return std::equal_range(begin(), end(), k, me);
- }
+ size_type count(const key_type& k) const
+ { return find(k) != end(); }
- std::pair<const_iterator, const_iterator> equal_range(
- const key_type& k) const
- {
- const MyCompare& me = *this;
- return std::equal_range(begin(), end(), k, me);
- }
+ iterator lower_bound(const key_type& k)
+ {
+ MyCompare& me = *this;
+ return std::lower_bound(begin(), end(), k, me);
+ }
- template <class K1, class V1, class C1, class A1>
- friend bool operator==(const AssocVector<K1, V1, C1, A1>& lhs,
- const AssocVector<K1, V1, C1, A1>& rhs);
+ const_iterator lower_bound(const key_type& k) const
+ {
+ const MyCompare& me = *this;
+ return std::lower_bound(begin(), end(), k, me);
+ }
- bool operator<(const AssocVector& rhs) const
- {
- const Base& me = *this;
- const Base& yo = rhs;
- return me < yo;
- }
+ iterator upper_bound(const key_type& k)
+ {
+ MyCompare& me = *this;
+ return std::upper_bound(begin(), end(), k, me);
+ }
- template <class K1, class V1, class C1, class A1>
- friend bool operator!=(const AssocVector<K1, V1, C1, A1>& lhs,
- const AssocVector<K1, V1, C1, A1>& rhs);
+ const_iterator upper_bound(const key_type& k) const
+ {
+ const MyCompare& me = *this;
+ return std::upper_bound(begin(), end(), k, me);
+ }
- template <class K1, class V1, class C1, class A1>
- friend bool operator>(const AssocVector<K1, V1, C1, A1>& lhs,
- const AssocVector<K1, V1, C1, A1>& rhs);
+ std::pair<iterator, iterator> equal_range(const key_type& k)
+ {
+ MyCompare& me = *this;
+ return std::equal_range(begin(), end(), k, me);
+ }
- template <class K1, class V1, class C1, class A1>
- friend bool operator>=(const AssocVector<K1, V1, C1, A1>& lhs,
- const AssocVector<K1, V1, C1, A1>& rhs);
+ std::pair<const_iterator, const_iterator> equal_range(
+ const key_type& k) const
+ {
+ const MyCompare& me = *this;
+ return std::equal_range(begin(), end(), k, me);
+ }
- template <class K1, class V1, class C1, class A1>
- friend bool operator<=(const AssocVector<K1, V1, C1, A1>& lhs,
- const AssocVector<K1, V1, C1, A1>& rhs);
- };
+ template <class K1, class V1, class C1, class A1>
+ friend bool operator==(const AssocVector<K1, V1, C1, A1>& lhs,
+ const AssocVector<K1, V1, C1, A1>& rhs);
- template <class K, class V, class C, class A>
- inline bool operator==(const AssocVector<K, V, C, A>& lhs,
- const AssocVector<K, V, C, A>& rhs)
+ bool operator<(const AssocVector& rhs) const
{
- const std::vector<std::pair<K, V>, A>& me = lhs;
- return me == rhs;
+ const Base& me = *this;
+ const Base& yo = rhs;
+ return me < yo;
}
- template <class K, class V, class C, class A>
- inline bool operator!=(const AssocVector<K, V, C, A>& lhs,
- const AssocVector<K, V, C, A>& rhs)
- { return !(lhs == rhs); }
+ template <class K1, class V1, class C1, class A1>
+ friend bool operator!=(const AssocVector<K1, V1, C1, A1>& lhs,
+ const AssocVector<K1, V1, C1, A1>& rhs);
+
+ template <class K1, class V1, class C1, class A1>
+ friend bool operator>(const AssocVector<K1, V1, C1, A1>& lhs,
+ const AssocVector<K1, V1, C1, A1>& rhs);
+
+ template <class K1, class V1, class C1, class A1>
+ friend bool operator>=(const AssocVector<K1, V1, C1, A1>& lhs,
+ const AssocVector<K1, V1, C1, A1>& rhs);
+
+ template <class K1, class V1, class C1, class A1>
+ friend bool operator<=(const AssocVector<K1, V1, C1, A1>& lhs,
+ const AssocVector<K1, V1, C1, A1>& rhs);
+};
+
+template <class K, class V, class C, class A>
+inline bool operator==(const AssocVector<K, V, C, A>& lhs,
+ const AssocVector<K, V, C, A>& rhs)
+{
+ const std::vector<std::pair<K, V>, A>& me = lhs;
+ return me == rhs;
+}
+
+template <class K, class V, class C, class A>
+inline bool operator!=(const AssocVector<K, V, C, A>& lhs,
+ const AssocVector<K, V, C, A>& rhs)
+{ return !(lhs == rhs); }
+
+template <class K, class V, class C, class A>
+inline bool operator>(const AssocVector<K, V, C, A>& lhs,
+ const AssocVector<K, V, C, A>& rhs)
+{ return rhs < lhs; }
- template <class K, class V, class C, class A>
- inline bool operator>(const AssocVector<K, V, C, A>& lhs,
- const AssocVector<K, V, C, A>& rhs)
- { return rhs < lhs; }
+template <class K, class V, class C, class A>
+inline bool operator>=(const AssocVector<K, V, C, A>& lhs,
+ const AssocVector<K, V, C, A>& rhs)
+{ return !(lhs < rhs); }
- template <class K, class V, class C, class A>
- inline bool operator>=(const AssocVector<K, V, C, A>& lhs,
- const AssocVector<K, V, C, A>& rhs)
- { return !(lhs < rhs); }
+template <class K, class V, class C, class A>
+inline bool operator<=(const AssocVector<K, V, C, A>& lhs,
+ const AssocVector<K, V, C, A>& rhs)
+{ return !(rhs < lhs); }
- template <class K, class V, class C, class A>
- inline bool operator<=(const AssocVector<K, V, C, A>& lhs,
- const AssocVector<K, V, C, A>& rhs)
- { return !(rhs < lhs); }
+// specialized algorithms:
+template <class K, class V, class C, class A>
+void swap(AssocVector<K, V, C, A>& lhs, AssocVector<K, V, C, A>& rhs)
+{ lhs.swap(rhs); }
- // specialized algorithms:
- template <class K, class V, class C, class A>
- void swap(AssocVector<K, V, C, A>& lhs, AssocVector<K, V, C, A>& rhs)
- { lhs.swap(rhs); }
-
} // namespace Loki
#endif // end file guardian
diff --git a/shared/loki/CachedFactory.h b/shared/loki/CachedFactory.h
index 15c9a801..567b035c 100644
--- a/shared/loki/CachedFactory.h
+++ b/shared/loki/CachedFactory.h
@@ -4,16 +4,16 @@
//
// Code covered by the MIT License
//
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
//
// The authors make no representations about the suitability of this software
// for any purpose. It is provided "as is" without express or implied warranty.
//
// This code DOES NOT accompany the book:
-// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
//
////////////////////////////////////////////////////////////////////////////////
@@ -32,9 +32,9 @@
#include <loki/Key.h>
#ifdef DO_EXTRA_LOKI_TESTS
- #define D( x ) x
+#define D( x ) x
#else
- #define D( x ) ;
+#define D( x ) ;
#endif
#if defined(_MSC_VER) || defined(__CYGWIN__)
@@ -47,7 +47,7 @@
* \ingroup FactoriesGroup
* \brief CachedFactory provides an extension of a Factory with caching
* support.
- *
+ *
* Once used objects are returned to the CachedFactory that manages its
* destruction.
* If your code uses lots of "long to construct/destruct objects" using the
@@ -60,231 +60,231 @@ namespace Loki
* \ingroup CachedFactoryGroup
* \brief Defines how the object is returned to the client
*/
- /**
- * \class SimplePointer
- * \ingroup EncapsulationPolicyCachedFactoryGroup
- * \brief No encaspulation : returns the pointer
- *
- * This implementation does not make any encapsulation.
- * It simply returns the object's pointer.
- */
- template<class AbstractProduct>
- class SimplePointer
- {
- protected:
- typedef AbstractProduct* ProductReturn;
- ProductReturn encapsulate(AbstractProduct* pProduct)
- {
- return pProduct;
- }
-
- AbstractProduct* release(ProductReturn &pProduct)
- {
- AbstractProduct* pPointer(pProduct);
- pProduct=NULL;
- return pPointer;
- }
- const char* name(){return "pointer";}
- };
+/**
+ * \class SimplePointer
+ * \ingroup EncapsulationPolicyCachedFactoryGroup
+ * \brief No encaspulation : returns the pointer
+ *
+ * This implementation does not make any encapsulation.
+ * It simply returns the object's pointer.
+ */
+template<class AbstractProduct>
+class SimplePointer
+{
+protected:
+ typedef AbstractProduct* ProductReturn;
+ ProductReturn encapsulate(AbstractProduct* pProduct)
+ {
+ return pProduct;
+ }
+
+ AbstractProduct* release(ProductReturn& pProduct)
+ {
+ AbstractProduct* pPointer(pProduct);
+ pProduct=NULL;
+ return pPointer;
+ }
+ const char* name() {return "pointer";}
+};
/**
* \defgroup CreationPolicyCachedFactoryGroup Creation policies
* \ingroup CachedFactoryGroup
* \brief Defines a way to limit the creation operation.
- *
+ *
* For instance one may want to be alerted (Exception) when
* - Cache has created a more than X object within the last x seconds
* - Cache creation rate has increased dramatically
* .
* which may result from bad caching strategy, or critical overload
*/
- /**
- * \class NeverCreate
- * \ingroup CreationPolicyCachedFactoryGroup
- * \brief Never allows creation. Testing purposes only.
- *
- * Using this policy will throw an exception.
- */
- class NeverCreate
- {
- protected:
- struct Exception : public std::exception
- {
- const char* what() const throw() { return "NeverFetch Policy : No Fetching allowed"; }
- };
-
- bool canCreate()
- {
- throw Exception();
- }
-
- void onCreate(){}
- void onDestroy(){}
- const char* name(){return "never";}
- };
-
- /**
- * \class AlwaysCreate
- * \ingroup CreationPolicyCachedFactoryGroup
- * \brief Always allows creation.
- *
- * Doesn't limit the creation in any way
- */
- class AlwaysCreate
- {
- protected:
- bool canCreate()
- {
- return true;
- }
+/**
+ * \class NeverCreate
+ * \ingroup CreationPolicyCachedFactoryGroup
+ * \brief Never allows creation. Testing purposes only.
+ *
+ * Using this policy will throw an exception.
+ */
+class NeverCreate
+{
+protected:
+ struct Exception : public std::exception
+ {
+ const char* what() const throw() { return "NeverFetch Policy : No Fetching allowed"; }
+ };
- void onCreate(){}
- void onDestroy(){}
- const char* name(){return "always";}
- };
+ bool canCreate()
+ {
+ throw Exception();
+ }
+ void onCreate() {}
+ void onDestroy() {}
+ const char* name() {return "never";}
+};
- /**
- * \class RateLimitedCreation
- * \ingroup CreationPolicyCachedFactoryGroup
- * \brief Limit in rate.
- *
- * This implementation will prevent from Creating more than maxCreation objects
- * within byTime ms by throwing an exception.
- * Could be usefull to detect prevent loads (http connection for instance).
- * Use the setRate method to set the rate parameters.
- * default is 10 objects in a second.
- */
- // !! CAUTION !!
- // The std::clock() function is not quite precise
- // under linux this policy might not work.
- // TODO : get a better implementation (platform dependant)
- class RateLimitedCreation
- {
- private:
- typedef std::vector< clock_t > Vector;
- Vector m_vTimes;
- unsigned maxCreation;
- clock_t timeValidity;
- clock_t lastUpdate;
-
- void cleanVector()
- {
- using namespace std;
- clock_t currentTime = clock();
- D( cout << "currentTime = " << currentTime<< endl; )
- D( cout << "currentTime - lastUpdate = " << currentTime - lastUpdate<< endl; )
- if(currentTime - lastUpdate > timeValidity)
- {
- m_vTimes.clear();
- D( cout << " is less than time validity " << timeValidity; )
- D( cout << " so clearing vector" << endl; )
- }
- else
- {
- D( cout << "Cleaning time less than " << currentTime - timeValidity << endl; )
- D( displayVector(); )
- Vector::iterator newEnd = remove_if(m_vTimes.begin(), m_vTimes.end(), bind2nd(less<clock_t>(), currentTime - timeValidity));
- // this rearrangement might be costly, consider optimization
- // by calling cleanVector in less used onCreate function
- // ... although it may not be correct
- m_vTimes.erase(newEnd, m_vTimes.end());
- D( displayVector(); )
- }
- lastUpdate = currentTime;
- }
-#ifdef DO_EXTRA_LOKI_TESTS
- void displayVector()
- {
- std::cout << "Vector : ";
- copy(m_vTimes.begin(), m_vTimes.end(), std::ostream_iterator<clock_t>(std::cout, " "));
- std::cout << std::endl;
- }
+/**
+ * \class AlwaysCreate
+ * \ingroup CreationPolicyCachedFactoryGroup
+ * \brief Always allows creation.
+ *
+ * Doesn't limit the creation in any way
+ */
+class AlwaysCreate
+{
+protected:
+ bool canCreate()
+ {
+ return true;
+ }
+
+ void onCreate() {}
+ void onDestroy() {}
+ const char* name() {return "always";}
+};
+
+
+/**
+ * \class RateLimitedCreation
+ * \ingroup CreationPolicyCachedFactoryGroup
+ * \brief Limit in rate.
+ *
+ * This implementation will prevent from Creating more than maxCreation objects
+ * within byTime ms by throwing an exception.
+ * Could be usefull to detect prevent loads (http connection for instance).
+ * Use the setRate method to set the rate parameters.
+ * default is 10 objects in a second.
+ */
+// !! CAUTION !!
+// The std::clock() function is not quite precise
+// under linux this policy might not work.
+// TODO : get a better implementation (platform dependant)
+class RateLimitedCreation
+{
+private:
+ typedef std::vector< clock_t > Vector;
+ Vector m_vTimes;
+ unsigned maxCreation;
+ clock_t timeValidity;
+ clock_t lastUpdate;
+
+ void cleanVector()
+ {
+ using namespace std;
+ clock_t currentTime = clock();
+ D( cout << "currentTime = " << currentTime<< endl; )
+ D( cout << "currentTime - lastUpdate = " << currentTime - lastUpdate<< endl; )
+ if(currentTime - lastUpdate > timeValidity)
+ {
+ m_vTimes.clear();
+ D( cout << " is less than time validity " << timeValidity; )
+ D( cout << " so clearing vector" << endl; )
+ }
+ else
+ {
+ D( cout << "Cleaning time less than " << currentTime - timeValidity << endl; )
+ D( displayVector(); )
+ Vector::iterator newEnd = remove_if(m_vTimes.begin(), m_vTimes.end(), bind2nd(less<clock_t>(), currentTime - timeValidity));
+ // this rearrangement might be costly, consider optimization
+ // by calling cleanVector in less used onCreate function
+ // ... although it may not be correct
+ m_vTimes.erase(newEnd, m_vTimes.end());
+ D( displayVector(); )
+ }
+ lastUpdate = currentTime;
+ }
+#ifdef DO_EXTRA_LOKI_TESTS
+ void displayVector()
+ {
+ std::cout << "Vector : ";
+ copy(m_vTimes.begin(), m_vTimes.end(), std::ostream_iterator<clock_t>(std::cout, " "));
+ std::cout << std::endl;
+ }
#endif
- protected:
- RateLimitedCreation() : maxCreation(10), timeValidity(CLOCKS_PER_SEC), lastUpdate(clock())
- {}
-
- struct Exception : public std::exception
- {
- const char* what() const throw() { return "RateLimitedCreation Policy : Exceeded the authorized creation rate"; }
- };
-
- bool canCreate()
- {
- cleanVector();
- if(m_vTimes.size()>maxCreation)
- throw Exception();
- else
- return true;
- }
+protected:
+ RateLimitedCreation() : maxCreation(10), timeValidity(CLOCKS_PER_SEC), lastUpdate(clock())
+ {}
- void onCreate()
- {
- m_vTimes.push_back(clock());
- }
-
- void onDestroy()
- {
- }
- const char* name(){return "rate limited";}
- public:
- // set the creation rate
- // No more than maxCreation within byTime milliseconds
- void setRate(unsigned maxCreation, unsigned byTime)
- {
- assert(byTime>0);
- this->maxCreation = maxCreation;
- this->timeValidity = static_cast<clock_t>(byTime * CLOCKS_PER_SEC / 1000);
- D( std::cout << "Setting no more than "<< maxCreation <<" creation within " << this->timeValidity <<" ms"<< std::endl; )
- }
- };
-
- /**
- * \class AmountLimitedCreation
- * \ingroup CreationPolicyCachedFactoryGroup
- * \brief Limit by number of objects
- *
- * This implementation will prevent from Creating more than maxCreation objects
- * within byTime ms by calling eviction policy.
- * Use the setRate method to set the rate parameters.
- * default is 10 objects.
- */
- class AmountLimitedCreation
- {
- private:
- unsigned maxCreation;
- unsigned created;
-
- protected:
- AmountLimitedCreation() : maxCreation(10), created(0)
- {}
-
- bool canCreate()
- {
- return !(created>=maxCreation);
- }
+ struct Exception : public std::exception
+ {
+ const char* what() const throw() { return "RateLimitedCreation Policy : Exceeded the authorized creation rate"; }
+ };
+
+ bool canCreate()
+ {
+ cleanVector();
+ if(m_vTimes.size()>maxCreation)
+ throw Exception();
+ else
+ return true;
+ }
+
+ void onCreate()
+ {
+ m_vTimes.push_back(clock());
+ }
+
+ void onDestroy()
+ {
+ }
+ const char* name() {return "rate limited";}
+public:
+ // set the creation rate
+ // No more than maxCreation within byTime milliseconds
+ void setRate(unsigned maxCreation, unsigned byTime)
+ {
+ assert(byTime>0);
+ this->maxCreation = maxCreation;
+ this->timeValidity = static_cast<clock_t>(byTime * CLOCKS_PER_SEC / 1000);
+ D( std::cout << "Setting no more than "<< maxCreation <<" creation within " << this->timeValidity <<" ms"<< std::endl; )
+ }
+};
+
+/**
+ * \class AmountLimitedCreation
+ * \ingroup CreationPolicyCachedFactoryGroup
+ * \brief Limit by number of objects
+ *
+ * This implementation will prevent from Creating more than maxCreation objects
+ * within byTime ms by calling eviction policy.
+ * Use the setRate method to set the rate parameters.
+ * default is 10 objects.
+ */
+class AmountLimitedCreation
+{
+private:
+ unsigned maxCreation;
+ unsigned created;
+
+protected:
+ AmountLimitedCreation() : maxCreation(10), created(0)
+ {}
+
+ bool canCreate()
+ {
+ return !(created>=maxCreation);
+ }
+
+ void onCreate()
+ {
+ ++created;
+ }
+
+ void onDestroy()
+ {
+ --created;
+ }
+ const char* name() {return "amount limited";}
+public:
+ // set the creation max amount
+ void setMaxCreation(unsigned maxCreation)
+ {
+ assert(maxCreation>0);
+ this->maxCreation = maxCreation;
+ D( std::cout << "Setting no more than " << maxCreation <<" creation" << std::endl; )
+ }
+};
- void onCreate()
- {
- ++created;
- }
-
- void onDestroy()
- {
- --created;
- }
- const char* name(){return "amount limited";}
- public:
- // set the creation max amount
- void setMaxCreation(unsigned maxCreation)
- {
- assert(maxCreation>0);
- this->maxCreation = maxCreation;
- D( std::cout << "Setting no more than " << maxCreation <<" creation" << std::endl; )
- }
- };
-
/**
* \defgroup EvictionPolicyCachedFactoryGroup Eviction policies
* \ingroup CachedFactoryGroup
@@ -292,875 +292,887 @@ namespace Loki
* candidate for eviction.
*/
- class EvictionException : public std::exception
+class EvictionException : public std::exception
+{
+public:
+ const char* what() const throw() { return "Eviction Policy : trying to make room but no objects are available"; }
+};
+
+// The following class is intented to provide helpers to sort
+// the container that will hold an eviction score
+template
+<
+typename ST, // Score type
+ typename DT // Data type
+ >
+class EvictionHelper
+{
+protected:
+ typedef typename std::map< DT, ST > HitMap;
+ typedef typename HitMap::iterator HitMapItr;
+private:
+ typedef std::pair< ST, DT > SwappedPair;
+ typedef std::multimap< ST, DT > SwappedHitMap;
+ typedef typename SwappedHitMap::iterator SwappedHitMapItr;
+protected:
+ HitMap m_mHitCount;
+
+ // This function sorts the map according to the score
+ // and returns the lower bound of the sorted container
+ DT& getLowerBound()
{
- public:
- const char* what() const throw() { return "Eviction Policy : trying to make room but no objects are available"; }
- };
+ assert(!m_mHitCount.empty());
+ // inserting the swapped pair into a multimap
+ SwappedHitMap copyMap;
+ for(HitMapItr itr = m_mHitCount.begin(); itr != m_mHitCount.end(); ++itr)
+ copyMap.insert(SwappedPair((*itr).second, (*itr).first));
+ if((*copyMap.rbegin()).first == 0) // the higher score is 0 ...
+ throw EvictionException(); // there is no key evict
+ return (*copyMap.begin()).second;
+ }
+};
- // The following class is intented to provide helpers to sort
- // the container that will hold an eviction score
- template
- <
- typename ST, // Score type
- typename DT // Data type
- >
- class EvictionHelper
- {
- protected:
- typedef typename std::map< DT, ST > HitMap;
- typedef typename HitMap::iterator HitMapItr;
- private:
- typedef std::pair< ST, DT > SwappedPair;
- typedef std::multimap< ST, DT > SwappedHitMap;
- typedef typename SwappedHitMap::iterator SwappedHitMapItr;
- protected:
- HitMap m_mHitCount;
-
- // This function sorts the map according to the score
- // and returns the lower bound of the sorted container
- DT& getLowerBound(){
- assert(!m_mHitCount.empty());
- // inserting the swapped pair into a multimap
- SwappedHitMap copyMap;
- for(HitMapItr itr = m_mHitCount.begin(); itr != m_mHitCount.end(); ++itr)
- copyMap.insert(SwappedPair((*itr).second, (*itr).first));
- if((*copyMap.rbegin()).first == 0) // the higher score is 0 ...
- throw EvictionException(); // there is no key evict
- return (*copyMap.begin()).second;
- }
- };
-
- /**
- * \class EvictLRU
- * \ingroup EvictionPolicyCachedFactoryGroup
- * \brief Evicts least accessed objects first.
- *
- * Implementation of the Least recent used algorithm as
- * described in http://en.wikipedia.org/wiki/Page_replacement_algorithms .
- *
- * WARNING : If an object is heavily fetched
- * (more than ULONG_MAX = UINT_MAX = 4294967295U)
- * it could unfortunately be removed from the cache.
- */
- template
- <
- typename DT, // Data Type (AbstractProduct*)
- typename ST = unsigned // default data type to use as Score Type
- >
- class EvictLRU : public EvictionHelper< ST , DT >
+/**
+ * \class EvictLRU
+ * \ingroup EvictionPolicyCachedFactoryGroup
+ * \brief Evicts least accessed objects first.
+ *
+ * Implementation of the Least recent used algorithm as
+ * described in http://en.wikipedia.org/wiki/Page_replacement_algorithms .
+ *
+ * WARNING : If an object is heavily fetched
+ * (more than ULONG_MAX = UINT_MAX = 4294967295U)
+ * it could unfortunately be removed from the cache.
+ */
+template
+<
+typename DT, // Data Type (AbstractProduct*)
+ typename ST = unsigned // default data type to use as Score Type
+ >
+class EvictLRU : public EvictionHelper< ST , DT >
+{
+private:
+ typedef EvictionHelper< ST , DT > EH;
+protected:
+
+ virtual ~EvictLRU() {}
+
+ // OnStore initialize the counter for the new key
+ // If the key already exists, the counter is reseted
+ void onCreate(const DT& key)
{
- private:
- typedef EvictionHelper< ST , DT > EH;
- protected:
-
- virtual ~EvictLRU(){}
-
- // OnStore initialize the counter for the new key
- // If the key already exists, the counter is reseted
- void onCreate(const DT& key)
- {
- EH::m_mHitCount[key] = 0;
- }
-
- void onFetch(const DT&)
- {
- }
-
- // onRelease increments the hit counter associated with the object
- void onRelease(const DT& key)
- {
- ++(EH::m_mHitCount[key]);
- }
+ EH::m_mHitCount[key] = 0;
+ }
- void onDestroy(const DT& key)
- {
- EH::m_mHitCount.erase(key);
- }
-
- // this function is implemented in Cache and redirected
- // to the Storage Policy
- virtual void remove(DT const key)=0;
-
- // LRU Eviction policy
- void evict()
- {
- remove(EH::getLowerBound());
- }
- const char* name(){return "LRU";}
- };
-
- /**
- * \class EvictAging
- * \ingroup EvictionPolicyCachedFactoryGroup
- * \brief LRU aware of the time span of use
- *
- * Implementation of the Aging algorithm as
- * described in http://en.wikipedia.org/wiki/Page_replacement_algorithms .
- *
- * This method is much more costly than evict LRU so
- * if you need extreme performance consider switching to EvictLRU
- */
- template
- <
- typename DT, // Data Type (AbstractProduct*)
- typename ST = unsigned // default data type to use as Score Type
- >
- class EvictAging : public EvictionHelper< ST, DT >
+ void onFetch(const DT&)
{
- private:
- EvictAging(const EvictAging&);
- EvictAging& operator=(const EvictAging&);
- typedef EvictionHelper< ST, DT > EH;
- typedef typename EH::HitMap HitMap;
- typedef typename EH::HitMapItr HitMapItr;
-
- // update the counter
- template<class T> struct updateCounter : public std::unary_function<T, void>
- {
- updateCounter(const DT& key): key_(key){}
- void operator()(T x)
- {
- x.second = (x.first == key_ ? (x.second >> 1) | ( 1 << ((sizeof(ST)-1)*8) ) : x.second >> 1);
- D( std::cout << x.second << std::endl; )
- }
- const DT &key_;
- updateCounter(const updateCounter& rhs) : key_(rhs.key_){}
- private:
- updateCounter& operator=(const updateCounter& rhs);
- };
- protected:
- EvictAging(){}
- virtual ~EvictAging(){}
-
- // OnStore initialize the counter for the new key
- // If the key already exists, the counter is reseted
- void onCreate(const DT& key){
- EH::m_mHitCount[key] = 0;
- }
-
- void onFetch(const DT&){}
-
- // onRelease increments the hit counter associated with the object
- // Updating every counters by iterating over the map
- // If the key is the key of the fetched object :
- // the counter is shifted to the right and it's MSB is set to 1
- // else
- // the counter is shifted to the left
- void onRelease(const DT& key)
- {
- std::for_each(EH::m_mHitCount.begin(), EH::m_mHitCount.end(), updateCounter< typename HitMap::value_type >(key));
- }
-
- void onDestroy(const DT& key)
- {
- EH::m_mHitCount.erase(key);
- }
+ }
- // this function is implemented in Cache and redirected
- // to the Storage Policy
- virtual void remove(DT const key)=0;
+ // onRelease increments the hit counter associated with the object
+ void onRelease(const DT& key)
+ {
+ ++(EH::m_mHitCount[key]);
+ }
- // LRU with Aging Eviction policy
- void evict()
- {
- remove(EH::getLowerBound());
- }
- const char* name(){return "LRU with aging";}
- };
-
- /**
- * \class EvictRandom
- * \ingroup EvictionPolicyCachedFactoryGroup
- * \brief Evicts a random object
- *
- * Implementation of the Random algorithm as
- * described in http://en.wikipedia.org/wiki/Page_replacement_algorithms .
- */
- template
- <
- typename DT, // Data Type (AbstractProduct*)
- typename ST = void // Score Type not used by this policy
- >
- class EvictRandom
+ void onDestroy(const DT& key)
+ {
+ EH::m_mHitCount.erase(key);
+ }
+
+ // this function is implemented in Cache and redirected
+ // to the Storage Policy
+ virtual void remove(DT const key)=0;
+
+ // LRU Eviction policy
+ void evict()
{
+ remove(EH::getLowerBound());
+ }
+ const char* name() {return "LRU";}
+};
+
+/**
+ * \class EvictAging
+ * \ingroup EvictionPolicyCachedFactoryGroup
+ * \brief LRU aware of the time span of use
+ *
+ * Implementation of the Aging algorithm as
+ * described in http://en.wikipedia.org/wiki/Page_replacement_algorithms .
+ *
+ * This method is much more costly than evict LRU so
+ * if you need extreme performance consider switching to EvictLRU
+ */
+template
+<
+typename DT, // Data Type (AbstractProduct*)
+ typename ST = unsigned // default data type to use as Score Type
+ >
+class EvictAging : public EvictionHelper< ST, DT >
+{
+private:
+ EvictAging(const EvictAging&);
+ EvictAging& operator=(const EvictAging&);
+ typedef EvictionHelper< ST, DT > EH;
+ typedef typename EH::HitMap HitMap;
+ typedef typename EH::HitMapItr HitMapItr;
+
+ // update the counter
+ template<class T> struct updateCounter : public std::unary_function<T, void>
+ {
+ updateCounter(const DT& key): key_(key) {}
+ void operator()(T x)
+ {
+ x.second = (x.first == key_ ? (x.second >> 1) | ( 1 << ((sizeof(ST)-1)*8) ) : x.second >> 1);
+ D( std::cout << x.second << std::endl; )
+ }
+ const DT& key_;
+ updateCounter(const updateCounter& rhs) : key_(rhs.key_) {}
private:
- std::vector< DT > m_vKeys;
- typedef typename std::vector< DT >::size_type size_type;
- typedef typename std::vector< DT >::iterator iterator;
-
- protected:
-
- virtual ~EvictRandom(){}
-
- void onCreate(const DT&){
- }
-
- void onFetch(const DT& ){
- }
-
- void onRelease(const DT& key){
- m_vKeys.push_back(key);
- }
-
- void onDestroy(const DT& key){
- using namespace std;
- m_vKeys.erase(remove_if(m_vKeys.begin(), m_vKeys.end(), bind2nd(equal_to< DT >(), key)), m_vKeys.end());
- }
-
- // Implemented in Cache and redirected to the Storage Policy
- virtual void remove(DT const key)=0;
-
- // Random Eviction policy
- void evict()
- {
- if(m_vKeys.empty())
- throw EvictionException();
- size_type random = static_cast<size_type>((m_vKeys.size()*rand())/(static_cast<size_type>(RAND_MAX) + 1));
- remove(*(m_vKeys.begin()+random));
- }
- const char* name(){return "random";}
+ updateCounter& operator=(const updateCounter& rhs);
};
+protected:
+ EvictAging() {}
+ virtual ~EvictAging() {}
+
+ // OnStore initialize the counter for the new key
+ // If the key already exists, the counter is reseted
+ void onCreate(const DT& key)
+ {
+ EH::m_mHitCount[key] = 0;
+ }
+
+ void onFetch(const DT&) {}
+
+ // onRelease increments the hit counter associated with the object
+ // Updating every counters by iterating over the map
+ // If the key is the key of the fetched object :
+ // the counter is shifted to the right and it's MSB is set to 1
+ // else
+ // the counter is shifted to the left
+ void onRelease(const DT& key)
+ {
+ std::for_each(EH::m_mHitCount.begin(), EH::m_mHitCount.end(), updateCounter< typename HitMap::value_type >(key));
+ }
+
+ void onDestroy(const DT& key)
+ {
+ EH::m_mHitCount.erase(key);
+ }
+
+ // this function is implemented in Cache and redirected
+ // to the Storage Policy
+ virtual void remove(DT const key)=0;
+
+ // LRU with Aging Eviction policy
+ void evict()
+ {
+ remove(EH::getLowerBound());
+ }
+ const char* name() {return "LRU with aging";}
+};
+
+/**
+ * \class EvictRandom
+ * \ingroup EvictionPolicyCachedFactoryGroup
+ * \brief Evicts a random object
+ *
+ * Implementation of the Random algorithm as
+ * described in http://en.wikipedia.org/wiki/Page_replacement_algorithms .
+ */
+template
+<
+typename DT, // Data Type (AbstractProduct*)
+ typename ST = void // Score Type not used by this policy
+ >
+class EvictRandom
+{
+private:
+ std::vector< DT > m_vKeys;
+ typedef typename std::vector< DT >::size_type size_type;
+ typedef typename std::vector< DT >::iterator iterator;
+
+protected:
+
+ virtual ~EvictRandom() {}
+
+ void onCreate(const DT&)
+ {
+ }
+
+ void onFetch(const DT& )
+ {
+ }
+
+ void onRelease(const DT& key)
+ {
+ m_vKeys.push_back(key);
+ }
+
+ void onDestroy(const DT& key)
+ {
+ using namespace std;
+ m_vKeys.erase(remove_if(m_vKeys.begin(), m_vKeys.end(), bind2nd(equal_to< DT >(), key)), m_vKeys.end());
+ }
+
+ // Implemented in Cache and redirected to the Storage Policy
+ virtual void remove(DT const key)=0;
+
+ // Random Eviction policy
+ void evict()
+ {
+ if(m_vKeys.empty())
+ throw EvictionException();
+ size_type random = static_cast<size_type>((m_vKeys.size()*rand())/(static_cast<size_type>(RAND_MAX) + 1));
+ remove(*(m_vKeys.begin()+random));
+ }
+ const char* name() {return "random";}
+};
/**
* \defgroup StatisticPolicyCachedFactoryGroup Statistic policies
* \ingroup CachedFactoryGroup
* \brief Gathers information about the cache.
- *
+ *
* For debugging purpose this policy proposes to gather informations
* about the cache. This could be useful to determine whether the cache is
* mandatory or if the policies are well suited to the application.
*/
- /**
- * \class NoStatisticPolicy
- * \ingroup StatisticPolicyCachedFactoryGroup
- * \brief Do nothing
- *
- * Should be used in release code for better performances
- */
- class NoStatisticPolicy
- {
- protected:
- void onDebug(){}
- void onFetch(){}
- void onRelease(){}
- void onCreate(){}
- void onDestroy(){}
- const char* name(){return "no";}
- };
-
- /**
- * \class SimpleStatisticPolicy
- * \ingroup StatisticPolicyCachedFactoryGroup
- * \brief Simple statistics
- *
- * Provides the following informations about the cache :
- * - Created objects
- * - Fetched objects
- * - Destroyed objects
- * - Cache hit
- * - Cache miss
- * - Currently allocated
- * - Currently out
- * - Cache overall efficiency
- */
- class SimpleStatisticPolicy
+/**
+ * \class NoStatisticPolicy
+ * \ingroup StatisticPolicyCachedFactoryGroup
+ * \brief Do nothing
+ *
+ * Should be used in release code for better performances
+ */
+class NoStatisticPolicy
+{
+protected:
+ void onDebug() {}
+ void onFetch() {}
+ void onRelease() {}
+ void onCreate() {}
+ void onDestroy() {}
+ const char* name() {return "no";}
+};
+
+/**
+ * \class SimpleStatisticPolicy
+ * \ingroup StatisticPolicyCachedFactoryGroup
+ * \brief Simple statistics
+ *
+ * Provides the following informations about the cache :
+ * - Created objects
+ * - Fetched objects
+ * - Destroyed objects
+ * - Cache hit
+ * - Cache miss
+ * - Currently allocated
+ * - Currently out
+ * - Cache overall efficiency
+ */
+class SimpleStatisticPolicy
+{
+private:
+ unsigned allocated, created, hit, out, fetched;
+protected:
+ SimpleStatisticPolicy() : allocated(0), created(0), hit(0), out(0), fetched(0)
{
- private:
- unsigned allocated, created, hit, out, fetched;
- protected:
- SimpleStatisticPolicy() : allocated(0), created(0), hit(0), out(0), fetched(0)
- {
- }
-
- void onDebug()
+ }
+
+ void onDebug()
+ {
+ using namespace std;
+ cout << "############################" << endl;
+ cout << "## About this cache " << this << endl;
+ cout << "## + Created objects : " << created << endl;
+ cout << "## + Fetched objects : " << fetched << endl;
+ cout << "## + Destroyed objects : " << created - allocated << endl;
+ cout << "## + Cache hit : " << hit << endl;
+ cout << "## + Cache miss : " << fetched - hit << endl;
+ cout << "## + Currently allocated : " << allocated << endl;
+ cout << "## + Currently out : " << out << endl;
+ cout << "############################" << endl;
+ if(fetched!=0)
{
- using namespace std;
- cout << "############################" << endl;
- cout << "## About this cache " << this << endl;
- cout << "## + Created objects : " << created << endl;
- cout << "## + Fetched objects : " << fetched << endl;
- cout << "## + Destroyed objects : " << created - allocated << endl;
- cout << "## + Cache hit : " << hit << endl;
- cout << "## + Cache miss : " << fetched - hit << endl;
- cout << "## + Currently allocated : " << allocated << endl;
- cout << "## + Currently out : " << out << endl;
+ cout << "## Overall efficiency " << 100*double(hit)/fetched <<"%"<< endl;
cout << "############################" << endl;
- if(fetched!=0){
- cout << "## Overall efficiency " << 100*double(hit)/fetched <<"%"<< endl;
- cout << "############################" << endl;
- }
- cout << endl;
}
-
- void onFetch()
- {
- ++fetched;
- ++out;
- ++hit;
- }
- void onRelease()
- {
- --out;
- }
- void onCreate()
+ cout << endl;
+ }
+
+ void onFetch()
+ {
+ ++fetched;
+ ++out;
+ ++hit;
+ }
+ void onRelease()
+ {
+ --out;
+ }
+ void onCreate()
+ {
+ ++created;
+ ++allocated;
+ --hit;
+ }
+ void onDestroy()
+ {
+ --allocated;
+ }
+
+ const char* name() {return "simple";}
+public:
+ unsigned getCreated() {return created;}
+ unsigned getFetched() {return fetched;}
+ unsigned getHit() {return hit;}
+ unsigned getMissed() {return fetched - hit;}
+ unsigned getAllocated() {return allocated;}
+ unsigned getOut() {return out;}
+ unsigned getDestroyed() {return created-allocated;}
+};
+
+///////////////////////////////////////////////////////////////////////////
+// Cache Factory definition
+///////////////////////////////////////////////////////////////////////////
+class CacheException : public std::exception
+{
+public:
+ const char* what() const throw() { return "Internal Cache Error"; }
+};
+
+/**
+ * \class CachedFactory
+ * \ingroup CachedFactoryGroup
+ * \brief Factory with caching support
+ *
+ * This class acts as a Factory (it creates objects)
+ * but also keeps the already created objects to prevent
+ * long constructions time.
+ *
+ * Note this implementation do not retain ownership.
+ */
+template
+<
+class AbstractProduct,
+ typename IdentifierType,
+ typename CreatorParmTList = NullType,
+ template<class> class EncapsulationPolicy = SimplePointer,
+ class CreationPolicy = AlwaysCreate,
+ template <typename , typename> class EvictionPolicy = EvictRandom,
+ class StatisticPolicy = NoStatisticPolicy,
+ template<typename, class> class FactoryErrorPolicy = DefaultFactoryError,
+ class ObjVector = std::vector<AbstractProduct*>
+ >
+class CachedFactory :
+ protected EncapsulationPolicy<AbstractProduct>,
+ public CreationPolicy, public StatisticPolicy, EvictionPolicy< AbstractProduct* , unsigned >
+{
+private:
+ typedef Factory< AbstractProduct, IdentifierType, CreatorParmTList, FactoryErrorPolicy> MyFactory;
+ typedef FactoryImpl< AbstractProduct, IdentifierType, CreatorParmTList > Impl;
+ typedef Functor< AbstractProduct* , CreatorParmTList > ProductCreator;
+ typedef EncapsulationPolicy<AbstractProduct> NP;
+ typedef CreationPolicy CP;
+ typedef StatisticPolicy SP;
+ typedef EvictionPolicy< AbstractProduct* , unsigned > EP;
+
+ typedef typename Impl::Parm1 Parm1;
+ typedef typename Impl::Parm2 Parm2;
+ typedef typename Impl::Parm3 Parm3;
+ typedef typename Impl::Parm4 Parm4;
+ typedef typename Impl::Parm5 Parm5;
+ typedef typename Impl::Parm6 Parm6;
+ typedef typename Impl::Parm7 Parm7;
+ typedef typename Impl::Parm8 Parm8;
+ typedef typename Impl::Parm9 Parm9;
+ typedef typename Impl::Parm10 Parm10;
+ typedef typename Impl::Parm11 Parm11;
+ typedef typename Impl::Parm12 Parm12;
+ typedef typename Impl::Parm13 Parm13;
+ typedef typename Impl::Parm14 Parm14;
+ typedef typename Impl::Parm15 Parm15;
+
+public:
+ typedef typename NP::ProductReturn ProductReturn;
+private:
+ typedef Key< Impl, IdentifierType > MyKey;
+ typedef std::map< MyKey, ObjVector > KeyToObjVectorMap;
+ typedef std::map< AbstractProduct*, MyKey > FetchedObjToKeyMap;
+
+ MyFactory factory;
+ KeyToObjVectorMap fromKeyToObjVector;
+ FetchedObjToKeyMap providedObjects;
+ unsigned outObjects;
+
+ ObjVector& getContainerFromKey(MyKey key)
+ {
+ return fromKeyToObjVector[key];
+ }
+
+ AbstractProduct* const getPointerToObjectInContainer(ObjVector& entry)
+ {
+ if(entry.empty()) // No object available
{
- ++created;
- ++allocated;
- --hit;
+ // the object will be created in the calling function.
+ // It has to be created in the calling function because of
+ // the variable number of parameters for CreateObject(...) method
+ return NULL;
}
- void onDestroy()
+ else
{
- --allocated;
+ // returning the found object
+ AbstractProduct* pObject(entry.back());
+ assert(pObject!=NULL);
+ entry.pop_back();
+ return pObject;
}
+ }
+
+ bool shouldCreateObject(AbstractProduct* const pProduct)
+ {
+ if(pProduct!=NULL) // object already exists
+ return false;
+ if(CP::canCreate()==false) // Are we allowed to Create ?
+ EP::evict(); // calling Eviction Policy to clean up
+ return true;
+ }
+
+ void ReleaseObjectFromContainer(ObjVector& entry, AbstractProduct* const object)
+ {
+ entry.push_back(object);
+ }
+
+ void onFetch(AbstractProduct* const pProduct)
+ {
+ SP::onFetch();
+ EP::onFetch(pProduct);
+ ++outObjects;
+ }
+
+ void onRelease(AbstractProduct* const pProduct)
+ {
+ SP::onRelease();
+ EP::onRelease(pProduct);
+ --outObjects;
+ }
+
+ void onCreate(AbstractProduct* const pProduct)
+ {
+ CP::onCreate();
+ SP::onCreate();
+ EP::onCreate(pProduct);
+ }
- const char* name(){return "simple";}
- public:
- unsigned getCreated(){return created;}
- unsigned getFetched(){return fetched;}
- unsigned getHit(){return hit;}
- unsigned getMissed(){return fetched - hit;}
- unsigned getAllocated(){return allocated;}
- unsigned getOut(){return out;}
- unsigned getDestroyed(){return created-allocated;}
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // Cache Factory definition
- ///////////////////////////////////////////////////////////////////////////
- class CacheException : public std::exception
- {
- public:
- const char* what() const throw() { return "Internal Cache Error"; }
+ void onDestroy(AbstractProduct* const pProduct)
+ {
+ CP::onDestroy();
+ SP::onDestroy();
+ EP::onDestroy(pProduct);
+ }
+
+ // delete the object
+ template<class T> struct deleteObject : public std::unary_function<T, void>
+ {
+ void operator()(T x) { delete x; }
};
-
- /**
- * \class CachedFactory
- * \ingroup CachedFactoryGroup
- * \brief Factory with caching support
- *
- * This class acts as a Factory (it creates objects)
- * but also keeps the already created objects to prevent
- * long constructions time.
- *
- * Note this implementation do not retain ownership.
- */
- template
- <
- class AbstractProduct,
- typename IdentifierType,
- typename CreatorParmTList = NullType,
- template<class> class EncapsulationPolicy = SimplePointer,
- class CreationPolicy = AlwaysCreate,
- template <typename , typename> class EvictionPolicy = EvictRandom,
- class StatisticPolicy = NoStatisticPolicy,
- template<typename, class> class FactoryErrorPolicy = DefaultFactoryError,
- class ObjVector = std::vector<AbstractProduct*>
- >
- class CachedFactory :
- protected EncapsulationPolicy<AbstractProduct>,
- public CreationPolicy, public StatisticPolicy, EvictionPolicy< AbstractProduct * , unsigned >
- {
- private:
- typedef Factory< AbstractProduct, IdentifierType, CreatorParmTList, FactoryErrorPolicy> MyFactory;
- typedef FactoryImpl< AbstractProduct, IdentifierType, CreatorParmTList > Impl;
- typedef Functor< AbstractProduct* , CreatorParmTList > ProductCreator;
- typedef EncapsulationPolicy<AbstractProduct> NP;
- typedef CreationPolicy CP;
- typedef StatisticPolicy SP;
- typedef EvictionPolicy< AbstractProduct* , unsigned > EP;
-
- typedef typename Impl::Parm1 Parm1;
- typedef typename Impl::Parm2 Parm2;
- typedef typename Impl::Parm3 Parm3;
- typedef typename Impl::Parm4 Parm4;
- typedef typename Impl::Parm5 Parm5;
- typedef typename Impl::Parm6 Parm6;
- typedef typename Impl::Parm7 Parm7;
- typedef typename Impl::Parm8 Parm8;
- typedef typename Impl::Parm9 Parm9;
- typedef typename Impl::Parm10 Parm10;
- typedef typename Impl::Parm11 Parm11;
- typedef typename Impl::Parm12 Parm12;
- typedef typename Impl::Parm13 Parm13;
- typedef typename Impl::Parm14 Parm14;
- typedef typename Impl::Parm15 Parm15;
-
- public:
- typedef typename NP::ProductReturn ProductReturn;
- private:
- typedef Key< Impl, IdentifierType > MyKey;
- typedef std::map< MyKey, ObjVector > KeyToObjVectorMap;
- typedef std::map< AbstractProduct*, MyKey > FetchedObjToKeyMap;
-
- MyFactory factory;
- KeyToObjVectorMap fromKeyToObjVector;
- FetchedObjToKeyMap providedObjects;
- unsigned outObjects;
-
- ObjVector& getContainerFromKey(MyKey key){
- return fromKeyToObjVector[key];
- }
- AbstractProduct* const getPointerToObjectInContainer(ObjVector &entry)
- {
- if(entry.empty()) // No object available
- { // the object will be created in the calling function.
- // It has to be created in the calling function because of
- // the variable number of parameters for CreateObject(...) method
- return NULL;
- }
- else
- { // returning the found object
- AbstractProduct* pObject(entry.back());
- assert(pObject!=NULL);
- entry.pop_back();
- return pObject;
- }
- }
-
- bool shouldCreateObject(AbstractProduct * const pProduct){
- if(pProduct!=NULL) // object already exists
- return false;
- if(CP::canCreate()==false) // Are we allowed to Create ?
- EP::evict(); // calling Eviction Policy to clean up
- return true;
- }
-
- void ReleaseObjectFromContainer(ObjVector &entry, AbstractProduct * const object)
- {
- entry.push_back(object);
- }
-
- void onFetch(AbstractProduct * const pProduct)
- {
- SP::onFetch();
- EP::onFetch(pProduct);
- ++outObjects;
- }
-
- void onRelease(AbstractProduct * const pProduct)
- {
- SP::onRelease();
- EP::onRelease(pProduct);
- --outObjects;
- }
-
- void onCreate(AbstractProduct * const pProduct)
- {
- CP::onCreate();
- SP::onCreate();
- EP::onCreate(pProduct);
- }
-
- void onDestroy(AbstractProduct * const pProduct)
+ // delete the objects in the vector
+ template<class T> struct deleteVectorObjects : public std::unary_function<T, void>
+ {
+ void operator()(T x)
{
- CP::onDestroy();
- SP::onDestroy();
- EP::onDestroy(pProduct);
+ ObjVector& vec(x.second);
+ std::for_each(vec.begin(), vec.end(), deleteObject< typename ObjVector::value_type>());
}
-
- // delete the object
- template<class T> struct deleteObject : public std::unary_function<T, void>
- {
- void operator()(T x){ delete x; }
- };
-
- // delete the objects in the vector
- template<class T> struct deleteVectorObjects : public std::unary_function<T, void>
- {
- void operator()(T x){
- ObjVector &vec(x.second);
- std::for_each(vec.begin(), vec.end(), deleteObject< typename ObjVector::value_type>());
- }
- };
-
- // delete the keys of the map
- template<class T> struct deleteMapKeys : public std::unary_function<T, void>
- {
- void operator()(T x){ delete x.first; }
- };
-
- protected:
- virtual void remove(AbstractProduct * const pProduct)
+ };
+
+ // delete the keys of the map
+ template<class T> struct deleteMapKeys : public std::unary_function<T, void>
+ {
+ void operator()(T x) { delete x.first; }
+ };
+
+protected:
+ virtual void remove(AbstractProduct* const pProduct)
+ {
+ typename FetchedObjToKeyMap::iterator fetchedItr = providedObjects.find(pProduct);
+ if(fetchedItr!=providedObjects.end()) // object is unreleased.
+ throw CacheException();
+ bool productRemoved = false;
+ typename KeyToObjVectorMap::iterator objVectorItr;
+ typename ObjVector::iterator objItr;
+ for(objVectorItr=fromKeyToObjVector.begin(); objVectorItr!=fromKeyToObjVector.end(); ++objVectorItr)
{
- typename FetchedObjToKeyMap::iterator fetchedItr = providedObjects.find(pProduct);
- if(fetchedItr!=providedObjects.end()) // object is unreleased.
- throw CacheException();
- bool productRemoved = false;
- typename KeyToObjVectorMap::iterator objVectorItr;
- typename ObjVector::iterator objItr;
- for(objVectorItr=fromKeyToObjVector.begin();objVectorItr!=fromKeyToObjVector.end();++objVectorItr)
+ ObjVector& v((*objVectorItr).second);
+ objItr = remove_if(v.begin(), v.end(), std::bind2nd(std::equal_to<AbstractProduct*>(), pProduct));
+ if(objItr != v.end()) // we found the vector containing pProduct and removed it
{
- ObjVector &v((*objVectorItr).second);
- objItr = remove_if(v.begin(), v.end(), std::bind2nd(std::equal_to<AbstractProduct*>(), pProduct));
- if(objItr != v.end()) // we found the vector containing pProduct and removed it
- {
- onDestroy(pProduct); // warning policies we are about to destroy an object
- v.erase(objItr, v.end()); // real removing
- productRemoved = true;
- break;
- }
+ onDestroy(pProduct); // warning policies we are about to destroy an object
+ v.erase(objItr, v.end()); // real removing
+ productRemoved = true;
+ break;
}
- if(productRemoved==false)
- throw CacheException(); // the product is not in the cache ?!
- delete pProduct; // deleting it
}
+ if(productRemoved==false)
+ throw CacheException(); // the product is not in the cache ?!
+ delete pProduct; // deleting it
+ }
- public:
- CachedFactory() : factory(), fromKeyToObjVector(), providedObjects(), outObjects(0)
- {
- }
+public:
+ CachedFactory() : factory(), fromKeyToObjVector(), providedObjects(), outObjects(0)
+ {
+ }
- ~CachedFactory()
- {
- using namespace std;
- // debug information
- SP::onDebug();
- // cleaning the Cache
- for_each(fromKeyToObjVector.begin(), fromKeyToObjVector.end(),
- deleteVectorObjects< typename KeyToObjVectorMap::value_type >()
- );
- if(!providedObjects.empty())
- {
- // The factory is responsible for the creation and destruction of objects.
- // If objects are out during the destruction of the Factory : deleting anyway.
- // This might not be a good idea. But throwing an exception in a destructor is
- // considered as a bad pratice and asserting might be too much.
- // What to do ? Leaking memory or corrupting in use pointers ? hmm...
- D( cout << "====>> Cache destructor : deleting "<< providedObjects.size()<<" in use objects <<====" << endl << endl; )
- for_each(providedObjects.begin(), providedObjects.end(),
- deleteMapKeys< typename FetchedObjToKeyMap::value_type >()
+ ~CachedFactory()
+ {
+ using namespace std;
+ // debug information
+ SP::onDebug();
+ // cleaning the Cache
+ for_each(fromKeyToObjVector.begin(), fromKeyToObjVector.end(),
+ deleteVectorObjects< typename KeyToObjVectorMap::value_type >()
);
- }
- }
-
- ///////////////////////////////////
- // Acts as the proxy pattern and //
- // forwards factory methods //
- ///////////////////////////////////
-
- bool Register(const IdentifierType& id, ProductCreator creator)
+ if(!providedObjects.empty())
{
- return factory.Register(id, creator);
- }
-
- template <class PtrObj, typename CreaFn>
- bool Register(const IdentifierType& id, const PtrObj& p, CreaFn fn)
- {
- return factory.Register(id, p, fn);
- }
-
- bool Unregister(const IdentifierType& id)
- {
- return factory.Unregister(id);
+ // The factory is responsible for the creation and destruction of objects.
+ // If objects are out during the destruction of the Factory : deleting anyway.
+ // This might not be a good idea. But throwing an exception in a destructor is
+ // considered as a bad pratice and asserting might be too much.
+ // What to do ? Leaking memory or corrupting in use pointers ? hmm...
+ D( cout << "====>> Cache destructor : deleting "<< providedObjects.size()<<" in use objects <<====" << endl << endl; )
+ for_each(providedObjects.begin(), providedObjects.end(),
+ deleteMapKeys< typename FetchedObjToKeyMap::value_type >()
+ );
}
+ }
- /// Return the registered ID in this Factory
- std::vector<IdentifierType>& RegisteredIds()
- {
- return factory.RegisteredIds();
- }
+ ///////////////////////////////////
+ // Acts as the proxy pattern and //
+ // forwards factory methods //
+ ///////////////////////////////////
- ProductReturn CreateObject(const IdentifierType& id)
- {
- MyKey key(id);
- AbstractProduct *pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
- if(shouldCreateObject(pProduct))
- {
- pProduct = factory.CreateObject(key.id);
- onCreate(pProduct);
- }
- onFetch(pProduct);
- providedObjects[pProduct] = key;
- return NP::encapsulate(pProduct);
- }
-
- ProductReturn CreateObject(const IdentifierType& id,
- Parm1 p1)
- {
- MyKey key(id,p1);
- AbstractProduct *pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
- if(shouldCreateObject(pProduct))
- {
- pProduct = factory.CreateObject(key.id,key.p1);
- onCreate(pProduct);
- }
- onFetch(pProduct);
- providedObjects[pProduct] = key;
- return NP::encapsulate(pProduct);
- }
+ bool Register(const IdentifierType& id, ProductCreator creator)
+ {
+ return factory.Register(id, creator);
+ }
+
+ template <class PtrObj, typename CreaFn>
+ bool Register(const IdentifierType& id, const PtrObj& p, CreaFn fn)
+ {
+ return factory.Register(id, p, fn);
+ }
+
+ bool Unregister(const IdentifierType& id)
+ {
+ return factory.Unregister(id);
+ }
- ProductReturn CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2)
+ /// Return the registered ID in this Factory
+ std::vector<IdentifierType>& RegisteredIds()
+ {
+ return factory.RegisteredIds();
+ }
+
+ ProductReturn CreateObject(const IdentifierType& id)
+ {
+ MyKey key(id);
+ AbstractProduct* pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
+ if(shouldCreateObject(pProduct))
{
- MyKey key(id,p1,p2);
- AbstractProduct *pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
- if(shouldCreateObject(pProduct))
- {
- pProduct = factory.CreateObject(key.id,key.p1,key.p2);
- onCreate(pProduct);
- }
- onFetch(pProduct);
- providedObjects[pProduct] = key;
- return NP::encapsulate(pProduct);
+ pProduct = factory.CreateObject(key.id);
+ onCreate(pProduct);
}
+ onFetch(pProduct);
+ providedObjects[pProduct] = key;
+ return NP::encapsulate(pProduct);
+ }
- ProductReturn CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3)
+ ProductReturn CreateObject(const IdentifierType& id,
+ Parm1 p1)
+ {
+ MyKey key(id,p1);
+ AbstractProduct* pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
+ if(shouldCreateObject(pProduct))
{
- MyKey key(id,p1,p2,p3);
- AbstractProduct *pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
- if(shouldCreateObject(pProduct))
- {
- pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3);
- onCreate(pProduct);
- }
- onFetch(pProduct);
- providedObjects[pProduct] = key;
- return NP::encapsulate(pProduct);
+ pProduct = factory.CreateObject(key.id,key.p1);
+ onCreate(pProduct);
}
+ onFetch(pProduct);
+ providedObjects[pProduct] = key;
+ return NP::encapsulate(pProduct);
+ }
- ProductReturn CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
+ ProductReturn CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2)
+ {
+ MyKey key(id,p1,p2);
+ AbstractProduct* pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
+ if(shouldCreateObject(pProduct))
{
- MyKey key(id,p1,p2,p3,p4);
- AbstractProduct *pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
- if(shouldCreateObject(pProduct))
- {
- pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3
- ,key.p4);
- onCreate(pProduct);
- }
- onFetch(pProduct);
- providedObjects[pProduct] = key;
- return NP::encapsulate(pProduct);
+ pProduct = factory.CreateObject(key.id,key.p1,key.p2);
+ onCreate(pProduct);
}
+ onFetch(pProduct);
+ providedObjects[pProduct] = key;
+ return NP::encapsulate(pProduct);
+ }
- ProductReturn CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
+ ProductReturn CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3)
+ {
+ MyKey key(id,p1,p2,p3);
+ AbstractProduct* pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
+ if(shouldCreateObject(pProduct))
{
- MyKey key(id,p1,p2,p3,p4,p5);
- AbstractProduct *pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
- if(shouldCreateObject(pProduct))
- {
- pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3
- ,key.p4,key.p5);
- onCreate(pProduct);
- }
- onFetch(pProduct);
- providedObjects[pProduct] = key;
- return NP::encapsulate(pProduct);
+ pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3);
+ onCreate(pProduct);
}
+ onFetch(pProduct);
+ providedObjects[pProduct] = key;
+ return NP::encapsulate(pProduct);
+ }
- ProductReturn CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6)
+ ProductReturn CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
+ {
+ MyKey key(id,p1,p2,p3,p4);
+ AbstractProduct* pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
+ if(shouldCreateObject(pProduct))
{
- MyKey key(id,p1,p2,p3,p4,p5,p6);
- AbstractProduct *pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
- if(shouldCreateObject(pProduct))
- {
- pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3
- ,key.p4,key.p5,key.p6);
- onCreate(pProduct);
- }
- onFetch(pProduct);
- providedObjects[pProduct] = key;
- return NP::encapsulate(pProduct);
+ pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3
+ ,key.p4);
+ onCreate(pProduct);
}
+ onFetch(pProduct);
+ providedObjects[pProduct] = key;
+ return NP::encapsulate(pProduct);
+ }
- ProductReturn CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7 )
+ ProductReturn CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
+ {
+ MyKey key(id,p1,p2,p3,p4,p5);
+ AbstractProduct* pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
+ if(shouldCreateObject(pProduct))
{
- MyKey key(id,p1,p2,p3,p4,p5,p6,p7);
- AbstractProduct *pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
- if(shouldCreateObject(pProduct))
- {
- pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3
- ,key.p4,key.p5,key.p6,key.p7);
- onCreate(pProduct);
- }
- onFetch(pProduct);
- providedObjects[pProduct] = key;
- return NP::encapsulate(pProduct);
+ pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3
+ ,key.p4,key.p5);
+ onCreate(pProduct);
}
+ onFetch(pProduct);
+ providedObjects[pProduct] = key;
+ return NP::encapsulate(pProduct);
+ }
- ProductReturn CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8)
+ ProductReturn CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6)
+ {
+ MyKey key(id,p1,p2,p3,p4,p5,p6);
+ AbstractProduct* pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
+ if(shouldCreateObject(pProduct))
{
- MyKey key(id,p1,p2,p3,p4,p5,p6,p7,p8);
- AbstractProduct *pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
- if(shouldCreateObject(pProduct))
- {
- pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3
- ,key.p4,key.p5,key.p6,key.p7,key.p8);
- onCreate(pProduct);
- }
- onFetch(pProduct);
- providedObjects[pProduct] = key;
- return NP::encapsulate(pProduct);
+ pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3
+ ,key.p4,key.p5,key.p6);
+ onCreate(pProduct);
}
+ onFetch(pProduct);
+ providedObjects[pProduct] = key;
+ return NP::encapsulate(pProduct);
+ }
- ProductReturn CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
+ ProductReturn CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7 )
+ {
+ MyKey key(id,p1,p2,p3,p4,p5,p6,p7);
+ AbstractProduct* pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
+ if(shouldCreateObject(pProduct))
{
- MyKey key(id,p1,p2,p3,p4,p5,p6,p7,p8,p9);
- AbstractProduct *pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
- if(shouldCreateObject(pProduct))
- {
- pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3
- ,key.p4,key.p5,key.p6,key.p7,key.p8,key.p9);
- onCreate(pProduct);
- }
- onFetch(pProduct);
- providedObjects[pProduct] = key;
- return NP::encapsulate(pProduct);
+ pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3
+ ,key.p4,key.p5,key.p6,key.p7);
+ onCreate(pProduct);
}
-
- ProductReturn CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9,Parm10 p10)
+ onFetch(pProduct);
+ providedObjects[pProduct] = key;
+ return NP::encapsulate(pProduct);
+ }
+
+ ProductReturn CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8)
+ {
+ MyKey key(id,p1,p2,p3,p4,p5,p6,p7,p8);
+ AbstractProduct* pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
+ if(shouldCreateObject(pProduct))
{
- MyKey key(id,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10);
- AbstractProduct *pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
- if(shouldCreateObject(pProduct))
- {
- pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3
- ,key.p4,key.p5,key.p6,key.p7,key.p8,key.p9,key.p10);
- onCreate(pProduct);
- }
- onFetch(pProduct);
- providedObjects[pProduct] = key;
- return NP::encapsulate(pProduct);
+ pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3
+ ,key.p4,key.p5,key.p6,key.p7,key.p8);
+ onCreate(pProduct);
}
+ onFetch(pProduct);
+ providedObjects[pProduct] = key;
+ return NP::encapsulate(pProduct);
+ }
- ProductReturn CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
- Parm11 p11)
+ ProductReturn CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
+ {
+ MyKey key(id,p1,p2,p3,p4,p5,p6,p7,p8,p9);
+ AbstractProduct* pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
+ if(shouldCreateObject(pProduct))
{
- MyKey key(id,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11);
- AbstractProduct *pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
- if(shouldCreateObject(pProduct))
- {
- pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3
- ,key.p4,key.p5,key.p6,key.p7,key.p8,key.p9,key.p10,key.p11);
- onCreate(pProduct);
- }
- onFetch(pProduct);
- providedObjects[pProduct] = key;
- return NP::encapsulate(pProduct);
+ pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3
+ ,key.p4,key.p5,key.p6,key.p7,key.p8,key.p9);
+ onCreate(pProduct);
}
+ onFetch(pProduct);
+ providedObjects[pProduct] = key;
+ return NP::encapsulate(pProduct);
+ }
- ProductReturn CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
- Parm11 p11, Parm12 p12)
+ ProductReturn CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9,Parm10 p10)
+ {
+ MyKey key(id,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10);
+ AbstractProduct* pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
+ if(shouldCreateObject(pProduct))
{
- MyKey key(id,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12);
- AbstractProduct *pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
- if(shouldCreateObject(pProduct))
- {
- pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3
- ,key.p4,key.p5,key.p6,key.p7,key.p8,key.p9,key.p10,key.p11,key.p12);
- onCreate(pProduct);
- }
- onFetch(pProduct);
- providedObjects[pProduct] = key;
- return NP::encapsulate(pProduct);
+ pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3
+ ,key.p4,key.p5,key.p6,key.p7,key.p8,key.p9,key.p10);
+ onCreate(pProduct);
}
+ onFetch(pProduct);
+ providedObjects[pProduct] = key;
+ return NP::encapsulate(pProduct);
+ }
- ProductReturn CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
- Parm11 p11, Parm12 p12, Parm13 p13)
+ ProductReturn CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
+ Parm11 p11)
+ {
+ MyKey key(id,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11);
+ AbstractProduct* pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
+ if(shouldCreateObject(pProduct))
{
- MyKey key(id,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13);
- AbstractProduct *pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
- if(shouldCreateObject(pProduct))
- {
- pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3
- ,key.p4,key.p5,key.p6,key.p7,key.p8,key.p9,key.p10,key.p11,key.p12
- ,key.p13);
- onCreate(pProduct);
- }
- onFetch(pProduct);
- providedObjects[pProduct] = key;
- return NP::encapsulate(pProduct);
+ pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3
+ ,key.p4,key.p5,key.p6,key.p7,key.p8,key.p9,key.p10,key.p11);
+ onCreate(pProduct);
}
+ onFetch(pProduct);
+ providedObjects[pProduct] = key;
+ return NP::encapsulate(pProduct);
+ }
- ProductReturn CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
- Parm11 p11, Parm12 p12, Parm13 p13, Parm14 p14)
+ ProductReturn CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
+ Parm11 p11, Parm12 p12)
+ {
+ MyKey key(id,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12);
+ AbstractProduct* pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
+ if(shouldCreateObject(pProduct))
{
- MyKey key(id,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14);
- AbstractProduct *pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
- if(shouldCreateObject(pProduct))
- {
- pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3
- ,key.p4,key.p5,key.p6,key.p7,key.p8,key.p9,key.p10,key.p11,key.p12
- ,key.p13,key.p14);
- onCreate(pProduct);
- }
- onFetch(pProduct);
- providedObjects[pProduct] = key;
- return NP::encapsulate(pProduct);
+ pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3
+ ,key.p4,key.p5,key.p6,key.p7,key.p8,key.p9,key.p10,key.p11,key.p12);
+ onCreate(pProduct);
}
+ onFetch(pProduct);
+ providedObjects[pProduct] = key;
+ return NP::encapsulate(pProduct);
+ }
- ProductReturn CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
- Parm11 p11, Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
+ ProductReturn CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
+ Parm11 p11, Parm12 p12, Parm13 p13)
+ {
+ MyKey key(id,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13);
+ AbstractProduct* pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
+ if(shouldCreateObject(pProduct))
{
- MyKey key(id,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15);
- AbstractProduct *pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
- if(shouldCreateObject(pProduct))
- {
- pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3
- ,key.p4,key.p5,key.p6,key.p7,key.p8,key.p9,key.p10,key.p11,key.p12
- ,key.p13,key.p14,key.p15);
- onCreate(pProduct);
- }
- onFetch(pProduct);
- providedObjects[pProduct] = key;
- return NP::encapsulate(pProduct);
+ pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3
+ ,key.p4,key.p5,key.p6,key.p7,key.p8,key.p9,key.p10,key.p11,key.p12
+ ,key.p13);
+ onCreate(pProduct);
}
+ onFetch(pProduct);
+ providedObjects[pProduct] = key;
+ return NP::encapsulate(pProduct);
+ }
- /// Use this function to release the object
- /**
- * if execution brakes in this function then you tried
- * to release an object that wasn't provided by this Cache
- * ... which is bad :-)
- */
- void ReleaseObject(ProductReturn &object)
+ ProductReturn CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
+ Parm11 p11, Parm12 p12, Parm13 p13, Parm14 p14)
+ {
+ MyKey key(id,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14);
+ AbstractProduct* pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
+ if(shouldCreateObject(pProduct))
{
- AbstractProduct* pProduct(NP::release(object));
- typename FetchedObjToKeyMap::iterator itr = providedObjects.find(pProduct);
- if(itr == providedObjects.end())
- throw CacheException();
- onRelease(pProduct);
- ReleaseObjectFromContainer(getContainerFromKey((*itr).second), pProduct);
- providedObjects.erase(itr);
+ pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3
+ ,key.p4,key.p5,key.p6,key.p7,key.p8,key.p9,key.p10,key.p11,key.p12
+ ,key.p13,key.p14);
+ onCreate(pProduct);
}
-
- /// display the cache configuration
- void displayCacheType()
+ onFetch(pProduct);
+ providedObjects[pProduct] = key;
+ return NP::encapsulate(pProduct);
+ }
+
+ ProductReturn CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
+ Parm11 p11, Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
+ {
+ MyKey key(id,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15);
+ AbstractProduct* pProduct(getPointerToObjectInContainer(getContainerFromKey(key)));
+ if(shouldCreateObject(pProduct))
{
- using namespace std;
- cout << "############################" << endl;
- cout << "## Cache configuration" << endl;
- cout << "## + Encapsulation " << NP::name() << endl;
- cout << "## + Creating " << CP::name() << endl;
- cout << "## + Eviction " << EP::name() << endl;
- cout << "## + Statistics " << SP::name() << endl;
- cout << "############################" << endl;
+ pProduct = factory.CreateObject(key.id,key.p1,key.p2,key.p3
+ ,key.p4,key.p5,key.p6,key.p7,key.p8,key.p9,key.p10,key.p11,key.p12
+ ,key.p13,key.p14,key.p15);
+ onCreate(pProduct);
}
- };
+ onFetch(pProduct);
+ providedObjects[pProduct] = key;
+ return NP::encapsulate(pProduct);
+ }
+
+ /// Use this function to release the object
+ /**
+ * if execution brakes in this function then you tried
+ * to release an object that wasn't provided by this Cache
+ * ... which is bad :-)
+ */
+ void ReleaseObject(ProductReturn& object)
+ {
+ AbstractProduct* pProduct(NP::release(object));
+ typename FetchedObjToKeyMap::iterator itr = providedObjects.find(pProduct);
+ if(itr == providedObjects.end())
+ throw CacheException();
+ onRelease(pProduct);
+ ReleaseObjectFromContainer(getContainerFromKey((*itr).second), pProduct);
+ providedObjects.erase(itr);
+ }
+
+ /// display the cache configuration
+ void displayCacheType()
+ {
+ using namespace std;
+ cout << "############################" << endl;
+ cout << "## Cache configuration" << endl;
+ cout << "## + Encapsulation " << NP::name() << endl;
+ cout << "## + Creating " << CP::name() << endl;
+ cout << "## + Eviction " << EP::name() << endl;
+ cout << "## + Statistics " << SP::name() << endl;
+ cout << "############################" << endl;
+ }
+};
} // namespace Loki
#endif // end file guardian
diff --git a/shared/loki/CheckReturn.h b/shared/loki/CheckReturn.h
index fbe63ed0..c0a65aa5 100644
--- a/shared/loki/CheckReturn.h
+++ b/shared/loki/CheckReturn.h
@@ -65,46 +65,46 @@ namespace Loki
template<class T>
struct IgnoreReturnValue
{
- static void run(const T&)
- {
- /// Do nothing at all.
- }
+ static void run(const T&)
+ {
+ /// Do nothing at all.
+ }
};
template<class T>
struct ThrowTheValue
{
- static void run(const T & value )
- {
- throw value;
- }
+ static void run(const T& value )
+ {
+ throw value;
+ }
};
template<class T>
struct ThrowLogicError
{
- static void run( const T & )
- {
- throw ::std::logic_error( "CheckReturn: return value was not checked.\n" );
- }
+ static void run( const T& )
+ {
+ throw ::std::logic_error( "CheckReturn: return value was not checked.\n" );
+ }
};
template<class T>
struct TriggerAssert
{
- static void run(const T&)
- {
- assert( 0 );
- }
+ static void run(const T&)
+ {
+ assert( 0 );
+ }
};
template<class T>
struct FprintfStderr
{
- static void run(const T&)
- {
- fprintf(stderr, "CheckReturn: return value was not checked.\n");
- }
+ static void run(const T&)
+ {
+ fprintf(stderr, "CheckReturn: return value was not checked.\n");
+ }
};
@@ -114,45 +114,45 @@ class CheckReturn
{
public:
- /// Conversion constructor changes Value type to CheckReturn type.
- inline CheckReturn( const Value & value ) :
- m_value( value ), m_checked( false ) {}
-
- /// Copy-constructor allows functions to call another function within the
- /// return statement. The other CheckReturn's m_checked flag is set since
- /// its duty has been passed to the m_checked flag in this one.
- inline CheckReturn( const CheckReturn & that ) :
- m_value( that.m_value ), m_checked( false )
- { that.m_checked = true; }
-
- /// Destructor checks if return value was used.
- inline ~CheckReturn( void )
- {
- // If m_checked is false, then a function failed to check the
- // return value from a function call.
- if (!m_checked)
- OnError<Value>::run(m_value);
- }
-
- /// Conversion operator changes CheckReturn back to Value type.
- inline operator Value ( void )
- {
- m_checked = true;
- return m_value;
- }
+ /// Conversion constructor changes Value type to CheckReturn type.
+ inline CheckReturn( const Value& value ) :
+ m_value( value ), m_checked( false ) {}
+
+ /// Copy-constructor allows functions to call another function within the
+ /// return statement. The other CheckReturn's m_checked flag is set since
+ /// its duty has been passed to the m_checked flag in this one.
+ inline CheckReturn( const CheckReturn& that ) :
+ m_value( that.m_value ), m_checked( false )
+ { that.m_checked = true; }
+
+ /// Destructor checks if return value was used.
+ inline ~CheckReturn( void )
+ {
+ // If m_checked is false, then a function failed to check the
+ // return value from a function call.
+ if (!m_checked)
+ OnError<Value>::run(m_value);
+ }
+
+ /// Conversion operator changes CheckReturn back to Value type.
+ inline operator Value ( void )
+ {
+ m_checked = true;
+ return m_value;
+ }
private:
- /// Default constructor not implemented.
- CheckReturn( void );
+ /// Default constructor not implemented.
+ CheckReturn( void );
- /// Copy-assignment operator not implemented.
- CheckReturn & operator = ( const CheckReturn & that );
+ /// Copy-assignment operator not implemented.
+ CheckReturn& operator = ( const CheckReturn& that );
- /// Copy of returned value.
- Value m_value;
+ /// Copy of returned value.
+ Value m_value;
- /// Flag for whether calling function checked return value yet.
- mutable bool m_checked;
+ /// Flag for whether calling function checked return value yet.
+ mutable bool m_checked;
};
// ----------------------------------------------------------------------------
diff --git a/shared/loki/Checker.h b/shared/loki/Checker.h
index 19350679..64579d2f 100644
--- a/shared/loki/Checker.h
+++ b/shared/loki/Checker.h
@@ -86,9 +86,9 @@ class CheckForNoThrow
{
public:
- inline explicit CheckForNoThrow( const Host * ) {}
+ inline explicit CheckForNoThrow( const Host* ) {}
- inline bool Check( const Host * ) const
+ inline bool Check( const Host* ) const
{
const bool okay = ( !::std::uncaught_exception() );
assert( okay );
@@ -117,13 +117,13 @@ class CheckForNoChange
{
public:
- inline explicit CheckForNoChange( const Host * host ) :
+ inline explicit CheckForNoChange( const Host* host ) :
m_compare( *host ) {}
- inline bool Check( const Host * host ) const
+ inline bool Check( const Host* host ) const
{
const bool okay = ( !::std::uncaught_exception() )
- || ( m_compare == *host );
+ || ( m_compare == *host );
assert( okay );
return okay;
}
@@ -152,10 +152,10 @@ class CheckForNoChangeOrThrow
{
public:
- inline explicit CheckForNoChangeOrThrow( const Host * host ) :
+ inline explicit CheckForNoChangeOrThrow( const Host* host ) :
m_compare( *host ) {}
- inline bool Check( const Host * host ) const
+ inline bool Check( const Host* host ) const
{
bool okay = ( !::std::uncaught_exception() );
assert( okay );
@@ -187,10 +187,10 @@ class CheckForEquality
{
public:
- inline explicit CheckForEquality( const Host * host ) :
+ inline explicit CheckForEquality( const Host* host ) :
m_compare( *host ) {}
- inline bool Check( const Host * host ) const
+ inline bool Check( const Host* host ) const
{
const bool okay = ( m_compare == *host );
assert( okay );
@@ -219,8 +219,8 @@ template < class Host >
class CheckForNothing
{
public:
- inline explicit CheckForNothing( const Host * ) {}
- inline bool Check( const Host * ) const { return true; }
+ inline explicit CheckForNothing( const Host* ) {}
+ inline bool Check( const Host* ) const { return true; }
};
// ----------------------------------------------------------------------------
@@ -271,9 +271,9 @@ public:
template
<
- class Host,
- template < class > class ExceptionPolicy
->
+class Host,
+ template < class > class ExceptionPolicy
+ >
class ContractChecker : public ExceptionPolicy< Host >
{
/// Shorthand for the ExceptionPolicy class.
@@ -291,8 +291,8 @@ public:
@par pre Optional pointer to function that checks pre-conditions.
@par post Optional pointer to function that checks post-conditions.
*/
- inline ContractChecker( const Host * host, Validator validator,
- Validator pre = 0, Validator post = 0 ) :
+ inline ContractChecker( const Host* host, Validator validator,
+ Validator pre = 0, Validator post = 0 ) :
Ep( host ),
m_host( host ),
m_validator( validator ),
@@ -342,12 +342,12 @@ private:
/// Default constructor is not implemented.
ContractChecker( void );
/// Copy constructor is not implemented.
- ContractChecker( const ContractChecker & );
+ ContractChecker( const ContractChecker& );
/// Copy-assignment operator is not implemented.
- ContractChecker & operator = ( const ContractChecker & );
+ ContractChecker& operator = ( const ContractChecker& );
/// Pointer to the host object.
- const Host * m_host;
+ const Host* m_host;
/// Pointer to member function that checks Host object's invariants.
Validator m_validator;
@@ -428,7 +428,7 @@ public:
template
<
- class ExceptionPolicy
+class ExceptionPolicy
>
class StaticChecker : public ExceptionPolicy
{
@@ -447,7 +447,7 @@ public:
@par post Optional pointer to function that checks post-conditions.
*/
inline explicit StaticChecker( Validator validator,
- Validator pre = 0, Validator post = 0 ) :
+ Validator pre = 0, Validator post = 0 ) :
Ep(),
m_validator( validator ),
m_pre( pre ),
@@ -494,9 +494,9 @@ private:
/// Default constructor is not implemented.
StaticChecker( void );
/// Copy constructor is not implemented.
- StaticChecker( const StaticChecker & );
+ StaticChecker( const StaticChecker& );
/// Copy-assignment operator is not implemented.
- StaticChecker & operator = ( const StaticChecker & );
+ StaticChecker& operator = ( const StaticChecker& );
/// Pointer to member function that checks Host object's invariants.
Validator m_validator;
diff --git a/shared/loki/ConstPolicy.h b/shared/loki/ConstPolicy.h
index 74c9e5aa..1adb227a 100644
--- a/shared/loki/ConstPolicy.h
+++ b/shared/loki/ConstPolicy.h
@@ -2,12 +2,12 @@
// The Loki Library
// Copyright (c) 2006 Richard Sposato
// Copyright (c) 2006 Peter Kümmel
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The authors make no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The authors make no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_CONST_POLICY_INC_
@@ -32,11 +32,11 @@ namespace Loki
/// Don't propagate constness of pointed or referred object.
////////////////////////////////////////////////////////////////////////////////
- template< class T >
- struct DontPropagateConst
- {
- typedef T Type;
- };
+template< class T >
+struct DontPropagateConst
+{
+ typedef T Type;
+};
////////////////////////////////////////////////////////////////////////////////
/// \class PropagateConst
@@ -45,11 +45,11 @@ namespace Loki
/// Propagate constness of pointed or referred object.
////////////////////////////////////////////////////////////////////////////////
- template< class T >
- struct PropagateConst
- {
- typedef const T Type;
- };
+template< class T >
+struct PropagateConst
+{
+ typedef const T Type;
+};
// default will not break existing code
#ifndef LOKI_DEFAULT_CONSTNESS
diff --git a/shared/loki/DataGenerators.h b/shared/loki/DataGenerators.h
index 1c8e2df0..7ac697af 100644
--- a/shared/loki/DataGenerators.h
+++ b/shared/loki/DataGenerators.h
@@ -2,7 +2,7 @@
// The Loki Library
// Data Generator by Shannon Barber
// This code DOES NOT accompany the book:
-// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
//
// Code covered by the MIT License
@@ -44,69 +44,69 @@ gendata(std::back_inserter(stuff));
*******************************************************************************/
namespace Loki
{
- namespace TL
- {
- template<typename T>
- struct nameof_type
- {
- const char* operator()()
- {
- return typeid(T).name();
- }
- };
- template<typename T>
- struct sizeof_type
- {
- size_t operator()()
- {
- return sizeof(T);
- }
- };
- template <class TList, template <class> class GenFunc>
- struct IterateTypes;
-
- template <class T1, class T2, template <class> class GenFunc>
- struct IterateTypes<Typelist<T1, T2>, GenFunc>
+namespace TL
+{
+template<typename T>
+struct nameof_type
+{
+ const char* operator()()
+ {
+ return typeid(T).name();
+ }
+};
+template<typename T>
+struct sizeof_type
+{
+ size_t operator()()
{
+ return sizeof(T);
+ }
+};
+template <class TList, template <class> class GenFunc>
+struct IterateTypes;
+
+template <class T1, class T2, template <class> class GenFunc>
+struct IterateTypes<Typelist<T1, T2>, GenFunc>
+{
typedef IterateTypes<T1, GenFunc> head_t;
head_t head;
typedef IterateTypes<T2, GenFunc> tail_t;
tail_t tail;
template<class II>
void operator()(II ii)
- {
+ {
head.operator()(ii);
tail.operator()(ii);
- }
- };
-
- template <class AtomicType, template <class> class GenFunc>
- struct IterateTypes
- {
+ }
+};
+
+template <class AtomicType, template <class> class GenFunc>
+struct IterateTypes
+{
template<class II>
void operator()(II ii)
- {
+ {
GenFunc<AtomicType> genfunc;
*ii = genfunc();
++ii; //Is this even needed?
- }
- };
-
- template <template <class> class GenFunc>
- struct IterateTypes<NullType, GenFunc>
- {
+ }
+};
+
+template <template <class> class GenFunc>
+struct IterateTypes<NullType, GenFunc>
+{
template<class II>
void operator()(II ii)
- {}
- };
-
- template<typename Types, template <class> class UnitFunc, typename II>
- void iterate_types(II ii)
- {
- Loki::TL::IterateTypes<Types, UnitFunc> it;
- it(ii);
- }
- }//ns TL
+ {}
+};
+
+template<typename Types, template <class> class UnitFunc, typename II>
+void iterate_types(II ii)
+{
+ Loki::TL::IterateTypes<Types, UnitFunc> it;
+ it(ii);
+}
+}//ns TL
}//ns Loki
#endif // end file guardian
diff --git a/shared/loki/EmptyType.h b/shared/loki/EmptyType.h
index b228e2e8..0f60c894 100644
--- a/shared/loki/EmptyType.h
+++ b/shared/loki/EmptyType.h
@@ -2,14 +2,14 @@
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
-// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author or Addison-Wesley Longman make no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author or Addison-Wesley Longman make no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_EMPTYTYPE_INC_
@@ -26,23 +26,23 @@ namespace Loki
// Useful as a strawman class
////////////////////////////////////////////////////////////////////////////////
- class EmptyType {};
-
-
- inline bool operator==(const EmptyType&, const EmptyType&)
- {
- return true;
- }
-
- inline bool operator<(const EmptyType&, const EmptyType&)
- {
- return false;
- }
-
- inline bool operator>(const EmptyType&, const EmptyType&)
- {
- return false;
- }
+class EmptyType {};
+
+
+inline bool operator==(const EmptyType&, const EmptyType&)
+{
+ return true;
+}
+
+inline bool operator<(const EmptyType&, const EmptyType&)
+{
+ return false;
+}
+
+inline bool operator>(const EmptyType&, const EmptyType&)
+{
+ return false;
+}
}
#endif // end file guardian
diff --git a/shared/loki/Factory.h b/shared/loki/Factory.h
index c4c3b22a..6a1ac6b7 100644
--- a/shared/loki/Factory.h
+++ b/shared/loki/Factory.h
@@ -33,7 +33,7 @@
* \defgroup FactoryGroup Factory
* \ingroup FactoriesGroup
* \brief Implements a generic object factory.
- *
+ *
* <i>The Factory Method pattern is an object-oriented design pattern.
* Like other creational patterns, it deals with the problem of creating objects
* (products) without specifying the exact class of object that will be created.
@@ -46,7 +46,7 @@
* whose main purpose is creation of objects.</i>
* <div ALIGN="RIGHT"><a href="http://en.wikipedia.org/wiki/Factory_method_pattern">
* Wikipedia</a></div>
- *
+ *
* Loki proposes a generic version of the Factory. Here is a typical use.<br>
* <code><br>
* 1. Factory< AbstractProduct, int > aFactory;<br>
@@ -62,7 +62,7 @@
* ProductCreator by registering them into the Factory.<br>
* A ProductCreator is a just a function that will return the right object. ie <br>
* <code>
- * Product* createProductNull()<br>
+ * Product* createProductNull()<br>
* {<br>
* return new Product<br>
* }<br>
@@ -80,27 +80,27 @@ namespace Loki
* \defgroup FactoryErrorPoliciesGroup Factory Error Policies
* \ingroup FactoryGroup
* \brief Manages the "Unknown Type" error in an object factory
- *
+ *
* \class DefaultFactoryError
* \ingroup FactoryErrorPoliciesGroup
- * \brief Default policy that throws an exception
- *
+ * \brief Default policy that throws an exception
+ *
*/
- template <typename IdentifierType, class AbstractProduct>
- struct DefaultFactoryError
+template <typename IdentifierType, class AbstractProduct>
+struct DefaultFactoryError
+{
+ struct Exception : public std::exception
{
- struct Exception : public std::exception
- {
- const char* what() const throw() { return "Unknown Type"; }
- };
-
- static AbstractProduct* OnUnknownType(IdentifierType)
- {
- throw Exception();
- }
+ const char* what() const throw() { return "Unknown Type"; }
};
+ static AbstractProduct* OnUnknownType(IdentifierType)
+ {
+ throw Exception();
+ }
+};
+
#define LOKI_ENABLE_NEW_FACTORY_CODE
#ifdef LOKI_ENABLE_NEW_FACTORY_CODE
@@ -110,911 +110,911 @@ namespace Loki
// class template FunctorImpl
////////////////////////////////////////////////////////////////////////////////
- struct FactoryImplBase
- {
- typedef EmptyType Parm1;
- typedef EmptyType Parm2;
- typedef EmptyType Parm3;
- typedef EmptyType Parm4;
- typedef EmptyType Parm5;
- typedef EmptyType Parm6;
- typedef EmptyType Parm7;
- typedef EmptyType Parm8;
- typedef EmptyType Parm9;
- typedef EmptyType Parm10;
- typedef EmptyType Parm11;
- typedef EmptyType Parm12;
- typedef EmptyType Parm13;
- typedef EmptyType Parm14;
- typedef EmptyType Parm15;
- };
-
- template <typename AP, typename Id, typename TList >
- struct FactoryImpl;
-
- template<typename AP, typename Id>
- struct FactoryImpl<AP, Id, NullType>
- : public FactoryImplBase
- {
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id & id ) = 0;
- };
+struct FactoryImplBase
+{
+ typedef EmptyType Parm1;
+ typedef EmptyType Parm2;
+ typedef EmptyType Parm3;
+ typedef EmptyType Parm4;
+ typedef EmptyType Parm5;
+ typedef EmptyType Parm6;
+ typedef EmptyType Parm7;
+ typedef EmptyType Parm8;
+ typedef EmptyType Parm9;
+ typedef EmptyType Parm10;
+ typedef EmptyType Parm11;
+ typedef EmptyType Parm12;
+ typedef EmptyType Parm13;
+ typedef EmptyType Parm14;
+ typedef EmptyType Parm15;
+};
+
+template <typename AP, typename Id, typename TList >
+struct FactoryImpl;
+
+template<typename AP, typename Id>
+struct FactoryImpl<AP, Id, NullType>
+ : public FactoryImplBase
+{
+ virtual ~FactoryImpl() {}
+ virtual AP* CreateObject(const Id& id ) = 0;
+};
template <typename AP, typename Id, typename P1 >
- struct FactoryImpl<AP,Id, Seq<P1> >
- : public FactoryImplBase
- {
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1 ) = 0;
- };
+struct FactoryImpl<AP,Id, Seq<P1> >
+ : public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ virtual ~FactoryImpl() {}
+ virtual AP* CreateObject(const Id& id,Parm1 ) = 0;
+};
+
+template<typename AP, typename Id, typename P1,typename P2 >
+struct FactoryImpl<AP, Id, Seq<P1, P2> >
+ : public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ virtual ~FactoryImpl() {}
+ virtual AP* CreateObject(const Id& id,Parm1, Parm2 ) = 0;
+};
+
+template<typename AP, typename Id, typename P1,typename P2,typename P3 >
+struct FactoryImpl<AP, Id, Seq<P1, P2, P3> >
+ : public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ virtual ~FactoryImpl() {}
+ virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3 ) = 0;
+};
+
+template<typename AP, typename Id, typename P1,typename P2,typename P3,typename P4 >
+struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4> >
+ : public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ virtual ~FactoryImpl() {}
+ virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4 ) = 0;
+};
+
+template<typename AP, typename Id,
+ typename P1,typename P2,typename P3,typename P4,typename P5 >
+struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5> >
+ : public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ virtual ~FactoryImpl() {}
+ virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5 ) = 0;
+};
+
+template<typename AP, typename Id,
+ typename P1,typename P2,typename P3,typename P4,typename P5,
+ typename P6>
+struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6> >
+ : public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ virtual ~FactoryImpl() {}
+ virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
+ Parm6 )
+ = 0;
+};
+
+template<typename AP, typename Id,
+ typename P1,typename P2,typename P3,typename P4,typename P5,
+ typename P6,typename P7>
+struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7> >
+ : public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ virtual ~FactoryImpl() {}
+ virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
+ Parm6, Parm7 )
+ = 0;
+};
+
+template<typename AP, typename Id,
+ typename P1,typename P2,typename P3,typename P4,typename P5,
+ typename P6,typename P7,typename P8>
+struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8> >
+ : public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ virtual ~FactoryImpl() {}
+ virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
+ Parm6, Parm7, Parm8)
+ = 0;
+};
+
+template<typename AP, typename Id,
+ typename P1,typename P2,typename P3,typename P4,typename P5,
+ typename P6,typename P7,typename P8,typename P9>
+struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9> >
+ : public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ virtual ~FactoryImpl() {}
+ virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
+ Parm6, Parm7, Parm8, Parm9)
+ = 0;
+};
+
+template<typename AP, typename Id,
+ typename P1,typename P2,typename P3,typename P4,typename P5,
+ typename P6,typename P7,typename P8,typename P9,typename P10>
+struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10> >
+ : public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ typedef typename TypeTraits<P10>::ParameterType Parm10;
+ virtual ~FactoryImpl() {}
+ virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
+ Parm6, Parm7, Parm8, Parm9,Parm10)
+ = 0;
+};
+
+template<typename AP, typename Id,
+ typename P1,typename P2,typename P3,typename P4,typename P5,
+ typename P6,typename P7,typename P8,typename P9,typename P10,
+ typename P11>
+struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11> >
+ : public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ typedef typename TypeTraits<P10>::ParameterType Parm10;
+ typedef typename TypeTraits<P11>::ParameterType Parm11;
+ virtual ~FactoryImpl() {}
+ virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
+ Parm6, Parm7, Parm8, Parm9,Parm10,
+ Parm11)
+ = 0;
+};
+
+template<typename AP, typename Id,
+ typename P1,typename P2,typename P3,typename P4,typename P5,
+ typename P6,typename P7,typename P8,typename P9,typename P10,
+ typename P11,typename P12>
+struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12> >
+ : public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ typedef typename TypeTraits<P10>::ParameterType Parm10;
+ typedef typename TypeTraits<P11>::ParameterType Parm11;
+ typedef typename TypeTraits<P12>::ParameterType Parm12;
+ virtual ~FactoryImpl() {}
+ virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
+ Parm6, Parm7, Parm8, Parm9,Parm10,
+ Parm11,Parm12)
+ = 0;
+};
+
+template<typename AP, typename Id,
+ typename P1,typename P2,typename P3,typename P4,typename P5,
+ typename P6,typename P7,typename P8,typename P9,typename P10,
+ typename P11,typename P12,typename P13>
+struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13> >
+ : public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ typedef typename TypeTraits<P10>::ParameterType Parm10;
+ typedef typename TypeTraits<P11>::ParameterType Parm11;
+ typedef typename TypeTraits<P12>::ParameterType Parm12;
+ typedef typename TypeTraits<P13>::ParameterType Parm13;
+ virtual ~FactoryImpl() {}
+ virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
+ Parm6, Parm7, Parm8, Parm9,Parm10,
+ Parm11,Parm12,Parm13)
+ = 0;
+};
+
+template<typename AP, typename Id,
+ typename P1,typename P2,typename P3,typename P4,typename P5,
+ typename P6,typename P7,typename P8,typename P9,typename P10,
+ typename P11,typename P12,typename P13,typename P14>
+struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14> >
+ : public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ typedef typename TypeTraits<P10>::ParameterType Parm10;
+ typedef typename TypeTraits<P11>::ParameterType Parm11;
+ typedef typename TypeTraits<P12>::ParameterType Parm12;
+ typedef typename TypeTraits<P13>::ParameterType Parm13;
+ typedef typename TypeTraits<P14>::ParameterType Parm14;
+ virtual ~FactoryImpl() {}
+ virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
+ Parm6, Parm7, Parm8, Parm8,Parm10,
+ Parm11,Parm12,Parm13,Parm14)
+ = 0;
+};
+
+template<typename AP, typename Id,
+ typename P1,typename P2,typename P3,typename P4,typename P5,
+ typename P6,typename P7,typename P8,typename P9,typename P10,
+ typename P11,typename P12,typename P13,typename P14,typename P15 >
+struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15> >
+ : public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ typedef typename TypeTraits<P10>::ParameterType Parm10;
+ typedef typename TypeTraits<P11>::ParameterType Parm11;
+ typedef typename TypeTraits<P12>::ParameterType Parm12;
+ typedef typename TypeTraits<P13>::ParameterType Parm13;
+ typedef typename TypeTraits<P14>::ParameterType Parm14;
+ typedef typename TypeTraits<P15>::ParameterType Parm15;
+ virtual ~FactoryImpl() {}
+ virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
+ Parm6, Parm7, Parm8, Parm9,Parm10,
+ Parm11,Parm12,Parm13,Parm14,Parm15 )
+ = 0;
+};
- template<typename AP, typename Id, typename P1,typename P2 >
- struct FactoryImpl<AP, Id, Seq<P1, P2> >
- : public FactoryImplBase
- {
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2 ) = 0;
- };
+#ifndef LOKI_DISABLE_TYPELIST_MACROS
- template<typename AP, typename Id, typename P1,typename P2,typename P3 >
- struct FactoryImpl<AP, Id, Seq<P1, P2, P3> >
- : public FactoryImplBase
- {
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3 ) = 0;
- };
+template <typename AP, typename Id, typename P1 >
+struct FactoryImpl<AP,Id, LOKI_TYPELIST_1( P1 )>
+: public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+virtual ~FactoryImpl() {}
+virtual AP* CreateObject(const Id& id,Parm1 ) = 0;
+};
+
+template<typename AP, typename Id, typename P1,typename P2 >
+struct FactoryImpl<AP, Id, LOKI_TYPELIST_2( P1, P2 )>
+: public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+virtual ~FactoryImpl() {}
+virtual AP* CreateObject(const Id& id,Parm1, Parm2 ) = 0;
+};
+
+template<typename AP, typename Id, typename P1,typename P2,typename P3 >
+struct FactoryImpl<AP, Id, LOKI_TYPELIST_3( P1, P2, P3 )>
+: public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+virtual ~FactoryImpl() {}
+virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3 ) = 0;
+};
+
+template<typename AP, typename Id, typename P1,typename P2,typename P3,typename P4 >
+struct FactoryImpl<AP, Id, LOKI_TYPELIST_4( P1, P2, P3, P4 )>
+: public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+virtual ~FactoryImpl() {}
+virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4 ) = 0;
+};
+
+template<typename AP, typename Id,
+ typename P1,typename P2,typename P3,typename P4,typename P5 >
+struct FactoryImpl<AP, Id, LOKI_TYPELIST_5( P1, P2, P3, P4, P5 )>
+: public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+virtual ~FactoryImpl() {}
+virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5 ) = 0;
+};
+
+template<typename AP, typename Id,
+ typename P1,typename P2,typename P3,typename P4,typename P5,
+ typename P6>
+struct FactoryImpl<AP, Id, LOKI_TYPELIST_6( P1, P2, P3, P4, P5, P6 )>
+: public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+virtual ~FactoryImpl() {}
+virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
+ Parm6 )
+= 0;
+};
+
+template<typename AP, typename Id,
+ typename P1,typename P2,typename P3,typename P4,typename P5,
+ typename P6,typename P7>
+struct FactoryImpl<AP, Id, LOKI_TYPELIST_7( P1, P2, P3, P4, P5, P6, P7 )>
+: public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+virtual ~FactoryImpl() {}
+virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
+ Parm6, Parm7 )
+= 0;
+};
+
+template<typename AP, typename Id,
+ typename P1,typename P2,typename P3,typename P4,typename P5,
+ typename P6,typename P7,typename P8>
+struct FactoryImpl<AP, Id, LOKI_TYPELIST_8( P1, P2, P3, P4, P5, P6, P7, P8 )>
+: public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+virtual ~FactoryImpl() {}
+virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
+ Parm6, Parm7, Parm8)
+= 0;
+};
+
+template<typename AP, typename Id,
+ typename P1,typename P2,typename P3,typename P4,typename P5,
+ typename P6,typename P7,typename P8,typename P9>
+struct FactoryImpl<AP, Id, LOKI_TYPELIST_9( P1, P2, P3, P4, P5, P6, P7, P8, P9 )>
+: public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+virtual ~FactoryImpl() {}
+virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
+ Parm6, Parm7, Parm8, Parm9)
+= 0;
+};
+
+template<typename AP, typename Id,
+ typename P1,typename P2,typename P3,typename P4,typename P5,
+ typename P6,typename P7,typename P8,typename P9,typename P10>
+struct FactoryImpl<AP, Id, LOKI_TYPELIST_10( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10 )>
+: public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ typedef typename TypeTraits<P10>::ParameterType Parm10;
+virtual ~FactoryImpl() {}
+virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
+ Parm6, Parm7, Parm8, Parm9,Parm10)
+= 0;
+};
+
+template<typename AP, typename Id,
+ typename P1,typename P2,typename P3,typename P4,typename P5,
+ typename P6,typename P7,typename P8,typename P9,typename P10,
+ typename P11>
+struct FactoryImpl<AP, Id, LOKI_TYPELIST_11( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11 )>
+: public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ typedef typename TypeTraits<P10>::ParameterType Parm10;
+ typedef typename TypeTraits<P11>::ParameterType Parm11;
+virtual ~FactoryImpl() {}
+virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
+ Parm6, Parm7, Parm8, Parm9,Parm10,
+ Parm11)
+= 0;
+};
+
+template<typename AP, typename Id,
+ typename P1,typename P2,typename P3,typename P4,typename P5,
+ typename P6,typename P7,typename P8,typename P9,typename P10,
+ typename P11,typename P12>
+struct FactoryImpl<AP, Id, LOKI_TYPELIST_12( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12 )>
+: public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ typedef typename TypeTraits<P10>::ParameterType Parm10;
+ typedef typename TypeTraits<P11>::ParameterType Parm11;
+ typedef typename TypeTraits<P12>::ParameterType Parm12;
+virtual ~FactoryImpl() {}
+virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
+ Parm6, Parm7, Parm8, Parm9,Parm10,
+ Parm11,Parm12)
+= 0;
+};
+
+template<typename AP, typename Id,
+ typename P1,typename P2,typename P3,typename P4,typename P5,
+ typename P6,typename P7,typename P8,typename P9,typename P10,
+ typename P11,typename P12,typename P13>
+struct FactoryImpl<AP, Id, LOKI_TYPELIST_13( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13 )>
+: public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ typedef typename TypeTraits<P10>::ParameterType Parm10;
+ typedef typename TypeTraits<P11>::ParameterType Parm11;
+ typedef typename TypeTraits<P12>::ParameterType Parm12;
+ typedef typename TypeTraits<P13>::ParameterType Parm13;
+virtual ~FactoryImpl() {}
+virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
+ Parm6, Parm7, Parm8, Parm9,Parm10,
+ Parm11,Parm12,Parm13)
+= 0;
+};
+
+template<typename AP, typename Id,
+ typename P1,typename P2,typename P3,typename P4,typename P5,
+ typename P6,typename P7,typename P8,typename P9,typename P10,
+ typename P11,typename P12,typename P13,typename P14>
+struct FactoryImpl<AP, Id, LOKI_TYPELIST_14( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14 )>
+: public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ typedef typename TypeTraits<P10>::ParameterType Parm10;
+ typedef typename TypeTraits<P11>::ParameterType Parm11;
+ typedef typename TypeTraits<P12>::ParameterType Parm12;
+ typedef typename TypeTraits<P13>::ParameterType Parm13;
+ typedef typename TypeTraits<P14>::ParameterType Parm14;
+virtual ~FactoryImpl() {}
+virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
+ Parm6, Parm7, Parm8, Parm8,Parm10,
+ Parm11,Parm12,Parm13,Parm14)
+= 0;
+};
+
+template<typename AP, typename Id,
+ typename P1,typename P2,typename P3,typename P4,typename P5,
+ typename P6,typename P7,typename P8,typename P9,typename P10,
+ typename P11,typename P12,typename P13,typename P14,typename P15 >
+struct FactoryImpl<AP, Id, LOKI_TYPELIST_15( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15 )>
+: public FactoryImplBase
+{
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ typedef typename TypeTraits<P10>::ParameterType Parm10;
+ typedef typename TypeTraits<P11>::ParameterType Parm11;
+ typedef typename TypeTraits<P12>::ParameterType Parm12;
+ typedef typename TypeTraits<P13>::ParameterType Parm13;
+ typedef typename TypeTraits<P14>::ParameterType Parm14;
+ typedef typename TypeTraits<P15>::ParameterType Parm15;
+virtual ~FactoryImpl() {}
+virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
+ Parm6, Parm7, Parm8, Parm9,Parm10,
+ Parm11,Parm12,Parm13,Parm14,Parm15 )
+= 0;
+};
- template<typename AP, typename Id, typename P1,typename P2,typename P3,typename P4 >
- struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4> >
- : public FactoryImplBase
- {
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4 ) = 0;
- };
+#endif //LOKI_DISABLE_TYPELIST_MACROS
- template<typename AP, typename Id,
- typename P1,typename P2,typename P3,typename P4,typename P5 >
- struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5> >
- : public FactoryImplBase
- {
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5 ) = 0;
- };
- template<typename AP, typename Id,
- typename P1,typename P2,typename P3,typename P4,typename P5,
- typename P6>
- struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6> >
- : public FactoryImplBase
+////////////////////////////////////////////////////////////////////////////////
+/// \class Factory
+///
+/// \ingroup FactoryGroup
+/// Implements a generic object factory.
+///
+/// Create functions can have up to 15 parameters.
+///
+/// \par Singleton lifetime when used with Loki::SingletonHolder
+/// Because Factory uses internally Functors which inherits from
+/// SmallObject you must use the singleton lifetime
+/// \code Loki::LongevityLifetime::DieAsSmallObjectChild \endcode
+/// Alternatively you could suppress for Functor the inheritance
+/// from SmallObject by defining the macro:
+/// \code LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT \endcode
+////////////////////////////////////////////////////////////////////////////////
+template
+<
+class AbstractProduct,
+ typename IdentifierType,
+ typename CreatorParmTList = NullType,
+ template<typename, class> class FactoryErrorPolicy = DefaultFactoryError
+ >
+class Factory : public FactoryErrorPolicy<IdentifierType, AbstractProduct>
+{
+ typedef FactoryImpl< AbstractProduct, IdentifierType, CreatorParmTList > Impl;
+
+ typedef typename Impl::Parm1 Parm1;
+ typedef typename Impl::Parm2 Parm2;
+ typedef typename Impl::Parm3 Parm3;
+ typedef typename Impl::Parm4 Parm4;
+ typedef typename Impl::Parm5 Parm5;
+ typedef typename Impl::Parm6 Parm6;
+ typedef typename Impl::Parm7 Parm7;
+ typedef typename Impl::Parm8 Parm8;
+ typedef typename Impl::Parm9 Parm9;
+ typedef typename Impl::Parm10 Parm10;
+ typedef typename Impl::Parm11 Parm11;
+ typedef typename Impl::Parm12 Parm12;
+ typedef typename Impl::Parm13 Parm13;
+ typedef typename Impl::Parm14 Parm14;
+ typedef typename Impl::Parm15 Parm15;
+
+ typedef Functor<AbstractProduct*, CreatorParmTList> ProductCreator;
+
+ typedef AssocVector<IdentifierType, ProductCreator> IdToProductMap;
+
+ IdToProductMap associations_;
+
+public:
+
+ Factory()
+ : associations_()
{
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
- Parm6 )
- = 0;
- };
+ }
- template<typename AP, typename Id,
- typename P1,typename P2,typename P3,typename P4,typename P5,
- typename P6,typename P7>
- struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7> >
- : public FactoryImplBase
+ ~Factory()
{
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
- Parm6, Parm7 )
- = 0;
- };
+ associations_.erase(associations_.begin(), associations_.end());
+ }
- template<typename AP, typename Id,
- typename P1,typename P2,typename P3,typename P4,typename P5,
- typename P6,typename P7,typename P8>
- struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8> >
- : public FactoryImplBase
+ bool Register(const IdentifierType& id, ProductCreator creator)
{
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
- Parm6, Parm7, Parm8)
- = 0;
- };
+ return associations_.insert(
+ typename IdToProductMap::value_type(id, creator)).second != 0;
+ }
- template<typename AP, typename Id,
- typename P1,typename P2,typename P3,typename P4,typename P5,
- typename P6,typename P7,typename P8,typename P9>
- struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9> >
- : public FactoryImplBase
+ template <class PtrObj, typename CreaFn>
+ bool Register(const IdentifierType& id, const PtrObj& p, CreaFn fn)
{
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
- Parm6, Parm7, Parm8, Parm9)
- = 0;
- };
+ ProductCreator creator( p, fn );
+ return associations_.insert(
+ typename IdToProductMap::value_type(id, creator)).second != 0;
+ }
- template<typename AP, typename Id,
- typename P1,typename P2,typename P3,typename P4,typename P5,
- typename P6,typename P7,typename P8,typename P9,typename P10>
- struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10> >
- : public FactoryImplBase
+ bool Unregister(const IdentifierType& id)
{
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- typedef typename TypeTraits<P10>::ParameterType Parm10;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
- Parm6, Parm7, Parm8, Parm9,Parm10)
- = 0;
- };
+ return associations_.erase(id) != 0;
+ }
- template<typename AP, typename Id,
- typename P1,typename P2,typename P3,typename P4,typename P5,
- typename P6,typename P7,typename P8,typename P9,typename P10,
- typename P11>
- struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11> >
- : public FactoryImplBase
+ std::vector<IdentifierType> RegisteredIds()
{
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- typedef typename TypeTraits<P10>::ParameterType Parm10;
- typedef typename TypeTraits<P11>::ParameterType Parm11;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
- Parm6, Parm7, Parm8, Parm9,Parm10,
- Parm11)
- = 0;
- };
+ std::vector<IdentifierType> ids;
+ for(typename IdToProductMap::iterator it = associations_.begin();
+ it != associations_.end(); ++it)
+ {
+ ids.push_back(it->first);
+ }
+ return ids;
+ }
- template<typename AP, typename Id,
- typename P1,typename P2,typename P3,typename P4,typename P5,
- typename P6,typename P7,typename P8,typename P9,typename P10,
- typename P11,typename P12>
- struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12> >
- : public FactoryImplBase
+ AbstractProduct* CreateObject(const IdentifierType& id)
{
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- typedef typename TypeTraits<P10>::ParameterType Parm10;
- typedef typename TypeTraits<P11>::ParameterType Parm11;
- typedef typename TypeTraits<P12>::ParameterType Parm12;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
- Parm6, Parm7, Parm8, Parm9,Parm10,
- Parm11,Parm12)
- = 0;
- };
-
- template<typename AP, typename Id,
- typename P1,typename P2,typename P3,typename P4,typename P5,
- typename P6,typename P7,typename P8,typename P9,typename P10,
- typename P11,typename P12,typename P13>
- struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13> >
- : public FactoryImplBase
+ typename IdToProductMap::iterator i = associations_.find(id);
+ if (i != associations_.end())
+ return (i->second)( );
+ return this->OnUnknownType(id);
+ }
+
+ AbstractProduct* CreateObject(const IdentifierType& id,
+ Parm1 p1)
{
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- typedef typename TypeTraits<P10>::ParameterType Parm10;
- typedef typename TypeTraits<P11>::ParameterType Parm11;
- typedef typename TypeTraits<P12>::ParameterType Parm12;
- typedef typename TypeTraits<P13>::ParameterType Parm13;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
- Parm6, Parm7, Parm8, Parm9,Parm10,
- Parm11,Parm12,Parm13)
- = 0;
- };
-
- template<typename AP, typename Id,
- typename P1,typename P2,typename P3,typename P4,typename P5,
- typename P6,typename P7,typename P8,typename P9,typename P10,
- typename P11,typename P12,typename P13,typename P14>
- struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14> >
- : public FactoryImplBase
+ typename IdToProductMap::iterator i = associations_.find(id);
+ if (i != associations_.end())
+ return (i->second)( p1 );
+ return this->OnUnknownType(id);
+ }
+
+ AbstractProduct* CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2)
{
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- typedef typename TypeTraits<P10>::ParameterType Parm10;
- typedef typename TypeTraits<P11>::ParameterType Parm11;
- typedef typename TypeTraits<P12>::ParameterType Parm12;
- typedef typename TypeTraits<P13>::ParameterType Parm13;
- typedef typename TypeTraits<P14>::ParameterType Parm14;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
- Parm6, Parm7, Parm8, Parm8,Parm10,
- Parm11,Parm12,Parm13,Parm14)
- = 0;
- };
-
- template<typename AP, typename Id,
- typename P1,typename P2,typename P3,typename P4,typename P5,
- typename P6,typename P7,typename P8,typename P9,typename P10,
- typename P11,typename P12,typename P13,typename P14,typename P15 >
- struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15> >
- : public FactoryImplBase
+ typename IdToProductMap::iterator i = associations_.find(id);
+ if (i != associations_.end())
+ return (i->second)( p1,p2 );
+ return this->OnUnknownType(id);
+ }
+
+ AbstractProduct* CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3)
{
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- typedef typename TypeTraits<P10>::ParameterType Parm10;
- typedef typename TypeTraits<P11>::ParameterType Parm11;
- typedef typename TypeTraits<P12>::ParameterType Parm12;
- typedef typename TypeTraits<P13>::ParameterType Parm13;
- typedef typename TypeTraits<P14>::ParameterType Parm14;
- typedef typename TypeTraits<P15>::ParameterType Parm15;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
- Parm6, Parm7, Parm8, Parm9,Parm10,
- Parm11,Parm12,Parm13,Parm14,Parm15 )
- = 0;
- };
-
-#ifndef LOKI_DISABLE_TYPELIST_MACROS
-
- template <typename AP, typename Id, typename P1 >
- struct FactoryImpl<AP,Id, LOKI_TYPELIST_1( P1 )>
- : public FactoryImplBase
+ typename IdToProductMap::iterator i = associations_.find(id);
+ if (i != associations_.end())
+ return (i->second)( p1,p2,p3 );
+ return this->OnUnknownType(id);
+ }
+
+ AbstractProduct* CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
{
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1 ) = 0;
- };
-
- template<typename AP, typename Id, typename P1,typename P2 >
- struct FactoryImpl<AP, Id, LOKI_TYPELIST_2( P1, P2 )>
- : public FactoryImplBase
+ typename IdToProductMap::iterator i = associations_.find(id);
+ if (i != associations_.end())
+ return (i->second)( p1,p2,p3,p4 );
+ return this->OnUnknownType(id);
+ }
+
+ AbstractProduct* CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
{
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2 ) = 0;
- };
-
- template<typename AP, typename Id, typename P1,typename P2,typename P3 >
- struct FactoryImpl<AP, Id, LOKI_TYPELIST_3( P1, P2, P3 )>
- : public FactoryImplBase
+ typename IdToProductMap::iterator i = associations_.find(id);
+ if (i != associations_.end())
+ return (i->second)( p1,p2,p3,p4,p5 );
+ return this->OnUnknownType(id);
+ }
+
+ AbstractProduct* CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6)
{
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3 ) = 0;
- };
-
- template<typename AP, typename Id, typename P1,typename P2,typename P3,typename P4 >
- struct FactoryImpl<AP, Id, LOKI_TYPELIST_4( P1, P2, P3, P4 )>
- : public FactoryImplBase
+ typename IdToProductMap::iterator i = associations_.find(id);
+ if (i != associations_.end())
+ return (i->second)( p1,p2,p3,p4,p5,p6 );
+ return this->OnUnknownType(id);
+ }
+
+ AbstractProduct* CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7 )
{
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4 ) = 0;
- };
-
- template<typename AP, typename Id,
- typename P1,typename P2,typename P3,typename P4,typename P5 >
- struct FactoryImpl<AP, Id, LOKI_TYPELIST_5( P1, P2, P3, P4, P5 )>
- : public FactoryImplBase
+ typename IdToProductMap::iterator i = associations_.find(id);
+ if (i != associations_.end())
+ return (i->second)( p1,p2,p3,p4,p5,p6,p7 );
+ return this->OnUnknownType(id);
+ }
+
+ AbstractProduct* CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8)
{
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5 ) = 0;
- };
-
- template<typename AP, typename Id,
- typename P1,typename P2,typename P3,typename P4,typename P5,
- typename P6>
- struct FactoryImpl<AP, Id, LOKI_TYPELIST_6( P1, P2, P3, P4, P5, P6 )>
- : public FactoryImplBase
+ typename IdToProductMap::iterator i = associations_.find(id);
+ if (i != associations_.end())
+ return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8 );
+ return this->OnUnknownType(id);
+ }
+
+ AbstractProduct* CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
{
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
- Parm6 )
- = 0;
- };
-
- template<typename AP, typename Id,
- typename P1,typename P2,typename P3,typename P4,typename P5,
- typename P6,typename P7>
- struct FactoryImpl<AP, Id, LOKI_TYPELIST_7( P1, P2, P3, P4, P5, P6, P7 )>
- : public FactoryImplBase
+ typename IdToProductMap::iterator i = associations_.find(id);
+ if (i != associations_.end())
+ return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9 );
+ return this->OnUnknownType(id);
+ }
+ AbstractProduct* CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9,Parm10 p10)
{
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
- Parm6, Parm7 )
- = 0;
- };
-
- template<typename AP, typename Id,
- typename P1,typename P2,typename P3,typename P4,typename P5,
- typename P6,typename P7,typename P8>
- struct FactoryImpl<AP, Id, LOKI_TYPELIST_8( P1, P2, P3, P4, P5, P6, P7, P8 )>
- : public FactoryImplBase
+ typename IdToProductMap::iterator i = associations_.find(id);
+ if (i != associations_.end())
+ return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10 );
+ return this->OnUnknownType(id);
+ }
+
+ AbstractProduct* CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
+ Parm11 p11)
{
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
- Parm6, Parm7, Parm8)
- = 0;
- };
-
- template<typename AP, typename Id,
- typename P1,typename P2,typename P3,typename P4,typename P5,
- typename P6,typename P7,typename P8,typename P9>
- struct FactoryImpl<AP, Id, LOKI_TYPELIST_9( P1, P2, P3, P4, P5, P6, P7, P8, P9 )>
- : public FactoryImplBase
+ typename IdToProductMap::iterator i = associations_.find(id);
+ if (i != associations_.end())
+ return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11 );
+ return this->OnUnknownType(id);
+ }
+
+ AbstractProduct* CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
+ Parm11 p11, Parm12 p12)
{
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
- Parm6, Parm7, Parm8, Parm9)
- = 0;
- };
-
- template<typename AP, typename Id,
- typename P1,typename P2,typename P3,typename P4,typename P5,
- typename P6,typename P7,typename P8,typename P9,typename P10>
- struct FactoryImpl<AP, Id, LOKI_TYPELIST_10( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10 )>
- : public FactoryImplBase
+ typename IdToProductMap::iterator i = associations_.find(id);
+ if (i != associations_.end())
+ return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12 );
+ return this->OnUnknownType(id);
+ }
+
+ AbstractProduct* CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
+ Parm11 p11, Parm12 p12, Parm13 p13)
{
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- typedef typename TypeTraits<P10>::ParameterType Parm10;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
- Parm6, Parm7, Parm8, Parm9,Parm10)
- = 0;
- };
-
- template<typename AP, typename Id,
- typename P1,typename P2,typename P3,typename P4,typename P5,
- typename P6,typename P7,typename P8,typename P9,typename P10,
- typename P11>
- struct FactoryImpl<AP, Id, LOKI_TYPELIST_11( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11 )>
- : public FactoryImplBase
+ typename IdToProductMap::iterator i = associations_.find(id);
+ if (i != associations_.end())
+ return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13 );
+ return this->OnUnknownType(id);
+ }
+
+ AbstractProduct* CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
+ Parm11 p11, Parm12 p12, Parm13 p13, Parm14 p14)
{
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- typedef typename TypeTraits<P10>::ParameterType Parm10;
- typedef typename TypeTraits<P11>::ParameterType Parm11;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
- Parm6, Parm7, Parm8, Parm9,Parm10,
- Parm11)
- = 0;
- };
-
- template<typename AP, typename Id,
- typename P1,typename P2,typename P3,typename P4,typename P5,
- typename P6,typename P7,typename P8,typename P9,typename P10,
- typename P11,typename P12>
- struct FactoryImpl<AP, Id, LOKI_TYPELIST_12( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12 )>
- : public FactoryImplBase
+ typename IdToProductMap::iterator i = associations_.find(id);
+ if (i != associations_.end())
+ return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14 );
+ return this->OnUnknownType(id);
+ }
+
+ AbstractProduct* CreateObject(const IdentifierType& id,
+ Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
+ Parm11 p11, Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
{
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- typedef typename TypeTraits<P10>::ParameterType Parm10;
- typedef typename TypeTraits<P11>::ParameterType Parm11;
- typedef typename TypeTraits<P12>::ParameterType Parm12;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
- Parm6, Parm7, Parm8, Parm9,Parm10,
- Parm11,Parm12)
- = 0;
- };
+ typename IdToProductMap::iterator i = associations_.find(id);
+ if (i != associations_.end())
+ return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15 );
+ return this->OnUnknownType(id);
+ }
- template<typename AP, typename Id,
- typename P1,typename P2,typename P3,typename P4,typename P5,
- typename P6,typename P7,typename P8,typename P9,typename P10,
- typename P11,typename P12,typename P13>
- struct FactoryImpl<AP, Id, LOKI_TYPELIST_13( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13 )>
- : public FactoryImplBase
- {
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- typedef typename TypeTraits<P10>::ParameterType Parm10;
- typedef typename TypeTraits<P11>::ParameterType Parm11;
- typedef typename TypeTraits<P12>::ParameterType Parm12;
- typedef typename TypeTraits<P13>::ParameterType Parm13;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
- Parm6, Parm7, Parm8, Parm9,Parm10,
- Parm11,Parm12,Parm13)
- = 0;
- };
+};
- template<typename AP, typename Id,
- typename P1,typename P2,typename P3,typename P4,typename P5,
- typename P6,typename P7,typename P8,typename P9,typename P10,
- typename P11,typename P12,typename P13,typename P14>
- struct FactoryImpl<AP, Id, LOKI_TYPELIST_14( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14 )>
- : public FactoryImplBase
- {
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- typedef typename TypeTraits<P10>::ParameterType Parm10;
- typedef typename TypeTraits<P11>::ParameterType Parm11;
- typedef typename TypeTraits<P12>::ParameterType Parm12;
- typedef typename TypeTraits<P13>::ParameterType Parm13;
- typedef typename TypeTraits<P14>::ParameterType Parm14;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
- Parm6, Parm7, Parm8, Parm8,Parm10,
- Parm11,Parm12,Parm13,Parm14)
- = 0;
- };
+#else
- template<typename AP, typename Id,
- typename P1,typename P2,typename P3,typename P4,typename P5,
- typename P6,typename P7,typename P8,typename P9,typename P10,
- typename P11,typename P12,typename P13,typename P14,typename P15 >
- struct FactoryImpl<AP, Id, LOKI_TYPELIST_15( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15 )>
- : public FactoryImplBase
+template
+<
+class AbstractProduct,
+ typename IdentifierType,
+ typename ProductCreator = AbstractProduct* (*)(),
+ template<typename, class>
+ class FactoryErrorPolicy = DefaultFactoryError
+ >
+class Factory
+ : public FactoryErrorPolicy<IdentifierType, AbstractProduct>
+{
+public:
+ bool Register(const IdentifierType& id, ProductCreator creator)
{
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- typedef typename TypeTraits<P10>::ParameterType Parm10;
- typedef typename TypeTraits<P11>::ParameterType Parm11;
- typedef typename TypeTraits<P12>::ParameterType Parm12;
- typedef typename TypeTraits<P13>::ParameterType Parm13;
- typedef typename TypeTraits<P14>::ParameterType Parm14;
- typedef typename TypeTraits<P15>::ParameterType Parm15;
- virtual ~FactoryImpl() {}
- virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5,
- Parm6, Parm7, Parm8, Parm9,Parm10,
- Parm11,Parm12,Parm13,Parm14,Parm15 )
- = 0;
- };
-
-#endif //LOKI_DISABLE_TYPELIST_MACROS
-
+ return associations_.insert(
+ typename IdToProductMap::value_type(id, creator)).second != 0;
+ }
-////////////////////////////////////////////////////////////////////////////////
-/// \class Factory
-///
-/// \ingroup FactoryGroup
-/// Implements a generic object factory.
-///
-/// Create functions can have up to 15 parameters.
-///
-/// \par Singleton lifetime when used with Loki::SingletonHolder
-/// Because Factory uses internally Functors which inherits from
-/// SmallObject you must use the singleton lifetime
-/// \code Loki::LongevityLifetime::DieAsSmallObjectChild \endcode
-/// Alternatively you could suppress for Functor the inheritance
-/// from SmallObject by defining the macro:
-/// \code LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT \endcode
-////////////////////////////////////////////////////////////////////////////////
- template
- <
- class AbstractProduct,
- typename IdentifierType,
- typename CreatorParmTList = NullType,
- template<typename, class> class FactoryErrorPolicy = DefaultFactoryError
- >
- class Factory : public FactoryErrorPolicy<IdentifierType, AbstractProduct>
+ bool Unregister(const IdentifierType& id)
{
- typedef FactoryImpl< AbstractProduct, IdentifierType, CreatorParmTList > Impl;
-
- typedef typename Impl::Parm1 Parm1;
- typedef typename Impl::Parm2 Parm2;
- typedef typename Impl::Parm3 Parm3;
- typedef typename Impl::Parm4 Parm4;
- typedef typename Impl::Parm5 Parm5;
- typedef typename Impl::Parm6 Parm6;
- typedef typename Impl::Parm7 Parm7;
- typedef typename Impl::Parm8 Parm8;
- typedef typename Impl::Parm9 Parm9;
- typedef typename Impl::Parm10 Parm10;
- typedef typename Impl::Parm11 Parm11;
- typedef typename Impl::Parm12 Parm12;
- typedef typename Impl::Parm13 Parm13;
- typedef typename Impl::Parm14 Parm14;
- typedef typename Impl::Parm15 Parm15;
-
- typedef Functor<AbstractProduct*, CreatorParmTList> ProductCreator;
-
- typedef AssocVector<IdentifierType, ProductCreator> IdToProductMap;
-
- IdToProductMap associations_;
-
- public:
-
- Factory()
- : associations_()
- {
- }
+ return associations_.erase(id) != 0;
+ }
- ~Factory()
- {
- associations_.erase(associations_.begin(), associations_.end());
- }
-
- bool Register(const IdentifierType& id, ProductCreator creator)
- {
- return associations_.insert(
- typename IdToProductMap::value_type(id, creator)).second != 0;
- }
-
- template <class PtrObj, typename CreaFn>
- bool Register(const IdentifierType& id, const PtrObj& p, CreaFn fn)
- {
- ProductCreator creator( p, fn );
- return associations_.insert(
- typename IdToProductMap::value_type(id, creator)).second != 0;
- }
-
- bool Unregister(const IdentifierType& id)
- {
- return associations_.erase(id) != 0;
- }
-
- std::vector<IdentifierType> RegisteredIds()
- {
- std::vector<IdentifierType> ids;
- for(typename IdToProductMap::iterator it = associations_.begin();
- it != associations_.end(); ++it)
- {
- ids.push_back(it->first);
- }
- return ids;
- }
-
- AbstractProduct* CreateObject(const IdentifierType& id)
- {
- typename IdToProductMap::iterator i = associations_.find(id);
- if (i != associations_.end())
- return (i->second)( );
- return this->OnUnknownType(id);
- }
-
- AbstractProduct* CreateObject(const IdentifierType& id,
- Parm1 p1)
- {
- typename IdToProductMap::iterator i = associations_.find(id);
- if (i != associations_.end())
- return (i->second)( p1 );
- return this->OnUnknownType(id);
- }
-
- AbstractProduct* CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2)
- {
- typename IdToProductMap::iterator i = associations_.find(id);
- if (i != associations_.end())
- return (i->second)( p1,p2 );
- return this->OnUnknownType(id);
- }
-
- AbstractProduct* CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3)
- {
- typename IdToProductMap::iterator i = associations_.find(id);
- if (i != associations_.end())
- return (i->second)( p1,p2,p3 );
- return this->OnUnknownType(id);
- }
-
- AbstractProduct* CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
- {
- typename IdToProductMap::iterator i = associations_.find(id);
- if (i != associations_.end())
- return (i->second)( p1,p2,p3,p4 );
- return this->OnUnknownType(id);
- }
-
- AbstractProduct* CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
- {
- typename IdToProductMap::iterator i = associations_.find(id);
- if (i != associations_.end())
- return (i->second)( p1,p2,p3,p4,p5 );
- return this->OnUnknownType(id);
- }
-
- AbstractProduct* CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6)
- {
- typename IdToProductMap::iterator i = associations_.find(id);
- if (i != associations_.end())
- return (i->second)( p1,p2,p3,p4,p5,p6 );
- return this->OnUnknownType(id);
- }
-
- AbstractProduct* CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7 )
- {
- typename IdToProductMap::iterator i = associations_.find(id);
- if (i != associations_.end())
- return (i->second)( p1,p2,p3,p4,p5,p6,p7 );
- return this->OnUnknownType(id);
- }
-
- AbstractProduct* CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8)
- {
- typename IdToProductMap::iterator i = associations_.find(id);
- if (i != associations_.end())
- return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8 );
- return this->OnUnknownType(id);
- }
-
- AbstractProduct* CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
- {
- typename IdToProductMap::iterator i = associations_.find(id);
- if (i != associations_.end())
- return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9 );
- return this->OnUnknownType(id);
- }
- AbstractProduct* CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9,Parm10 p10)
- {
- typename IdToProductMap::iterator i = associations_.find(id);
- if (i != associations_.end())
- return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10 );
- return this->OnUnknownType(id);
- }
-
- AbstractProduct* CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
- Parm11 p11)
- {
- typename IdToProductMap::iterator i = associations_.find(id);
- if (i != associations_.end())
- return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11 );
- return this->OnUnknownType(id);
- }
-
- AbstractProduct* CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
- Parm11 p11, Parm12 p12)
- {
- typename IdToProductMap::iterator i = associations_.find(id);
- if (i != associations_.end())
- return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12 );
- return this->OnUnknownType(id);
- }
-
- AbstractProduct* CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
- Parm11 p11, Parm12 p12, Parm13 p13)
- {
- typename IdToProductMap::iterator i = associations_.find(id);
- if (i != associations_.end())
- return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13 );
- return this->OnUnknownType(id);
- }
-
- AbstractProduct* CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
- Parm11 p11, Parm12 p12, Parm13 p13, Parm14 p14)
- {
- typename IdToProductMap::iterator i = associations_.find(id);
- if (i != associations_.end())
- return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14 );
- return this->OnUnknownType(id);
- }
-
- AbstractProduct* CreateObject(const IdentifierType& id,
- Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10,
- Parm11 p11, Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
- {
- typename IdToProductMap::iterator i = associations_.find(id);
- if (i != associations_.end())
- return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15 );
- return this->OnUnknownType(id);
- }
-
- };
-
-#else
-
- template
- <
- class AbstractProduct,
- typename IdentifierType,
- typename ProductCreator = AbstractProduct* (*)(),
- template<typename, class>
- class FactoryErrorPolicy = DefaultFactoryError
- >
- class Factory
- : public FactoryErrorPolicy<IdentifierType, AbstractProduct>
+ AbstractProduct* CreateObject(const IdentifierType& id)
{
- public:
- bool Register(const IdentifierType& id, ProductCreator creator)
- {
- return associations_.insert(
- typename IdToProductMap::value_type(id, creator)).second != 0;
- }
-
- bool Unregister(const IdentifierType& id)
+ typename IdToProductMap::iterator i = associations_.find(id);
+ if (i != associations_.end())
{
- return associations_.erase(id) != 0;
+ return (i->second)();
}
+ return this->OnUnknownType(id);
+ }
- AbstractProduct* CreateObject(const IdentifierType& id)
- {
- typename IdToProductMap::iterator i = associations_.find(id);
- if (i != associations_.end())
- {
- return (i->second)();
- }
- return this->OnUnknownType(id);
- }
-
- private:
- typedef AssocVector<IdentifierType, ProductCreator> IdToProductMap;
- IdToProductMap associations_;
- };
+private:
+ typedef AssocVector<IdentifierType, ProductCreator> IdToProductMap;
+ IdToProductMap associations_;
+};
#endif //#define ENABLE_NEW_FACTORY_CODE
@@ -1028,51 +1028,51 @@ template <typename AP, typename Id, typename P1 >
* \brief Creates a copy from a polymorphic object.
*/
- template
- <
- class AbstractProduct,
- class ProductCreator =
- AbstractProduct* (*)(const AbstractProduct*),
- template<typename, class>
- class FactoryErrorPolicy = DefaultFactoryError
- >
- class CloneFactory
- : public FactoryErrorPolicy<TypeInfo, AbstractProduct>
+template
+<
+class AbstractProduct,
+ class ProductCreator =
+ AbstractProduct* (*)(const AbstractProduct*),
+ template<typename, class>
+ class FactoryErrorPolicy = DefaultFactoryError
+ >
+class CloneFactory
+ : public FactoryErrorPolicy<TypeInfo, AbstractProduct>
+{
+public:
+ bool Register(const TypeInfo& ti, ProductCreator creator)
{
- public:
- bool Register(const TypeInfo& ti, ProductCreator creator)
- {
- return associations_.insert(
- typename IdToProductMap::value_type(ti, creator)).second != 0;
- }
+ return associations_.insert(
+ typename IdToProductMap::value_type(ti, creator)).second != 0;
+ }
+
+ bool Unregister(const TypeInfo& id)
+ {
+ return associations_.erase(id) != 0;
+ }
- bool Unregister(const TypeInfo& id)
+ AbstractProduct* CreateObject(const AbstractProduct* model)
+ {
+ if (model == NULL)
{
- return associations_.erase(id) != 0;
+ return NULL;
}
- AbstractProduct* CreateObject(const AbstractProduct* model)
+ typename IdToProductMap::iterator i =
+ associations_.find(typeid(*model));
+
+ if (i != associations_.end())
{
- if (model == NULL)
- {
- return NULL;
- }
-
- typename IdToProductMap::iterator i =
- associations_.find(typeid(*model));
-
- if (i != associations_.end())
- {
- return (i->second)(model);
- }
- return this->OnUnknownType(typeid(*model));
+ return (i->second)(model);
}
+ return this->OnUnknownType(typeid(*model));
+ }
+
+private:
+ typedef AssocVector<TypeInfo, ProductCreator> IdToProductMap;
+ IdToProductMap associations_;
+};
- private:
- typedef AssocVector<TypeInfo, ProductCreator> IdToProductMap;
- IdToProductMap associations_;
- };
-
} // namespace Loki
diff --git a/shared/loki/Function.h b/shared/loki/Function.h
index 2d0ad4bb..f2badfe9 100644
--- a/shared/loki/Function.h
+++ b/shared/loki/Function.h
@@ -1,12 +1,12 @@
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2005 Peter Kümmel
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author makes no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author makes no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_FUNCTION_INC_
@@ -25,63 +25,63 @@
namespace Loki
{
- ////////////////////////////////////////////////////////////////////////////////
- /// \struct Function
- ///
- /// \ingroup FunctorGroup
- /// Allows a boost/TR1 like usage of Functor.
- ///
- /// \par Usage
- ///
- /// - free functions: e.g. \code Function<int(int,int)> f(&freeFunction);
- /// \endcode
- /// - member functions: e.g \code Function<int()> f(&object,&ObjectType::memberFunction);
- /// \endcode
- ///
- /// see also test/Function/FunctionTest.cpp (the modified test program from boost)
- ////////////////////////////////////////////////////////////////////////////////
-
- template<class R = void()>
- struct Function;
-
-
- template<class R>
- struct Function<R()> : public Functor<R>
- {
- typedef Functor<R> FBase;
-
- Function() : FBase() {}
-
- Function(const Function& func) : FBase()
- {
- if( !func.empty())
- FBase::operator=(func);
- }
-
- // test on emptiness
- template<class R2>
- Function(Function<R2()> func) : FBase()
- {
- if(!func.empty())
- FBase::operator=(func);
- }
-
- // clear by '= 0'
- Function(const int i) : FBase()
- {
- if(i==0)
- FBase::clear();
- else
- throw std::runtime_error("Loki::Function(const int i): i!=0");
- }
-
- template<class Func>
- Function(Func func) : FBase(func) {}
+////////////////////////////////////////////////////////////////////////////////
+/// \struct Function
+///
+/// \ingroup FunctorGroup
+/// Allows a boost/TR1 like usage of Functor.
+///
+/// \par Usage
+///
+/// - free functions: e.g. \code Function<int(int,int)> f(&freeFunction);
+/// \endcode
+/// - member functions: e.g \code Function<int()> f(&object,&ObjectType::memberFunction);
+/// \endcode
+///
+/// see also test/Function/FunctionTest.cpp (the modified test program from boost)
+////////////////////////////////////////////////////////////////////////////////
+
+template<class R = void()>
+struct Function;
+
+
+template<class R>
+struct Function<R()> : public Functor<R>
+{
+ typedef Functor<R> FBase;
- template<class Host, class Func>
- Function(const Host& host, const Func& func) : FBase(host,func) {}
+ Function() : FBase() {}
- };
+Function(const Function& func) : FBase()
+{
+ if( !func.empty())
+ FBase::operator=(func);
+}
+
+// test on emptiness
+template<class R2>
+Function(Function<R2()> func) : FBase()
+{
+ if(!func.empty())
+ FBase::operator=(func);
+}
+
+// clear by '= 0'
+Function(const int i) : FBase()
+{
+ if(i==0)
+ FBase::clear();
+ else
+ throw std::runtime_error("Loki::Function(const int i): i!=0");
+}
+
+template<class Func>
+Function(Func func) : FBase(func) {}
+
+template<class Host, class Func>
+Function(const Host& host, const Func& func) : FBase(host,func) {}
+
+};
////////////////////////////////////////////////////////////////////////////////
@@ -113,7 +113,7 @@ namespace Loki
template<class Host, class Func> \
Function(const Host& host, const Func& func): FBase(host,func) {}
-
+
#define LOKI_FUNCTION_R2_CTOR_BODY \
\
: FBase() \
@@ -127,245 +127,245 @@ namespace Loki
// repetitions
////////////////////////////////////////////////////////////////////////////////
- template<>
- struct Function<>
+template<>
+struct Function<>
: public Loki::Functor<>
- {
- typedef Functor<> FBase;
-
- template<class R2>
- Function(Function<R2()> func)
- LOKI_FUNCTION_R2_CTOR_BODY
-
- LOKI_FUNCTION_BODY // if compilation breaks here then
- // Function.h was not included before
- // Functor.h, check your include order
- // or define LOKI_ENABLE_FUNCTION
- };
-
- template<class R,class P01>
- struct Function<R(P01)>
- : public Loki::Functor<R, Seq<P01> >
- {
- typedef Functor<R, Seq<P01> > FBase;
-
- template<class R2,class Q01>
- Function(Function<R2(Q01)> func)
- LOKI_FUNCTION_R2_CTOR_BODY
-
- LOKI_FUNCTION_BODY
- };
-
- template<class R,class P01,class P02>
- struct Function<R(P01,P02)>
- : public Functor<R, Seq<P01,P02> >
- {
- typedef Functor<R, Seq<P01,P02> > FBase;
-
- template<class R2,class Q01, class Q02>
- Function(Function<R2(Q01,Q02)> func)
- LOKI_FUNCTION_R2_CTOR_BODY
-
- LOKI_FUNCTION_BODY
- };
-
- template<class R,class P01,class P02, class P03>
- struct Function<R(P01,P02,P03)>
- : public Functor<R, Seq<P01,P02,P03> >
- {
- typedef Functor<R, Seq<P01,P02,P03> > FBase;
-
- template<class R2,class Q01, class Q02,class Q03>
- Function(Function<R2(Q01,Q02,Q03)> func)
- LOKI_FUNCTION_R2_CTOR_BODY
-
- LOKI_FUNCTION_BODY
- };
-
- template<class R,class P01,class P02, class P03,class P04>
- struct Function<R(P01,P02,P03,P04)>
- : public Functor<R, Seq<P01,P02,P03,P04> >
- {
- typedef Functor<R, Seq<P01,P02,P03,P04> > FBase;
-
- template<class R2,class Q01,class Q02, class Q03,class Q04>
- Function(Function<R2(Q01,Q02,Q03,Q04)> func)
- LOKI_FUNCTION_R2_CTOR_BODY
-
- LOKI_FUNCTION_BODY
- };
-
- template<class R,class P01,class P02, class P03,class P04,class P05>
- struct Function<R(P01,P02,P03,P04,P05)>
- : public Functor<R, Seq<P01,P02,P03,P04,P05> >
- {
- typedef Functor<R, Seq<P01,P02,P03,P04,P05> > FBase;
-
- template<class R2,class Q01,class Q02, class Q03,class Q04,class Q05>
- Function(Function<R2(Q01,Q02,Q03,Q04,Q05)> func)
- LOKI_FUNCTION_R2_CTOR_BODY
-
- LOKI_FUNCTION_BODY
- };
-
- template<class R, class P01,class P02, class P03,class P04,class P05,
- class P06>
- struct Function<R(P01,P02,P03,P04,P05,P06)>
- : public Functor<R, Seq<P01,P02,P03,P04,P05,P06> >
- {
- typedef Functor<R, Seq<P01,P02,P03,P04,P05,P06> > FBase;
-
- template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
- class Q06>
- Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06)> func)
- LOKI_FUNCTION_R2_CTOR_BODY
-
- LOKI_FUNCTION_BODY
- };
-
- template<class R, class P01,class P02, class P03,class P04,class P05,
- class P06,class P07>
- struct Function<R(P01,P02,P03,P04,P05,P06,P07)>
- : public Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07> >
- {
- typedef Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07> > FBase;
-
- template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
- class Q06,class Q07>
- Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07)> func)
- LOKI_FUNCTION_R2_CTOR_BODY
-
- LOKI_FUNCTION_BODY
- };
-
- template<class R, class P01,class P02, class P03,class P04,class P05,
- class P06,class P07, class P08>
- struct Function<R(P01,P02,P03,P04,P05,P06,P07,P08)>
- : public Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08> >
- {
- typedef Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08> > FBase;
-
- template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
- class Q06,class Q07, class Q08>
- Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07,Q08)> func)
- LOKI_FUNCTION_R2_CTOR_BODY
-
- LOKI_FUNCTION_BODY
- };
-
- template<class R, class P01,class P02, class P03,class P04,class P05,
- class P06,class P07, class P08,class P09>
- struct Function<R(P01,P02,P03,P04,P05,P06,P07,P08,P09)>
- : public Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09> >
- {
- typedef Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09 > > FBase;
-
- template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
- class Q06,class Q07, class Q08,class Q09>
- Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07,Q08,Q09)> func)
- LOKI_FUNCTION_R2_CTOR_BODY
-
- LOKI_FUNCTION_BODY
- };
-
- template<class R, class P01,class P02, class P03,class P04,class P05,
- class P06,class P07, class P08,class P09,class P10>
- struct Function<R(P01,P02,P03,P04,P05,P06,P07,P08,P09,P10)>
- : public Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10> >
- {
- typedef Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10> > FBase;
-
- template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
- class Q06,class Q07, class Q08,class Q09,class Q10>
- Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07,Q08,Q09,Q10)> func)
- LOKI_FUNCTION_R2_CTOR_BODY
-
- LOKI_FUNCTION_BODY
- };
-
- template<class R, class P01,class P02, class P03,class P04,class P05,
- class P06,class P07, class P08,class P09,class P10,
- class P11>
- struct Function<R(P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11)>
- : public Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11> >
- {
- typedef Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11> >FBase;
-
- template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
- class Q06,class Q07, class Q08,class Q09,class Q10,
- class Q11>
- Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07,Q08,Q09,Q10,Q11)> func)
- LOKI_FUNCTION_R2_CTOR_BODY
-
- LOKI_FUNCTION_BODY
- };
-
- template<class R, class P01,class P02, class P03,class P04,class P05,
- class P06,class P07, class P08,class P09,class P10,
- class P11,class P12>
- struct Function<R(P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12)>
- : public Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12> >
- {
- typedef Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12> > FBase;
-
- template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
- class Q06,class Q07, class Q08,class Q09,class Q10,
- class Q11,class Q12>
- Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07,Q08,Q09,Q10,Q11,Q12)> func)
- LOKI_FUNCTION_R2_CTOR_BODY
-
- LOKI_FUNCTION_BODY
- };
-
- template<class R, class P01,class P02, class P03,class P04,class P05,
- class P06,class P07, class P08,class P09,class P10,
- class P11,class P12, class P13>
- struct Function<R(P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13)>
- : public Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13> >
- {
- typedef Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13> > FBase;
-
- template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
- class Q06,class Q07, class Q08,class Q09,class Q10,
- class Q11,class Q12, class Q13>
- Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07,Q08,Q09,Q10,Q11,Q12,Q13)> func)
- LOKI_FUNCTION_R2_CTOR_BODY
-
- LOKI_FUNCTION_BODY
- };
-
- template<class R, class P01,class P02, class P03,class P04,class P05,
- class P06,class P07, class P08,class P09,class P10,
- class P11,class P12, class P13,class P14>
- struct Function<R(P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13,P14)>
- : public Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13,P14> >
- {
- typedef Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13,P14> > FBase;
- template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
- class Q06,class Q07, class Q08,class Q09,class Q10,
- class Q11,class Q12, class Q13,class Q14>
- Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07,Q08,Q09,Q10,Q11,Q12,Q13,Q14)> func)
- LOKI_FUNCTION_R2_CTOR_BODY
-
- LOKI_FUNCTION_BODY
- };
-
- template<class R, class P01,class P02, class P03,class P04,class P05,
- class P06,class P07, class P08,class P09,class P10,
- class P11,class P12, class P13,class P14,class P15>
- struct Function<R(P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13,P14,P15)>
- : public Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13,P14,P15> >
- {
- typedef Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13,P14,P15> > FBase;
-
- template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
- class Q06,class Q07, class Q08,class Q09,class Q10,
- class Q11,class Q12, class Q13,class Q14,class Q15>
- Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07,Q08,Q09,Q10,Q11,Q12,Q13,Q14,Q15)> func)
- LOKI_FUNCTION_R2_CTOR_BODY
-
- LOKI_FUNCTION_BODY
- };
+{
+ typedef Functor<> FBase;
+
+ template<class R2>
+ Function(Function<R2()> func)
+ LOKI_FUNCTION_R2_CTOR_BODY
+
+ LOKI_FUNCTION_BODY // if compilation breaks here then
+ // Function.h was not included before
+ // Functor.h, check your include order
+ // or define LOKI_ENABLE_FUNCTION
+};
+
+template<class R,class P01>
+struct Function<R(P01)>
+: public Loki::Functor<R, Seq<P01> >
+{
+ typedef Functor<R, Seq<P01> > FBase;
+
+ template<class R2,class Q01>
+ Function(Function<R2(Q01)> func)
+ LOKI_FUNCTION_R2_CTOR_BODY
+
+ LOKI_FUNCTION_BODY
+};
+
+template<class R,class P01,class P02>
+struct Function<R(P01,P02)>
+: public Functor<R, Seq<P01,P02> >
+{
+ typedef Functor<R, Seq<P01,P02> > FBase;
+
+ template<class R2,class Q01, class Q02>
+ Function(Function<R2(Q01,Q02)> func)
+ LOKI_FUNCTION_R2_CTOR_BODY
+
+ LOKI_FUNCTION_BODY
+};
+
+template<class R,class P01,class P02, class P03>
+struct Function<R(P01,P02,P03)>
+: public Functor<R, Seq<P01,P02,P03> >
+{
+ typedef Functor<R, Seq<P01,P02,P03> > FBase;
+
+ template<class R2,class Q01, class Q02,class Q03>
+ Function(Function<R2(Q01,Q02,Q03)> func)
+ LOKI_FUNCTION_R2_CTOR_BODY
+
+ LOKI_FUNCTION_BODY
+};
+
+template<class R,class P01,class P02, class P03,class P04>
+struct Function<R(P01,P02,P03,P04)>
+: public Functor<R, Seq<P01,P02,P03,P04> >
+{
+ typedef Functor<R, Seq<P01,P02,P03,P04> > FBase;
+
+ template<class R2,class Q01,class Q02, class Q03,class Q04>
+ Function(Function<R2(Q01,Q02,Q03,Q04)> func)
+ LOKI_FUNCTION_R2_CTOR_BODY
+
+ LOKI_FUNCTION_BODY
+};
+
+template<class R,class P01,class P02, class P03,class P04,class P05>
+struct Function<R(P01,P02,P03,P04,P05)>
+: public Functor<R, Seq<P01,P02,P03,P04,P05> >
+{
+ typedef Functor<R, Seq<P01,P02,P03,P04,P05> > FBase;
+
+ template<class R2,class Q01,class Q02, class Q03,class Q04,class Q05>
+ Function(Function<R2(Q01,Q02,Q03,Q04,Q05)> func)
+ LOKI_FUNCTION_R2_CTOR_BODY
+
+ LOKI_FUNCTION_BODY
+};
+
+template<class R, class P01,class P02, class P03,class P04,class P05,
+ class P06>
+struct Function<R(P01,P02,P03,P04,P05,P06)>
+: public Functor<R, Seq<P01,P02,P03,P04,P05,P06> >
+{
+ typedef Functor<R, Seq<P01,P02,P03,P04,P05,P06> > FBase;
+
+ template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
+ class Q06>
+ Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06)> func)
+ LOKI_FUNCTION_R2_CTOR_BODY
+
+ LOKI_FUNCTION_BODY
+};
+
+template<class R, class P01,class P02, class P03,class P04,class P05,
+ class P06,class P07>
+struct Function<R(P01,P02,P03,P04,P05,P06,P07)>
+: public Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07> >
+{
+ typedef Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07> > FBase;
+
+ template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
+ class Q06,class Q07>
+ Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07)> func)
+ LOKI_FUNCTION_R2_CTOR_BODY
+
+ LOKI_FUNCTION_BODY
+};
+
+template<class R, class P01,class P02, class P03,class P04,class P05,
+ class P06,class P07, class P08>
+struct Function<R(P01,P02,P03,P04,P05,P06,P07,P08)>
+: public Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08> >
+{
+ typedef Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08> > FBase;
+
+ template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
+ class Q06,class Q07, class Q08>
+ Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07,Q08)> func)
+ LOKI_FUNCTION_R2_CTOR_BODY
+
+ LOKI_FUNCTION_BODY
+};
+
+template<class R, class P01,class P02, class P03,class P04,class P05,
+ class P06,class P07, class P08,class P09>
+struct Function<R(P01,P02,P03,P04,P05,P06,P07,P08,P09)>
+: public Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09> >
+{
+ typedef Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09 > > FBase;
+
+ template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
+ class Q06,class Q07, class Q08,class Q09>
+ Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07,Q08,Q09)> func)
+ LOKI_FUNCTION_R2_CTOR_BODY
+
+ LOKI_FUNCTION_BODY
+};
+
+template<class R, class P01,class P02, class P03,class P04,class P05,
+ class P06,class P07, class P08,class P09,class P10>
+struct Function<R(P01,P02,P03,P04,P05,P06,P07,P08,P09,P10)>
+: public Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10> >
+{
+ typedef Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10> > FBase;
+
+ template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
+ class Q06,class Q07, class Q08,class Q09,class Q10>
+ Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07,Q08,Q09,Q10)> func)
+ LOKI_FUNCTION_R2_CTOR_BODY
+
+ LOKI_FUNCTION_BODY
+};
+
+template<class R, class P01,class P02, class P03,class P04,class P05,
+ class P06,class P07, class P08,class P09,class P10,
+ class P11>
+struct Function<R(P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11)>
+: public Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11> >
+{
+ typedef Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11> >FBase;
+
+ template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
+ class Q06,class Q07, class Q08,class Q09,class Q10,
+ class Q11>
+ Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07,Q08,Q09,Q10,Q11)> func)
+ LOKI_FUNCTION_R2_CTOR_BODY
+
+ LOKI_FUNCTION_BODY
+};
+
+template<class R, class P01,class P02, class P03,class P04,class P05,
+ class P06,class P07, class P08,class P09,class P10,
+ class P11,class P12>
+struct Function<R(P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12)>
+: public Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12> >
+{
+ typedef Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12> > FBase;
+
+ template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
+ class Q06,class Q07, class Q08,class Q09,class Q10,
+ class Q11,class Q12>
+ Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07,Q08,Q09,Q10,Q11,Q12)> func)
+ LOKI_FUNCTION_R2_CTOR_BODY
+
+ LOKI_FUNCTION_BODY
+};
+
+template<class R, class P01,class P02, class P03,class P04,class P05,
+ class P06,class P07, class P08,class P09,class P10,
+ class P11,class P12, class P13>
+struct Function<R(P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13)>
+: public Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13> >
+{
+ typedef Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13> > FBase;
+
+ template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
+ class Q06,class Q07, class Q08,class Q09,class Q10,
+ class Q11,class Q12, class Q13>
+ Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07,Q08,Q09,Q10,Q11,Q12,Q13)> func)
+ LOKI_FUNCTION_R2_CTOR_BODY
+
+ LOKI_FUNCTION_BODY
+};
+
+template<class R, class P01,class P02, class P03,class P04,class P05,
+ class P06,class P07, class P08,class P09,class P10,
+ class P11,class P12, class P13,class P14>
+struct Function<R(P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13,P14)>
+: public Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13,P14> >
+{
+ typedef Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13,P14> > FBase;
+ template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
+ class Q06,class Q07, class Q08,class Q09,class Q10,
+ class Q11,class Q12, class Q13,class Q14>
+ Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07,Q08,Q09,Q10,Q11,Q12,Q13,Q14)> func)
+ LOKI_FUNCTION_R2_CTOR_BODY
+
+ LOKI_FUNCTION_BODY
+};
+
+template<class R, class P01,class P02, class P03,class P04,class P05,
+ class P06,class P07, class P08,class P09,class P10,
+ class P11,class P12, class P13,class P14,class P15>
+struct Function<R(P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13,P14,P15)>
+: public Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13,P14,P15> >
+{
+ typedef Functor<R, Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13,P14,P15> > FBase;
+
+ template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
+ class Q06,class Q07, class Q08,class Q09,class Q10,
+ class Q11,class Q12, class Q13,class Q14,class Q15>
+ Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07,Q08,Q09,Q10,Q11,Q12,Q13,Q14,Q15)> func)
+ LOKI_FUNCTION_R2_CTOR_BODY
+
+ LOKI_FUNCTION_BODY
+};
}// namespace Loki
diff --git a/shared/loki/Functor.h b/shared/loki/Functor.h
index bcba855d..a03f87c8 100644
--- a/shared/loki/Functor.h
+++ b/shared/loki/Functor.h
@@ -2,14 +2,14 @@
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
-// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author or Addison-Wesley Longman make no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author or Addison-Wesley Longman make no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_FUNCTOR_INC_
@@ -45,65 +45,66 @@ namespace Loki
// class template FunctorImpl (internal)
////////////////////////////////////////////////////////////////////////////////
- namespace Private
- {
- template <typename R, template <class, class> class ThreadingModel>
- struct FunctorImplBase
+namespace Private
+{
+template <typename R, template <class, class> class ThreadingModel>
+struct FunctorImplBase
#ifdef LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT
- {
+{
#else
- : public SmallValueObject<ThreadingModel>
- {
- inline FunctorImplBase() :
- SmallValueObject<ThreadingModel>() {}
- inline FunctorImplBase(const FunctorImplBase&) :
- SmallValueObject<ThreadingModel>() {}
+ :
+ public SmallValueObject<ThreadingModel>
+{
+ inline FunctorImplBase() :
+ SmallValueObject<ThreadingModel>() {}
+ inline FunctorImplBase(const FunctorImplBase&) :
+ SmallValueObject<ThreadingModel>() {}
#endif
- typedef R ResultType;
- typedef FunctorImplBase<R, ThreadingModel> FunctorImplBaseType;
-
- typedef EmptyType Parm1;
- typedef EmptyType Parm2;
- typedef EmptyType Parm3;
- typedef EmptyType Parm4;
- typedef EmptyType Parm5;
- typedef EmptyType Parm6;
- typedef EmptyType Parm7;
- typedef EmptyType Parm8;
- typedef EmptyType Parm9;
- typedef EmptyType Parm10;
- typedef EmptyType Parm11;
- typedef EmptyType Parm12;
- typedef EmptyType Parm13;
- typedef EmptyType Parm14;
- typedef EmptyType Parm15;
-
-
- virtual ~FunctorImplBase()
- {}
-
- virtual FunctorImplBase* DoClone() const = 0;
-
- template <class U>
- static U* Clone(U* pObj)
- {
- if (!pObj) return 0;
- U* pClone = static_cast<U*>(pObj->DoClone());
- assert(typeid(*pClone) == typeid(*pObj));
- return pClone;
- }
+ typedef R ResultType;
+ typedef FunctorImplBase<R, ThreadingModel> FunctorImplBaseType;
+
+ typedef EmptyType Parm1;
+ typedef EmptyType Parm2;
+ typedef EmptyType Parm3;
+ typedef EmptyType Parm4;
+ typedef EmptyType Parm5;
+ typedef EmptyType Parm6;
+ typedef EmptyType Parm7;
+ typedef EmptyType Parm8;
+ typedef EmptyType Parm9;
+ typedef EmptyType Parm10;
+ typedef EmptyType Parm11;
+ typedef EmptyType Parm12;
+ typedef EmptyType Parm13;
+ typedef EmptyType Parm14;
+ typedef EmptyType Parm15;
+
+
+ virtual ~FunctorImplBase()
+ {}
+
+ virtual FunctorImplBase* DoClone() const = 0;
+
+ template <class U>
+ static U* Clone(U* pObj)
+ {
+ if (!pObj) return 0;
+ U* pClone = static_cast<U*>(pObj->DoClone());
+ assert(typeid(*pClone) == typeid(*pObj));
+ return pClone;
+ }
#ifdef LOKI_FUNCTORS_ARE_COMPARABLE
- virtual bool operator==(const FunctorImplBase&) const = 0;
-
-#endif
-
- };
- }
-
+ virtual bool operator==(const FunctorImplBase&) const = 0;
+
+#endif
+
+};
+}
+
////////////////////////////////////////////////////////////////////////////////
// macro LOKI_DEFINE_CLONE_FUNCTORIMPL
// Implements the DoClone function for a functor implementation
@@ -121,409 +122,409 @@ namespace Loki
// Specializations of FunctorImpl for up to 15 parameters follow
////////////////////////////////////////////////////////////////////////////////
- template <typename R, class TList,
- template <class, class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL>
- class FunctorImpl;
+template <typename R, class TList,
+ template <class, class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL>
+class FunctorImpl;
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 0 (zero) parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, template <class, class> class ThreadingModel>
- class FunctorImpl<R, NullType, ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- virtual R operator()() = 0;
- };
+template <typename R, template <class, class> class ThreadingModel>
+class FunctorImpl<R, NullType, ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ virtual R operator()() = 0;
+};
- ////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 1 parameter
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, template <class, class> class ThreadingModel>
- class FunctorImpl<R, Seq<P1>, ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- virtual R operator()(Parm1) = 0;
- };
+template <typename R, typename P1, template <class, class> class ThreadingModel>
+class FunctorImpl<R, Seq<P1>, ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ virtual R operator()(Parm1) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 2 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R, Seq<P1, P2>, ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- virtual R operator()(Parm1, Parm2) = 0;
- };
+template <typename R, typename P1, typename P2,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R, Seq<P1, P2>, ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ virtual R operator()(Parm1, Parm2) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 3 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R, Seq<P1, P2, P3>, ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- virtual R operator()(Parm1, Parm2, Parm3) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R, Seq<P1, P2, P3>, ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ virtual R operator()(Parm1, Parm2, Parm3) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 4 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3, typename P4,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R, Seq<P1, P2, P3, P4>, ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- virtual R operator()(Parm1, Parm2, Parm3, Parm4) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R, Seq<P1, P2, P3, P4>, ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ virtual R operator()(Parm1, Parm2, Parm3, Parm4) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 5 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3, typename P4,
- typename P5,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R, Seq<P1, P2, P3, P4, P5>, ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R, Seq<P1, P2, P3, P4, P5>, ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 6 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3, typename P4,
- typename P5, typename P6,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R, Seq<P1, P2, P3, P4, P5, P6>, ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R, Seq<P1, P2, P3, P4, P5, P6>, ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 7 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3, typename P4,
- typename P5, typename P6, typename P7,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R, Seq<P1, P2, P3, P4, P5, P6, P7>, ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
- Parm7) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename P7,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R, Seq<P1, P2, P3, P4, P5, P6, P7>, ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
+ Parm7) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 8 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3, typename P4,
- typename P5, typename P6, typename P7, typename P8,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R, Seq<P1, P2, P3, P4, P5, P6, P7, P8>,
- ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
- Parm7, Parm8) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename P7, typename P8,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R, Seq<P1, P2, P3, P4, P5, P6, P7, P8>,
+ ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
+ Parm7, Parm8) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 9 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3, typename P4,
- typename P5, typename P6, typename P7, typename P8, typename P9,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9>,
- ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
- Parm7, Parm8, Parm9) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename P7, typename P8, typename P9,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9>,
+ ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
+ Parm7, Parm8, Parm9) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 10 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3, typename P4,
- typename P5, typename P6, typename P7, typename P8, typename P9,
- typename P10,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10>,
- ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- typedef typename TypeTraits<P10>::ParameterType Parm10;
- virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
- Parm7, Parm8, Parm9, Parm10) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename P7, typename P8, typename P9,
+ typename P10,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10>,
+ ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ typedef typename TypeTraits<P10>::ParameterType Parm10;
+ virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
+ Parm7, Parm8, Parm9, Parm10) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 11 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3, typename P4,
- typename P5, typename P6, typename P7, typename P8, typename P9,
- typename P10, typename P11,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R,
- Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11>,
- ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- typedef typename TypeTraits<P10>::ParameterType Parm10;
- typedef typename TypeTraits<P11>::ParameterType Parm11;
- virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
- Parm7, Parm8, Parm9, Parm10, Parm11) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename P7, typename P8, typename P9,
+ typename P10, typename P11,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R,
+ Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11>,
+ ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ typedef typename TypeTraits<P10>::ParameterType Parm10;
+ typedef typename TypeTraits<P11>::ParameterType Parm11;
+ virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
+ Parm7, Parm8, Parm9, Parm10, Parm11) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 12 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3, typename P4,
- typename P5, typename P6, typename P7, typename P8, typename P9,
- typename P10, typename P11, typename P12,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R,
- Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12>,
- ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- typedef typename TypeTraits<P10>::ParameterType Parm10;
- typedef typename TypeTraits<P11>::ParameterType Parm11;
- typedef typename TypeTraits<P12>::ParameterType Parm12;
- virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
- Parm7, Parm8, Parm9, Parm10, Parm11, Parm12) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename P7, typename P8, typename P9,
+ typename P10, typename P11, typename P12,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R,
+ Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12>,
+ ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ typedef typename TypeTraits<P10>::ParameterType Parm10;
+ typedef typename TypeTraits<P11>::ParameterType Parm11;
+ typedef typename TypeTraits<P12>::ParameterType Parm12;
+ virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
+ Parm7, Parm8, Parm9, Parm10, Parm11, Parm12) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 13 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3, typename P4,
- typename P5, typename P6, typename P7, typename P8, typename P9,
- typename P10, typename P11, typename P12, typename P13,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R,
- Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13>,
- ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- typedef typename TypeTraits<P10>::ParameterType Parm10;
- typedef typename TypeTraits<P11>::ParameterType Parm11;
- typedef typename TypeTraits<P12>::ParameterType Parm12;
- typedef typename TypeTraits<P13>::ParameterType Parm13;
- virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
- Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename P7, typename P8, typename P9,
+ typename P10, typename P11, typename P12, typename P13,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R,
+ Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13>,
+ ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ typedef typename TypeTraits<P10>::ParameterType Parm10;
+ typedef typename TypeTraits<P11>::ParameterType Parm11;
+ typedef typename TypeTraits<P12>::ParameterType Parm12;
+ typedef typename TypeTraits<P13>::ParameterType Parm13;
+ virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
+ Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 14 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3, typename P4,
- typename P5, typename P6, typename P7, typename P8, typename P9,
- typename P10, typename P11, typename P12, typename P13, typename P14,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R,
- Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13,
- P14>,
- ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- typedef typename TypeTraits<P10>::ParameterType Parm10;
- typedef typename TypeTraits<P11>::ParameterType Parm11;
- typedef typename TypeTraits<P12>::ParameterType Parm12;
- typedef typename TypeTraits<P13>::ParameterType Parm13;
- typedef typename TypeTraits<P14>::ParameterType Parm14;
- virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
- Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13, Parm14) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename P7, typename P8, typename P9,
+ typename P10, typename P11, typename P12, typename P13, typename P14,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R,
+ Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13,
+ P14>,
+ ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ typedef typename TypeTraits<P10>::ParameterType Parm10;
+ typedef typename TypeTraits<P11>::ParameterType Parm11;
+ typedef typename TypeTraits<P12>::ParameterType Parm12;
+ typedef typename TypeTraits<P13>::ParameterType Parm13;
+ typedef typename TypeTraits<P14>::ParameterType Parm14;
+ virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
+ Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13, Parm14) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 15 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3, typename P4,
- typename P5, typename P6, typename P7, typename P8, typename P9,
- typename P10, typename P11, typename P12, typename P13, typename P14,
- typename P15, template <class, class> class ThreadingModel>
- class FunctorImpl<R,
- Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13,
- P14, P15>,
- ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- typedef typename TypeTraits<P10>::ParameterType Parm10;
- typedef typename TypeTraits<P11>::ParameterType Parm11;
- typedef typename TypeTraits<P12>::ParameterType Parm12;
- typedef typename TypeTraits<P13>::ParameterType Parm13;
- typedef typename TypeTraits<P14>::ParameterType Parm14;
- typedef typename TypeTraits<P15>::ParameterType Parm15;
- virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
- Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13, Parm14,
- Parm15) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename P7, typename P8, typename P9,
+ typename P10, typename P11, typename P12, typename P13, typename P14,
+ typename P15, template <class, class> class ThreadingModel>
+class FunctorImpl<R,
+ Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13,
+ P14, P15>,
+ ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ typedef typename TypeTraits<P10>::ParameterType Parm10;
+ typedef typename TypeTraits<P11>::ParameterType Parm11;
+ typedef typename TypeTraits<P12>::ParameterType Parm12;
+ typedef typename TypeTraits<P13>::ParameterType Parm13;
+ typedef typename TypeTraits<P14>::ParameterType Parm14;
+ typedef typename TypeTraits<P15>::ParameterType Parm15;
+ virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
+ Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13, Parm14,
+ Parm15) = 0;
+};
#ifndef LOKI_DISABLE_TYPELIST_MACROS
@@ -532,386 +533,386 @@ namespace Loki
// Specialization for 1 parameter
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, template <class, class> class ThreadingModel>
- class FunctorImpl<R, LOKI_TYPELIST_1(P1), ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- virtual R operator()(Parm1) = 0;
- };
+template <typename R, typename P1, template <class, class> class ThreadingModel>
+class FunctorImpl<R, LOKI_TYPELIST_1(P1), ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ virtual R operator()(Parm1) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 2 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R, LOKI_TYPELIST_2(P1, P2), ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- virtual R operator()(Parm1, Parm2) = 0;
- };
+template <typename R, typename P1, typename P2,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R, LOKI_TYPELIST_2(P1, P2), ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ virtual R operator()(Parm1, Parm2) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 3 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R, LOKI_TYPELIST_3(P1, P2, P3), ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- virtual R operator()(Parm1, Parm2, Parm3) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R, LOKI_TYPELIST_3(P1, P2, P3), ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ virtual R operator()(Parm1, Parm2, Parm3) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 4 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3, typename P4,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R, LOKI_TYPELIST_4(P1, P2, P3, P4), ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- virtual R operator()(Parm1, Parm2, Parm3, Parm4) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R, LOKI_TYPELIST_4(P1, P2, P3, P4), ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ virtual R operator()(Parm1, Parm2, Parm3, Parm4) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 5 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3, typename P4,
- typename P5,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R, LOKI_TYPELIST_5(P1, P2, P3, P4, P5), ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R, LOKI_TYPELIST_5(P1, P2, P3, P4, P5), ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 6 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3, typename P4,
- typename P5, typename P6,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R, LOKI_TYPELIST_6(P1, P2, P3, P4, P5, P6), ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R, LOKI_TYPELIST_6(P1, P2, P3, P4, P5, P6), ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 7 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3, typename P4,
- typename P5, typename P6, typename P7,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R, LOKI_TYPELIST_7(P1, P2, P3, P4, P5, P6, P7), ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
- Parm7) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename P7,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R, LOKI_TYPELIST_7(P1, P2, P3, P4, P5, P6, P7), ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
+ Parm7) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 8 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3, typename P4,
- typename P5, typename P6, typename P7, typename P8,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R, LOKI_TYPELIST_8(P1, P2, P3, P4, P5, P6, P7, P8),
- ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
- Parm7, Parm8) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename P7, typename P8,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R, LOKI_TYPELIST_8(P1, P2, P3, P4, P5, P6, P7, P8),
+ ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
+ Parm7, Parm8) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 9 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3, typename P4,
- typename P5, typename P6, typename P7, typename P8, typename P9,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R, LOKI_TYPELIST_9(P1, P2, P3, P4, P5, P6, P7, P8, P9),
- ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
- Parm7, Parm8, Parm9) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename P7, typename P8, typename P9,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R, LOKI_TYPELIST_9(P1, P2, P3, P4, P5, P6, P7, P8, P9),
+ ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
+ Parm7, Parm8, Parm9) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 10 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3, typename P4,
- typename P5, typename P6, typename P7, typename P8, typename P9,
- typename P10,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R, LOKI_TYPELIST_10(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10),
- ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- typedef typename TypeTraits<P10>::ParameterType Parm10;
- virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
- Parm7, Parm8, Parm9, Parm10) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename P7, typename P8, typename P9,
+ typename P10,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R, LOKI_TYPELIST_10(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10),
+ ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ typedef typename TypeTraits<P10>::ParameterType Parm10;
+ virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
+ Parm7, Parm8, Parm9, Parm10) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 11 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3, typename P4,
- typename P5, typename P6, typename P7, typename P8, typename P9,
- typename P10, typename P11,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R,
- LOKI_TYPELIST_11(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11),
- ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- typedef typename TypeTraits<P10>::ParameterType Parm10;
- typedef typename TypeTraits<P11>::ParameterType Parm11;
- virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
- Parm7, Parm8, Parm9, Parm10, Parm11) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename P7, typename P8, typename P9,
+ typename P10, typename P11,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R,
+ LOKI_TYPELIST_11(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11),
+ ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ typedef typename TypeTraits<P10>::ParameterType Parm10;
+ typedef typename TypeTraits<P11>::ParameterType Parm11;
+ virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
+ Parm7, Parm8, Parm9, Parm10, Parm11) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 12 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3, typename P4,
- typename P5, typename P6, typename P7, typename P8, typename P9,
- typename P10, typename P11, typename P12,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R,
- LOKI_TYPELIST_12(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12),
- ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- typedef typename TypeTraits<P10>::ParameterType Parm10;
- typedef typename TypeTraits<P11>::ParameterType Parm11;
- typedef typename TypeTraits<P12>::ParameterType Parm12;
- virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
- Parm7, Parm8, Parm9, Parm10, Parm11, Parm12) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename P7, typename P8, typename P9,
+ typename P10, typename P11, typename P12,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R,
+ LOKI_TYPELIST_12(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12),
+ ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ typedef typename TypeTraits<P10>::ParameterType Parm10;
+ typedef typename TypeTraits<P11>::ParameterType Parm11;
+ typedef typename TypeTraits<P12>::ParameterType Parm12;
+ virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
+ Parm7, Parm8, Parm9, Parm10, Parm11, Parm12) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 13 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3, typename P4,
- typename P5, typename P6, typename P7, typename P8, typename P9,
- typename P10, typename P11, typename P12, typename P13,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R,
- LOKI_TYPELIST_13(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13),
- ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- typedef typename TypeTraits<P10>::ParameterType Parm10;
- typedef typename TypeTraits<P11>::ParameterType Parm11;
- typedef typename TypeTraits<P12>::ParameterType Parm12;
- typedef typename TypeTraits<P13>::ParameterType Parm13;
- virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
- Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename P7, typename P8, typename P9,
+ typename P10, typename P11, typename P12, typename P13,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R,
+ LOKI_TYPELIST_13(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13),
+ ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ typedef typename TypeTraits<P10>::ParameterType Parm10;
+ typedef typename TypeTraits<P11>::ParameterType Parm11;
+ typedef typename TypeTraits<P12>::ParameterType Parm12;
+ typedef typename TypeTraits<P13>::ParameterType Parm13;
+ virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
+ Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 14 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3, typename P4,
- typename P5, typename P6, typename P7, typename P8, typename P9,
- typename P10, typename P11, typename P12, typename P13, typename P14,
- template <class, class> class ThreadingModel>
- class FunctorImpl<R,
- LOKI_TYPELIST_14(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13,
- P14),
- ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- typedef typename TypeTraits<P10>::ParameterType Parm10;
- typedef typename TypeTraits<P11>::ParameterType Parm11;
- typedef typename TypeTraits<P12>::ParameterType Parm12;
- typedef typename TypeTraits<P13>::ParameterType Parm13;
- typedef typename TypeTraits<P14>::ParameterType Parm14;
- virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
- Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13, Parm14) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename P7, typename P8, typename P9,
+ typename P10, typename P11, typename P12, typename P13, typename P14,
+ template <class, class> class ThreadingModel>
+class FunctorImpl<R,
+ LOKI_TYPELIST_14(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13,
+ P14),
+ ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ typedef typename TypeTraits<P10>::ParameterType Parm10;
+ typedef typename TypeTraits<P11>::ParameterType Parm11;
+ typedef typename TypeTraits<P12>::ParameterType Parm12;
+ typedef typename TypeTraits<P13>::ParameterType Parm13;
+ typedef typename TypeTraits<P14>::ParameterType Parm14;
+ virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
+ Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13, Parm14) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 15 parameters
////////////////////////////////////////////////////////////////////////////////
- template <typename R, typename P1, typename P2, typename P3, typename P4,
- typename P5, typename P6, typename P7, typename P8, typename P9,
- typename P10, typename P11, typename P12, typename P13, typename P14,
- typename P15, template <class, class> class ThreadingModel>
- class FunctorImpl<R,
- LOKI_TYPELIST_15(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13,
- P14, P15),
- ThreadingModel>
- : public Private::FunctorImplBase<R, ThreadingModel>
- {
- public:
- typedef R ResultType;
- typedef typename TypeTraits<P1>::ParameterType Parm1;
- typedef typename TypeTraits<P2>::ParameterType Parm2;
- typedef typename TypeTraits<P3>::ParameterType Parm3;
- typedef typename TypeTraits<P4>::ParameterType Parm4;
- typedef typename TypeTraits<P5>::ParameterType Parm5;
- typedef typename TypeTraits<P6>::ParameterType Parm6;
- typedef typename TypeTraits<P7>::ParameterType Parm7;
- typedef typename TypeTraits<P8>::ParameterType Parm8;
- typedef typename TypeTraits<P9>::ParameterType Parm9;
- typedef typename TypeTraits<P10>::ParameterType Parm10;
- typedef typename TypeTraits<P11>::ParameterType Parm11;
- typedef typename TypeTraits<P12>::ParameterType Parm12;
- typedef typename TypeTraits<P13>::ParameterType Parm13;
- typedef typename TypeTraits<P14>::ParameterType Parm14;
- typedef typename TypeTraits<P15>::ParameterType Parm15;
- virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
- Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13, Parm14,
- Parm15) = 0;
- };
+template <typename R, typename P1, typename P2, typename P3, typename P4,
+ typename P5, typename P6, typename P7, typename P8, typename P9,
+ typename P10, typename P11, typename P12, typename P13, typename P14,
+ typename P15, template <class, class> class ThreadingModel>
+class FunctorImpl<R,
+ LOKI_TYPELIST_15(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13,
+ P14, P15),
+ ThreadingModel>
+ : public Private::FunctorImplBase<R, ThreadingModel>
+{
+public:
+ typedef R ResultType;
+ typedef typename TypeTraits<P1>::ParameterType Parm1;
+ typedef typename TypeTraits<P2>::ParameterType Parm2;
+ typedef typename TypeTraits<P3>::ParameterType Parm3;
+ typedef typename TypeTraits<P4>::ParameterType Parm4;
+ typedef typename TypeTraits<P5>::ParameterType Parm5;
+ typedef typename TypeTraits<P6>::ParameterType Parm6;
+ typedef typename TypeTraits<P7>::ParameterType Parm7;
+ typedef typename TypeTraits<P8>::ParameterType Parm8;
+ typedef typename TypeTraits<P9>::ParameterType Parm9;
+ typedef typename TypeTraits<P10>::ParameterType Parm10;
+ typedef typename TypeTraits<P11>::ParameterType Parm11;
+ typedef typename TypeTraits<P12>::ParameterType Parm12;
+ typedef typename TypeTraits<P13>::ParameterType Parm13;
+ typedef typename TypeTraits<P14>::ParameterType Parm14;
+ typedef typename TypeTraits<P15>::ParameterType Parm15;
+ virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6,
+ Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13, Parm14,
+ Parm15) = 0;
+};
#endif //LOKI_DISABLE_TYPELIST_MACROS
@@ -920,275 +921,275 @@ namespace Loki
// Wraps functors and pointers to functions
////////////////////////////////////////////////////////////////////////////////
- template <class ParentFunctor, typename Fun>
- class FunctorHandler
- : public ParentFunctor::Impl
- {
- typedef typename ParentFunctor::Impl Base;
-
- public:
- typedef typename Base::ResultType ResultType;
- typedef typename Base::Parm1 Parm1;
- typedef typename Base::Parm2 Parm2;
- typedef typename Base::Parm3 Parm3;
- typedef typename Base::Parm4 Parm4;
- typedef typename Base::Parm5 Parm5;
- typedef typename Base::Parm6 Parm6;
- typedef typename Base::Parm7 Parm7;
- typedef typename Base::Parm8 Parm8;
- typedef typename Base::Parm9 Parm9;
- typedef typename Base::Parm10 Parm10;
- typedef typename Base::Parm11 Parm11;
- typedef typename Base::Parm12 Parm12;
- typedef typename Base::Parm13 Parm13;
- typedef typename Base::Parm14 Parm14;
- typedef typename Base::Parm15 Parm15;
-
- FunctorHandler(const Fun& fun) : f_(fun) {}
-
- LOKI_DEFINE_CLONE_FUNCTORIMPL(FunctorHandler)
+template <class ParentFunctor, typename Fun>
+class FunctorHandler
+ : public ParentFunctor::Impl
+{
+ typedef typename ParentFunctor::Impl Base;
+
+public:
+ typedef typename Base::ResultType ResultType;
+ typedef typename Base::Parm1 Parm1;
+ typedef typename Base::Parm2 Parm2;
+ typedef typename Base::Parm3 Parm3;
+ typedef typename Base::Parm4 Parm4;
+ typedef typename Base::Parm5 Parm5;
+ typedef typename Base::Parm6 Parm6;
+ typedef typename Base::Parm7 Parm7;
+ typedef typename Base::Parm8 Parm8;
+ typedef typename Base::Parm9 Parm9;
+ typedef typename Base::Parm10 Parm10;
+ typedef typename Base::Parm11 Parm11;
+ typedef typename Base::Parm12 Parm12;
+ typedef typename Base::Parm13 Parm13;
+ typedef typename Base::Parm14 Parm14;
+ typedef typename Base::Parm15 Parm15;
+
+ FunctorHandler(const Fun& fun) : f_(fun) {}
+
+ LOKI_DEFINE_CLONE_FUNCTORIMPL(FunctorHandler)
#ifdef LOKI_FUNCTORS_ARE_COMPARABLE
- bool operator==(const typename Base::FunctorImplBaseType& rhs) const
- {
- // there is no static information if Functor holds a member function
- // or a free function; this is the main difference to tr1::function
- if(typeid(*this) != typeid(rhs))
- return false; // cannot be equal
-
- const FunctorHandler& fh = static_cast<const FunctorHandler&>(rhs);
- // if this line gives a compiler error, you are using a function object.
- // you need to implement bool MyFnObj::operator == (const MyFnObj&) const;
- return f_==fh.f_;
- }
+ bool operator==(const typename Base::FunctorImplBaseType& rhs) const
+ {
+ // there is no static information if Functor holds a member function
+ // or a free function; this is the main difference to tr1::function
+ if(typeid(*this) != typeid(rhs))
+ return false; // cannot be equal
+
+ const FunctorHandler& fh = static_cast<const FunctorHandler&>(rhs);
+ // if this line gives a compiler error, you are using a function object.
+ // you need to implement bool MyFnObj::operator == (const MyFnObj&) const;
+ return f_==fh.f_;
+ }
#endif
- // operator() implementations for up to 15 arguments
-
- ResultType operator()()
- { return f_(); }
-
- ResultType operator()(Parm1 p1)
- { return f_(p1); }
-
- ResultType operator()(Parm1 p1, Parm2 p2)
- { return f_(p1, p2); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
- { return f_(p1, p2, p3); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
- { return f_(p1, p2, p3, p4); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
- { return f_(p1, p2, p3, p4, p5); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6)
- { return f_(p1, p2, p3, p4, p5, p6); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7)
- { return f_(p1, p2, p3, p4, p5, p6, p7); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8)
- { return f_(p1, p2, p3, p4, p5, p6, p7, p8); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
- { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
- { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
- { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
- Parm12 p12)
- { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
- Parm12 p12, Parm13 p13)
- { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
- Parm12 p12, Parm13 p13, Parm14 p14)
- {
- return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13,
- p14);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
- Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
- {
- return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13,
- p14, p15);
- }
-
- private:
- Fun f_;
- };
-
+ // operator() implementations for up to 15 arguments
+
+ ResultType operator()()
+ { return f_(); }
+
+ ResultType operator()(Parm1 p1)
+ { return f_(p1); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2)
+ { return f_(p1, p2); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
+ { return f_(p1, p2, p3); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
+ { return f_(p1, p2, p3, p4); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
+ { return f_(p1, p2, p3, p4, p5); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6)
+ { return f_(p1, p2, p3, p4, p5, p6); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7)
+ { return f_(p1, p2, p3, p4, p5, p6, p7); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8)
+ { return f_(p1, p2, p3, p4, p5, p6, p7, p8); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
+ { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
+ { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
+ { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
+ Parm12 p12)
+ { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
+ Parm12 p12, Parm13 p13)
+ { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
+ Parm12 p12, Parm13 p13, Parm14 p14)
+ {
+ return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13,
+ p14);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
+ Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
+ {
+ return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13,
+ p14, p15);
+ }
+
+private:
+ Fun f_;
+};
+
////////////////////////////////////////////////////////////////////////////////
// class template FunctorHandler
// Wraps pointers to member functions
////////////////////////////////////////////////////////////////////////////////
- template <class ParentFunctor, typename PointerToObj,
- typename PointerToMemFn>
- class MemFunHandler : public ParentFunctor::Impl
- {
- typedef typename ParentFunctor::Impl Base;
-
- public:
- typedef typename Base::ResultType ResultType;
- typedef typename Base::Parm1 Parm1;
- typedef typename Base::Parm2 Parm2;
- typedef typename Base::Parm3 Parm3;
- typedef typename Base::Parm4 Parm4;
- typedef typename Base::Parm5 Parm5;
- typedef typename Base::Parm6 Parm6;
- typedef typename Base::Parm7 Parm7;
- typedef typename Base::Parm8 Parm8;
- typedef typename Base::Parm9 Parm9;
- typedef typename Base::Parm10 Parm10;
- typedef typename Base::Parm11 Parm11;
- typedef typename Base::Parm12 Parm12;
- typedef typename Base::Parm13 Parm13;
- typedef typename Base::Parm14 Parm14;
- typedef typename Base::Parm15 Parm15;
-
- MemFunHandler(const PointerToObj& pObj, PointerToMemFn pMemFn)
+template <class ParentFunctor, typename PointerToObj,
+ typename PointerToMemFn>
+class MemFunHandler : public ParentFunctor::Impl
+{
+ typedef typename ParentFunctor::Impl Base;
+
+public:
+ typedef typename Base::ResultType ResultType;
+ typedef typename Base::Parm1 Parm1;
+ typedef typename Base::Parm2 Parm2;
+ typedef typename Base::Parm3 Parm3;
+ typedef typename Base::Parm4 Parm4;
+ typedef typename Base::Parm5 Parm5;
+ typedef typename Base::Parm6 Parm6;
+ typedef typename Base::Parm7 Parm7;
+ typedef typename Base::Parm8 Parm8;
+ typedef typename Base::Parm9 Parm9;
+ typedef typename Base::Parm10 Parm10;
+ typedef typename Base::Parm11 Parm11;
+ typedef typename Base::Parm12 Parm12;
+ typedef typename Base::Parm13 Parm13;
+ typedef typename Base::Parm14 Parm14;
+ typedef typename Base::Parm15 Parm15;
+
+ MemFunHandler(const PointerToObj& pObj, PointerToMemFn pMemFn)
: pObj_(pObj), pMemFn_(pMemFn)
- {}
-
- LOKI_DEFINE_CLONE_FUNCTORIMPL(MemFunHandler)
+ {}
+
+ LOKI_DEFINE_CLONE_FUNCTORIMPL(MemFunHandler)
#ifdef LOKI_FUNCTORS_ARE_COMPARABLE
- bool operator==(const typename Base::FunctorImplBaseType& rhs) const
- {
- if(typeid(*this) != typeid(rhs))
- return false; // cannot be equal
-
- const MemFunHandler& mfh = static_cast<const MemFunHandler&>(rhs);
- // if this line gives a compiler error, you are using a function object.
- // you need to implement bool MyFnObj::operator == (const MyFnObj&) const;
- return pObj_==mfh.pObj_ && pMemFn_==mfh.pMemFn_;
- }
-#endif
-
- ResultType operator()()
- { return ((*pObj_).*pMemFn_)(); }
-
- ResultType operator()(Parm1 p1)
- { return ((*pObj_).*pMemFn_)(p1); }
-
- ResultType operator()(Parm1 p1, Parm2 p2)
- { return ((*pObj_).*pMemFn_)(p1, p2); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
- { return ((*pObj_).*pMemFn_)(p1, p2, p3); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
- { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
- { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6)
- { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7)
- { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8)
- { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
- { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
- { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
- {
- return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
- p11);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
- Parm12 p12)
- {
- return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
- p11, p12);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
- Parm12 p12, Parm13 p13)
- {
- return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
- p11, p12, p13);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
- Parm12 p12, Parm13 p13, Parm14 p14)
- {
- return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
- p11, p12, p13, p14);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
- Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
- {
- return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
- p11, p12, p13, p14, p15);
- }
-
- private:
- PointerToObj pObj_;
- PointerToMemFn pMemFn_;
- };
-
+ bool operator==(const typename Base::FunctorImplBaseType& rhs) const
+ {
+ if(typeid(*this) != typeid(rhs))
+ return false; // cannot be equal
+
+ const MemFunHandler& mfh = static_cast<const MemFunHandler&>(rhs);
+ // if this line gives a compiler error, you are using a function object.
+ // you need to implement bool MyFnObj::operator == (const MyFnObj&) const;
+ return pObj_==mfh.pObj_ && pMemFn_==mfh.pMemFn_;
+ }
+#endif
+
+ ResultType operator()()
+ { return ((*pObj_).*pMemFn_)(); }
+
+ ResultType operator()(Parm1 p1)
+ { return ((*pObj_).*pMemFn_)(p1); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2)
+ { return ((*pObj_).*pMemFn_)(p1, p2); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
+ { return ((*pObj_).*pMemFn_)(p1, p2, p3); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
+ { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
+ { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6)
+ { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7)
+ { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8)
+ { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
+ { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
+ { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
+ {
+ return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
+ p11);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
+ Parm12 p12)
+ {
+ return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
+ p11, p12);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
+ Parm12 p12, Parm13 p13)
+ {
+ return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
+ p11, p12, p13);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
+ Parm12 p12, Parm13 p13, Parm14 p14)
+ {
+ return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
+ p11, p12, p13, p14);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
+ Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
+ {
+ return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
+ p11, p12, p13, p14, p15);
+ }
+
+private:
+ PointerToObj pObj_;
+ PointerToMemFn pMemFn_;
+};
+
////////////////////////////////////////////////////////////////////////////////
// TR1 exception
//////////////////////////////////////////////////////////////////////////////////
#ifdef LOKI_ENABLE_FUNCTION
- class bad_function_call : public std::runtime_error
- {
- public:
- bad_function_call() : std::runtime_error("bad_function_call in Loki::Functor")
- {}
- };
+class bad_function_call : public std::runtime_error
+{
+public:
+ bad_function_call() : std::runtime_error("bad_function_call in Loki::Functor")
+ {}
+};
#define LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL if(empty()) throw bad_function_call();
#else
-#define LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
+#define LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
#endif
@@ -1199,9 +1200,9 @@ namespace Loki
/// A generalized functor implementation with value semantics
///
/// \par Macro: LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT
-/// Define
+/// Define
/// \code LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT \endcode
-/// to avoid static instantiation/delete
+/// to avoid static instantiation/delete
/// order problems.
/// It often helps against crashes when using static Functors and multi threading.
/// Defining also removes problems when unloading Dlls which hosts
@@ -1210,415 +1211,415 @@ namespace Loki
/// \par Macro: LOKI_FUNCTORS_ARE_COMPARABLE
/// To enable the operator== define the macro
/// \code LOKI_FUNCTORS_ARE_COMPARABLE \endcode
-/// The macro is disabled by default, because it breaks compiling functor
+/// The macro is disabled by default, because it breaks compiling functor
/// objects which have no operator== implemented, keep in mind when you enable
/// operator==.
////////////////////////////////////////////////////////////////////////////////
- template <typename R = void, class TList = NullType,
- template<class, class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL>
- class Functor
- {
- public:
- // Handy type definitions for the body type
- typedef FunctorImpl<R, TList, ThreadingModel> Impl;
- typedef R ResultType;
- typedef TList ParmList;
- typedef typename Impl::Parm1 Parm1;
- typedef typename Impl::Parm2 Parm2;
- typedef typename Impl::Parm3 Parm3;
- typedef typename Impl::Parm4 Parm4;
- typedef typename Impl::Parm5 Parm5;
- typedef typename Impl::Parm6 Parm6;
- typedef typename Impl::Parm7 Parm7;
- typedef typename Impl::Parm8 Parm8;
- typedef typename Impl::Parm9 Parm9;
- typedef typename Impl::Parm10 Parm10;
- typedef typename Impl::Parm11 Parm11;
- typedef typename Impl::Parm12 Parm12;
- typedef typename Impl::Parm13 Parm13;
- typedef typename Impl::Parm14 Parm14;
- typedef typename Impl::Parm15 Parm15;
-
- // Member functions
-
- Functor() : spImpl_(0)
- {}
-
- Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get()))
- {}
-
- Functor(std::auto_ptr<Impl> spImpl) : spImpl_(spImpl)
- {}
-
- template <typename Fun>
- Functor(Fun fun)
+template <typename R = void, class TList = NullType,
+ template<class, class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL>
+class Functor
+{
+public:
+ // Handy type definitions for the body type
+ typedef FunctorImpl<R, TList, ThreadingModel> Impl;
+ typedef R ResultType;
+ typedef TList ParmList;
+ typedef typename Impl::Parm1 Parm1;
+ typedef typename Impl::Parm2 Parm2;
+ typedef typename Impl::Parm3 Parm3;
+ typedef typename Impl::Parm4 Parm4;
+ typedef typename Impl::Parm5 Parm5;
+ typedef typename Impl::Parm6 Parm6;
+ typedef typename Impl::Parm7 Parm7;
+ typedef typename Impl::Parm8 Parm8;
+ typedef typename Impl::Parm9 Parm9;
+ typedef typename Impl::Parm10 Parm10;
+ typedef typename Impl::Parm11 Parm11;
+ typedef typename Impl::Parm12 Parm12;
+ typedef typename Impl::Parm13 Parm13;
+ typedef typename Impl::Parm14 Parm14;
+ typedef typename Impl::Parm15 Parm15;
+
+ // Member functions
+
+ Functor() : spImpl_(0)
+ {}
+
+ Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get()))
+ {}
+
+ Functor(std::auto_ptr<Impl> spImpl) : spImpl_(spImpl)
+ {}
+
+ template <typename Fun>
+ Functor(Fun fun)
: spImpl_(new FunctorHandler<Functor, Fun>(fun))
- {}
+ {}
- template <class PtrObj, typename MemFn>
- Functor(const PtrObj& p, MemFn memFn)
+ template <class PtrObj, typename MemFn>
+ Functor(const PtrObj& p, MemFn memFn)
: spImpl_(new MemFunHandler<Functor, PtrObj, MemFn>(p, memFn))
- {}
+ {}
- typedef Impl * (std::auto_ptr<Impl>::*unspecified_bool_type)() const;
+ typedef Impl* (std::auto_ptr<Impl>::*unspecified_bool_type)() const;
- operator unspecified_bool_type() const
- {
- return spImpl_.get() ? &std::auto_ptr<Impl>::get : 0;
- }
+ operator unspecified_bool_type() const
+ {
+ return spImpl_.get() ? &std::auto_ptr<Impl>::get : 0;
+ }
- Functor& operator=(const Functor& rhs)
- {
- Functor copy(rhs);
- // swap auto_ptrs by hand
- Impl* p = spImpl_.release();
- spImpl_.reset(copy.spImpl_.release());
- copy.spImpl_.reset(p);
- return *this;
- }
+ Functor& operator=(const Functor& rhs)
+ {
+ Functor copy(rhs);
+ // swap auto_ptrs by hand
+ Impl* p = spImpl_.release();
+ spImpl_.reset(copy.spImpl_.release());
+ copy.spImpl_.reset(p);
+ return *this;
+ }
#ifdef LOKI_ENABLE_FUNCTION
- bool empty() const
- {
- return spImpl_.get() == 0;
- }
+ bool empty() const
+ {
+ return spImpl_.get() == 0;
+ }
- void clear()
- {
- spImpl_.reset(0);
- }
+ void clear()
+ {
+ spImpl_.reset(0);
+ }
#endif
#ifdef LOKI_FUNCTORS_ARE_COMPARABLE
- bool operator==(const Functor& rhs) const
- {
- if(spImpl_.get()==0 && rhs.spImpl_.get()==0)
- return true;
- if(spImpl_.get()!=0 && rhs.spImpl_.get()!=0)
- return *spImpl_.get() == *rhs.spImpl_.get();
- else
- return false;
- }
-
- bool operator!=(const Functor& rhs) const
- {
- return !(*this==rhs);
- }
+ bool operator==(const Functor& rhs) const
+ {
+ if(spImpl_.get()==0 && rhs.spImpl_.get()==0)
+ return true;
+ if(spImpl_.get()!=0 && rhs.spImpl_.get()!=0)
+ return *spImpl_.get() == *rhs.spImpl_.get();
+ else
+ return false;
+ }
+
+ bool operator!=(const Functor& rhs) const
+ {
+ return !(*this==rhs);
+ }
#endif
- // operator() implementations for up to 15 arguments
-
- ResultType operator()() const
- {
- LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
- return (*spImpl_)();
- }
-
- ResultType operator()(Parm1 p1) const
- {
- LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
- return (*spImpl_)(p1);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2) const
- {
- LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
- return (*spImpl_)(p1, p2);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3) const
- {
- LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
- return (*spImpl_)(p1, p2, p3);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4) const
- {
- LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
- return (*spImpl_)(p1, p2, p3, p4);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5) const
- {
- LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
- return (*spImpl_)(p1, p2, p3, p4, p5);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6) const
- {
- LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
- return (*spImpl_)(p1, p2, p3, p4, p5, p6);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7) const
- {
- LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
- return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8) const
- {
- LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
- return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9) const
- {
- LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
- return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10) const
- {
- LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
- return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11) const
- {
- LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
- return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
- Parm12 p12) const
- {
- LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
- return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,
- p12);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
- Parm12 p12, Parm13 p13) const
- {
- LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
- return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,
- p12, p13);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
- Parm12 p12, Parm13 p13, Parm14 p14) const
- {
- LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
- return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,
- p12, p13, p14);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
- Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15) const
- {
- LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
- return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,
- p12, p13, p14, p15);
- }
-
- private:
- std::auto_ptr<Impl> spImpl_;
- };
-
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// BindersFirst and Chainer
+ // operator() implementations for up to 15 arguments
+
+ ResultType operator()() const
+ {
+ LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
+ return (*spImpl_)();
+ }
+
+ ResultType operator()(Parm1 p1) const
+ {
+ LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
+ return (*spImpl_)(p1);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2) const
+ {
+ LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
+ return (*spImpl_)(p1, p2);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3) const
+ {
+ LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
+ return (*spImpl_)(p1, p2, p3);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4) const
+ {
+ LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
+ return (*spImpl_)(p1, p2, p3, p4);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5) const
+ {
+ LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
+ return (*spImpl_)(p1, p2, p3, p4, p5);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6) const
+ {
+ LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
+ return (*spImpl_)(p1, p2, p3, p4, p5, p6);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7) const
+ {
+ LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
+ return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8) const
+ {
+ LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
+ return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9) const
+ {
+ LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
+ return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10) const
+ {
+ LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
+ return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11) const
+ {
+ LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
+ return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
+ Parm12 p12) const
+ {
+ LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
+ return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,
+ p12);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
+ Parm12 p12, Parm13 p13) const
+ {
+ LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
+ return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,
+ p12, p13);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
+ Parm12 p12, Parm13 p13, Parm14 p14) const
+ {
+ LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
+ return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,
+ p12, p13, p14);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
+ Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15) const
+ {
+ LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
+ return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,
+ p12, p13, p14, p15);
+ }
+
+private:
+ std::auto_ptr<Impl> spImpl_;
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// BindersFirst and Chainer
//
////////////////////////////////////////////////////////////////////////////////
- namespace Private
- {
- template <class Fctor> struct BinderFirstTraits;
+namespace Private
+{
+template <class Fctor> struct BinderFirstTraits;
+
+template <typename R, class TList, template <class, class> class ThreadingModel>
+struct BinderFirstTraits< Functor<R, TList, ThreadingModel> >
+{
+ typedef Functor<R, TList, ThreadingModel> OriginalFunctor;
- template <typename R, class TList, template <class, class> class ThreadingModel>
- struct BinderFirstTraits< Functor<R, TList, ThreadingModel> >
- {
- typedef Functor<R, TList, ThreadingModel> OriginalFunctor;
+ typedef typename TL::Erase<TList,typename TL::TypeAt<TList, 0>::Result>
+ ::Result
+ ParmList;
- typedef typename TL::Erase<TList,typename TL::TypeAt<TList, 0>::Result>
- ::Result
- ParmList;
+ typedef typename TL::TypeAt<TList, 0>::Result OriginalParm1;
- typedef typename TL::TypeAt<TList, 0>::Result OriginalParm1;
+ typedef Functor<R, ParmList, ThreadingModel> BoundFunctorType;
- typedef Functor<R, ParmList, ThreadingModel> BoundFunctorType;
+ typedef typename BoundFunctorType::Impl Impl;
- typedef typename BoundFunctorType::Impl Impl;
+};
- };
+template<class T>
+struct BinderFirstBoundTypeStorage;
- template<class T>
- struct BinderFirstBoundTypeStorage;
+template<class T>
+struct BinderFirstBoundTypeStorage
+{
+ typedef typename TypeTraits<T>::ParameterType RefOrValue;
+};
- template<class T>
- struct BinderFirstBoundTypeStorage
- {
- typedef typename TypeTraits<T>::ParameterType RefOrValue;
- };
-
- template <typename R, class TList, template <class, class> class ThreadingModel>
- struct BinderFirstBoundTypeStorage< Functor<R, TList, ThreadingModel> >
- {
- typedef Functor<R, TList, ThreadingModel> OriginalFunctor;
- typedef const typename TypeTraits<OriginalFunctor>::ReferredType RefOrValue;
- };
+template <typename R, class TList, template <class, class> class ThreadingModel>
+struct BinderFirstBoundTypeStorage< Functor<R, TList, ThreadingModel> >
+{
+ typedef Functor<R, TList, ThreadingModel> OriginalFunctor;
+ typedef const typename TypeTraits<OriginalFunctor>::ReferredType RefOrValue;
+};
- } // namespace Private
+} // namespace Private
////////////////////////////////////////////////////////////////////////////////
/// \class BinderFirst
-///
+///
/// \ingroup FunctorGroup
/// Binds the first parameter of a Functor object to a specific value
////////////////////////////////////////////////////////////////////////////////
- template <class OriginalFunctor>
- class BinderFirst
- : public Private::BinderFirstTraits<OriginalFunctor>::Impl
- {
- typedef typename Private::BinderFirstTraits<OriginalFunctor>::Impl Base;
- typedef typename OriginalFunctor::ResultType ResultType;
-
- typedef typename OriginalFunctor::Parm1 BoundType;
-
- typedef typename Private::BinderFirstBoundTypeStorage<
- typename Private::BinderFirstTraits<OriginalFunctor>
- ::OriginalParm1>
- ::RefOrValue
- BoundTypeStorage;
-
- typedef typename OriginalFunctor::Parm2 Parm1;
- typedef typename OriginalFunctor::Parm3 Parm2;
- typedef typename OriginalFunctor::Parm4 Parm3;
- typedef typename OriginalFunctor::Parm5 Parm4;
- typedef typename OriginalFunctor::Parm6 Parm5;
- typedef typename OriginalFunctor::Parm7 Parm6;
- typedef typename OriginalFunctor::Parm8 Parm7;
- typedef typename OriginalFunctor::Parm9 Parm8;
- typedef typename OriginalFunctor::Parm10 Parm9;
- typedef typename OriginalFunctor::Parm11 Parm10;
- typedef typename OriginalFunctor::Parm12 Parm11;
- typedef typename OriginalFunctor::Parm13 Parm12;
- typedef typename OriginalFunctor::Parm14 Parm13;
- typedef typename OriginalFunctor::Parm15 Parm14;
- typedef EmptyType Parm15;
-
- public:
-
- BinderFirst(const OriginalFunctor& fun, BoundType bound)
+template <class OriginalFunctor>
+class BinderFirst
+ : public Private::BinderFirstTraits<OriginalFunctor>::Impl
+{
+ typedef typename Private::BinderFirstTraits<OriginalFunctor>::Impl Base;
+ typedef typename OriginalFunctor::ResultType ResultType;
+
+ typedef typename OriginalFunctor::Parm1 BoundType;
+
+ typedef typename Private::BinderFirstBoundTypeStorage<
+ typename Private::BinderFirstTraits<OriginalFunctor>
+ ::OriginalParm1>
+ ::RefOrValue
+ BoundTypeStorage;
+
+ typedef typename OriginalFunctor::Parm2 Parm1;
+ typedef typename OriginalFunctor::Parm3 Parm2;
+ typedef typename OriginalFunctor::Parm4 Parm3;
+ typedef typename OriginalFunctor::Parm5 Parm4;
+ typedef typename OriginalFunctor::Parm6 Parm5;
+ typedef typename OriginalFunctor::Parm7 Parm6;
+ typedef typename OriginalFunctor::Parm8 Parm7;
+ typedef typename OriginalFunctor::Parm9 Parm8;
+ typedef typename OriginalFunctor::Parm10 Parm9;
+ typedef typename OriginalFunctor::Parm11 Parm10;
+ typedef typename OriginalFunctor::Parm12 Parm11;
+ typedef typename OriginalFunctor::Parm13 Parm12;
+ typedef typename OriginalFunctor::Parm14 Parm13;
+ typedef typename OriginalFunctor::Parm15 Parm14;
+ typedef EmptyType Parm15;
+
+public:
+
+ BinderFirst(const OriginalFunctor& fun, BoundType bound)
: f_(fun), b_(bound)
- {}
+ {}
- LOKI_DEFINE_CLONE_FUNCTORIMPL(BinderFirst)
+ LOKI_DEFINE_CLONE_FUNCTORIMPL(BinderFirst)
#ifdef LOKI_FUNCTORS_ARE_COMPARABLE
-
- bool operator==(const typename Base::FunctorImplBaseType& rhs) const
- {
- if(typeid(*this) != typeid(rhs))
- return false; // cannot be equal
- // if this line gives a compiler error, you are using a function object.
- // you need to implement bool MyFnObj::operator == (const MyFnObj&) const;
- return f_ == ((static_cast<const BinderFirst&> (rhs)).f_) &&
- b_ == ((static_cast<const BinderFirst&> (rhs)).b_);
- }
+
+ bool operator==(const typename Base::FunctorImplBaseType& rhs) const
+ {
+ if(typeid(*this) != typeid(rhs))
+ return false; // cannot be equal
+ // if this line gives a compiler error, you are using a function object.
+ // you need to implement bool MyFnObj::operator == (const MyFnObj&) const;
+ return f_ == ((static_cast<const BinderFirst&> (rhs)).f_) &&
+ b_ == ((static_cast<const BinderFirst&> (rhs)).b_);
+ }
#endif
- // operator() implementations for up to 15 arguments
-
- ResultType operator()()
- { return f_(b_); }
-
- ResultType operator()(Parm1 p1)
- { return f_(b_, p1); }
-
- ResultType operator()(Parm1 p1, Parm2 p2)
- { return f_(b_, p1, p2); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
- { return f_(b_, p1, p2, p3); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
- { return f_(b_, p1, p2, p3, p4); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
- { return f_(b_, p1, p2, p3, p4, p5); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6)
- { return f_(b_, p1, p2, p3, p4, p5, p6); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7)
- { return f_(b_, p1, p2, p3, p4, p5, p6, p7); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8)
- { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
- { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
- { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
- { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
- Parm12 p12)
- { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
- Parm12 p12, Parm13 p13)
- { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
- Parm12 p12, Parm13 p13, Parm14 p14)
- {
- return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13,
- p14);
- }
-
- private:
- OriginalFunctor f_;
- BoundTypeStorage b_;
- };
-
+ // operator() implementations for up to 15 arguments
+
+ ResultType operator()()
+ { return f_(b_); }
+
+ ResultType operator()(Parm1 p1)
+ { return f_(b_, p1); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2)
+ { return f_(b_, p1, p2); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
+ { return f_(b_, p1, p2, p3); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
+ { return f_(b_, p1, p2, p3, p4); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
+ { return f_(b_, p1, p2, p3, p4, p5); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6)
+ { return f_(b_, p1, p2, p3, p4, p5, p6); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7)
+ { return f_(b_, p1, p2, p3, p4, p5, p6, p7); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8)
+ { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
+ { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
+ { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
+ { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
+ Parm12 p12)
+ { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
+ Parm12 p12, Parm13 p13)
+ { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
+ Parm12 p12, Parm13 p13, Parm14 p14)
+ {
+ return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13,
+ p14);
+ }
+
+private:
+ OriginalFunctor f_;
+ BoundTypeStorage b_;
+};
+
////////////////////////////////////////////////////////////////////////////////
/// Binds the first parameter of a Functor object to a specific value
/// \ingroup FunctorGroup
////////////////////////////////////////////////////////////////////////////////
- template <class Fctor>
- typename Private::BinderFirstTraits<Fctor>::BoundFunctorType
- BindFirst(
- const Fctor& fun,
- typename Fctor::Parm1 bound)
- {
- typedef typename Private::BinderFirstTraits<Fctor>::BoundFunctorType
- Outgoing;
-
- return Outgoing(std::auto_ptr<typename Outgoing::Impl>(
- new BinderFirst<Fctor>(fun, bound)));
- }
+template <class Fctor>
+typename Private::BinderFirstTraits<Fctor>::BoundFunctorType
+BindFirst(
+ const Fctor& fun,
+ typename Fctor::Parm1 bound)
+{
+ typedef typename Private::BinderFirstTraits<Fctor>::BoundFunctorType
+ Outgoing;
+
+ return Outgoing(std::auto_ptr<typename Outgoing::Impl>(
+ new BinderFirst<Fctor>(fun, bound)));
+}
////////////////////////////////////////////////////////////////////////////////
/// \class Chainer
@@ -1627,160 +1628,160 @@ namespace Loki
/// Chains two functor calls one after another
////////////////////////////////////////////////////////////////////////////////
- template <typename Fun1, typename Fun2>
- class Chainer : public Fun2::Impl
- {
- typedef Fun2 Base;
-
- public:
- typedef typename Base::ResultType ResultType;
- typedef typename Base::Parm1 Parm1;
- typedef typename Base::Parm2 Parm2;
- typedef typename Base::Parm3 Parm3;
- typedef typename Base::Parm4 Parm4;
- typedef typename Base::Parm5 Parm5;
- typedef typename Base::Parm6 Parm6;
- typedef typename Base::Parm7 Parm7;
- typedef typename Base::Parm8 Parm8;
- typedef typename Base::Parm9 Parm9;
- typedef typename Base::Parm10 Parm10;
- typedef typename Base::Parm11 Parm11;
- typedef typename Base::Parm12 Parm12;
- typedef typename Base::Parm13 Parm13;
- typedef typename Base::Parm14 Parm14;
- typedef typename Base::Parm15 Parm15;
-
- Chainer(const Fun1& fun1, const Fun2& fun2) : f1_(fun1), f2_(fun2) {}
-
- LOKI_DEFINE_CLONE_FUNCTORIMPL(Chainer)
+template <typename Fun1, typename Fun2>
+class Chainer : public Fun2::Impl
+{
+ typedef Fun2 Base;
+
+public:
+ typedef typename Base::ResultType ResultType;
+ typedef typename Base::Parm1 Parm1;
+ typedef typename Base::Parm2 Parm2;
+ typedef typename Base::Parm3 Parm3;
+ typedef typename Base::Parm4 Parm4;
+ typedef typename Base::Parm5 Parm5;
+ typedef typename Base::Parm6 Parm6;
+ typedef typename Base::Parm7 Parm7;
+ typedef typename Base::Parm8 Parm8;
+ typedef typename Base::Parm9 Parm9;
+ typedef typename Base::Parm10 Parm10;
+ typedef typename Base::Parm11 Parm11;
+ typedef typename Base::Parm12 Parm12;
+ typedef typename Base::Parm13 Parm13;
+ typedef typename Base::Parm14 Parm14;
+ typedef typename Base::Parm15 Parm15;
+
+ Chainer(const Fun1& fun1, const Fun2& fun2) : f1_(fun1), f2_(fun2) {}
+
+ LOKI_DEFINE_CLONE_FUNCTORIMPL(Chainer)
#ifdef LOKI_FUNCTORS_ARE_COMPARABLE
-
- bool operator==(const typename Base::Impl::FunctorImplBaseType& rhs) const
- {
- if(typeid(*this) != typeid(rhs))
- return false; // cannot be equal
- // if this line gives a compiler error, you are using a function object.
- // you need to implement bool MyFnObj::operator == (const MyFnObj&) const;
- return f1_ == ((static_cast<const Chainer&> (rhs)).f2_) &&
- f2_ == ((static_cast<const Chainer&> (rhs)).f1_);
- }
+
+ bool operator==(const typename Base::Impl::FunctorImplBaseType& rhs) const
+ {
+ if(typeid(*this) != typeid(rhs))
+ return false; // cannot be equal
+ // if this line gives a compiler error, you are using a function object.
+ // you need to implement bool MyFnObj::operator == (const MyFnObj&) const;
+ return f1_ == ((static_cast<const Chainer&> (rhs)).f2_) &&
+ f2_ == ((static_cast<const Chainer&> (rhs)).f1_);
+ }
#endif
- // operator() implementations for up to 15 arguments
-
- ResultType operator()()
- { return f1_(), f2_(); }
-
- ResultType operator()(Parm1 p1)
- { return f1_(p1), f2_(p1); }
-
- ResultType operator()(Parm1 p1, Parm2 p2)
- { return f1_(p1, p2), f2_(p1, p2); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
- { return f1_(p1, p2, p3), f2_(p1, p2, p3); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
- { return f1_(p1, p2, p3, p4), f2_(p1, p2, p3, p4); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
- { return f1_(p1, p2, p3, p4, p5), f2_(p1, p2, p3, p4, p5); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6)
- { return f1_(p1, p2, p3, p4, p5, p6), f2_(p1, p2, p3, p4, p5, p6); }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7)
- {
- return f1_(p1, p2, p3, p4, p5, p6, p7),
- f2_(p1, p2, p3, p4, p5, p6, p7);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8)
- {
- return f1_(p1, p2, p3, p4, p5, p6, p7, p8),
- f2_(p1, p2, p3, p4, p5, p6, p7, p8);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
- {
- return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9),
- f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
- {
- return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10),
- f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
- {
- return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11),
- f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
- Parm12 p12)
- {
- return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12),
- f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
- Parm12 p12, Parm13 p13)
- {
- return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13),
- f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
- Parm12 p12, Parm13 p13, Parm14 p14)
- {
- return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13,
- p14),
- f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13,
+ // operator() implementations for up to 15 arguments
+
+ ResultType operator()()
+ { return f1_(), f2_(); }
+
+ ResultType operator()(Parm1 p1)
+ { return f1_(p1), f2_(p1); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2)
+ { return f1_(p1, p2), f2_(p1, p2); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
+ { return f1_(p1, p2, p3), f2_(p1, p2, p3); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
+ { return f1_(p1, p2, p3, p4), f2_(p1, p2, p3, p4); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
+ { return f1_(p1, p2, p3, p4, p5), f2_(p1, p2, p3, p4, p5); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6)
+ { return f1_(p1, p2, p3, p4, p5, p6), f2_(p1, p2, p3, p4, p5, p6); }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7)
+ {
+ return f1_(p1, p2, p3, p4, p5, p6, p7),
+ f2_(p1, p2, p3, p4, p5, p6, p7);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8)
+ {
+ return f1_(p1, p2, p3, p4, p5, p6, p7, p8),
+ f2_(p1, p2, p3, p4, p5, p6, p7, p8);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
+ {
+ return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9),
+ f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
+ {
+ return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10),
+ f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
+ {
+ return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11),
+ f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
+ Parm12 p12)
+ {
+ return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12),
+ f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
+ Parm12 p12, Parm13 p13)
+ {
+ return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13),
+ f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13);
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
+ Parm12 p12, Parm13 p13, Parm14 p14)
+ {
+ return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13,
+ p14),
+ f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13,
p14);
- }
-
- ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
- Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
- Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
- {
- return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13,
- p14, p15),
- f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13,
- p14, p15);
- }
-
- private:
- Fun1 f1_;
- Fun2 f2_;
- };
-
+ }
+
+ ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
+ Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
+ Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
+ {
+ return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13,
+ p14, p15),
+ f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13,
+ p14, p15);
+ }
+
+private:
+ Fun1 f1_;
+ Fun2 f2_;
+};
+
////////////////////////////////////////////////////////////////////////////////
/// Chains two functor calls one after another
/// \ingroup FunctorGroup
////////////////////////////////////////////////////////////////////////////////
- template <class Fun1, class Fun2>
- Fun2 Chain(
- const Fun1& fun1,
- const Fun2& fun2)
- {
- return Fun2(std::auto_ptr<typename Fun2::Impl>(
- new Chainer<Fun1, Fun2>(fun1, fun2)));
- }
+template <class Fun1, class Fun2>
+Fun2 Chain(
+ const Fun1& fun1,
+ const Fun2& fun2)
+{
+ return Fun2(std::auto_ptr<typename Fun2::Impl>(
+ new Chainer<Fun1, Fun2>(fun1, fun2)));
+}
} // namespace Loki
diff --git a/shared/loki/HierarchyGenerators.h b/shared/loki/HierarchyGenerators.h
index 3fa11ffc..83ec194c 100644
--- a/shared/loki/HierarchyGenerators.h
+++ b/shared/loki/HierarchyGenerators.h
@@ -2,14 +2,14 @@
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
-// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author or Addison-Wesley Longman make no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author or Addison-Wesley Longman make no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_HIERARCHYGENERATORS_INC_
@@ -25,8 +25,8 @@
namespace Loki
{
#if defined(_MSC_VER) && _MSC_VER >= 1300
-#pragma warning( push )
- // 'class1' : base-class 'class2' is already a base-class of 'class3'
+#pragma warning( push )
+// 'class1' : base-class 'class2' is already a base-class of 'class3'
#pragma warning( disable : 4584 )
#endif // _MSC_VER
@@ -35,180 +35,180 @@ namespace Loki
// Generates a scattered hierarchy starting from a typelist and a template
// Invocation (TList is a typelist, Unit is a template of one arg):
// GenScatterHierarchy<TList, Unit>
-// The generated class inherits all classes generated by instantiating the
-// template 'Unit' with the types contained in TList
+// The generated class inherits all classes generated by instantiating the
+// template 'Unit' with the types contained in TList
////////////////////////////////////////////////////////////////////////////////
- namespace Private
- {
- // The following type helps to overcome subtle flaw in the original
- // implementation of GenScatterHierarchy.
- // The flaw is revealed when the input type list of GenScatterHierarchy
- // contains more then one element of the same type (e.g. LOKI_TYPELIST_2(int, int)).
- // In this case GenScatterHierarchy will contain multiple bases of the same
- // type and some of them will not be reachable (per 10.3).
- // For example before the fix the first element of Tuple<LOKI_TYPELIST_2(int, int)>
- // is not reachable in any way!
- template<class, class>
- struct ScatterHierarchyTag;
- }
+namespace Private
+{
+// The following type helps to overcome subtle flaw in the original
+// implementation of GenScatterHierarchy.
+// The flaw is revealed when the input type list of GenScatterHierarchy
+// contains more then one element of the same type (e.g. LOKI_TYPELIST_2(int, int)).
+// In this case GenScatterHierarchy will contain multiple bases of the same
+// type and some of them will not be reachable (per 10.3).
+// For example before the fix the first element of Tuple<LOKI_TYPELIST_2(int, int)>
+// is not reachable in any way!
+template<class, class>
+struct ScatterHierarchyTag;
+}
- template <class TList, template <class> class Unit>
- class GenScatterHierarchy;
-
- template <class T1, class T2, template <class> class Unit>
- class GenScatterHierarchy<Typelist<T1, T2>, Unit>
- : public GenScatterHierarchy<Private::ScatterHierarchyTag<T1, T2>, Unit>
- , public GenScatterHierarchy<T2, Unit>
- {
- public:
- typedef Typelist<T1, T2> TList;
- // Insure that LeftBase is unique and therefore reachable
- typedef GenScatterHierarchy<Private::ScatterHierarchyTag<T1, T2>, Unit> LeftBase;
- typedef GenScatterHierarchy<T2, Unit> RightBase;
- template <typename T> struct Rebind
- {
- typedef Unit<T> Result;
- };
- };
-
- // In the middle *unique* class that resolve possible ambiguity
- template <class T1, class T2, template <class> class Unit>
- class GenScatterHierarchy<Private::ScatterHierarchyTag<T1, T2>, Unit>
- : public GenScatterHierarchy<T1, Unit>
+template <class TList, template <class> class Unit>
+class GenScatterHierarchy;
+
+template <class T1, class T2, template <class> class Unit>
+class GenScatterHierarchy<Typelist<T1, T2>, Unit>
+ : public GenScatterHierarchy<Private::ScatterHierarchyTag<T1, T2>, Unit>
+ , public GenScatterHierarchy<T2, Unit>
+{
+public:
+ typedef Typelist<T1, T2> TList;
+ // Insure that LeftBase is unique and therefore reachable
+ typedef GenScatterHierarchy<Private::ScatterHierarchyTag<T1, T2>, Unit> LeftBase;
+ typedef GenScatterHierarchy<T2, Unit> RightBase;
+ template <typename T> struct Rebind
{
+ typedef Unit<T> Result;
};
+};
+
+// In the middle *unique* class that resolve possible ambiguity
+template <class T1, class T2, template <class> class Unit>
+class GenScatterHierarchy<Private::ScatterHierarchyTag<T1, T2>, Unit>
+ : public GenScatterHierarchy<T1, Unit>
+{
+};
- template <class AtomicType, template <class> class Unit>
- class GenScatterHierarchy : public Unit<AtomicType>
+template <class AtomicType, template <class> class Unit>
+class GenScatterHierarchy : public Unit<AtomicType>
+{
+ typedef Unit<AtomicType> LeftBase;
+ template <typename T> struct Rebind
{
- typedef Unit<AtomicType> LeftBase;
- template <typename T> struct Rebind
- {
- typedef Unit<T> Result;
- };
+ typedef Unit<T> Result;
};
-
- template <template <class> class Unit>
- class GenScatterHierarchy<NullType, Unit>
+};
+
+template <template <class> class Unit>
+class GenScatterHierarchy<NullType, Unit>
+{
+ template <typename T> struct Rebind
{
- template <typename T> struct Rebind
- {
- typedef Unit<T> Result;
- };
+ typedef Unit<T> Result;
};
-
+};
+
////////////////////////////////////////////////////////////////////////////////
// function template Field
// Accesses a field in an object of a type generated with GenScatterHierarchy
// Invocation (obj is an object of a type H generated with GenScatterHierarchy,
// T is a type in the typelist used to generate H):
// Field<T>(obj)
-// returns a reference to Unit<T>, where Unit is the template used to generate H
+// returns a reference to Unit<T>, where Unit is the template used to generate H
////////////////////////////////////////////////////////////////////////////////
- template <class T, class H>
- typename H::template Rebind<T>::Result& Field(H& obj)
- {
- return obj;
- }
-
- template <class T, class H>
- const typename H::template Rebind<T>::Result& Field(const H& obj)
- {
- return obj;
- }
-
+template <class T, class H>
+typename H::template Rebind<T>::Result& Field(H& obj)
+{
+ return obj;
+}
+
+template <class T, class H>
+const typename H::template Rebind<T>::Result& Field(const H& obj)
+{
+ return obj;
+}
+
////////////////////////////////////////////////////////////////////////////////
// function template TupleUnit
-// The building block of tuples
+// The building block of tuples
////////////////////////////////////////////////////////////////////////////////
- template <class T>
- struct TupleUnit
- {
- T value_;
- operator T&() { return value_; }
- operator const T&() const { return value_; }
- };
+template <class T>
+struct TupleUnit
+{
+ T value_;
+ operator T& () { return value_; }
+ operator const T& () const { return value_; }
+};
////////////////////////////////////////////////////////////////////////////////
// class template Tuple
-// Implements a tuple class that holds a number of values and provides field
-// access to them via the Field function (below)
+// Implements a tuple class that holds a number of values and provides field
+// access to them via the Field function (below)
////////////////////////////////////////////////////////////////////////////////
- template <class TList>
- struct Tuple : public GenScatterHierarchy<TList, TupleUnit>
- {
- };
+template <class TList>
+struct Tuple : public GenScatterHierarchy<TList, TupleUnit>
+{
+};
////////////////////////////////////////////////////////////////////////////////
// helper class template FieldHelper
// See Field below
////////////////////////////////////////////////////////////////////////////////
- template <class H, unsigned int i> struct FieldHelper;
-
- template <class H>
- struct FieldHelper<H, 0>
+template <class H, unsigned int i> struct FieldHelper;
+
+template <class H>
+struct FieldHelper<H, 0>
+{
+ typedef typename H::TList::Head ElementType;
+ typedef typename H::template Rebind<ElementType>::Result UnitType;
+
+ enum
{
- typedef typename H::TList::Head ElementType;
- typedef typename H::template Rebind<ElementType>::Result UnitType;
-
- enum
- {
- isTuple = Conversion<UnitType, TupleUnit<ElementType> >::sameType,
- isConst = TypeTraits<H>::isConst
- };
-
- typedef const typename H::LeftBase ConstLeftBase;
-
- typedef typename Select<isConst, ConstLeftBase,
+ isTuple = Conversion<UnitType, TupleUnit<ElementType> >::sameType,
+ isConst = TypeTraits<H>::isConst
+ };
+
+ typedef const typename H::LeftBase ConstLeftBase;
+
+ typedef typename Select<isConst, ConstLeftBase,
typename H::LeftBase>::Result LeftBase;
-
- typedef typename Select<isTuple, ElementType,
+
+ typedef typename Select<isTuple, ElementType,
UnitType>::Result UnqualifiedResultType;
- typedef typename Select<isConst, const UnqualifiedResultType,
- UnqualifiedResultType>::Result ResultType;
-
- static ResultType& Do(H& obj)
- {
- LeftBase& leftBase = obj;
- return leftBase;
- }
- };
+ typedef typename Select<isConst, const UnqualifiedResultType,
+ UnqualifiedResultType>::Result ResultType;
+
+ static ResultType& Do(H& obj)
+ {
+ LeftBase& leftBase = obj;
+ return leftBase;
+ }
+};
+
+template <class H, unsigned int i>
+struct FieldHelper
+{
+ typedef typename TL::TypeAt<typename H::TList, i>::Result ElementType;
+ typedef typename H::template Rebind<ElementType>::Result UnitType;
- template <class H, unsigned int i>
- struct FieldHelper
+ enum
{
- typedef typename TL::TypeAt<typename H::TList, i>::Result ElementType;
- typedef typename H::template Rebind<ElementType>::Result UnitType;
-
- enum
- {
- isTuple = Conversion<UnitType, TupleUnit<ElementType> >::sameType,
- isConst = TypeTraits<H>::isConst
- };
-
- typedef const typename H::RightBase ConstRightBase;
-
- typedef typename Select<isConst, ConstRightBase,
+ isTuple = Conversion<UnitType, TupleUnit<ElementType> >::sameType,
+ isConst = TypeTraits<H>::isConst
+ };
+
+ typedef const typename H::RightBase ConstRightBase;
+
+ typedef typename Select<isConst, ConstRightBase,
typename H::RightBase>::Result RightBase;
- typedef typename Select<isTuple, ElementType,
+ typedef typename Select<isTuple, ElementType,
UnitType>::Result UnqualifiedResultType;
- typedef typename Select<isConst, const UnqualifiedResultType,
- UnqualifiedResultType>::Result ResultType;
-
- static ResultType& Do(H& obj)
- {
- RightBase& rightBase = obj;
- return FieldHelper<RightBase, i - 1>::Do(rightBase);
- }
- };
+ typedef typename Select<isConst, const UnqualifiedResultType,
+ UnqualifiedResultType>::Result ResultType;
+
+ static ResultType& Do(H& obj)
+ {
+ RightBase& rightBase = obj;
+ return FieldHelper<RightBase, i - 1>::Do(rightBase);
+ }
+};
////////////////////////////////////////////////////////////////////////////////
// function template Field
@@ -217,23 +217,23 @@ namespace Loki
// i is the index of a type in the typelist used to generate H):
// Field<i>(obj)
// returns a reference to Unit<T>, where Unit is the template used to generate H
-// and T is the i-th type in the typelist
+// and T is the i-th type in the typelist
////////////////////////////////////////////////////////////////////////////////
- template <int i, class H>
- typename FieldHelper<H, i>::ResultType&
- Field(H& obj)
- {
- return FieldHelper<H, i>::Do(obj);
- }
-
+template <int i, class H>
+typename FieldHelper<H, i>::ResultType&
+Field(H& obj)
+{
+ return FieldHelper<H, i>::Do(obj);
+}
+
// template <int i, class H>
// const typename FieldHelper<H, i>::ResultType&
// Field(const H& obj)
// {
// return FieldHelper<H, i>::Do(obj);
// }
-
+
////////////////////////////////////////////////////////////////////////////////
// class template GenLinearHierarchy
// Generates a linear hierarchy starting from a typelist and a template
@@ -241,49 +241,49 @@ namespace Loki
// GenScatterHierarchy<TList, Unit>
////////////////////////////////////////////////////////////////////////////////
- template
- <
- class TList,
- template <class AtomicType, class Base> class Unit,
- class Root = EmptyType
- >
- class GenLinearHierarchy;
-
- template
- <
- class T1,
- class T2,
- template <class, class> class Unit,
- class Root
- >
- class GenLinearHierarchy<Typelist<T1, T2>, Unit, Root>
- : public Unit< T1, GenLinearHierarchy<T2, Unit, Root> >
- {
- };
+template
+<
+class TList,
+ template <class AtomicType, class Base> class Unit,
+ class Root = EmptyType
+ >
+class GenLinearHierarchy;
- template
- <
- class T,
- template <class, class> class Unit,
- class Root
- >
- class GenLinearHierarchy<Typelist<T, NullType>, Unit, Root>
- : public Unit<T, Root>
- {
- };
+template
+<
+class T1,
+ class T2,
+ template <class, class> class Unit,
+ class Root
+ >
+class GenLinearHierarchy<Typelist<T1, T2>, Unit, Root>
+ : public Unit< T1, GenLinearHierarchy<T2, Unit, Root> >
+{
+};
- template
- <
- template <class, class> class Unit,
- class Root
- >
- class GenLinearHierarchy<NullType , Unit, Root>
- : public Root // is this better: Unit<NullType, Root> ?
- {
- };
+template
+<
+class T,
+ template <class, class> class Unit,
+ class Root
+ >
+class GenLinearHierarchy<Typelist<T, NullType>, Unit, Root>
+ : public Unit<T, Root>
+{
+};
+
+template
+<
+template <class, class> class Unit,
+ class Root
+ >
+class GenLinearHierarchy<NullType , Unit, Root>
+ : public Root // is this better: Unit<NullType, Root> ?
+{
+};
#if defined(_MSC_VER) && _MSC_VER >= 1300
-#pragma warning( pop )
+#pragma warning( pop )
#endif
} // namespace Loki
diff --git a/shared/loki/Key.h b/shared/loki/Key.h
index 4daaa603..c80d6f4e 100644
--- a/shared/loki/Key.h
+++ b/shared/loki/Key.h
@@ -4,16 +4,16 @@
//
// Code covered by the MIT License
//
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
//
// The authors make no representations about the suitability of this software
// for any purpose. It is provided "as is" without express or implied warranty.
//
// This code DOES NOT accompany the book:
-// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
//
////////////////////////////////////////////////////////////////////////////////
@@ -28,735 +28,737 @@
namespace Loki
{
- template<
- class Factory,
- typename IdentifierType
- >
- class Key;
+template<
+class Factory,
+ typename IdentifierType
+ >
+class Key;
- template<class F, typename I>
- bool operator==(const Key<F, I> &k1, const Key<F, I> &k2);
+template<class F, typename I>
+bool operator==(const Key<F, I> &k1, const Key<F, I> &k2);
+
+template<class F, typename I>
+bool operator<(const Key<F, I> &k1, const Key<F, I> &k2);
+
+
+/**
+ * A Key class
+ */
+template<
+class Factory,
+ typename IdentifierType
+ >
+class Key
+{
+ typedef typename Factory::Parm1 Parm1;
+ typedef typename Factory::Parm2 Parm2;
+ typedef typename Factory::Parm3 Parm3;
+ typedef typename Factory::Parm4 Parm4;
+ typedef typename Factory::Parm5 Parm5;
+ typedef typename Factory::Parm6 Parm6;
+ typedef typename Factory::Parm7 Parm7;
+ typedef typename Factory::Parm8 Parm8;
+ typedef typename Factory::Parm9 Parm9;
+ typedef typename Factory::Parm10 Parm10;
+ typedef typename Factory::Parm11 Parm11;
+ typedef typename Factory::Parm12 Parm12;
+ typedef typename Factory::Parm13 Parm13;
+ typedef typename Factory::Parm14 Parm14;
+ typedef typename Factory::Parm15 Parm15;
+public:
+ // member variables
+ int count; // should be const, but constness prevent default copy ctor
+ IdentifierType id;
+ Parm1 p1;
+ Parm2 p2;
+ Parm3 p3;
+ Parm4 p4;
+ Parm5 p5;
+ Parm6 p6;
+ Parm7 p7;
+ Parm8 p8;
+ Parm9 p9;
+ Parm10 p10;
+ Parm11 p11;
+ Parm12 p12;
+ Parm13 p13;
+ Parm14 p14;
+ Parm15 p15;
+
+ // member functions
+ Key() : count(-1)
+ {
+ }
+
+ Key(const IdentifierType& id) : count(0)
+ {
+ this->id = id;
+ }
+
+ Key(const IdentifierType& id,
+ Parm1& p1) : count(1)
+ {
+ this->id = id;
+ this->p1 = p1;
+ }
+
+ Key(const IdentifierType& id,
+ Parm1& p1, Parm2& p2) : count(2)
+ {
+ this->id = id;
+ this->p1 = p1;
+ this->p2 = p2;
+ }
+
+ Key(const IdentifierType& id,
+ Parm1& p1, Parm2& p2, Parm3& p3) : count(3)
+ {
+ this->id = id;
+ this->p1 = p1;
+ this->p2 = p2;
+ this->p3 = p3;
+ }
+
+ Key(const IdentifierType& id,
+ Parm1& p1, Parm2& p2, Parm3& p3, Parm4& p4) : count(4)
+ {
+ this->id = id;
+ this->p1 = p1;
+ this->p2 = p2;
+ this->p3 = p3;
+ this->p4 = p4;
+ }
+
+ Key(const IdentifierType& id,
+ Parm1& p1, Parm2& p2, Parm3& p3, Parm4& p4, Parm5& p5) : count(5)
+ {
+ this->id = id;
+ this->p1 = p1;
+ this->p2 = p2;
+ this->p3 = p3;
+ this->p4 = p4;
+ this->p5 = p5;
+ }
+
+ Key(const IdentifierType& id,
+ Parm1& p1, Parm2& p2, Parm3& p3, Parm4& p4, Parm5& p5,
+ Parm6& p6) : count(6)
+ {
+ this->id = id;
+ this->p1 = p1;
+ this->p2 = p2;
+ this->p3 = p3;
+ this->p4 = p4;
+ this->p5 = p5;
+ this->p6 = p6;
+ }
+
+ Key(const IdentifierType& id,
+ Parm1& p1, Parm2& p2, Parm3& p3, Parm4& p4, Parm5& p5,
+ Parm6& p6, Parm7& p7 ) : count(7)
+ {
+ this->id = id;
+ this->p1 = p1;
+ this->p2 = p2;
+ this->p3 = p3;
+ this->p4 = p4;
+ this->p5 = p5;
+ this->p6 = p6;
+ this->p7 = p7;
+ }
+
+ Key(const IdentifierType& id,
+ Parm1& p1, Parm2& p2, Parm3& p3, Parm4& p4, Parm5& p5,
+ Parm6& p6, Parm7& p7, Parm8& p8) : count(8)
+ {
+ this->id = id;
+ this->p1 = p1;
+ this->p2 = p2;
+ this->p3 = p3;
+ this->p4 = p4;
+ this->p5 = p5;
+ this->p6 = p6;
+ this->p7 = p7;
+ this->p8 = p8;
+ }
+
+ Key(const IdentifierType& id,
+ Parm1& p1, Parm2& p2, Parm3& p3, Parm4& p4, Parm5& p5,
+ Parm6& p6, Parm7& p7, Parm8& p8, Parm9& p9) : count(9)
+ {
+ this->id = id;
+ this->p1 = p1;
+ this->p2 = p2;
+ this->p3 = p3;
+ this->p4 = p4;
+ this->p5 = p5;
+ this->p6 = p6;
+ this->p7 = p7;
+ this->p8 = p8;
+ this->p9 = p9;
+ }
+
+ Key(const IdentifierType& id,
+ Parm1& p1, Parm2& p2, Parm3& p3, Parm4& p4, Parm5& p5,
+ Parm6& p6, Parm7& p7, Parm8& p8, Parm9& p9,Parm10& p10) : count(10)
+ {
+ this->id = id;
+ this->p1 = p1;
+ this->p2 = p2;
+ this->p3 = p3;
+ this->p4 = p4;
+ this->p5 = p5;
+ this->p6 = p6;
+ this->p7 = p7;
+ this->p8 = p8;
+ this->p9 = p9;
+ this->p10 = p10;
+ }
+
+ Key(const IdentifierType& id,
+ Parm1& p1, Parm2& p2, Parm3& p3, Parm4& p4, Parm5& p5,
+ Parm6& p6, Parm7& p7, Parm8& p8, Parm9& p9, Parm10& p10,
+ Parm11& p11) : count(11)
+ {
+ this->id = id;
+ this->p1 = p1;
+ this->p2 = p2;
+ this->p3 = p3;
+ this->p4 = p4;
+ this->p5 = p5;
+ this->p6 = p6;
+ this->p7 = p7;
+ this->p8 = p8;
+ this->p9 = p9;
+ this->p10 = p10;
+ this->p11 = p11;
+ }
+
+ Key(const IdentifierType& id,
+ Parm1& p1, Parm2& p2, Parm3& p3, Parm4& p4, Parm5& p5,
+ Parm6& p6, Parm7& p7, Parm8& p8, Parm9& p9, Parm10& p10,
+ Parm11& p11, Parm12& p12) : count(12)
+ {
+ this->id = id;
+ this->p1 = p1;
+ this->p2 = p2;
+ this->p3 = p3;
+ this->p4 = p4;
+ this->p5 = p5;
+ this->p6 = p6;
+ this->p7 = p7;
+ this->p8 = p8;
+ this->p9 = p9;
+ this->p10 = p10;
+ this->p11 = p11;
+ this->p12 = p12;
+ }
+
+ Key(const IdentifierType& id,
+ Parm1& p1, Parm2& p2, Parm3& p3, Parm4& p4, Parm5& p5,
+ Parm6& p6, Parm7& p7, Parm8& p8, Parm9& p9, Parm10& p10,
+ Parm11& p11, Parm12& p12, Parm13& p13) : count(13)
+ {
+ this->id = id;
+ this->p1 = p1;
+ this->p2 = p2;
+ this->p3 = p3;
+ this->p4 = p4;
+ this->p5 = p5;
+ this->p6 = p6;
+ this->p7 = p7;
+ this->p8 = p8;
+ this->p9 = p9;
+ this->p10 = p10;
+ this->p11 = p11;
+ this->p12 = p12;
+ this->p13 = p13;
+ }
+
+ Key(const IdentifierType& id,
+ Parm1& p1, Parm2& p2, Parm3& p3, Parm4& p4, Parm5& p5,
+ Parm6& p6, Parm7& p7, Parm8& p8, Parm9& p9, Parm10& p10,
+ Parm11& p11, Parm12& p12, Parm13& p13, Parm14& p14) : count(14)
+ {
+ this->id = id;
+ this->p1 = p1;
+ this->p2 = p2;
+ this->p3 = p3;
+ this->p4 = p4;
+ this->p5 = p5;
+ this->p6 = p6;
+ this->p7 = p7;
+ this->p8 = p8;
+ this->p9 = p9;
+ this->p10 = p10;
+ this->p11 = p11;
+ this->p12 = p12;
+ this->p13 = p13;
+ this->p14 = p14;
+ }
+
+ Key(const IdentifierType& id,
+ Parm1& p1, Parm2& p2, Parm3& p3, Parm4& p4, Parm5& p5,
+ Parm6& p6, Parm7& p7, Parm8& p8, Parm9& p9, Parm10& p10,
+ Parm11& p11, Parm12& p12, Parm13& p13, Parm14& p14, Parm15& p15) : count(15)
+ {
+ this->id = id;
+ this->p1 = p1;
+ this->p2 = p2;
+ this->p3 = p3;
+ this->p4 = p4;
+ this->p5 = p5;
+ this->p6 = p6;
+ this->p7 = p7;
+ this->p8 = p8;
+ this->p9 = p9;
+ this->p10 = p10;
+ this->p11 = p11;
+ this->p12 = p12;
+ this->p13 = p13;
+ this->p14 = p14;
+ this->p15 = p15;
+ }
template<class F, typename I>
- bool operator<(const Key<F, I> &k1, const Key<F, I> &k2);
-
-
- /**
- * A Key class
- */
- template<
- class Factory,
- typename IdentifierType
- >
- class Key
- {
- typedef typename Factory::Parm1 Parm1;
- typedef typename Factory::Parm2 Parm2;
- typedef typename Factory::Parm3 Parm3;
- typedef typename Factory::Parm4 Parm4;
- typedef typename Factory::Parm5 Parm5;
- typedef typename Factory::Parm6 Parm6;
- typedef typename Factory::Parm7 Parm7;
- typedef typename Factory::Parm8 Parm8;
- typedef typename Factory::Parm9 Parm9;
- typedef typename Factory::Parm10 Parm10;
- typedef typename Factory::Parm11 Parm11;
- typedef typename Factory::Parm12 Parm12;
- typedef typename Factory::Parm13 Parm13;
- typedef typename Factory::Parm14 Parm14;
- typedef typename Factory::Parm15 Parm15;
- public:
- // member variables
- int count; // should be const, but constness prevent default copy ctor
- IdentifierType id;
- Parm1 p1;
- Parm2 p2;
- Parm3 p3;
- Parm4 p4;
- Parm5 p5;
- Parm6 p6;
- Parm7 p7;
- Parm8 p8;
- Parm9 p9;
- Parm10 p10;
- Parm11 p11;
- Parm12 p12;
- Parm13 p13;
- Parm14 p14;
- Parm15 p15;
-
- // member functions
- Key() : count(-1)
- {
- }
-
- Key(const IdentifierType& id) : count(0)
- {
- this->id = id;
- }
-
- Key(const IdentifierType& id,
- Parm1 &p1) : count(1)
- {
- this->id = id;
- this->p1 = p1;
- }
-
- Key(const IdentifierType& id,
- Parm1 &p1, Parm2 &p2) : count(2)
- {
- this->id = id;
- this->p1 = p1;
- this->p2 = p2;
- }
-
- Key(const IdentifierType& id,
- Parm1 &p1, Parm2 &p2, Parm3 &p3) : count(3)
- {
- this->id = id;
- this->p1 = p1;
- this->p2 = p2;
- this->p3 = p3;
- }
-
- Key(const IdentifierType& id,
- Parm1 &p1, Parm2 &p2, Parm3 &p3, Parm4 &p4) : count(4)
- {
- this->id = id;
- this->p1 = p1;
- this->p2 = p2;
- this->p3 = p3;
- this->p4 = p4;
- }
-
- Key(const IdentifierType& id,
- Parm1 &p1, Parm2 &p2, Parm3 &p3, Parm4 &p4, Parm5 &p5) : count(5)
- {
- this->id = id;
- this->p1 = p1;
- this->p2 = p2;
- this->p3 = p3;
- this->p4 = p4;
- this->p5 = p5;
- }
-
- Key(const IdentifierType& id,
- Parm1 &p1, Parm2 &p2, Parm3 &p3, Parm4 &p4, Parm5 &p5,
- Parm6 &p6) : count(6)
- {
- this->id = id;
- this->p1 = p1;
- this->p2 = p2;
- this->p3 = p3;
- this->p4 = p4;
- this->p5 = p5;
- this->p6 = p6;
- }
-
- Key(const IdentifierType& id,
- Parm1 &p1, Parm2 &p2, Parm3 &p3, Parm4 &p4, Parm5 &p5,
- Parm6 &p6, Parm7 &p7 ) : count(7)
- {
- this->id = id;
- this->p1 = p1;
- this->p2 = p2;
- this->p3 = p3;
- this->p4 = p4;
- this->p5 = p5;
- this->p6 = p6;
- this->p7 = p7;
- }
-
- Key(const IdentifierType& id,
- Parm1 &p1, Parm2 &p2, Parm3 &p3, Parm4 &p4, Parm5 &p5,
- Parm6 &p6, Parm7 &p7, Parm8 &p8) : count(8)
- {
- this->id = id;
- this->p1 = p1;
- this->p2 = p2;
- this->p3 = p3;
- this->p4 = p4;
- this->p5 = p5;
- this->p6 = p6;
- this->p7 = p7;
- this->p8 = p8;
- }
-
- Key(const IdentifierType& id,
- Parm1 &p1, Parm2 &p2, Parm3 &p3, Parm4 &p4, Parm5 &p5,
- Parm6 &p6, Parm7 &p7, Parm8 &p8, Parm9 &p9) : count(9)
- {
- this->id = id;
- this->p1 = p1;
- this->p2 = p2;
- this->p3 = p3;
- this->p4 = p4;
- this->p5 = p5;
- this->p6 = p6;
- this->p7 = p7;
- this->p8 = p8;
- this->p9 = p9;
- }
-
- Key(const IdentifierType& id,
- Parm1 &p1, Parm2 &p2, Parm3 &p3, Parm4 &p4, Parm5 &p5,
- Parm6 &p6, Parm7 &p7, Parm8 &p8, Parm9 &p9,Parm10 &p10) : count(10)
- {
- this->id = id;
- this->p1 = p1;
- this->p2 = p2;
- this->p3 = p3;
- this->p4 = p4;
- this->p5 = p5;
- this->p6 = p6;
- this->p7 = p7;
- this->p8 = p8;
- this->p9 = p9;
- this->p10 = p10;
- }
-
- Key(const IdentifierType& id,
- Parm1 &p1, Parm2 &p2, Parm3 &p3, Parm4 &p4, Parm5 &p5,
- Parm6 &p6, Parm7 &p7, Parm8 &p8, Parm9 &p9, Parm10 &p10,
- Parm11 &p11) : count(11)
- {
- this->id = id;
- this->p1 = p1;
- this->p2 = p2;
- this->p3 = p3;
- this->p4 = p4;
- this->p5 = p5;
- this->p6 = p6;
- this->p7 = p7;
- this->p8 = p8;
- this->p9 = p9;
- this->p10 = p10;
- this->p11 = p11;
- }
-
- Key(const IdentifierType& id,
- Parm1 &p1, Parm2 &p2, Parm3 &p3, Parm4 &p4, Parm5 &p5,
- Parm6 &p6, Parm7 &p7, Parm8 &p8, Parm9 &p9, Parm10 &p10,
- Parm11 &p11, Parm12 &p12) : count(12)
- {
- this->id = id;
- this->p1 = p1;
- this->p2 = p2;
- this->p3 = p3;
- this->p4 = p4;
- this->p5 = p5;
- this->p6 = p6;
- this->p7 = p7;
- this->p8 = p8;
- this->p9 = p9;
- this->p10 = p10;
- this->p11 = p11;
- this->p12 = p12;
- }
-
- Key(const IdentifierType& id,
- Parm1 &p1, Parm2 &p2, Parm3 &p3, Parm4 &p4, Parm5 &p5,
- Parm6 &p6, Parm7 &p7, Parm8 &p8, Parm9 &p9, Parm10 &p10,
- Parm11 &p11, Parm12 &p12, Parm13 &p13) : count(13)
- {
- this->id = id;
- this->p1 = p1;
- this->p2 = p2;
- this->p3 = p3;
- this->p4 = p4;
- this->p5 = p5;
- this->p6 = p6;
- this->p7 = p7;
- this->p8 = p8;
- this->p9 = p9;
- this->p10 = p10;
- this->p11 = p11;
- this->p12 = p12;
- this->p13 = p13;
- }
-
- Key(const IdentifierType& id,
- Parm1 &p1, Parm2 &p2, Parm3 &p3, Parm4 &p4, Parm5 &p5,
- Parm6 &p6, Parm7 &p7, Parm8 &p8, Parm9 &p9, Parm10 &p10,
- Parm11 &p11, Parm12 &p12, Parm13 &p13, Parm14 &p14) : count(14)
- {
- this->id = id;
- this->p1 = p1;
- this->p2 = p2;
- this->p3 = p3;
- this->p4 = p4;
- this->p5 = p5;
- this->p6 = p6;
- this->p7 = p7;
- this->p8 = p8;
- this->p9 = p9;
- this->p10 = p10;
- this->p11 = p11;
- this->p12 = p12;
- this->p13 = p13;
- this->p14 = p14;
- }
-
- Key(const IdentifierType& id,
- Parm1 &p1, Parm2 &p2, Parm3 &p3, Parm4 &p4, Parm5 &p5,
- Parm6 &p6, Parm7 &p7, Parm8 &p8, Parm9 &p9, Parm10 &p10,
- Parm11 &p11, Parm12 &p12, Parm13 &p13, Parm14 &p14, Parm15 &p15) : count(15)
- {
- this->id = id;
- this->p1 = p1;
- this->p2 = p2;
- this->p3 = p3;
- this->p4 = p4;
- this->p5 = p5;
- this->p6 = p6;
- this->p7 = p7;
- this->p8 = p8;
- this->p9 = p9;
- this->p10 = p10;
- this->p11 = p11;
- this->p12 = p12;
- this->p13 = p13;
- this->p14 = p14;
- this->p15 = p15;
- }
-
- template<class F, typename I>
- friend bool operator==(const Key<F, I> &k1, const Key<F, I> &k2);
-
- template<class F, typename I>
- friend bool operator<(const Key<F, I> &k1, const Key<F, I> &k2);
- };
-
-
+ friend bool operator==(const Key<F, I> &k1, const Key<F, I> &k2);
+
template<class F, typename I>
- bool operator==(const Key<F, I> &k1, const Key<F, I> &k2)
+ friend bool operator<(const Key<F, I> &k1, const Key<F, I> &k2);
+};
+
+
+template<class F, typename I>
+bool operator==(const Key<F, I> &k1, const Key<F, I> &k2)
+{
+ if( k1.count != k2.count )
+ return false;
+ switch(k1.count)
{
- if( k1.count != k2.count )
+ case -1:
+ return true;
+ case 0:
+ if( k1.id == k2.id )
+ return true;
+ else
+ return false;
+ case 1:
+ if( (k1.id == k2.id) &&
+ (k1.p1 == k2.p1) )
+ return true;
+ else
+ return false;
+ case 2:
+ if( (k1.id == k2.id) &&
+ (k1.p1 == k2.p1) &&
+ (k1.p2 == k2.p2) )
+ return true;
+ else
+ return false;
+ case 3:
+ if( (k1.id == k2.id) &&
+ (k1.p1 == k2.p1) &&
+ (k1.p2 == k2.p2) &&
+ (k1.p3 == k2.p3) )
+ return true;
+ else
+ return false;
+ case 4:
+ if( (k1.id == k2.id) &&
+ (k1.p1 == k2.p1) &&
+ (k1.p2 == k2.p2) &&
+ (k1.p3 == k2.p3) &&
+ (k1.p4 == k2.p4) )
+ return true;
+ else
+ return false;
+ case 5:
+ if( (k1.id == k2.id) &&
+ (k1.p1 == k2.p1) &&
+ (k1.p2 == k2.p2) &&
+ (k1.p3 == k2.p3) &&
+ (k1.p4 == k2.p4) &&
+ (k1.p5 == k2.p5) )
+ return true;
+ else
+ return false;
+ case 6:
+ if( (k1.id == k2.id) &&
+ (k1.p1 == k2.p1) &&
+ (k1.p2 == k2.p2) &&
+ (k1.p3 == k2.p3) &&
+ (k1.p4 == k2.p4) &&
+ (k1.p5 == k2.p5) &&
+ (k1.p6 == k2.p6) )
+ return true;
+ else
+ return false;
+ case 7:
+ if( (k1.id == k2.id) &&
+ (k1.p1 == k2.p1) &&
+ (k1.p2 == k2.p2) &&
+ (k1.p3 == k2.p3) &&
+ (k1.p4 == k2.p4) &&
+ (k1.p5 == k2.p5) &&
+ (k1.p6 == k2.p6) &&
+ (k1.p7 == k2.p7) )
+ return true;
+ else
+ return false;
+ case 8:
+ if( (k1.id == k2.id) &&
+ (k1.p1 == k2.p1) &&
+ (k1.p2 == k2.p2) &&
+ (k1.p3 == k2.p3) &&
+ (k1.p4 == k2.p4) &&
+ (k1.p5 == k2.p5) &&
+ (k1.p6 == k2.p6) &&
+ (k1.p7 == k2.p7) &&
+ (k1.p8 == k2.p8) )
+ return true;
+ else
+ return false;
+ case 9:
+ if( (k1.id == k2.id) &&
+ (k1.p1 == k2.p1) &&
+ (k1.p2 == k2.p2) &&
+ (k1.p3 == k2.p3) &&
+ (k1.p4 == k2.p4) &&
+ (k1.p5 == k2.p5) &&
+ (k1.p6 == k2.p6) &&
+ (k1.p7 == k2.p7) &&
+ (k1.p8 == k2.p8) &&
+ (k1.p9 == k2.p9) )
+ return true;
+ else
+ return false;
+ case 10:
+ if( (k1.id == k2.id) &&
+ (k1.p1 == k2.p1) &&
+ (k1.p2 == k2.p2) &&
+ (k1.p3 == k2.p3) &&
+ (k1.p4 == k2.p4) &&
+ (k1.p5 == k2.p5) &&
+ (k1.p6 == k2.p6) &&
+ (k1.p7 == k2.p7) &&
+ (k1.p8 == k2.p8) &&
+ (k1.p9 == k2.p9) &&
+ (k1.p10 == k2.p10) )
+ return true;
+ else
+ return false;
+ case 11:
+ if( (k1.id == k2.id) &&
+ (k1.p1 == k2.p1) &&
+ (k1.p2 == k2.p2) &&
+ (k1.p3 == k2.p3) &&
+ (k1.p4 == k2.p4) &&
+ (k1.p5 == k2.p5) &&
+ (k1.p6 == k2.p6) &&
+ (k1.p7 == k2.p7) &&
+ (k1.p8 == k2.p8) &&
+ (k1.p9 == k2.p9) &&
+ (k1.p10 == k2.p10) &&
+ (k1.p11 == k2.p11) )
+ return true;
+ else
+ return false;
+ case 12:
+ if( (k1.id == k2.id) &&
+ (k1.p1 == k2.p1) &&
+ (k1.p2 == k2.p2) &&
+ (k1.p3 == k2.p3) &&
+ (k1.p4 == k2.p4) &&
+ (k1.p5 == k2.p5) &&
+ (k1.p6 == k2.p6) &&
+ (k1.p7 == k2.p7) &&
+ (k1.p8 == k2.p8) &&
+ (k1.p9 == k2.p9) &&
+ (k1.p10 == k2.p10) &&
+ (k1.p11 == k2.p11) &&
+ (k1.p12 == k2.p12) )
+ return true;
+ else
+ return false;
+ case 13:
+ if( (k1.id == k2.id) &&
+ (k1.p1 == k2.p1) &&
+ (k1.p2 == k2.p2) &&
+ (k1.p3 == k2.p3) &&
+ (k1.p4 == k2.p4) &&
+ (k1.p5 == k2.p5) &&
+ (k1.p6 == k2.p6) &&
+ (k1.p7 == k2.p7) &&
+ (k1.p8 == k2.p8) &&
+ (k1.p9 == k2.p9) &&
+ (k1.p10 == k2.p10) &&
+ (k1.p11 == k2.p11) &&
+ (k1.p12 == k2.p12) &&
+ (k1.p13 == k2.p13) )
+ return true;
+ else
+ return false;
+ case 14:
+ if( (k1.id == k2.id) &&
+ (k1.p1 == k2.p1) &&
+ (k1.p2 == k2.p2) &&
+ (k1.p3 == k2.p3) &&
+ (k1.p4 == k2.p4) &&
+ (k1.p5 == k2.p5) &&
+ (k1.p6 == k2.p6) &&
+ (k1.p7 == k2.p7) &&
+ (k1.p8 == k2.p8) &&
+ (k1.p9 == k2.p9) &&
+ (k1.p10 == k2.p10) &&
+ (k1.p11 == k2.p11) &&
+ (k1.p12 == k2.p12) &&
+ (k1.p13 == k2.p13) &&
+ (k1.p14 == k2.p14) )
+ return true;
+ else
+ return false;
+ case 15:
+ if( (k1.id == k2.id) &&
+ (k1.p1 == k2.p1) &&
+ (k1.p2 == k2.p2) &&
+ (k1.p3 == k2.p3) &&
+ (k1.p4 == k2.p4) &&
+ (k1.p5 == k2.p5) &&
+ (k1.p6 == k2.p6) &&
+ (k1.p7 == k2.p7) &&
+ (k1.p8 == k2.p8) &&
+ (k1.p9 == k2.p9) &&
+ (k1.p10 == k2.p10) &&
+ (k1.p11 == k2.p11) &&
+ (k1.p12 == k2.p12) &&
+ (k1.p13 == k2.p13) &&
+ (k1.p14 == k2.p14) &&
+ (k1.p15 == k2.p15) )
+ return true;
+ else
+ return false;
+ default:
return false;
- switch(k1.count){
- case -1:
- return true;
- case 0:
- if( k1.id == k2.id )
- return true;
- else
- return false;
- case 1:
- if( (k1.id == k2.id) &&
- (k1.p1 == k2.p1) )
- return true;
- else
- return false;
- case 2:
- if( (k1.id == k2.id) &&
- (k1.p1 == k2.p1) &&
- (k1.p2 == k2.p2) )
- return true;
- else
- return false;
- case 3:
- if( (k1.id == k2.id) &&
- (k1.p1 == k2.p1) &&
- (k1.p2 == k2.p2) &&
- (k1.p3 == k2.p3) )
- return true;
- else
- return false;
- case 4:
- if( (k1.id == k2.id) &&
- (k1.p1 == k2.p1) &&
- (k1.p2 == k2.p2) &&
- (k1.p3 == k2.p3) &&
- (k1.p4 == k2.p4) )
- return true;
- else
- return false;
- case 5:
- if( (k1.id == k2.id) &&
- (k1.p1 == k2.p1) &&
- (k1.p2 == k2.p2) &&
- (k1.p3 == k2.p3) &&
- (k1.p4 == k2.p4) &&
- (k1.p5 == k2.p5) )
- return true;
- else
- return false;
- case 6:
- if( (k1.id == k2.id) &&
- (k1.p1 == k2.p1) &&
- (k1.p2 == k2.p2) &&
- (k1.p3 == k2.p3) &&
- (k1.p4 == k2.p4) &&
- (k1.p5 == k2.p5) &&
- (k1.p6 == k2.p6) )
- return true;
- else
- return false;
- case 7:
- if( (k1.id == k2.id) &&
- (k1.p1 == k2.p1) &&
- (k1.p2 == k2.p2) &&
- (k1.p3 == k2.p3) &&
- (k1.p4 == k2.p4) &&
- (k1.p5 == k2.p5) &&
- (k1.p6 == k2.p6) &&
- (k1.p7 == k2.p7) )
- return true;
- else
- return false;
- case 8:
- if( (k1.id == k2.id) &&
- (k1.p1 == k2.p1) &&
- (k1.p2 == k2.p2) &&
- (k1.p3 == k2.p3) &&
- (k1.p4 == k2.p4) &&
- (k1.p5 == k2.p5) &&
- (k1.p6 == k2.p6) &&
- (k1.p7 == k2.p7) &&
- (k1.p8 == k2.p8) )
- return true;
- else
- return false;
- case 9:
- if( (k1.id == k2.id) &&
- (k1.p1 == k2.p1) &&
- (k1.p2 == k2.p2) &&
- (k1.p3 == k2.p3) &&
- (k1.p4 == k2.p4) &&
- (k1.p5 == k2.p5) &&
- (k1.p6 == k2.p6) &&
- (k1.p7 == k2.p7) &&
- (k1.p8 == k2.p8) &&
- (k1.p9 == k2.p9) )
- return true;
- else
- return false;
- case 10:
- if( (k1.id == k2.id) &&
- (k1.p1 == k2.p1) &&
- (k1.p2 == k2.p2) &&
- (k1.p3 == k2.p3) &&
- (k1.p4 == k2.p4) &&
- (k1.p5 == k2.p5) &&
- (k1.p6 == k2.p6) &&
- (k1.p7 == k2.p7) &&
- (k1.p8 == k2.p8) &&
- (k1.p9 == k2.p9) &&
- (k1.p10 == k2.p10) )
- return true;
- else
- return false;
- case 11:
- if( (k1.id == k2.id) &&
- (k1.p1 == k2.p1) &&
- (k1.p2 == k2.p2) &&
- (k1.p3 == k2.p3) &&
- (k1.p4 == k2.p4) &&
- (k1.p5 == k2.p5) &&
- (k1.p6 == k2.p6) &&
- (k1.p7 == k2.p7) &&
- (k1.p8 == k2.p8) &&
- (k1.p9 == k2.p9) &&
- (k1.p10 == k2.p10) &&
- (k1.p11 == k2.p11) )
- return true;
- else
- return false;
- case 12:
- if( (k1.id == k2.id) &&
- (k1.p1 == k2.p1) &&
- (k1.p2 == k2.p2) &&
- (k1.p3 == k2.p3) &&
- (k1.p4 == k2.p4) &&
- (k1.p5 == k2.p5) &&
- (k1.p6 == k2.p6) &&
- (k1.p7 == k2.p7) &&
- (k1.p8 == k2.p8) &&
- (k1.p9 == k2.p9) &&
- (k1.p10 == k2.p10) &&
- (k1.p11 == k2.p11) &&
- (k1.p12 == k2.p12) )
- return true;
- else
- return false;
- case 13:
- if( (k1.id == k2.id) &&
- (k1.p1 == k2.p1) &&
- (k1.p2 == k2.p2) &&
- (k1.p3 == k2.p3) &&
- (k1.p4 == k2.p4) &&
- (k1.p5 == k2.p5) &&
- (k1.p6 == k2.p6) &&
- (k1.p7 == k2.p7) &&
- (k1.p8 == k2.p8) &&
- (k1.p9 == k2.p9) &&
- (k1.p10 == k2.p10) &&
- (k1.p11 == k2.p11) &&
- (k1.p12 == k2.p12) &&
- (k1.p13 == k2.p13) )
- return true;
- else
- return false;
- case 14:
- if( (k1.id == k2.id) &&
- (k1.p1 == k2.p1) &&
- (k1.p2 == k2.p2) &&
- (k1.p3 == k2.p3) &&
- (k1.p4 == k2.p4) &&
- (k1.p5 == k2.p5) &&
- (k1.p6 == k2.p6) &&
- (k1.p7 == k2.p7) &&
- (k1.p8 == k2.p8) &&
- (k1.p9 == k2.p9) &&
- (k1.p10 == k2.p10) &&
- (k1.p11 == k2.p11) &&
- (k1.p12 == k2.p12) &&
- (k1.p13 == k2.p13) &&
- (k1.p14 == k2.p14) )
- return true;
- else
- return false;
- case 15:
- if( (k1.id == k2.id) &&
- (k1.p1 == k2.p1) &&
- (k1.p2 == k2.p2) &&
- (k1.p3 == k2.p3) &&
- (k1.p4 == k2.p4) &&
- (k1.p5 == k2.p5) &&
- (k1.p6 == k2.p6) &&
- (k1.p7 == k2.p7) &&
- (k1.p8 == k2.p8) &&
- (k1.p9 == k2.p9) &&
- (k1.p10 == k2.p10) &&
- (k1.p11 == k2.p11) &&
- (k1.p12 == k2.p12) &&
- (k1.p13 == k2.p13) &&
- (k1.p14 == k2.p14) &&
- (k1.p15 == k2.p15) )
- return true;
- else
- return false;
- default:
- return false;
- }
}
+}
- template<class F, typename I>
- bool operator<(const Key<F, I> &k1, const Key<F, I> &k2)
+template<class F, typename I>
+bool operator<(const Key<F, I> &k1, const Key<F, I> &k2)
+{
+ if( k1.count < k2.count )
+ return true;
+ switch(k1.count)
{
- if( k1.count < k2.count )
- return true;
- switch(k1.count){
- case -1:
- return false;
- case 0:
- if( k1.id < k2.id )
- return true;
- else
- return false;
- case 1:
- if( (k1.id < k2.id) ||
- (k1.p1 < k2.p1) )
- return true;
- else
- return false;
- case 2:
- if( (k1.id < k2.id) ||
- (k1.p1 < k2.p1) ||
- (k1.p2 < k2.p2) )
- return true;
- else
- return false;
- case 3:
- if( (k1.id < k2.id) ||
- (k1.p1 < k2.p1) ||
- (k1.p2 < k2.p2) ||
- (k1.p3 < k2.p3) )
- return true;
- else
- return false;
- case 4:
- if( (k1.id < k2.id) ||
- (k1.p1 < k2.p1) ||
- (k1.p2 < k2.p2) ||
- (k1.p3 < k2.p3) ||
- (k1.p4 < k2.p4) )
- return true;
- else
- return false;
- case 5:
- if( (k1.id < k2.id) ||
- (k1.p1 < k2.p1) ||
- (k1.p2 < k2.p2) ||
- (k1.p3 < k2.p3) ||
- (k1.p4 < k2.p4) ||
- (k1.p5 < k2.p5) )
- return true;
- else
- return false;
- case 6:
- if( (k1.id < k2.id) ||
- (k1.p1 < k2.p1) ||
- (k1.p2 < k2.p2) ||
- (k1.p3 < k2.p3) ||
- (k1.p4 < k2.p4) ||
- (k1.p5 < k2.p5) ||
- (k1.p6 < k2.p6) )
- return true;
- else
- return false;
- case 7:
- if( (k1.id < k2.id) ||
- (k1.p1 < k2.p1) ||
- (k1.p2 < k2.p2) ||
- (k1.p3 < k2.p3) ||
- (k1.p4 < k2.p4) ||
- (k1.p5 < k2.p5) ||
- (k1.p6 < k2.p6) ||
- (k1.p7 < k2.p7) )
- return true;
- else
- return false;
- case 8:
- if( (k1.id < k2.id) ||
- (k1.p1 < k2.p1) ||
- (k1.p2 < k2.p2) ||
- (k1.p3 < k2.p3) ||
- (k1.p4 < k2.p4) ||
- (k1.p5 < k2.p5) ||
- (k1.p6 < k2.p6) ||
- (k1.p7 < k2.p7) ||
- (k1.p8 < k2.p8) )
- return true;
- else
- return false;
- case 9:
- if( (k1.id < k2.id) ||
- (k1.p1 < k2.p1) ||
- (k1.p2 < k2.p2) ||
- (k1.p3 < k2.p3) ||
- (k1.p4 < k2.p4) ||
- (k1.p5 < k2.p5) ||
- (k1.p6 < k2.p6) ||
- (k1.p7 < k2.p7) ||
- (k1.p8 < k2.p8) ||
- (k1.p9 < k2.p9) )
- return true;
- else
- return false;
- case 10:
- if( (k1.id < k2.id) ||
- (k1.p1 < k2.p1) ||
- (k1.p2 < k2.p2) ||
- (k1.p3 < k2.p3) ||
- (k1.p4 < k2.p4) ||
- (k1.p5 < k2.p5) ||
- (k1.p6 < k2.p6) ||
- (k1.p7 < k2.p7) ||
- (k1.p8 < k2.p8) ||
- (k1.p9 < k2.p9) ||
- (k1.p10 < k2.p10) )
- return true;
- else
- return false;
- case 11:
- if( (k1.id < k2.id) ||
- (k1.p1 < k2.p1) ||
- (k1.p2 < k2.p2) ||
- (k1.p3 < k2.p3) ||
- (k1.p4 < k2.p4) ||
- (k1.p5 < k2.p5) ||
- (k1.p6 < k2.p6) ||
- (k1.p7 < k2.p7) ||
- (k1.p8 < k2.p8) ||
- (k1.p9 < k2.p9) ||
- (k1.p10 < k2.p10) ||
- (k1.p11 < k2.p11) )
- return true;
- else
- return false;
- case 12:
- if( (k1.id < k2.id) ||
- (k1.p1 < k2.p1) ||
- (k1.p2 < k2.p2) ||
- (k1.p3 < k2.p3) ||
- (k1.p4 < k2.p4) ||
- (k1.p5 < k2.p5) ||
- (k1.p6 < k2.p6) ||
- (k1.p7 < k2.p7) ||
- (k1.p8 < k2.p8) ||
- (k1.p9 < k2.p9) ||
- (k1.p10 < k2.p10) ||
- (k1.p11 < k2.p11) ||
- (k1.p12 < k2.p12) )
- return true;
- else
- return false;
- case 13:
- if( (k1.id < k2.id) ||
- (k1.p1 < k2.p1) ||
- (k1.p2 < k2.p2) ||
- (k1.p3 < k2.p3) ||
- (k1.p4 < k2.p4) ||
- (k1.p5 < k2.p5) ||
- (k1.p6 < k2.p6) ||
- (k1.p7 < k2.p7) ||
- (k1.p8 < k2.p8) ||
- (k1.p9 < k2.p9) ||
- (k1.p10 < k2.p10) ||
- (k1.p11 < k2.p11) ||
- (k1.p12 < k2.p12) ||
- (k1.p13 < k2.p13) )
- return true;
- else
- return false;
- case 14:
- if( (k1.id < k2.id) ||
- (k1.p1 < k2.p1) ||
- (k1.p2 < k2.p2) ||
- (k1.p3 < k2.p3) ||
- (k1.p4 < k2.p4) ||
- (k1.p5 < k2.p5) ||
- (k1.p6 < k2.p6) ||
- (k1.p7 < k2.p7) ||
- (k1.p8 < k2.p8) ||
- (k1.p9 < k2.p9) ||
- (k1.p10 < k2.p10) ||
- (k1.p11 < k2.p11) ||
- (k1.p12 < k2.p12) ||
- (k1.p13 < k2.p13) ||
- (k1.p14 < k2.p14) )
- return true;
- else
- return false;
- case 15:
- if( (k1.id < k2.id) ||
- (k1.p1 < k2.p1) ||
- (k1.p2 < k2.p2) ||
- (k1.p3 < k2.p3) ||
- (k1.p4 < k2.p4) ||
- (k1.p5 < k2.p5) ||
- (k1.p6 < k2.p6) ||
- (k1.p7 < k2.p7) ||
- (k1.p8 < k2.p8) ||
- (k1.p9 < k2.p9) ||
- (k1.p10 < k2.p10) ||
- (k1.p11 < k2.p11) ||
- (k1.p12 < k2.p12) ||
- (k1.p13 < k2.p13) ||
- (k1.p14 < k2.p14) ||
- (k1.p15 < k2.p15) )
- return true;
- else
- return false;
- default:
- return false;
- }
+ case -1:
+ return false;
+ case 0:
+ if( k1.id < k2.id )
+ return true;
+ else
+ return false;
+ case 1:
+ if( (k1.id < k2.id) ||
+ (k1.p1 < k2.p1) )
+ return true;
+ else
+ return false;
+ case 2:
+ if( (k1.id < k2.id) ||
+ (k1.p1 < k2.p1) ||
+ (k1.p2 < k2.p2) )
+ return true;
+ else
+ return false;
+ case 3:
+ if( (k1.id < k2.id) ||
+ (k1.p1 < k2.p1) ||
+ (k1.p2 < k2.p2) ||
+ (k1.p3 < k2.p3) )
+ return true;
+ else
+ return false;
+ case 4:
+ if( (k1.id < k2.id) ||
+ (k1.p1 < k2.p1) ||
+ (k1.p2 < k2.p2) ||
+ (k1.p3 < k2.p3) ||
+ (k1.p4 < k2.p4) )
+ return true;
+ else
+ return false;
+ case 5:
+ if( (k1.id < k2.id) ||
+ (k1.p1 < k2.p1) ||
+ (k1.p2 < k2.p2) ||
+ (k1.p3 < k2.p3) ||
+ (k1.p4 < k2.p4) ||
+ (k1.p5 < k2.p5) )
+ return true;
+ else
+ return false;
+ case 6:
+ if( (k1.id < k2.id) ||
+ (k1.p1 < k2.p1) ||
+ (k1.p2 < k2.p2) ||
+ (k1.p3 < k2.p3) ||
+ (k1.p4 < k2.p4) ||
+ (k1.p5 < k2.p5) ||
+ (k1.p6 < k2.p6) )
+ return true;
+ else
+ return false;
+ case 7:
+ if( (k1.id < k2.id) ||
+ (k1.p1 < k2.p1) ||
+ (k1.p2 < k2.p2) ||
+ (k1.p3 < k2.p3) ||
+ (k1.p4 < k2.p4) ||
+ (k1.p5 < k2.p5) ||
+ (k1.p6 < k2.p6) ||
+ (k1.p7 < k2.p7) )
+ return true;
+ else
+ return false;
+ case 8:
+ if( (k1.id < k2.id) ||
+ (k1.p1 < k2.p1) ||
+ (k1.p2 < k2.p2) ||
+ (k1.p3 < k2.p3) ||
+ (k1.p4 < k2.p4) ||
+ (k1.p5 < k2.p5) ||
+ (k1.p6 < k2.p6) ||
+ (k1.p7 < k2.p7) ||
+ (k1.p8 < k2.p8) )
+ return true;
+ else
+ return false;
+ case 9:
+ if( (k1.id < k2.id) ||
+ (k1.p1 < k2.p1) ||
+ (k1.p2 < k2.p2) ||
+ (k1.p3 < k2.p3) ||
+ (k1.p4 < k2.p4) ||
+ (k1.p5 < k2.p5) ||
+ (k1.p6 < k2.p6) ||
+ (k1.p7 < k2.p7) ||
+ (k1.p8 < k2.p8) ||
+ (k1.p9 < k2.p9) )
+ return true;
+ else
+ return false;
+ case 10:
+ if( (k1.id < k2.id) ||
+ (k1.p1 < k2.p1) ||
+ (k1.p2 < k2.p2) ||
+ (k1.p3 < k2.p3) ||
+ (k1.p4 < k2.p4) ||
+ (k1.p5 < k2.p5) ||
+ (k1.p6 < k2.p6) ||
+ (k1.p7 < k2.p7) ||
+ (k1.p8 < k2.p8) ||
+ (k1.p9 < k2.p9) ||
+ (k1.p10 < k2.p10) )
+ return true;
+ else
+ return false;
+ case 11:
+ if( (k1.id < k2.id) ||
+ (k1.p1 < k2.p1) ||
+ (k1.p2 < k2.p2) ||
+ (k1.p3 < k2.p3) ||
+ (k1.p4 < k2.p4) ||
+ (k1.p5 < k2.p5) ||
+ (k1.p6 < k2.p6) ||
+ (k1.p7 < k2.p7) ||
+ (k1.p8 < k2.p8) ||
+ (k1.p9 < k2.p9) ||
+ (k1.p10 < k2.p10) ||
+ (k1.p11 < k2.p11) )
+ return true;
+ else
+ return false;
+ case 12:
+ if( (k1.id < k2.id) ||
+ (k1.p1 < k2.p1) ||
+ (k1.p2 < k2.p2) ||
+ (k1.p3 < k2.p3) ||
+ (k1.p4 < k2.p4) ||
+ (k1.p5 < k2.p5) ||
+ (k1.p6 < k2.p6) ||
+ (k1.p7 < k2.p7) ||
+ (k1.p8 < k2.p8) ||
+ (k1.p9 < k2.p9) ||
+ (k1.p10 < k2.p10) ||
+ (k1.p11 < k2.p11) ||
+ (k1.p12 < k2.p12) )
+ return true;
+ else
+ return false;
+ case 13:
+ if( (k1.id < k2.id) ||
+ (k1.p1 < k2.p1) ||
+ (k1.p2 < k2.p2) ||
+ (k1.p3 < k2.p3) ||
+ (k1.p4 < k2.p4) ||
+ (k1.p5 < k2.p5) ||
+ (k1.p6 < k2.p6) ||
+ (k1.p7 < k2.p7) ||
+ (k1.p8 < k2.p8) ||
+ (k1.p9 < k2.p9) ||
+ (k1.p10 < k2.p10) ||
+ (k1.p11 < k2.p11) ||
+ (k1.p12 < k2.p12) ||
+ (k1.p13 < k2.p13) )
+ return true;
+ else
+ return false;
+ case 14:
+ if( (k1.id < k2.id) ||
+ (k1.p1 < k2.p1) ||
+ (k1.p2 < k2.p2) ||
+ (k1.p3 < k2.p3) ||
+ (k1.p4 < k2.p4) ||
+ (k1.p5 < k2.p5) ||
+ (k1.p6 < k2.p6) ||
+ (k1.p7 < k2.p7) ||
+ (k1.p8 < k2.p8) ||
+ (k1.p9 < k2.p9) ||
+ (k1.p10 < k2.p10) ||
+ (k1.p11 < k2.p11) ||
+ (k1.p12 < k2.p12) ||
+ (k1.p13 < k2.p13) ||
+ (k1.p14 < k2.p14) )
+ return true;
+ else
+ return false;
+ case 15:
+ if( (k1.id < k2.id) ||
+ (k1.p1 < k2.p1) ||
+ (k1.p2 < k2.p2) ||
+ (k1.p3 < k2.p3) ||
+ (k1.p4 < k2.p4) ||
+ (k1.p5 < k2.p5) ||
+ (k1.p6 < k2.p6) ||
+ (k1.p7 < k2.p7) ||
+ (k1.p8 < k2.p8) ||
+ (k1.p9 < k2.p9) ||
+ (k1.p10 < k2.p10) ||
+ (k1.p11 < k2.p11) ||
+ (k1.p12 < k2.p12) ||
+ (k1.p13 < k2.p13) ||
+ (k1.p14 < k2.p14) ||
+ (k1.p15 < k2.p15) )
+ return true;
+ else
+ return false;
+ default:
+ return false;
}
+}
+
-
} // namespace Loki
diff --git a/shared/loki/LevelMutex.h b/shared/loki/LevelMutex.h
index c048000f..eb01f44a 100644
--- a/shared/loki/LevelMutex.h
+++ b/shared/loki/LevelMutex.h
@@ -4,9 +4,9 @@
// Copyright (c) 2008 Richard Sposato
// The copyright on this file is protected under the terms of the MIT license.
//
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
//
// The author makes no representations about the suitability of this software
@@ -29,13 +29,13 @@
#include <time.h>
#if defined( _MSC_VER )
- #include <Windows.h>
+#include <Windows.h>
#else
- #include <pthread.h>
+#include <pthread.h>
#endif
#if !defined(_WIN32) && !defined(_WIN64)
- #include <unistd.h> // declares sleep under Linux
+#include <unistd.h> // declares sleep under Linux
#endif
/** @par thread_local Keyword
@@ -49,26 +49,26 @@
you can't use LevelMutex.
*/
#ifndef LOKI_THREAD_LOCAL
- #if defined( _MSC_VER )
- #if ( _MSC_VER >= 1300 )
- #define LOKI_THREAD_LOCAL __declspec( thread )
- #else
- #error "Only Visual Studio versions 7.0 and after supported."
- #endif
-
- #elif ( __GNUC__ )
- #define LOKI_THREAD_LOCAL __thread
-
- #else
- #warning "Check if your compiler provides thread local storage."
- #define LOKI_THREAD_LOCAL thread_local
- #endif
+#if defined( _MSC_VER )
+#if ( _MSC_VER >= 1300 )
+#define LOKI_THREAD_LOCAL __declspec( thread )
+#else
+#error "Only Visual Studio versions 7.0 and after supported."
+#endif
+
+#elif ( __GNUC__ )
+#define LOKI_THREAD_LOCAL __thread
+
+#else
+#warning "Check if your compiler provides thread local storage."
+#define LOKI_THREAD_LOCAL thread_local
+#endif
#endif
#if defined( DEBUG ) || defined( _DEBUG )
- #define LOKI_MUTEX_DEBUG_CODE( x ) x
+#define LOKI_MUTEX_DEBUG_CODE( x ) x
#else
- #define LOKI_MUTEX_DEBUG_CODE( x )
+#define LOKI_MUTEX_DEBUG_CODE( x )
#endif
@@ -154,7 +154,7 @@ public:
static const unsigned int UnlockedLevel = 0xFFFFFFFF;
/// Container for locking multiple mutexes at once.
- typedef ::std::vector< volatile LevelMutexInfo * > MutexContainer;
+ typedef ::std::vector< volatile LevelMutexInfo* > MutexContainer;
typedef MutexContainer::iterator LevelMutexContainerIter;
typedef MutexContainer::const_iterator LevelMutexContainerCIter;
typedef MutexContainer::reverse_iterator LevelMutexContainerRIter;
@@ -170,7 +170,7 @@ public:
by address order.
@return Enum value indicating success or error.
*/
- static MutexErrors::Type MultiLock( MutexContainer & mutexes );
+ static MutexErrors::Type MultiLock( MutexContainer& mutexes );
/** Locks several mutexes at once. Requires O(m + n*n + n*t) actions where m is
the number of mutexes currently locked by the thread, n is the number of mutexes
@@ -184,8 +184,8 @@ public:
@param milliSeconds Amount of time to wait for each mutex.
@return Enum value indicating success or error.
*/
- static MutexErrors::Type MultiLock( MutexContainer & mutexes,
- unsigned int milliSeconds );
+ static MutexErrors::Type MultiLock( MutexContainer& mutexes,
+ unsigned int milliSeconds );
/** Unlocks several mutexes at once. Requires O(m) actions where m is the number of
mutexes in the container. This provides strong exception safety. If an exception
@@ -195,14 +195,14 @@ public:
be locked by the current thread. This sorts the container dby address order.
@return Enum value indicating success or error.
*/
- static MutexErrors::Type MultiUnlock( MutexContainer & mutexes );
+ static MutexErrors::Type MultiUnlock( MutexContainer& mutexes );
/** Gives pointer to most recently locked mutex, or NULL if nothing locked.
The pointer is for a const mutex so the mutex can't be modified inappropriately.
The pointer is for a volatile mutex so callers can call volatile member
functions to get info about the mutex.
*/
- static const volatile LevelMutexInfo * GetCurrentMutex( void );
+ static const volatile LevelMutexInfo* GetCurrentMutex( void );
/// Returns the level of this mutex.
inline unsigned int GetLevel( void ) const volatile { return m_level; }
@@ -214,7 +214,7 @@ public:
inline unsigned int GetLockCount( void ) const volatile { return m_count; }
/// Returns pointer to mutex previously locked by the thread which locked this.
- inline const volatile LevelMutexInfo * GetPrevious( void ) const volatile
+ inline const volatile LevelMutexInfo* GetPrevious( void ) const volatile
{
return m_previous;
}
@@ -279,14 +279,14 @@ protected:
class Checker
{
public:
- inline explicit Checker( const volatile LevelMutexInfo * mutex ) :
+ inline explicit Checker( const volatile LevelMutexInfo* mutex ) :
m_mutex( mutex ) {}
inline ~Checker( void ) { m_mutex->IsValid(); }
private:
Checker( void );
- Checker( const Checker & );
- Checker & operator = ( const Checker & );
- const volatile LevelMutexInfo * m_mutex;
+ Checker( const Checker& );
+ Checker& operator = ( const Checker& );
+ const volatile LevelMutexInfo* m_mutex;
};
/** @class MutexUndoer
@@ -299,18 +299,18 @@ protected:
{
public:
- explicit MutexUndoer( MutexContainer & mutexes );
+ explicit MutexUndoer( MutexContainer& mutexes );
~MutexUndoer( void );
- void SetPlace( LevelMutexContainerIter & here );
+ void SetPlace( LevelMutexContainerIter& here );
void Cancel( void );
private:
MutexUndoer( void );
- MutexUndoer( const MutexUndoer & );
- MutexUndoer & operator = ( const MutexUndoer & );
+ MutexUndoer( const MutexUndoer& );
+ MutexUndoer& operator = ( const MutexUndoer& );
- MutexContainer & m_mutexes;
+ MutexContainer& m_mutexes;
LevelMutexContainerIter m_here;
};
@@ -354,9 +354,9 @@ protected:
private:
/// Copy constructor is not implemented.
- LevelMutexInfo( const LevelMutexInfo & );
+ LevelMutexInfo( const LevelMutexInfo& );
/// Copy-assignment operator is not implemented.
- LevelMutexInfo & operator = ( const LevelMutexInfo & );
+ LevelMutexInfo& operator = ( const LevelMutexInfo& );
/** Called only by MultiLock & MultiUnlock to pass a result through an
error checking policy.
@@ -373,11 +373,11 @@ private:
*/
virtual MutexErrors::Type LockThis( unsigned int milliSeconds ) volatile = 0;
- /// Called only by MultiUnlock to unlock each particular mutex within a container.
+ /// Called only by MultiUnlock to unlock each particular mutex within a container.
virtual MutexErrors::Type UnlockThis( void ) volatile = 0;
/// Pointer to singly-linked list of mutexes locked by the current thread.
- static LOKI_THREAD_LOCAL volatile LevelMutexInfo * s_currentMutex;
+ static LOKI_THREAD_LOCAL volatile LevelMutexInfo* s_currentMutex;
/// Level of this mutex.
const unsigned int m_level;
@@ -386,7 +386,7 @@ private:
unsigned int m_count;
/// Pointer to mutex locked before this one.
- volatile LevelMutexInfo * m_previous;
+ volatile LevelMutexInfo* m_previous;
};
@@ -401,7 +401,7 @@ class ThrowOnAnyMutexError
{
public:
static MutexErrors::Type CheckError( MutexErrors::Type error,
- unsigned int level );
+ unsigned int level );
};
// ----------------------------------------------------------------------------
@@ -415,7 +415,7 @@ class ThrowOnBadDesignMutexError
{
public:
static MutexErrors::Type CheckError( MutexErrors::Type error,
- unsigned int level );
+ unsigned int level );
};
// ----------------------------------------------------------------------------
@@ -429,11 +429,11 @@ class AssertAnyMutexError
{
public:
static inline MutexErrors::Type CheckError( MutexErrors::Type error,
- unsigned int level )
+ unsigned int level )
{
(void)level;
assert( ( error == MutexErrors::Success )
- || ( error == MutexErrors::NoProblem ) );
+ || ( error == MutexErrors::NoProblem ) );
return error;
}
};
@@ -449,11 +449,11 @@ class AssertBadDesignMutexError
{
public:
static inline MutexErrors::Type CheckError( MutexErrors::Type error,
- unsigned int level )
+ unsigned int level )
{
(void)level;
assert( ( error != MutexErrors::LevelTooHigh )
- && ( error != MutexErrors::LevelTooLow ) );
+ && ( error != MutexErrors::LevelTooLow ) );
return error;
}
};
@@ -469,7 +469,7 @@ class JustReturnMutexError
{
public:
static inline MutexErrors::Type CheckError( MutexErrors::Type error,
- unsigned int level )
+ unsigned int level )
{
(void)level;
return error;
@@ -533,24 +533,24 @@ public:
private:
/// Copy constructor is not implemented.
- SpinLevelMutex( const SpinLevelMutex & );
+ SpinLevelMutex( const SpinLevelMutex& );
/// Copy-assignment operator is not implemented.
- SpinLevelMutex & operator = ( const SpinLevelMutex & );
+ SpinLevelMutex& operator = ( const SpinLevelMutex& );
#if defined( _MSC_VER )
- #if ( _MSC_VER >= 1300 )
- /// The actual mutex.
- CRITICAL_SECTION m_mutex;
- #else
- #error "Only Visual Studio versions 7.0 and after supported."
- #endif
+#if ( _MSC_VER >= 1300 )
+ /// The actual mutex.
+ CRITICAL_SECTION m_mutex;
+#else
+#error "Only Visual Studio versions 7.0 and after supported."
+#endif
#elif ( __GNUC__ )
/// The actual mutex.
pthread_mutex_t m_mutex;
#else
- #error "Check if any mutex libraries are compatible with your compiler."
+#error "Check if any mutex libraries are compatible with your compiler."
#endif
/// Keep a copy of the mutex level around for error reporting.
@@ -564,7 +564,7 @@ private:
Implements a sleeping loop to wait for the mutex to unlock.
@par Purpose
- Since this class puts the thread to sleep for short intervals, you can use this
+ Since this class puts the thread to sleep for short intervals, you can use this
class for most of your mutexes. Especially for locking any high level resources
where any one operation on the resouce consumes many CPU cycles. The purpose of
this mutex is to reduce the number of CPU cycles spent in idle loops. All
@@ -613,17 +613,17 @@ private:
/// Default constructor is not implemented.
SleepLevelMutex( void );
/// Copy constructor is not implemented.
- SleepLevelMutex( const SleepLevelMutex & );
+ SleepLevelMutex( const SleepLevelMutex& );
/// Copy-assignment operator is not implemented.
- SleepLevelMutex & operator = ( const SleepLevelMutex & );
+ SleepLevelMutex& operator = ( const SleepLevelMutex& );
#if defined( _MSC_VER )
- #if ( _MSC_VER >= 1300 )
- /// True if operating system may wake thread to respond to events.
- bool m_wakable;
- #else
- #error "Only Visual Studio versions 7.0 and after supported."
- #endif
+#if ( _MSC_VER >= 1300 )
+ /// True if operating system may wake thread to respond to events.
+ bool m_wakable;
+#else
+#error "Only Visual Studio versions 7.0 and after supported."
+#endif
#endif
/// How many milli-seconds to sleep before trying to lock mutex again.
@@ -738,11 +738,11 @@ private:
template
<
- class MutexPolicy,
- unsigned int DefaultLevel,
- class ErrorPolicy = ::Loki::ThrowOnBadDesignMutexError,
- class WaitPolicy = ::Loki::NoMutexWait
->
+class MutexPolicy,
+ unsigned int DefaultLevel,
+ class ErrorPolicy = ::Loki::ThrowOnBadDesignMutexError,
+ class WaitPolicy = ::Loki::NoMutexWait
+ >
class LevelMutex : public LevelMutexInfo
{
public:
@@ -775,10 +775,10 @@ public:
const and volatile qualifiers so callers get a reference to a MutexPolicy
with the proper qualifiers.
*/
- inline const volatile MutexPolicy & GetMutexPolicy( void ) const volatile { return m_mutex; }
- inline volatile MutexPolicy & GetMutexPolicy( void ) volatile { return m_mutex; }
- inline const MutexPolicy & GetMutexPolicy( void ) const { return m_mutex; }
- inline MutexPolicy & GetMutexPolicy( void ) { return m_mutex; }
+ inline const volatile MutexPolicy& GetMutexPolicy( void ) const volatile { return m_mutex; }
+ inline volatile MutexPolicy& GetMutexPolicy( void ) volatile { return m_mutex; }
+ inline const MutexPolicy& GetMutexPolicy( void ) const { return m_mutex; }
+ inline MutexPolicy& GetMutexPolicy( void ) { return m_mutex; }
virtual MutexErrors::Type TryLock( void ) volatile
{
@@ -889,9 +889,9 @@ public:
private:
/// Copy constructor is not implemented since mutexes don't get copied.
- LevelMutex( const LevelMutex & );
+ LevelMutex( const LevelMutex& );
/// Copy-assignment operator is not implemented since mutexes don't get copied.
- LevelMutex & operator = ( const LevelMutex & );
+ LevelMutex& operator = ( const LevelMutex& );
virtual MutexErrors::Type DoErrorCheck( MutexErrors::Type result ) const volatile
{
@@ -1002,7 +1002,7 @@ unsigned int CountMutexesAtCurrentLevel( void );
/** Determines if container of mutexes matches the recently locked mutexes.
If they do match, it returns success, otherwise an error condition.
*/
-MutexErrors::Type DoMutexesMatchContainer( const LevelMutexInfo::MutexContainer & mutexes );
+MutexErrors::Type DoMutexesMatchContainer( const LevelMutexInfo::MutexContainer& mutexes );
// ----------------------------------------------------------------------------
@@ -1018,19 +1018,19 @@ public:
/** Constructs an exception which stores information about a mutex and the
reason an attempt to use a mutex failed.
*/
- MutexException( const char * message, unsigned int level, MutexErrors::Type reason );
+ MutexException( const char* message, unsigned int level, MutexErrors::Type reason );
/// Copy constructor performs a member-by-member copy of an exception.
- MutexException( const MutexException & that ) throw ();
+ MutexException( const MutexException& that ) throw ();
/// Copy-assignment operator performs a member-by-member copy of an exception.
- MutexException & operator = ( const MutexException & that ) throw ();
+ MutexException& operator = ( const MutexException& that ) throw ();
/// Destroys the exception.
virtual ~MutexException( void ) throw();
/// Returns a simple message about which operation failed.
- virtual const char * what( void ) const throw();
+ virtual const char* what( void ) const throw();
/// Returns level of mutex(es) used when problem occurred.
unsigned int GetLevel( void ) const { return m_level; }
@@ -1044,7 +1044,7 @@ private:
MutexException( void ) throw ();
/// Simple message about operation that failed.
- const char * m_message;
+ const char* m_message;
/// Level of mutex(es) used when problem occurred.
unsigned int m_level;
/// Error status for why operation failed.
@@ -1071,7 +1071,7 @@ public:
@param lock True if function wants to lock the mutex as this gets
constructed.
*/
- explicit MutexLocker( volatile LevelMutexInfo & mutex, bool lock = true );
+ explicit MutexLocker( volatile LevelMutexInfo& mutex, bool lock = true );
/** Creates an object to lock an unlock a mutex for a function. This waits
a specified amount of time for another thread to unlock the mutex if it is
@@ -1082,8 +1082,8 @@ public:
@param lock True if function wants to lock the mutex as this gets
constructed.
*/
- MutexLocker( volatile LevelMutexInfo & mutex, unsigned int milliSeconds,
- bool lock = true );
+ MutexLocker( volatile LevelMutexInfo& mutex, unsigned int milliSeconds,
+ bool lock = true );
/// Destructs the locker, and determines if it needs to unlock the mutex.
~MutexLocker( void );
@@ -1107,23 +1107,23 @@ public:
/// Returns true if the mutex is locked by this object.
inline bool IsLocked( void ) const { return m_locked; }
- /// Provides access to mutex controlled by this.
- const volatile LevelMutexInfo & GetMutex( void ) const { return m_mutex; }
+ /// Provides access to mutex controlled by this.
+ const volatile LevelMutexInfo& GetMutex( void ) const { return m_mutex; }
private:
/// Default constructor is not implemented.
MutexLocker( void );
/// Copy constructor is not implemented.
- MutexLocker( const MutexLocker & );
+ MutexLocker( const MutexLocker& );
/// Copy-assignment operator is not implemented.
- MutexLocker & operator = ( const MutexLocker & );
+ MutexLocker& operator = ( const MutexLocker& );
/// True if mutex got locked.
bool m_locked;
/// Reference to mutex.
- volatile LevelMutexInfo & m_mutex;
+ volatile LevelMutexInfo& m_mutex;
};
// ----------------------------------------------------------------------------
@@ -1147,8 +1147,8 @@ public:
@param lock True if function wants to lock the mutex as this gets
constructed.
*/
- explicit MultiMutexLocker( LevelMutexInfo::MutexContainer & mutexes,
- bool lock = true );
+ explicit MultiMutexLocker( LevelMutexInfo::MutexContainer& mutexes,
+ bool lock = true );
/** Creates an object to lock and unlock a collection of mutexes for a function.
This waits a specified amount of time for other threads to unlock each mutex
@@ -1160,8 +1160,8 @@ public:
@param lock True if function wants to lock the mutexes as this gets
constructed.
*/
- MultiMutexLocker( LevelMutexInfo::MutexContainer & mutexes,
- unsigned int milliSeconds, bool lock = true );
+ MultiMutexLocker( LevelMutexInfo::MutexContainer& mutexes,
+ unsigned int milliSeconds, bool lock = true );
/// Destructs the locker, and determines if it needs to unlock the mutexes.
~MultiMutexLocker( void );
@@ -1185,23 +1185,23 @@ public:
/// Returns true if the mutexes are locked by this object.
inline bool IsLocked( void ) const { return m_locked; }
- /// Provides access to the collection of mutexes controlled by this.
- const LevelMutexInfo::MutexContainer & GetMutexes( void ) const { return m_mutexes; }
+ /// Provides access to the collection of mutexes controlled by this.
+ const LevelMutexInfo::MutexContainer& GetMutexes( void ) const { return m_mutexes; }
private:
/// Default constructor is not implemented.
MultiMutexLocker( void );
/// Copy constructor is not implemented.
- MultiMutexLocker( const MultiMutexLocker & );
+ MultiMutexLocker( const MultiMutexLocker& );
/// Copy-assignment operator is not implemented.
- MultiMutexLocker & operator = ( const MultiMutexLocker & );
+ MultiMutexLocker& operator = ( const MultiMutexLocker& );
/// True if mutexes got locked.
bool m_locked;
/// Reference to external container of mutexes;
- LevelMutexInfo::MutexContainer & m_mutexes;
+ LevelMutexInfo::MutexContainer& m_mutexes;
};
// ----------------------------------------------------------------------------
diff --git a/shared/loki/LockingPtr.h b/shared/loki/LockingPtr.h
index a50f5d6d..5482f075 100644
--- a/shared/loki/LockingPtr.h
+++ b/shared/loki/LockingPtr.h
@@ -7,12 +7,12 @@
// for You" by Alexandrescu, Andrei.
// Published in the February 2001 issue of the C/C++ Users Journal.
// http://www.cuj.com/documents/s=7998/cujcexp1902alexandr/
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author makes no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author makes no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
// Prepared for Loki library by Richard Sposato
////////////////////////////////////////////////////////////////////////////////
@@ -28,81 +28,81 @@
namespace Loki
{
- /** @class LockingPtr
- Locks a volatile object and casts away volatility so that the object
- can be safely used in a single-threaded region of code.
- Original version of LockingPtr had only one template - for the shared
- object, but not the mutex type. This version allows users to specify a
- the mutex type as a LockingPolicy class. The only requirements for a
- LockingPolicy class are to provide Lock and Unlock methods.
+/** @class LockingPtr
+ Locks a volatile object and casts away volatility so that the object
+ can be safely used in a single-threaded region of code.
+ Original version of LockingPtr had only one template - for the shared
+ object, but not the mutex type. This version allows users to specify a
+ the mutex type as a LockingPolicy class. The only requirements for a
+ LockingPolicy class are to provide Lock and Unlock methods.
+ */
+template < typename SharedObject, typename LockingPolicy = LOKI_DEFAULT_MUTEX,
+ template<class> class ConstPolicy = LOKI_DEFAULT_CONSTNESS >
+class LockingPtr
+{
+public:
+
+ typedef typename ConstPolicy<SharedObject>::Type ConstOrNotType;
+
+ /** Constructor locks mutex associated with an object.
+ @param object Reference to object.
+ @param mutex Mutex used to control thread access to object.
+ */
+ LockingPtr( volatile ConstOrNotType& object, LockingPolicy& mutex )
+ : pObject_( const_cast< SharedObject* >( &object ) ),
+ pMutex_( &mutex )
+ {
+ mutex.Lock();
+ }
+
+ typedef typename std::pair<volatile ConstOrNotType*, LockingPolicy*> Pair;
+
+ /** Constructor locks mutex associated with an object.
+ @param lockpair a std::pair of pointers to the object and the mutex
*/
- template < typename SharedObject, typename LockingPolicy = LOKI_DEFAULT_MUTEX,
- template<class> class ConstPolicy = LOKI_DEFAULT_CONSTNESS >
- class LockingPtr
+ LockingPtr( Pair lockpair )
+ : pObject_( const_cast< SharedObject* >( lockpair.first ) ),
+ pMutex_( lockpair.second )
+ {
+ lockpair.second->Lock();
+ }
+
+ /// Destructor unlocks the mutex.
+ ~LockingPtr()
+ {
+ pMutex_->Unlock();
+ }
+
+ /// Star-operator dereferences pointer.
+ ConstOrNotType& operator * ()
+ {
+ return *pObject_;
+ }
+
+ /// Point-operator returns pointer to object.
+ ConstOrNotType* operator -> ()
{
- public:
-
- typedef typename ConstPolicy<SharedObject>::Type ConstOrNotType;
-
- /** Constructor locks mutex associated with an object.
- @param object Reference to object.
- @param mutex Mutex used to control thread access to object.
- */
- LockingPtr( volatile ConstOrNotType & object, LockingPolicy & mutex )
- : pObject_( const_cast< SharedObject * >( &object ) ),
- pMutex_( &mutex )
- {
- mutex.Lock();
- }
-
- typedef typename std::pair<volatile ConstOrNotType *, LockingPolicy *> Pair;
-
- /** Constructor locks mutex associated with an object.
- @param lockpair a std::pair of pointers to the object and the mutex
- */
- LockingPtr( Pair lockpair )
- : pObject_( const_cast< SharedObject * >( lockpair.first ) ),
- pMutex_( lockpair.second )
- {
- lockpair.second->Lock();
- }
-
- /// Destructor unlocks the mutex.
- ~LockingPtr()
- {
- pMutex_->Unlock();
- }
-
- /// Star-operator dereferences pointer.
- ConstOrNotType & operator * ()
- {
- return *pObject_;
- }
-
- /// Point-operator returns pointer to object.
- ConstOrNotType * operator -> ()
- {
- return pObject_;
- }
-
- private:
-
- /// Default constructor is not implemented.
- LockingPtr();
-
- /// Copy-constructor is not implemented.
- LockingPtr( const LockingPtr & );
-
- /// Copy-assignment-operator is not implemented.
- LockingPtr & operator = ( const LockingPtr & );
-
- /// Pointer to the shared object.
- ConstOrNotType * pObject_;
-
- /// Pointer to the mutex.
- LockingPolicy * pMutex_;
-
- }; // end class LockingPtr
+ return pObject_;
+ }
+
+private:
+
+ /// Default constructor is not implemented.
+ LockingPtr();
+
+ /// Copy-constructor is not implemented.
+ LockingPtr( const LockingPtr& );
+
+ /// Copy-assignment-operator is not implemented.
+ LockingPtr& operator = ( const LockingPtr& );
+
+ /// Pointer to the shared object.
+ ConstOrNotType* pObject_;
+
+ /// Pointer to the mutex.
+ LockingPolicy* pMutex_;
+
+}; // end class LockingPtr
} // namespace Loki
diff --git a/shared/loki/LokiExport.h b/shared/loki/LokiExport.h
index 625449f2..eb02516b 100644
--- a/shared/loki/LokiExport.h
+++ b/shared/loki/LokiExport.h
@@ -1,12 +1,12 @@
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2006 by Peter Kümmel
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author makes no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author makes no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_LOKIEXPORT_INC_
@@ -19,10 +19,10 @@
#ifdef _HAVE_GCC_VISIBILITY
#define LOKI_EXPORT_SPEC __attribute__ ((visibility("default")))
-#define LOKI_IMPORT_SPEC
+#define LOKI_IMPORT_SPEC
#else
#define LOKI_EXPORT_SPEC
-#define LOKI_IMPORT_SPEC
+#define LOKI_IMPORT_SPEC
#endif
#else
@@ -31,8 +31,8 @@
#define LOKI_EXPORT_SPEC __declspec(dllexport)
#define LOKI_IMPORT_SPEC __declspec(dllimport)
#else
-#define LOKI_EXPORT_SPEC
-#define LOKI_IMPORT_SPEC
+#define LOKI_EXPORT_SPEC
+#define LOKI_IMPORT_SPEC
#endif
#endif
diff --git a/shared/loki/LokiTypeInfo.h b/shared/loki/LokiTypeInfo.h
index 715dab1a..ecb657d4 100644
--- a/shared/loki/LokiTypeInfo.h
+++ b/shared/loki/LokiTypeInfo.h
@@ -2,14 +2,14 @@
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
-// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author or Addison-Wesley Longman make no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author or Addison-Wesley Longman make no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_LOKITYPEINFO_INC_
@@ -29,75 +29,75 @@ namespace Loki
// Purpose: offer a first-class, comparable wrapper over std::type_info
////////////////////////////////////////////////////////////////////////////////
- class TypeInfo
- {
- public:
- // Constructors
- TypeInfo(); // needed for containers
- TypeInfo(const std::type_info&); // non-explicit
-
- // Access for the wrapped std::type_info
- const std::type_info& Get() const;
- // Compatibility functions
- bool before(const TypeInfo& rhs) const;
- const char* name() const;
-
- private:
- const std::type_info* pInfo_;
- };
-
+class TypeInfo
+{
+public:
+ // Constructors
+ TypeInfo(); // needed for containers
+ TypeInfo(const std::type_info&); // non-explicit
+
+ // Access for the wrapped std::type_info
+ const std::type_info& Get() const;
+ // Compatibility functions
+ bool before(const TypeInfo& rhs) const;
+ const char* name() const;
+
+private:
+ const std::type_info* pInfo_;
+};
+
// Implementation
-
- inline TypeInfo::TypeInfo()
- {
- class Nil {};
- pInfo_ = &typeid(Nil);
- assert(pInfo_);
- }
-
- inline TypeInfo::TypeInfo(const std::type_info& ti)
+
+inline TypeInfo::TypeInfo()
+{
+ class Nil {};
+ pInfo_ = &typeid(Nil);
+ assert(pInfo_);
+}
+
+inline TypeInfo::TypeInfo(const std::type_info& ti)
: pInfo_(&ti)
- { assert(pInfo_); }
-
- inline bool TypeInfo::before(const TypeInfo& rhs) const
- {
- assert(pInfo_);
- // type_info::before return type is int in some VC libraries
- return pInfo_->before(*rhs.pInfo_) != 0;
- }
-
- inline const std::type_info& TypeInfo::Get() const
- {
- assert(pInfo_);
- return *pInfo_;
- }
-
- inline const char* TypeInfo::name() const
- {
- assert(pInfo_);
- return pInfo_->name();
- }
+{ assert(pInfo_); }
+
+inline bool TypeInfo::before(const TypeInfo& rhs) const
+{
+ assert(pInfo_);
+ // type_info::before return type is int in some VC libraries
+ return pInfo_->before(*rhs.pInfo_) != 0;
+}
+
+inline const std::type_info& TypeInfo::Get() const
+{
+ assert(pInfo_);
+ return *pInfo_;
+}
+
+inline const char* TypeInfo::name() const
+{
+ assert(pInfo_);
+ return pInfo_->name();
+}
// Comparison operators
-
- inline bool operator==(const TypeInfo& lhs, const TypeInfo& rhs)
- // type_info::operator== return type is int in some VC libraries
- { return (lhs.Get() == rhs.Get()) != 0; }
-
- inline bool operator<(const TypeInfo& lhs, const TypeInfo& rhs)
- { return lhs.before(rhs); }
-
- inline bool operator!=(const TypeInfo& lhs, const TypeInfo& rhs)
- { return !(lhs == rhs); }
-
- inline bool operator>(const TypeInfo& lhs, const TypeInfo& rhs)
- { return rhs < lhs; }
-
- inline bool operator<=(const TypeInfo& lhs, const TypeInfo& rhs)
- { return !(lhs > rhs); }
-
- inline bool operator>=(const TypeInfo& lhs, const TypeInfo& rhs)
- { return !(lhs < rhs); }
+
+inline bool operator==(const TypeInfo& lhs, const TypeInfo& rhs)
+// type_info::operator== return type is int in some VC libraries
+{ return (lhs.Get() == rhs.Get()) != 0; }
+
+inline bool operator<(const TypeInfo& lhs, const TypeInfo& rhs)
+{ return lhs.before(rhs); }
+
+inline bool operator!=(const TypeInfo& lhs, const TypeInfo& rhs)
+{ return !(lhs == rhs); }
+
+inline bool operator>(const TypeInfo& lhs, const TypeInfo& rhs)
+{ return rhs < lhs; }
+
+inline bool operator<=(const TypeInfo& lhs, const TypeInfo& rhs)
+{ return !(lhs > rhs); }
+
+inline bool operator>=(const TypeInfo& lhs, const TypeInfo& rhs)
+{ return !(lhs < rhs); }
}
#endif // end file guardian
diff --git a/shared/loki/MultiMethods.h b/shared/loki/MultiMethods.h
index d095cfae..ece4fb17 100644
--- a/shared/loki/MultiMethods.h
+++ b/shared/loki/MultiMethods.h
@@ -2,14 +2,14 @@
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
-// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author or Addison-Wesley Longman make no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author or Addison-Wesley Longman make no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_MULTIMETHODS_INC_
@@ -36,210 +36,210 @@ namespace Loki
// Helps implementing optional symmetry
////////////////////////////////////////////////////////////////////////////////
- namespace Private
+namespace Private
+{
+template <class SomeLhs, class SomeRhs,
+ class Executor, typename ResultType>
+struct InvocationTraits
+{
+ static ResultType
+ DoDispatch(SomeLhs& lhs, SomeRhs& rhs,
+ Executor& exec, Int2Type<false>)
{
- template <class SomeLhs, class SomeRhs,
- class Executor, typename ResultType>
- struct InvocationTraits
- {
- static ResultType
- DoDispatch(SomeLhs& lhs, SomeRhs& rhs,
- Executor& exec, Int2Type<false>)
- {
- return exec.Fire(lhs, rhs);
- }
- static ResultType
- DoDispatch(SomeLhs& lhs, SomeRhs& rhs,
- Executor& exec, Int2Type<true>)
- {
- return exec.Fire(rhs, lhs);
- }
- };
+ return exec.Fire(lhs, rhs);
}
+ static ResultType
+ DoDispatch(SomeLhs& lhs, SomeRhs& rhs,
+ Executor& exec, Int2Type<true>)
+ {
+ return exec.Fire(rhs, lhs);
+ }
+};
+}
////////////////////////////////////////////////////////////////////////////////
// class template StaticDispatcher
// Implements an automatic static double dispatcher based on two typelists
////////////////////////////////////////////////////////////////////////////////
- template
- <
- class Executor,
- class BaseLhs,
- class TypesLhs,
- bool symmetric = true,
- class BaseRhs = BaseLhs,
- class TypesRhs = TypesLhs,
- typename ResultType = void
- >
- class StaticDispatcher
+template
+<
+class Executor,
+ class BaseLhs,
+ class TypesLhs,
+ bool symmetric = true,
+ class BaseRhs = BaseLhs,
+ class TypesRhs = TypesLhs,
+ typename ResultType = void
+ >
+class StaticDispatcher
+{
+ template <class SomeLhs>
+ static ResultType DispatchRhs(SomeLhs& lhs, BaseRhs& rhs,
+ Executor exec, NullType)
+ { return exec.OnError(lhs, rhs); }
+
+ template <class Head, class Tail, class SomeLhs>
+ static ResultType DispatchRhs(SomeLhs& lhs, BaseRhs& rhs,
+ Executor exec, Typelist<Head, Tail>)
{
- template <class SomeLhs>
- static ResultType DispatchRhs(SomeLhs& lhs, BaseRhs& rhs,
- Executor exec, NullType)
- { return exec.OnError(lhs, rhs); }
-
- template <class Head, class Tail, class SomeLhs>
- static ResultType DispatchRhs(SomeLhs& lhs, BaseRhs& rhs,
- Executor exec, Typelist<Head, Tail>)
- {
- if (Head* p2 = dynamic_cast<Head*>(&rhs))
- {
- Int2Type<(symmetric &&
- int(TL::IndexOf<TypesRhs, Head>::value) <
- int(TL::IndexOf<TypesLhs, SomeLhs>::value))> i2t;
-
- typedef Private::InvocationTraits<
- SomeLhs, Head, Executor, ResultType> CallTraits;
-
- return CallTraits::DoDispatch(lhs, *p2, exec, i2t);
- }
- return DispatchRhs(lhs, rhs, exec, Tail());
+ if (Head* p2 = dynamic_cast<Head*>(&rhs))
+ {
+ Int2Type<(symmetric &&
+ int(TL::IndexOf<TypesRhs, Head>::value) <
+ int(TL::IndexOf<TypesLhs, SomeLhs>::value))> i2t;
+
+ typedef Private::InvocationTraits<
+ SomeLhs, Head, Executor, ResultType> CallTraits;
+
+ return CallTraits::DoDispatch(lhs, *p2, exec, i2t);
}
-
- static ResultType DispatchLhs(BaseLhs& lhs, BaseRhs& rhs,
- Executor exec, NullType)
- { return exec.OnError(lhs, rhs); }
-
- template <class Head, class Tail>
- static ResultType DispatchLhs(BaseLhs& lhs, BaseRhs& rhs,
- Executor exec, Typelist<Head, Tail>)
- {
- if (Head* p1 = dynamic_cast<Head*>(&lhs))
- {
- return DispatchRhs(*p1, rhs, exec, TypesRhs());
- }
- return DispatchLhs(lhs, rhs, exec, Tail());
+ return DispatchRhs(lhs, rhs, exec, Tail());
+ }
+
+ static ResultType DispatchLhs(BaseLhs& lhs, BaseRhs& rhs,
+ Executor exec, NullType)
+ { return exec.OnError(lhs, rhs); }
+
+ template <class Head, class Tail>
+ static ResultType DispatchLhs(BaseLhs& lhs, BaseRhs& rhs,
+ Executor exec, Typelist<Head, Tail>)
+ {
+ if (Head* p1 = dynamic_cast<Head*>(&lhs))
+ {
+ return DispatchRhs(*p1, rhs, exec, TypesRhs());
}
+ return DispatchLhs(lhs, rhs, exec, Tail());
+ }
+
+public:
+ static ResultType Go(BaseLhs& lhs, BaseRhs& rhs,
+ Executor exec)
+ { return DispatchLhs(lhs, rhs, exec, TypesLhs()); }
+};
- public:
- static ResultType Go(BaseLhs& lhs, BaseRhs& rhs,
- Executor exec)
- { return DispatchLhs(lhs, rhs, exec, TypesLhs()); }
- };
-
////////////////////////////////////////////////////////////////////////////////
// class template BasicDispatcher
// Implements a logarithmic double dispatcher for functors (or functions)
// Doesn't offer automated casts or symmetry
////////////////////////////////////////////////////////////////////////////////
- template
- <
- class BaseLhs,
- class BaseRhs = BaseLhs,
- typename ResultType = void,
- typename CallbackType = ResultType (*)(BaseLhs&, BaseRhs&)
- >
- class BasicDispatcher
- {
- typedef std::pair<TypeInfo,TypeInfo> KeyType;
- typedef CallbackType MappedType;
- typedef AssocVector<KeyType, MappedType> MapType;
- MapType callbackMap_;
-
- void DoAdd(TypeInfo lhs, TypeInfo rhs, CallbackType fun);
- bool DoRemove(TypeInfo lhs, TypeInfo rhs);
-
- public:
- template <class SomeLhs, class SomeRhs>
- void Add(CallbackType fun)
- {
- DoAdd(typeid(SomeLhs), typeid(SomeRhs), fun);
- }
-
- template <class SomeLhs, class SomeRhs>
- bool Remove()
- {
- return DoRemove(typeid(SomeLhs), typeid(SomeRhs));
- }
-
- ResultType Go(BaseLhs& lhs, BaseRhs& rhs);
- };
-
- // Non-inline to reduce compile time overhead...
- template <class BaseLhs, class BaseRhs,
- typename ResultType, typename CallbackType>
- void BasicDispatcher<BaseLhs,BaseRhs,ResultType,CallbackType>
- ::DoAdd(TypeInfo lhs, TypeInfo rhs, CallbackType fun)
+template
+<
+class BaseLhs,
+ class BaseRhs = BaseLhs,
+ typename ResultType = void,
+ typename CallbackType = ResultType (*)(BaseLhs&, BaseRhs&)
+ >
+class BasicDispatcher
+{
+ typedef std::pair<TypeInfo,TypeInfo> KeyType;
+ typedef CallbackType MappedType;
+ typedef AssocVector<KeyType, MappedType> MapType;
+ MapType callbackMap_;
+
+ void DoAdd(TypeInfo lhs, TypeInfo rhs, CallbackType fun);
+ bool DoRemove(TypeInfo lhs, TypeInfo rhs);
+
+public:
+ template <class SomeLhs, class SomeRhs>
+ void Add(CallbackType fun)
{
- callbackMap_[KeyType(lhs, rhs)] = fun;
+ DoAdd(typeid(SomeLhs), typeid(SomeRhs), fun);
}
-
- template <class BaseLhs, class BaseRhs,
- typename ResultType, typename CallbackType>
- bool BasicDispatcher<BaseLhs,BaseRhs,ResultType,CallbackType>
- ::DoRemove(TypeInfo lhs, TypeInfo rhs)
+
+ template <class SomeLhs, class SomeRhs>
+ bool Remove()
{
- return callbackMap_.erase(KeyType(lhs, rhs)) == 1;
+ return DoRemove(typeid(SomeLhs), typeid(SomeRhs));
}
- template <class BaseLhs, class BaseRhs,
- typename ResultType, typename CallbackType>
- ResultType BasicDispatcher<BaseLhs,BaseRhs,ResultType,CallbackType>
- ::Go(BaseLhs& lhs, BaseRhs& rhs)
+ ResultType Go(BaseLhs& lhs, BaseRhs& rhs);
+};
+
+// Non-inline to reduce compile time overhead...
+template <class BaseLhs, class BaseRhs,
+ typename ResultType, typename CallbackType>
+void BasicDispatcher<BaseLhs,BaseRhs,ResultType,CallbackType>
+::DoAdd(TypeInfo lhs, TypeInfo rhs, CallbackType fun)
+{
+ callbackMap_[KeyType(lhs, rhs)] = fun;
+}
+
+template <class BaseLhs, class BaseRhs,
+ typename ResultType, typename CallbackType>
+bool BasicDispatcher<BaseLhs,BaseRhs,ResultType,CallbackType>
+::DoRemove(TypeInfo lhs, TypeInfo rhs)
+{
+ return callbackMap_.erase(KeyType(lhs, rhs)) == 1;
+}
+
+template <class BaseLhs, class BaseRhs,
+ typename ResultType, typename CallbackType>
+ResultType BasicDispatcher<BaseLhs,BaseRhs,ResultType,CallbackType>
+::Go(BaseLhs& lhs, BaseRhs& rhs)
+{
+ typename MapType::key_type k(typeid(lhs),typeid(rhs));
+ typename MapType::iterator i = callbackMap_.find(k);
+ if (i == callbackMap_.end())
{
- typename MapType::key_type k(typeid(lhs),typeid(rhs));
- typename MapType::iterator i = callbackMap_.find(k);
- if (i == callbackMap_.end())
- {
- throw std::runtime_error("Function not found");
- }
- return (i->second)(lhs, rhs);
+ throw std::runtime_error("Function not found");
}
+ return (i->second)(lhs, rhs);
+}
////////////////////////////////////////////////////////////////////////////////
// class template StaticCaster
// Implementation of the CastingPolicy used by FunctorDispatcher
////////////////////////////////////////////////////////////////////////////////
- template <class To, class From>
- struct StaticCaster
+template <class To, class From>
+struct StaticCaster
+{
+ static To& Cast(From& obj)
{
- static To& Cast(From& obj)
- {
- return static_cast<To&>(obj);
- }
- };
+ return static_cast<To&>(obj);
+ }
+};
////////////////////////////////////////////////////////////////////////////////
// class template DynamicCaster
// Implementation of the CastingPolicy used by FunctorDispatcher
////////////////////////////////////////////////////////////////////////////////
- template <class To, class From>
- struct DynamicCaster
+template <class To, class From>
+struct DynamicCaster
+{
+ static To& Cast(From& obj)
{
- static To& Cast(From& obj)
- {
- return dynamic_cast<To&>(obj);
- }
- };
+ return dynamic_cast<To&>(obj);
+ }
+};
////////////////////////////////////////////////////////////////////////////////
// class template Private::FnDispatcherHelper
// Implements trampolines and argument swapping used by FnDispatcher
////////////////////////////////////////////////////////////////////////////////
- namespace Private
+namespace Private
+{
+template <class BaseLhs, class BaseRhs,
+ class SomeLhs, class SomeRhs,
+ typename ResultType,
+ class CastLhs, class CastRhs,
+ ResultType (*Callback)(SomeLhs&, SomeRhs&)>
+struct FnDispatcherHelper
+{
+ static ResultType Trampoline(BaseLhs& lhs, BaseRhs& rhs)
{
- template <class BaseLhs, class BaseRhs,
- class SomeLhs, class SomeRhs,
- typename ResultType,
- class CastLhs, class CastRhs,
- ResultType (*Callback)(SomeLhs&, SomeRhs&)>
- struct FnDispatcherHelper
- {
- static ResultType Trampoline(BaseLhs& lhs, BaseRhs& rhs)
- {
- return Callback(CastLhs::Cast(lhs), CastRhs::Cast(rhs));
- }
- static ResultType TrampolineR(BaseRhs& rhs, BaseLhs& lhs)
- {
- return Trampoline(lhs, rhs);
- }
- };
+ return Callback(CastLhs::Cast(lhs), CastRhs::Cast(rhs));
+ }
+ static ResultType TrampolineR(BaseRhs& rhs, BaseLhs& lhs)
+ {
+ return Trampoline(lhs, rhs);
}
+};
+}
////////////////////////////////////////////////////////////////////////////////
// class template FnDispatcher
@@ -247,102 +247,102 @@ namespace Loki
// Features automated conversions
////////////////////////////////////////////////////////////////////////////////
- template <class BaseLhs, class BaseRhs = BaseLhs,
- typename ResultType = void,
- template <class, class> class CastingPolicy = DynamicCaster,
- template <class, class, class, class>
- class DispatcherBackend = BasicDispatcher>
- class FnDispatcher
+template <class BaseLhs, class BaseRhs = BaseLhs,
+ typename ResultType = void,
+ template <class, class> class CastingPolicy = DynamicCaster,
+ template <class, class, class, class>
+ class DispatcherBackend = BasicDispatcher>
+class FnDispatcher
+{
+ DispatcherBackend<BaseLhs, BaseRhs, ResultType,
+ ResultType (*)(BaseLhs&, BaseRhs&)> backEnd_;
+
+public:
+ template <class SomeLhs, class SomeRhs>
+ void Add(ResultType (*pFun)(BaseLhs&, BaseRhs&))
+ {
+ return backEnd_.template Add<SomeLhs, SomeRhs>(pFun);
+ }
+
+ template <class SomeLhs, class SomeRhs,
+ ResultType (*callback)(SomeLhs&, SomeRhs&)>
+ void Add()
{
- DispatcherBackend<BaseLhs, BaseRhs, ResultType,
- ResultType (*)(BaseLhs&, BaseRhs&)> backEnd_;
-
- public:
- template <class SomeLhs, class SomeRhs>
- void Add(ResultType (*pFun)(BaseLhs&, BaseRhs&))
- {
- return backEnd_.template Add<SomeLhs, SomeRhs>(pFun);
- }
-
- template <class SomeLhs, class SomeRhs,
- ResultType (*callback)(SomeLhs&, SomeRhs&)>
- void Add()
- {
typedef Private::FnDispatcherHelper<
- BaseLhs, BaseRhs,
- SomeLhs, SomeRhs,
- ResultType,
- CastingPolicy<SomeLhs,BaseLhs>,
- CastingPolicy<SomeRhs,BaseRhs>,
- callback> Local;
-
- Add<SomeLhs, SomeRhs>(&Local::Trampoline);
- }
-
- template <class SomeLhs, class SomeRhs,
- ResultType (*callback)(SomeLhs&, SomeRhs&),
- bool symmetric>
- void Add(bool = true) // [gcc] dummy bool
- {
+ BaseLhs, BaseRhs,
+ SomeLhs, SomeRhs,
+ ResultType,
+ CastingPolicy<SomeLhs,BaseLhs>,
+ CastingPolicy<SomeRhs,BaseRhs>,
+ callback> Local;
+
+ Add<SomeLhs, SomeRhs>(&Local::Trampoline);
+ }
+
+ template <class SomeLhs, class SomeRhs,
+ ResultType (*callback)(SomeLhs&, SomeRhs&),
+ bool symmetric>
+ void Add(bool = true) // [gcc] dummy bool
+ {
typedef Private::FnDispatcherHelper<
- BaseLhs, BaseRhs,
- SomeLhs, SomeRhs,
- ResultType,
- CastingPolicy<SomeLhs,BaseLhs>,
- CastingPolicy<SomeRhs,BaseRhs>,
- callback> Local;
-
- Add<SomeLhs, SomeRhs>(&Local::Trampoline);
- if (symmetric)
- {
- Add<SomeRhs, SomeLhs>(&Local::TrampolineR);
- }
- }
-
- template <class SomeLhs, class SomeRhs>
- void Remove()
+ BaseLhs, BaseRhs,
+ SomeLhs, SomeRhs,
+ ResultType,
+ CastingPolicy<SomeLhs,BaseLhs>,
+ CastingPolicy<SomeRhs,BaseRhs>,
+ callback> Local;
+
+ Add<SomeLhs, SomeRhs>(&Local::Trampoline);
+ if (symmetric)
{
- backEnd_.template Remove<SomeLhs, SomeRhs>();
+ Add<SomeRhs, SomeLhs>(&Local::TrampolineR);
}
+ }
- ResultType Go(BaseLhs& lhs, BaseRhs& rhs)
- {
- return backEnd_.Go(lhs, rhs);
- }
- };
+ template <class SomeLhs, class SomeRhs>
+ void Remove()
+ {
+ backEnd_.template Remove<SomeLhs, SomeRhs>();
+ }
+
+ ResultType Go(BaseLhs& lhs, BaseRhs& rhs)
+ {
+ return backEnd_.Go(lhs, rhs);
+ }
+};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorDispatcherAdaptor
// permits use of FunctorDispatcher under gcc.2.95.2/3
///////////////////////////////////////////////////////////////////////////////
- namespace Private
+namespace Private
+{
+template <class BaseLhs, class BaseRhs,
+ class SomeLhs, class SomeRhs,
+ typename ResultType,
+ class CastLhs, class CastRhs,
+ class Fun, bool SwapArgs>
+class FunctorDispatcherHelper
+{
+ Fun fun_;
+ ResultType Fire(BaseLhs& lhs, BaseRhs& rhs,Int2Type<false>)
{
- template <class BaseLhs, class BaseRhs,
- class SomeLhs, class SomeRhs,
- typename ResultType,
- class CastLhs, class CastRhs,
- class Fun, bool SwapArgs>
- class FunctorDispatcherHelper
- {
- Fun fun_;
- ResultType Fire(BaseLhs& lhs, BaseRhs& rhs,Int2Type<false>)
- {
- return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs));
- }
- ResultType Fire(BaseLhs& rhs, BaseRhs& lhs,Int2Type<true>)
- {
- return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs));
- }
- public:
- FunctorDispatcherHelper(const Fun& fun) : fun_(fun) {}
-
- ResultType operator()(BaseLhs& lhs, BaseRhs& rhs)
- {
- return Fire(lhs,rhs,Int2Type<SwapArgs>());
- }
- };
+ return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs));
}
+ ResultType Fire(BaseLhs& rhs, BaseRhs& lhs,Int2Type<true>)
+ {
+ return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs));
+ }
+public:
+ FunctorDispatcherHelper(const Fun& fun) : fun_(fun) {}
+
+ ResultType operator()(BaseLhs& lhs, BaseRhs& rhs)
+ {
+ return Fire(lhs,rhs,Int2Type<SwapArgs>());
+ }
+};
+}
////////////////////////////////////////////////////////////////////////////////
// class template FunctorDispatcher
@@ -350,63 +350,63 @@ namespace Loki
// Features automated casting
////////////////////////////////////////////////////////////////////////////////
- template <class BaseLhs, class BaseRhs = BaseLhs,
- typename ResultType = void,
- template <class, class> class CastingPolicy = DynamicCaster,
- template <class, class, class, class>
- class DispatcherBackend = BasicDispatcher>
- class FunctorDispatcher
- {
- typedef LOKI_TYPELIST_2(BaseLhs&, BaseRhs&) ArgsList;
- typedef Functor<ResultType, ArgsList, LOKI_DEFAULT_THREADING> FunctorType;
+template <class BaseLhs, class BaseRhs = BaseLhs,
+ typename ResultType = void,
+ template <class, class> class CastingPolicy = DynamicCaster,
+ template <class, class, class, class>
+ class DispatcherBackend = BasicDispatcher>
+class FunctorDispatcher
+{
+ typedef LOKI_TYPELIST_2(BaseLhs&, BaseRhs&) ArgsList;
+ typedef Functor<ResultType, ArgsList, LOKI_DEFAULT_THREADING> FunctorType;
- DispatcherBackend<BaseLhs, BaseRhs, ResultType, FunctorType> backEnd_;
+ DispatcherBackend<BaseLhs, BaseRhs, ResultType, FunctorType> backEnd_;
- public:
- template <class SomeLhs, class SomeRhs, class Fun>
- void Add(const Fun& fun)
- {
- typedef Private::FunctorDispatcherHelper<
- BaseLhs, BaseRhs,
- SomeLhs, SomeRhs,
- ResultType,
- CastingPolicy<SomeLhs, BaseLhs>,
- CastingPolicy<SomeRhs, BaseRhs>,
- Fun, false> Adapter;
-
- backEnd_.template Add<SomeLhs, SomeRhs>(FunctorType(Adapter(fun)));
+public:
+ template <class SomeLhs, class SomeRhs, class Fun>
+ void Add(const Fun& fun)
+ {
+ typedef Private::FunctorDispatcherHelper<
+ BaseLhs, BaseRhs,
+ SomeLhs, SomeRhs,
+ ResultType,
+ CastingPolicy<SomeLhs, BaseLhs>,
+ CastingPolicy<SomeRhs, BaseRhs>,
+ Fun, false> Adapter;
+
+ backEnd_.template Add<SomeLhs, SomeRhs>(FunctorType(Adapter(fun)));
}
- template <class SomeLhs, class SomeRhs, bool symmetric, class Fun>
- void Add(const Fun& fun)
- {
+ template <class SomeLhs, class SomeRhs, bool symmetric, class Fun>
+ void Add(const Fun& fun)
+ {
Add<SomeLhs,SomeRhs>(fun);
if (symmetric)
{
- // Note: symmetry only makes sense where BaseLhs==BaseRhs
- typedef Private::FunctorDispatcherHelper<
- BaseLhs, BaseLhs,
- SomeLhs, SomeRhs,
- ResultType,
- CastingPolicy<SomeLhs, BaseLhs>,
- CastingPolicy<SomeRhs, BaseLhs>,
- Fun, true> AdapterR;
-
- backEnd_.template Add<SomeRhs, SomeLhs>(FunctorType(AdapterR(fun)));
- }
- }
-
- template <class SomeLhs, class SomeRhs>
- void Remove()
- {
- backEnd_.template Remove<SomeLhs, SomeRhs>();
+ // Note: symmetry only makes sense where BaseLhs==BaseRhs
+ typedef Private::FunctorDispatcherHelper<
+ BaseLhs, BaseLhs,
+ SomeLhs, SomeRhs,
+ ResultType,
+ CastingPolicy<SomeLhs, BaseLhs>,
+ CastingPolicy<SomeRhs, BaseLhs>,
+ Fun, true> AdapterR;
+
+ backEnd_.template Add<SomeRhs, SomeLhs>(FunctorType(AdapterR(fun)));
}
+ }
- ResultType Go(BaseLhs& lhs, BaseRhs& rhs)
- {
- return backEnd_.Go(lhs, rhs);
- }
- };
+ template <class SomeLhs, class SomeRhs>
+ void Remove()
+ {
+ backEnd_.template Remove<SomeLhs, SomeRhs>();
+ }
+
+ ResultType Go(BaseLhs& lhs, BaseRhs& rhs)
+ {
+ return backEnd_.Go(lhs, rhs);
+ }
+};
} // namespace Loki
diff --git a/shared/loki/NullType.h b/shared/loki/NullType.h
index 9403901a..8a4bb008 100644
--- a/shared/loki/NullType.h
+++ b/shared/loki/NullType.h
@@ -2,14 +2,14 @@
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
-// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author or Addison-Wesley Longman make no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author or Addison-Wesley Longman make no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_NULLTYPE_INC_
@@ -23,11 +23,11 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
// class NullType
// Used as a placeholder for "no type here"
-// Useful as an end marker in typelists
+// Useful as an end marker in typelists
////////////////////////////////////////////////////////////////////////////////
- class NullType {};
-
+class NullType {};
+
} // namespace Loki
diff --git a/shared/loki/OrderedStatic.h b/shared/loki/OrderedStatic.h
index 6eaa20b9..0f26b6e0 100644
--- a/shared/loki/OrderedStatic.h
+++ b/shared/loki/OrderedStatic.h
@@ -1,12 +1,12 @@
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2005 Peter Kümmel
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author makes no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author makes no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_ORDEREDSTATIC_INC_
@@ -27,197 +27,197 @@
namespace Loki
{
- namespace Private
+namespace Private
+{
+////////////////////////////////////////////////////////////////////////////////
+// polymorph base class for OrderedStatic template,
+// necessary because of the creator
+////////////////////////////////////////////////////////////////////////////////
+class LOKI_EXPORT OrderedStaticCreatorFunc
+{
+public:
+ virtual void createObject() = 0;
+
+protected:
+ OrderedStaticCreatorFunc();
+ virtual ~OrderedStaticCreatorFunc();
+
+private:
+ OrderedStaticCreatorFunc(const OrderedStaticCreatorFunc&);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// template base clase for OrderedStatic template,
+// common for all specializations
+////////////////////////////////////////////////////////////////////////////////
+template<class T>
+class OrderedStaticBase : public OrderedStaticCreatorFunc
+{
+public:
+ T& operator*()
{
- ////////////////////////////////////////////////////////////////////////////////
- // polymorph base class for OrderedStatic template,
- // necessary because of the creator
- ////////////////////////////////////////////////////////////////////////////////
- class LOKI_EXPORT OrderedStaticCreatorFunc
- {
- public:
- virtual void createObject() = 0;
-
- protected:
- OrderedStaticCreatorFunc();
- virtual ~OrderedStaticCreatorFunc();
-
- private:
- OrderedStaticCreatorFunc(const OrderedStaticCreatorFunc&);
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- // template base clase for OrderedStatic template,
- // common for all specializations
- ////////////////////////////////////////////////////////////////////////////////
- template<class T>
- class OrderedStaticBase : public OrderedStaticCreatorFunc
- {
- public:
- T& operator*()
- {
- return *val_;
- }
-
- T* operator->()
- {
- return val_;
- }
-
- protected:
-
- OrderedStaticBase(unsigned int longevity) : val_(0), longevity_(longevity)
- {
- }
-
- virtual ~OrderedStaticBase()
- {
- }
-
- void SetLongevity(T* ptr)
- {
- val_=ptr;
- Loki::SetLongevity(val_,longevity_);
- }
-
- private:
- OrderedStaticBase();
- OrderedStaticBase(const OrderedStaticBase&);
- OrderedStaticBase& operator=(const OrderedStaticBase&);
- T* val_;
- unsigned int longevity_;
-
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- // OrderedStaticManagerClass implements details
- // OrderedStaticManager is then defined as a Singleton
- ////////////////////////////////////////////////////////////////////////////////
- class LOKI_EXPORT OrderedStaticManagerClass
- {
- public:
- OrderedStaticManagerClass();
- virtual ~OrderedStaticManagerClass();
-
- typedef void (OrderedStaticCreatorFunc::*Creator)();
-
- void createObjects();
- void registerObject(unsigned int longevity,OrderedStaticCreatorFunc*,Creator);
-
- private:
- OrderedStaticManagerClass(const OrderedStaticManagerClass&);
- OrderedStaticManagerClass& operator=(const OrderedStaticManagerClass&);
-
- struct Data
- {
- Data(unsigned int,OrderedStaticCreatorFunc*, Creator);
- unsigned int longevity;
- OrderedStaticCreatorFunc* object;
- Creator creator;
- };
-
- std::vector<Data> staticObjects_;
- unsigned int max_longevity_;
- unsigned int min_longevity_;
- };
-
- }// namespace Private
-
- ////////////////////////////////////////////////////////////////////////////////
- // OrderedStaticManager is only a Singleton typedef
- ////////////////////////////////////////////////////////////////////////////////
-
- typedef Loki::SingletonHolder
- <
- Loki::Private::OrderedStaticManagerClass,
- Loki::CreateUsingNew,
- Loki::NoDestroy,
- Loki::SingleThreaded
- >
- OrderedStaticManager;
-
- ////////////////////////////////////////////////////////////////////////////////
- // template OrderedStatic template:
- // L : longevity
- // T : object type
- // TList : creator parameters
- ////////////////////////////////////////////////////////////////////////////////
-
- template<unsigned int L, class T, class TList = Loki::NullType>
- class OrderedStatic;
-
-
- ////////////////////////////////////////////////////////////////////////////////
- // OrderedStatic specializations
- ////////////////////////////////////////////////////////////////////////////////
-
- template<unsigned int L, class T>
- class OrderedStatic<L, T, Loki::NullType> : public Private::OrderedStaticBase<T>
+ return *val_;
+ }
+
+ T* operator->()
{
- public:
- OrderedStatic() : Private::OrderedStaticBase<T>(L)
- {
- OrderedStaticManager::Instance().registerObject
- (L,this,&Private::OrderedStaticCreatorFunc::createObject);
- }
-
- void createObject()
- {
- Private::OrderedStaticBase<T>::SetLongevity(new T);
- }
-
- private:
- OrderedStatic(const OrderedStatic&);
- OrderedStatic& operator=(const OrderedStatic&);
- };
+ return val_;
+ }
- template<unsigned int L, class T, typename P1>
- class OrderedStatic<L, T, Loki::Seq<P1> > : public Private::OrderedStaticBase<T>
+protected:
+
+ OrderedStaticBase(unsigned int longevity) : val_(0), longevity_(longevity)
{
- public:
- OrderedStatic(P1 p) : Private::OrderedStaticBase<T>(L), para_(p)
- {
- OrderedStaticManager::Instance().registerObject
- (L,this,&Private::OrderedStaticCreatorFunc::createObject);
- }
-
- void createObject()
- {
- Private::OrderedStaticBase<T>::SetLongevity(new T(para_));
- }
-
- private:
- OrderedStatic();
- OrderedStatic(const OrderedStatic&);
- OrderedStatic& operator=(const OrderedStatic&);
- P1 para_;
- };
+ }
- template<unsigned int L, class T, typename P1>
- class OrderedStatic<L, T, P1(*)() > : public Private::OrderedStaticBase<T>
+ virtual ~OrderedStaticBase()
{
- public:
-
- typedef P1(*Func)();
-
- OrderedStatic(Func p) : Private::OrderedStaticBase<T>(L), para_(p)
- {
- OrderedStaticManager::Instance().registerObject
- (L,this,&Private::OrderedStaticCreatorFunc::createObject);
- }
-
- void createObject()
- {
- Private::OrderedStaticBase<T>::SetLongevity(new T(para_()));
- }
-
- private:
- OrderedStatic();
- OrderedStatic(const OrderedStatic&);
- OrderedStatic& operator=(const OrderedStatic&);
- Func para_;
+ }
+
+ void SetLongevity(T* ptr)
+ {
+ val_=ptr;
+ Loki::SetLongevity(val_,longevity_);
+ }
+
+private:
+ OrderedStaticBase();
+ OrderedStaticBase(const OrderedStaticBase&);
+ OrderedStaticBase& operator=(const OrderedStaticBase&);
+ T* val_;
+ unsigned int longevity_;
+
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// OrderedStaticManagerClass implements details
+// OrderedStaticManager is then defined as a Singleton
+////////////////////////////////////////////////////////////////////////////////
+class LOKI_EXPORT OrderedStaticManagerClass
+{
+public:
+ OrderedStaticManagerClass();
+ virtual ~OrderedStaticManagerClass();
+
+ typedef void (OrderedStaticCreatorFunc::*Creator)();
+
+ void createObjects();
+ void registerObject(unsigned int longevity,OrderedStaticCreatorFunc*,Creator);
+
+private:
+ OrderedStaticManagerClass(const OrderedStaticManagerClass&);
+ OrderedStaticManagerClass& operator=(const OrderedStaticManagerClass&);
+
+ struct Data
+ {
+ Data(unsigned int,OrderedStaticCreatorFunc*, Creator);
+ unsigned int longevity;
+ OrderedStaticCreatorFunc* object;
+ Creator creator;
};
+ std::vector<Data> staticObjects_;
+ unsigned int max_longevity_;
+ unsigned int min_longevity_;
+};
+
+}// namespace Private
+
+////////////////////////////////////////////////////////////////////////////////
+// OrderedStaticManager is only a Singleton typedef
+////////////////////////////////////////////////////////////////////////////////
+
+typedef Loki::SingletonHolder
+<
+Loki::Private::OrderedStaticManagerClass,
+ Loki::CreateUsingNew,
+ Loki::NoDestroy,
+ Loki::SingleThreaded
+ >
+ OrderedStaticManager;
+
+////////////////////////////////////////////////////////////////////////////////
+// template OrderedStatic template:
+// L : longevity
+// T : object type
+// TList : creator parameters
+////////////////////////////////////////////////////////////////////////////////
+
+template<unsigned int L, class T, class TList = Loki::NullType>
+class OrderedStatic;
+
+
+////////////////////////////////////////////////////////////////////////////////
+// OrderedStatic specializations
+////////////////////////////////////////////////////////////////////////////////
+
+template<unsigned int L, class T>
+class OrderedStatic<L, T, Loki::NullType> : public Private::OrderedStaticBase<T>
+{
+public:
+ OrderedStatic() : Private::OrderedStaticBase<T>(L)
+ {
+ OrderedStaticManager::Instance().registerObject
+ (L,this,&Private::OrderedStaticCreatorFunc::createObject);
+ }
+
+ void createObject()
+ {
+ Private::OrderedStaticBase<T>::SetLongevity(new T);
+ }
+
+private:
+ OrderedStatic(const OrderedStatic&);
+ OrderedStatic& operator=(const OrderedStatic&);
+};
+
+template<unsigned int L, class T, typename P1>
+class OrderedStatic<L, T, Loki::Seq<P1> > : public Private::OrderedStaticBase<T>
+{
+public:
+ OrderedStatic(P1 p) : Private::OrderedStaticBase<T>(L), para_(p)
+ {
+ OrderedStaticManager::Instance().registerObject
+ (L,this,&Private::OrderedStaticCreatorFunc::createObject);
+ }
+
+ void createObject()
+ {
+ Private::OrderedStaticBase<T>::SetLongevity(new T(para_));
+ }
+
+private:
+ OrderedStatic();
+ OrderedStatic(const OrderedStatic&);
+ OrderedStatic& operator=(const OrderedStatic&);
+ P1 para_;
+};
+
+template<unsigned int L, class T, typename P1>
+class OrderedStatic<L, T, P1(*)() > : public Private::OrderedStaticBase<T>
+{
+public:
+
+ typedef P1(*Func)();
+
+ OrderedStatic(Func p) : Private::OrderedStaticBase<T>(L), para_(p)
+ {
+ OrderedStaticManager::Instance().registerObject
+ (L,this,&Private::OrderedStaticCreatorFunc::createObject);
+ }
+
+ void createObject()
+ {
+ Private::OrderedStaticBase<T>::SetLongevity(new T(para_()));
+ }
+
+private:
+ OrderedStatic();
+ OrderedStatic(const OrderedStatic&);
+ OrderedStatic& operator=(const OrderedStatic&);
+ Func para_;
+};
+
}// namespace Loki
diff --git a/shared/loki/Pimpl.h b/shared/loki/Pimpl.h
index ed0d1c7b..788f76d8 100644
--- a/shared/loki/Pimpl.h
+++ b/shared/loki/Pimpl.h
@@ -1,12 +1,12 @@
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2006 Peter Kümmel
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author makes no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author makes no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_PIMPL_INC_
@@ -15,7 +15,7 @@
// $Id: Pimpl.h 751 2006-10-17 19:50:37Z syntheticpp $
-/// \defgroup PimplGroup Pimpl
+/// \defgroup PimplGroup Pimpl
#ifndef LOKI_INHERITED_PIMPL_NAME
#define LOKI_INHERITED_PIMPL_NAME d
@@ -28,170 +28,170 @@
namespace Loki
{
- //////////////////////////////////////////
- /// \class ConstPropPtr
- ///
- /// \ingroup PimplGroup
- /// Simple const propagating smart pointer
- /// Is the default smart pointer of Pimpl.
- //////////////////////////////////////////
+//////////////////////////////////////////
+/// \class ConstPropPtr
+///
+/// \ingroup PimplGroup
+/// Simple const propagating smart pointer
+/// Is the default smart pointer of Pimpl.
+//////////////////////////////////////////
- template<class T>
- struct ConstPropPtr
+template<class T>
+struct ConstPropPtr
+{
+ explicit ConstPropPtr(T* p) : ptr_(p) {}
+ ~ConstPropPtr() { delete ptr_; ptr_ = 0; }
+ T* operator->() { return ptr_; }
+ T& operator*() { return *ptr_; }
+ const T* operator->() const { return ptr_; }
+ const T& operator*() const { return *ptr_; }
+
+private:
+ ConstPropPtr();
+ ConstPropPtr(const ConstPropPtr&);
+ ConstPropPtr& operator=(const ConstPropPtr&);
+ T* ptr_;
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+/// \class Pimpl
+///
+/// \ingroup PimplGroup
+///
+/// Implements the Pimpl idiom. It's a wrapper for a smart pointer which
+/// automatically creates and deletes the implementation object and adds
+/// const propagation to the smart pointer.
+///
+/// \par Usage
+/// see test/Pimpl
+////////////////////////////////////////////////////////////////////////////////
+
+template
+<
+class T,
+ typename Pointer = ConstPropPtr<T>
+ >
+class Pimpl
+{
+public:
+
+ typedef T Impl;
+
+ Pimpl() : ptr_(new T)
+ {}
+
+ ~Pimpl()
{
- explicit ConstPropPtr(T* p) : ptr_(p) {}
- ~ConstPropPtr() { delete ptr_; ptr_ = 0; }
- T* operator->() { return ptr_; }
- T& operator*() { return *ptr_; }
- const T* operator->() const { return ptr_; }
- const T& operator*() const { return *ptr_; }
-
- private:
- ConstPropPtr();
- ConstPropPtr(const ConstPropPtr&);
- ConstPropPtr& operator=(const ConstPropPtr&);
- T* ptr_;
- };
+ // Don't compile with incomplete type
+ //
+ // If compilation breaks here make sure
+ // the compiler does not auto-generate the
+ // destructor of the class hosting the pimpl:
+ // - implement the destructor of the class
+ // - don't inline the destructor
+ typedef char T_must_be_defined[sizeof(T) ? 1 : -1 ];
+ }
+
+
+ T* operator->()
+ {
+ return ptr_.operator->();
+ }
+ T& operator*()
+ {
+ return ptr_.operator*();
+ }
- ////////////////////////////////////////////////////////////////////////////////
- /// \class Pimpl
- ///
- /// \ingroup PimplGroup
- ///
- /// Implements the Pimpl idiom. It's a wrapper for a smart pointer which
- /// automatically creates and deletes the implementation object and adds
- /// const propagation to the smart pointer.
- ///
- /// \par Usage
- /// see test/Pimpl
- ////////////////////////////////////////////////////////////////////////////////
-
- template
- <
- class T,
- typename Pointer = ConstPropPtr<T>
- >
- class Pimpl
+ const T* operator->() const
{
- public:
+ return ptr_.operator->();
+ }
- typedef T Impl;
+ const T& operator*() const
+ {
+ return ptr_.operator*();
+ }
- Pimpl() : ptr_(new T)
- {}
+ Pointer& wrapped()
+ {
+ return ptr_;
+ }
- ~Pimpl()
- {
- // Don't compile with incomplete type
- //
- // If compilation breaks here make sure
- // the compiler does not auto-generate the
- // destructor of the class hosting the pimpl:
- // - implement the destructor of the class
- // - don't inline the destructor
- typedef char T_must_be_defined[sizeof(T) ? 1 : -1 ];
- }
-
-
- T* operator->()
- {
- return ptr_.operator->();
- }
-
- T& operator*()
- {
- return ptr_.operator*();
- }
-
- const T* operator->() const
- {
- return ptr_.operator->();
- }
-
- const T& operator*() const
- {
- return ptr_.operator*();
- }
-
- Pointer& wrapped()
- {
- return ptr_;
- }
-
- const Pointer& wrapped() const
- {
- return ptr_;
- }
-
-
- private:
- Pimpl(const Pimpl&);
- Pimpl& operator=(const Pimpl&);
-
- Pointer ptr_;
- };
+ const Pointer& wrapped() const
+ {
+ return ptr_;
+ }
- template<class T, typename Pointer = ConstPropPtr<T> >
- struct PimplOwner
- {
- Pimpl<T,Pointer> LOKI_INHERITED_PIMPL_NAME;
- };
+private:
+ Pimpl(const Pimpl&);
+ Pimpl& operator=(const Pimpl&);
+ Pointer ptr_;
+};
- //////////////////////////////////////////
- /// \class ImplOf
- ///
- /// \ingroup PimplGroup
- /// Convenience template for the
- /// implementations which Pimpl points to.
- //////////////////////////////////////////
- template<class T>
- struct ImplOf;
+template<class T, typename Pointer = ConstPropPtr<T> >
+struct PimplOwner
+{
+ Pimpl<T,Pointer> LOKI_INHERITED_PIMPL_NAME;
+};
- //////////////////////////////////////////
- /// \class PImplOf
- ///
- /// \ingroup PimplGroup
- /// Convenience template which uses ImplOf
- /// as implementation structure
- //////////////////////////////////////////
+//////////////////////////////////////////
+/// \class ImplOf
+///
+/// \ingroup PimplGroup
+/// Convenience template for the
+/// implementations which Pimpl points to.
+//////////////////////////////////////////
+template<class T>
+struct ImplOf;
- template<class T, template<class> class Ptr = ConstPropPtr>
- struct PimplOf
- {
- typedef T Impl;
- // declare pimpl
- typedef Pimpl<ImplOf<T>, Ptr<ImplOf<T> > > Type;
+//////////////////////////////////////////
+/// \class PImplOf
+///
+/// \ingroup PimplGroup
+/// Convenience template which uses ImplOf
+/// as implementation structure
+//////////////////////////////////////////
- // inherit pimpl
- typedef PimplOwner<ImplOf<T>, Ptr<ImplOf<T> > > Owner;
- };
+template<class T, template<class> class Ptr = ConstPropPtr>
+struct PimplOf
+{
+ typedef T Impl;
- template<class T, class UsedPimpl = typename PimplOf<T>::Type >
- struct RimplOf
- {
- typedef typename UsedPimpl::Impl & Type;
+ // declare pimpl
+ typedef Pimpl<ImplOf<T>, Ptr<ImplOf<T> > > Type;
- class Owner
- {
- UsedPimpl pimpl;
+ // inherit pimpl
+ typedef PimplOwner<ImplOf<T>, Ptr<ImplOf<T> > > Owner;
+};
- public:
- Owner() : LOKI_INHERITED_RIMPL_NAME(*pimpl)
- {}
- Type LOKI_INHERITED_RIMPL_NAME;
- };
+template<class T, class UsedPimpl = typename PimplOf<T>::Type >
+struct RimplOf
+{
+ typedef typename UsedPimpl::Impl& Type;
+
+ class Owner
+ {
+ UsedPimpl pimpl;
+
+ public:
+ Owner() : LOKI_INHERITED_RIMPL_NAME(*pimpl)
+ {}
+ Type LOKI_INHERITED_RIMPL_NAME;
};
-
+
+};
+
}
#endif // end file guardian
diff --git a/shared/loki/RefToValue.h b/shared/loki/RefToValue.h
index 248de792..3f7ecfef 100644
--- a/shared/loki/RefToValue.h
+++ b/shared/loki/RefToValue.h
@@ -2,12 +2,12 @@
// The Loki Library
// Copyright (c) 2006 Richard Sposato
// Copyright (c) 2006 Peter Kümmel
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The authors make no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The authors make no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_REFTOVALUE_INC_
@@ -19,50 +19,50 @@
namespace Loki
{
- ////////////////////////////////////////////////////////////////////////////////
- /// \class RefToValue
- ///
- /// \ingroup SmartPointerGroup
- /// Transports a reference as a value
- /// Serves to implement the Colvin/Gibbons trick for SmartPtr/ScopeGuard
- ////////////////////////////////////////////////////////////////////////////////
-
- template <class T>
- class RefToValue
- {
- public:
-
- RefToValue(T& ref) : ref_(ref)
- {}
-
- RefToValue(const RefToValue& rhs) : ref_(rhs.ref_)
- {}
-
- operator T& () const
- {
- return ref_;
- }
-
- private:
- // Disable - not implemented
- RefToValue();
- RefToValue& operator=(const RefToValue&);
-
- T& ref_;
- };
-
-
- ////////////////////////////////////////////////////////////////////////////////
- /// \ingroup ExceptionGroup
- /// RefToValue creator.
- ////////////////////////////////////////////////////////////////////////////////
-
- template <class T>
- inline RefToValue<T> ByRef(T& t)
+////////////////////////////////////////////////////////////////////////////////
+/// \class RefToValue
+///
+/// \ingroup SmartPointerGroup
+/// Transports a reference as a value
+/// Serves to implement the Colvin/Gibbons trick for SmartPtr/ScopeGuard
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T>
+class RefToValue
+{
+public:
+
+ RefToValue(T& ref) : ref_(ref)
+ {}
+
+ RefToValue(const RefToValue& rhs) : ref_(rhs.ref_)
+ {}
+
+ operator T& () const
{
- return RefToValue<T>(t);
- }
-
+ return ref_;
+ }
+
+private:
+ // Disable - not implemented
+ RefToValue();
+ RefToValue& operator=(const RefToValue&);
+
+ T& ref_;
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+/// \ingroup ExceptionGroup
+/// RefToValue creator.
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T>
+inline RefToValue<T> ByRef(T& t)
+{
+ return RefToValue<T>(t);
+}
+
}
diff --git a/shared/loki/Register.h b/shared/loki/Register.h
index 0ad014ab..0edf4a37 100644
--- a/shared/loki/Register.h
+++ b/shared/loki/Register.h
@@ -1,12 +1,12 @@
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2006 Peter Kümmel
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author makes no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author makes no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_REGISTER_INC_
@@ -18,98 +18,98 @@
#include "TypeManip.h"
#include "HierarchyGenerators.h"
-/// \defgroup RegisterGroup Register
+/// \defgroup RegisterGroup Register
namespace Loki
{
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Helper classes/functions for RegisterByCreateSet
- //
- ////////////////////////////////////////////////////////////////////////////////
-
- ////////////////////////////////////////////////////////////////////////////////
- /// \ingroup RegisterGroup
- /// Must be specialized be the user
- ////////////////////////////////////////////////////////////////////////////////
- template<class t> bool RegisterFunction();
-
- ////////////////////////////////////////////////////////////////////////////////
- /// \ingroup RegisterGroup
- /// Must be specialized be the user
- ////////////////////////////////////////////////////////////////////////////////
- template<class t> bool UnRegisterFunction();
-
- namespace Private
- {
- template<class T>
- struct RegisterOnCreate
- {
- RegisterOnCreate() { RegisterFunction<T>(); }
- };
-
- template<class T>
- struct UnRegisterOnDelete
- {
- ~UnRegisterOnDelete() { UnRegisterFunction<T>(); }
- };
-
- template<class T>
- struct RegisterOnCreateElement
- {
- RegisterOnCreate<T> registerObj;
- };
-
- template<class T>
- struct UnRegisterOnDeleteElement
- {
- UnRegisterOnDelete<T> unregisterObj;
- };
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- /// \class RegisterOnCreateSet
- ///
- /// \ingroup RegisterGroup
- /// Implements a generic register class which registers classes of a typelist
- ///
- /// \par Usage
- /// see test/Register
- ////////////////////////////////////////////////////////////////////////////////
-
- template<typename ElementList>
- struct RegisterOnCreateSet
+////////////////////////////////////////////////////////////////////////////////
+//
+// Helper classes/functions for RegisterByCreateSet
+//
+////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////
+/// \ingroup RegisterGroup
+/// Must be specialized be the user
+////////////////////////////////////////////////////////////////////////////////
+template<class t> bool RegisterFunction();
+
+////////////////////////////////////////////////////////////////////////////////
+/// \ingroup RegisterGroup
+/// Must be specialized be the user
+////////////////////////////////////////////////////////////////////////////////
+template<class t> bool UnRegisterFunction();
+
+namespace Private
+{
+template<class T>
+struct RegisterOnCreate
+{
+ RegisterOnCreate() { RegisterFunction<T>(); }
+};
+
+template<class T>
+struct UnRegisterOnDelete
+{
+ ~UnRegisterOnDelete() { UnRegisterFunction<T>(); }
+};
+
+template<class T>
+struct RegisterOnCreateElement
+{
+ RegisterOnCreate<T> registerObj;
+};
+
+template<class T>
+struct UnRegisterOnDeleteElement
+{
+ UnRegisterOnDelete<T> unregisterObj;
+};
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// \class RegisterOnCreateSet
+///
+/// \ingroup RegisterGroup
+/// Implements a generic register class which registers classes of a typelist
+///
+/// \par Usage
+/// see test/Register
+////////////////////////////////////////////////////////////////////////////////
+
+template<typename ElementList>
+struct RegisterOnCreateSet
: GenScatterHierarchy<ElementList, Private::RegisterOnCreateElement>
{};
- ////////////////////////////////////////////////////////////////////////////////
- /// \class UnRegisterOnDeleteSet
- ///
- /// \ingroup RegisterGroup
- /// Implements a generic register class which unregisters classes of a typelist
- ///
- /// \par Usage
- /// see test/Register
- ////////////////////////////////////////////////////////////////////////////////
- template<typename ElementList>
- struct UnRegisterOnDeleteSet
+////////////////////////////////////////////////////////////////////////////////
+/// \class UnRegisterOnDeleteSet
+///
+/// \ingroup RegisterGroup
+/// Implements a generic register class which unregisters classes of a typelist
+///
+/// \par Usage
+/// see test/Register
+////////////////////////////////////////////////////////////////////////////////
+template<typename ElementList>
+struct UnRegisterOnDeleteSet
: GenScatterHierarchy<ElementList, Private::UnRegisterOnDeleteElement>
{};
- ////////////////////////////////////////////////////////////////////////////////
- /// \def LOKI_CHECK_CLASS_IN_LIST( CLASS , LIST )
- ///
- /// \ingroup RegisterGroup
- /// Check if CLASS is in the typelist LIST.
- ///
- /// \par Usage
- /// see test/Register
- ////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+/// \def LOKI_CHECK_CLASS_IN_LIST( CLASS , LIST )
+///
+/// \ingroup RegisterGroup
+/// Check if CLASS is in the typelist LIST.
+///
+/// \par Usage
+/// see test/Register
+////////////////////////////////////////////////////////////////////////////////
+
-
-#define LOKI_CONCATE(a,b,c,d) a ## b ## c ## d
+#define LOKI_CONCATE(a,b,c,d) a ## b ## c ## d
#define LOKI_CONCAT(a,b,c,d) LOKI_CONCATE(a,b,c,d)
#define LOKI_CHECK_CLASS_IN_LIST( CLASS , LIST ) \
diff --git a/shared/loki/SPCachedFactory.h b/shared/loki/SPCachedFactory.h
index 71c72644..aab37127 100644
--- a/shared/loki/SPCachedFactory.h
+++ b/shared/loki/SPCachedFactory.h
@@ -4,16 +4,16 @@
//
// Code covered by the MIT License
//
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
//
// The authors make no representations about the suitability of this software
// for any purpose. It is provided "as is" without express or implied warranty.
//
// This code DOES NOT accompany the book:
-// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
//
////////////////////////////////////////////////////////////////////////////////
@@ -29,8 +29,8 @@
* It as been defined in a separate file because of the many introduced
* dependencies (SmartPtr.h would depend on Functor.h and CachedFactory.h
* would depend on SmartPtr.h). By defining another header you pay for those
- * extra dependencies only if you need it.
- *
+ * extra dependencies only if you need it.
+ *
* This file defines FunctionStorage a new SmartPointer storage policy and
* SmartPointer a new CachedFactory encapsulation policy.
*/
@@ -45,7 +45,7 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
/// \class FunctionStorage
///
-/// \ingroup SmartPointerStorageGroup
+/// \ingroup SmartPointerStorageGroup
/// \brief Implementation of the StoragePolicy used by SmartPtr.
///
/// This storage policy is used by SmartPointer CachedFactory's encapsulation
@@ -58,146 +58,146 @@ namespace Loki
/// the FunctionStorage template to know the full definition of the SmartPtr.
////////////////////////////////////////////////////////////////////////////////
- template <class T>
- class FunctionStorage
+template <class T>
+class FunctionStorage
+{
+public:
+ /// the type of the pointee_ object
+ typedef T* StoredType;
+ /// type used to declare OwnershipPolicy type.
+ typedef T* InitPointerType;
+ /// type returned by operator->
+ typedef T* PointerType;
+ /// type returned by operator*
+ typedef T& ReferenceType;
+ /// type of the Functor to set
+ typedef Functor< void , Seq< void* > > FunctorType;
+
+ FunctionStorage() : pointee_(Default()), functor_()
+ {}
+
+ // The storage policy doesn't initialize the stored pointer
+ // which will be initialized by the OwnershipPolicy's Clone fn
+ FunctionStorage(const FunctionStorage& rsh) : pointee_(0), functor_(rsh.functor_)
+ {}
+
+ template <class U>
+ FunctionStorage(const FunctionStorage<U>& rsh) : pointee_(0), functor_(rsh.functor_)
+ {}
+
+ FunctionStorage(const StoredType& p) : pointee_(p), functor_() {}
+
+ PointerType operator->() const { return pointee_; }
+
+ ReferenceType operator*() const { return *pointee_; }
+
+ void Swap(FunctionStorage& rhs)
+ {
+ std::swap(pointee_, rhs.pointee_);
+ std::swap(functor_, rhs.functor_);
+ }
+
+ /// Sets the callback function to call. You have to specify it or
+ /// the smartPtr will throw a bad_function_call exception.
+ void SetCallBackFunction(const FunctorType& functor)
+ {
+ functor_ = functor;
+ }
+
+ // Accessors
+ template <class F>
+ friend typename FunctionStorage<F>::PointerType GetImpl(const FunctionStorage<F>& sp);
+
+ template <class F>
+ friend const typename FunctionStorage<F>::StoredType& GetImplRef(const FunctionStorage<F>& sp);
+
+ template <class F>
+ friend typename FunctionStorage<F>::StoredType& GetImplRef(FunctionStorage<F>& sp);
+
+protected:
+ // Destroys the data stored
+ // (Destruction might be taken over by the OwnershipPolicy)
+ void Destroy()
+ {
+ functor_(this);
+ }
+
+ // Default value to initialize the pointer
+ static StoredType Default()
+ { return 0; }
+
+private:
+ // Data
+ StoredType pointee_;
+ FunctorType functor_;
+};
+
+template <class T>
+inline typename FunctionStorage<T>::PointerType GetImpl(const FunctionStorage<T>& sp)
+{ return sp.pointee_; }
+
+template <class T>
+inline const typename FunctionStorage<T>::StoredType& GetImplRef(const FunctionStorage<T>& sp)
+{ return sp.pointee_; }
+
+template <class T>
+inline typename FunctionStorage<T>::StoredType& GetImplRef(FunctionStorage<T>& sp)
+{ return sp.pointee_; }
+
+/**
+ * \class SmartPointer
+ * \ingroup EncapsulationPolicyCachedFactoryGroup
+ * \brief Encapsulate the object in a SmartPtr with FunctionStorage policy.
+ *
+ * The object will come back to the Cache as soon as no more SmartPtr are
+ * referencing this object. You can customize the SmartPointer with the standard
+ * SmartPtr policies (OwnershipPolicy, ConversionPolicy, CheckingPolicy,
+ * ConstnessPolicy) but StoragePolicy is forced to FunctionStorage.
+ */
+template
+<
+class AbstractProduct,
+ template <class> class OwnershipPolicy = RefCounted,
+ class ConversionPolicy = DisallowConversion,
+ template <class> class CheckingPolicy = AssertCheck,
+ template<class> class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS
+ >
+class SmartPointer
+{
+private:
+ typedef SmartPtr< AbstractProduct,OwnershipPolicy,
+ ConversionPolicy, CheckingPolicy,
+ FunctionStorage, ConstnessPolicy > CallBackSP;
+protected:
+ typedef CallBackSP ProductReturn;
+ SmartPointer() : fun(this, &SmartPointer::smartPointerCallbackFunction) {}
+ virtual ~SmartPointer() {}
+
+ ProductReturn encapsulate(AbstractProduct* pProduct)
+ {
+ CallBackSP SP(pProduct);
+ SP.SetCallBackFunction(fun);
+ return SP;
+ }
+
+ AbstractProduct* release(ProductReturn& pProduct)
+ {
+ return GetImpl(pProduct);
+ }
+
+ const char* name() {return "smart pointer";}
+
+private:
+ SmartPointer& operator=(const SmartPointer&);
+ SmartPointer(const SmartPointer&);
+ void smartPointerCallbackFunction(void* pSP)
{
- public:
- /// the type of the pointee_ object
- typedef T* StoredType;
- /// type used to declare OwnershipPolicy type.
- typedef T* InitPointerType;
- /// type returned by operator->
- typedef T* PointerType;
- /// type returned by operator*
- typedef T& ReferenceType;
- /// type of the Functor to set
- typedef Functor< void , Seq< void* > > FunctorType;
-
- FunctionStorage() : pointee_(Default()), functor_()
- {}
-
- // The storage policy doesn't initialize the stored pointer
- // which will be initialized by the OwnershipPolicy's Clone fn
- FunctionStorage(const FunctionStorage& rsh) : pointee_(0), functor_(rsh.functor_)
- {}
-
- template <class U>
- FunctionStorage(const FunctionStorage<U>& rsh) : pointee_(0), functor_(rsh.functor_)
- {}
-
- FunctionStorage(const StoredType& p) : pointee_(p), functor_() {}
-
- PointerType operator->() const { return pointee_; }
-
- ReferenceType operator*() const { return *pointee_; }
-
- void Swap(FunctionStorage& rhs)
- {
- std::swap(pointee_, rhs.pointee_);
- std::swap(functor_, rhs.functor_);
- }
-
- /// Sets the callback function to call. You have to specify it or
- /// the smartPtr will throw a bad_function_call exception.
- void SetCallBackFunction(const FunctorType &functor)
- {
- functor_ = functor;
- }
-
- // Accessors
- template <class F>
- friend typename FunctionStorage<F>::PointerType GetImpl(const FunctionStorage<F>& sp);
-
- template <class F>
- friend const typename FunctionStorage<F>::StoredType& GetImplRef(const FunctionStorage<F>& sp);
-
- template <class F>
- friend typename FunctionStorage<F>::StoredType& GetImplRef(FunctionStorage<F>& sp);
-
- protected:
- // Destroys the data stored
- // (Destruction might be taken over by the OwnershipPolicy)
- void Destroy()
- {
- functor_(this);
- }
-
- // Default value to initialize the pointer
- static StoredType Default()
- { return 0; }
-
- private:
- // Data
- StoredType pointee_;
- FunctorType functor_;
- };
-
- template <class T>
- inline typename FunctionStorage<T>::PointerType GetImpl(const FunctionStorage<T>& sp)
- { return sp.pointee_; }
-
- template <class T>
- inline const typename FunctionStorage<T>::StoredType& GetImplRef(const FunctionStorage<T>& sp)
- { return sp.pointee_; }
-
- template <class T>
- inline typename FunctionStorage<T>::StoredType& GetImplRef(FunctionStorage<T>& sp)
- { return sp.pointee_; }
-
- /**
- * \class SmartPointer
- * \ingroup EncapsulationPolicyCachedFactoryGroup
- * \brief Encapsulate the object in a SmartPtr with FunctionStorage policy.
- *
- * The object will come back to the Cache as soon as no more SmartPtr are
- * referencing this object. You can customize the SmartPointer with the standard
- * SmartPtr policies (OwnershipPolicy, ConversionPolicy, CheckingPolicy,
- * ConstnessPolicy) but StoragePolicy is forced to FunctionStorage.
- */
- template
- <
- class AbstractProduct,
- template <class> class OwnershipPolicy = RefCounted,
- class ConversionPolicy = DisallowConversion,
- template <class> class CheckingPolicy = AssertCheck,
- template<class> class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS
- >
- class SmartPointer
- {
- private:
- typedef SmartPtr< AbstractProduct,OwnershipPolicy,
- ConversionPolicy, CheckingPolicy,
- FunctionStorage, ConstnessPolicy > CallBackSP;
- protected:
- typedef CallBackSP ProductReturn;
- SmartPointer() : fun(this, &SmartPointer::smartPointerCallbackFunction) {}
- virtual ~SmartPointer(){}
-
- ProductReturn encapsulate(AbstractProduct* pProduct)
- {
- CallBackSP SP(pProduct);
- SP.SetCallBackFunction(fun);
- return SP;
- }
-
- AbstractProduct* release(ProductReturn &pProduct)
- {
- return GetImpl(pProduct);
- }
-
- const char* name(){return "smart pointer";}
-
- private:
- SmartPointer& operator=(const SmartPointer&);
- SmartPointer(const SmartPointer&);
- void smartPointerCallbackFunction(void* pSP)
- {
- CallBackSP &SP(*reinterpret_cast<CallBackSP*>(pSP));
- ReleaseObject(SP);
- }
- virtual void ReleaseObject(ProductReturn &object)=0;
- const typename CallBackSP::FunctorType fun;
- };
+ CallBackSP& SP(*reinterpret_cast<CallBackSP*>(pSP));
+ ReleaseObject(SP);
+ }
+ virtual void ReleaseObject(ProductReturn& object)=0;
+ const typename CallBackSP::FunctorType fun;
+};
} // namespace Loki
diff --git a/shared/loki/SafeBits.h b/shared/loki/SafeBits.h
index f45065ed..4105f375 100644
--- a/shared/loki/SafeBits.h
+++ b/shared/loki/SafeBits.h
@@ -102,7 +102,7 @@ namespace Loki
/// the template one. The only downside is that instead of compile-time checking
/// of the index argument, it does runtime checking.
#if defined(__SUNPRO_CC) || ( defined(__GNUC__) && (__GNUC__ < 3) )
- #define LOKI_BIT_FIELD_NONTEMPLATE_INIT
+#define LOKI_BIT_FIELD_NONTEMPLATE_INIT
#endif
/// @par Forbidding Conversions.
@@ -118,9 +118,9 @@ template < typename > struct Forbidden_conversion; // This struct must not be d
/// Forward declaration of the field type.
template <
- unsigned int unique_index,
- typename word_t = unsigned long
-> class SafeBitField;
+unsigned int unique_index,
+ typename word_t = unsigned long
+ > class SafeBitField;
////////////////////////////////////////////////////////////////////////////////
/// \class SafeBitConst Bit constants.
@@ -141,9 +141,9 @@ template <
template
<
- unsigned int unique_index,
- typename word_t = unsigned long
->
+unsigned int unique_index,
+ typename word_t = unsigned long
+ >
class SafeBitConst
{
public:
@@ -193,32 +193,32 @@ public:
SafeBitConst( const SafeBitConst& rhs ) : word( rhs.word ) {}
/// Comparison operators which take a constant bit value.
- bool operator == ( const SafeBitConst & rhs ) const { return word == rhs.word; }
- bool operator != ( const SafeBitConst & rhs ) const { return word != rhs.word; }
- bool operator < ( const SafeBitConst & rhs ) const { return word < rhs.word; }
- bool operator > ( const SafeBitConst & rhs ) const { return word > rhs.word; }
- bool operator <= ( const SafeBitConst & rhs ) const { return word <= rhs.word; }
- bool operator >= ( const SafeBitConst & rhs ) const { return word >= rhs.word; }
+ bool operator == ( const SafeBitConst& rhs ) const { return word == rhs.word; }
+ bool operator != ( const SafeBitConst& rhs ) const { return word != rhs.word; }
+ bool operator < ( const SafeBitConst& rhs ) const { return word < rhs.word; }
+ bool operator > ( const SafeBitConst& rhs ) const { return word > rhs.word; }
+ bool operator <= ( const SafeBitConst& rhs ) const { return word <= rhs.word; }
+ bool operator >= ( const SafeBitConst& rhs ) const { return word >= rhs.word; }
/// Comparision operators for mutable bit fields.
- bool operator == ( const field_t & rhs ) const { return word == rhs.word; }
- bool operator != ( const field_t & rhs ) const { return word != rhs.word; }
- bool operator < ( const field_t & rhs ) const { return word < rhs.word; }
- bool operator > ( const field_t & rhs ) const { return word > rhs.word; }
- bool operator <= ( const field_t & rhs ) const { return word <= rhs.word; }
- bool operator >= ( const field_t & rhs ) const { return word >= rhs.word; }
+ bool operator == ( const field_t& rhs ) const { return word == rhs.word; }
+ bool operator != ( const field_t& rhs ) const { return word != rhs.word; }
+ bool operator < ( const field_t& rhs ) const { return word < rhs.word; }
+ bool operator > ( const field_t& rhs ) const { return word > rhs.word; }
+ bool operator <= ( const field_t& rhs ) const { return word <= rhs.word; }
+ bool operator >= ( const field_t& rhs ) const { return word >= rhs.word; }
/// Bitwise operations. Operation-assignment operators are not needed,
/// since bit constants cannot be changed after they are initialized.
- const SafeBitConst operator | ( const SafeBitConst & rhs ) const { return SafeBitConst( word | rhs.word ); }
- const SafeBitConst operator & ( const SafeBitConst & rhs ) const { return SafeBitConst( word & rhs.word ); }
- const SafeBitConst operator ^ ( const SafeBitConst & rhs ) const { return SafeBitConst( word ^ rhs.word ); }
+ const SafeBitConst operator | ( const SafeBitConst& rhs ) const { return SafeBitConst( word | rhs.word ); }
+ const SafeBitConst operator & ( const SafeBitConst& rhs ) const { return SafeBitConst( word & rhs.word ); }
+ const SafeBitConst operator ^ ( const SafeBitConst& rhs ) const { return SafeBitConst( word ^ rhs.word ); }
const SafeBitConst operator ~ ( void ) const { return SafeBitConst( ~word ); }
/// These bitwise operators return a bit-field instead of a bit-const.
- field_t operator | ( const field_t & rhs ) const { return field_t( word | rhs.word ); }
- field_t operator & ( const field_t & rhs ) const { return field_t( word & rhs.word ); }
- field_t operator ^ ( const field_t & rhs ) const { return field_t( word ^ rhs.word ); }
+ field_t operator | ( const field_t& rhs ) const { return field_t( word | rhs.word ); }
+ field_t operator & ( const field_t& rhs ) const { return field_t( word & rhs.word ); }
+ field_t operator ^ ( const field_t& rhs ) const { return field_t( word ^ rhs.word ); }
/// The shift operators move bits inside the bit field. These are useful in
/// loops which act over bit fields and increment them.
@@ -232,7 +232,7 @@ private:
/// Copy-assignment operator is not implemented since it does not make sense
/// for a constant object.
- SafeBitConst operator = ( const SafeBitConst & rhs );
+ SafeBitConst operator = ( const SafeBitConst& rhs );
// Private constructor from an integer type.
explicit SafeBitConst( word_t init ) : word( init ) {}
@@ -287,9 +287,9 @@ private:
template
<
- unsigned int unique_index,
- typename word_t
->
+unsigned int unique_index,
+ typename word_t
+ >
class SafeBitField
{
public:
@@ -305,37 +305,37 @@ public:
SafeBitField() : word( 0 ) {}
/// Copy constructor and assignment operators.
- SafeBitField( const SafeBitField & rhs ) : word( rhs.word ) {}
- SafeBitField & operator = ( const SafeBitField & rhs ) { word = rhs.word; return *this; }
+ SafeBitField( const SafeBitField& rhs ) : word( rhs.word ) {}
+ SafeBitField& operator = ( const SafeBitField& rhs ) { word = rhs.word; return *this; }
/// Copy constructor and assignment operators from constant bit fields.
- SafeBitField( const const_t & rhs ) : word( rhs.word ) {}
- SafeBitField & operator = ( const const_t & rhs ) { word = rhs.word; return *this; }
+ SafeBitField( const const_t& rhs ) : word( rhs.word ) {}
+ SafeBitField& operator = ( const const_t& rhs ) { word = rhs.word; return *this; }
/// These comparison operators act on bit-fields of the same type.
- bool operator == ( const SafeBitField & rhs ) const { return word == rhs.word; }
- bool operator != ( const SafeBitField & rhs ) const { return word != rhs.word; }
- bool operator < ( const SafeBitField & rhs ) const { return word < rhs.word; }
- bool operator > ( const SafeBitField & rhs ) const { return word > rhs.word; }
- bool operator <= ( const SafeBitField & rhs ) const { return word <= rhs.word; }
- bool operator >= ( const SafeBitField & rhs ) const { return word >= rhs.word; }
+ bool operator == ( const SafeBitField& rhs ) const { return word == rhs.word; }
+ bool operator != ( const SafeBitField& rhs ) const { return word != rhs.word; }
+ bool operator < ( const SafeBitField& rhs ) const { return word < rhs.word; }
+ bool operator > ( const SafeBitField& rhs ) const { return word > rhs.word; }
+ bool operator <= ( const SafeBitField& rhs ) const { return word <= rhs.word; }
+ bool operator >= ( const SafeBitField& rhs ) const { return word >= rhs.word; }
/// These comparison operators act on bit-constants of a similar type.
- bool operator == ( const const_t & rhs ) const { return word == rhs.word; }
- bool operator != ( const const_t & rhs ) const { return word != rhs.word; }
- bool operator < ( const const_t & rhs ) const { return word < rhs.word; }
- bool operator > ( const const_t & rhs ) const { return word > rhs.word; }
- bool operator <= ( const const_t & rhs ) const { return word <= rhs.word; }
- bool operator >= ( const const_t & rhs ) const { return word >= rhs.word; }
+ bool operator == ( const const_t& rhs ) const { return word == rhs.word; }
+ bool operator != ( const const_t& rhs ) const { return word != rhs.word; }
+ bool operator < ( const const_t& rhs ) const { return word < rhs.word; }
+ bool operator > ( const const_t& rhs ) const { return word > rhs.word; }
+ bool operator <= ( const const_t& rhs ) const { return word <= rhs.word; }
+ bool operator >= ( const const_t& rhs ) const { return word >= rhs.word; }
/// Bitwise operations that use bit-fields.
- SafeBitField operator | ( const SafeBitField & rhs ) const { return SafeBitField( word | rhs.word ); }
- SafeBitField operator & ( const SafeBitField & rhs ) const { return SafeBitField( word & rhs.word ); }
- SafeBitField operator ^ ( const SafeBitField & rhs ) const { return SafeBitField( word ^ rhs.word ); }
+ SafeBitField operator | ( const SafeBitField& rhs ) const { return SafeBitField( word | rhs.word ); }
+ SafeBitField operator & ( const SafeBitField& rhs ) const { return SafeBitField( word & rhs.word ); }
+ SafeBitField operator ^ ( const SafeBitField& rhs ) const { return SafeBitField( word ^ rhs.word ); }
SafeBitField operator ~ ( void ) const { return SafeBitField( ~word ); }
- SafeBitField operator |= ( const SafeBitField & rhs ) { word |= rhs.word; return SafeBitField( *this ); }
- SafeBitField operator &= ( const SafeBitField & rhs ) { word &= rhs.word; return SafeBitField( *this ); }
- SafeBitField operator ^= ( const SafeBitField & rhs ) { word ^= rhs.word; return SafeBitField( *this ); }
+ SafeBitField operator |= ( const SafeBitField& rhs ) { word |= rhs.word; return SafeBitField( *this ); }
+ SafeBitField operator &= ( const SafeBitField& rhs ) { word &= rhs.word; return SafeBitField( *this ); }
+ SafeBitField operator ^= ( const SafeBitField& rhs ) { word ^= rhs.word; return SafeBitField( *this ); }
/// Bitwise operators that use bit-constants.
SafeBitField operator | ( const_t rhs ) const { return SafeBitField( word | rhs.word ); }
@@ -471,42 +471,42 @@ inline SafeBitField< unique_index, word_t > operator != ( bool, SafeBitField< un
// This creates a typedef field_t for SafeBitField<unique_index, ulong> where index is the current line number. Since line numbers __LINE__ are counted
// separately for all header files, this ends up being the same type in all files using the header which defines field_t.
#ifdef LOKI_SAFE_BIT_FIELD
- #define LOKI_BIT_FIELD( word_t ) typedef SafeBitField<__LINE__, word_t>
+#define LOKI_BIT_FIELD( word_t ) typedef SafeBitField<__LINE__, word_t>
#else
- #define LOKI_BIT_FIELD( word_t ) typedef word_t
+#define LOKI_BIT_FIELD( word_t ) typedef word_t
#endif // LOKI_SAFE_BIT_FIELD
// The second macro helps to declare static bit constants:
// LOKI_BIT_CONST( field_t, Label_1, 1 );
// creates new bit field object named Label_1 of type field_t which represents the field with the 1st (junior) bit set.
#ifdef LOKI_SAFE_BIT_FIELD
- #ifndef LOKI_BIT_FIELD_NONTEMPLATE_INIT
- #define LOKI_BIT_CONST( field_t, label, bit_index ) \
+#ifndef LOKI_BIT_FIELD_NONTEMPLATE_INIT
+#define LOKI_BIT_CONST( field_t, label, bit_index ) \
static const field_t::const_t label = field_t::const_t::make_bit_const<bit_index>()
- #else
- #define LOKI_BIT_CONST( field_t, label, bit_index ) \
+#else
+#define LOKI_BIT_CONST( field_t, label, bit_index ) \
static const field_t::const_t label = field_t::const_t::make_bit_const( bit_index )
- #endif // LOKI_BIT_FIELD_NONTEMPLATE_INIT
+#endif // LOKI_BIT_FIELD_NONTEMPLATE_INIT
#else
- inline size_t make_bit_const( size_t i ) { return ( i > 0 ) ? ( size_t(1) << ( ( i > 0 ) ? ( i - 1 ) : 0 ) ) : 0; }
- #define LOKI_BIT_CONST( field_t, label, bit_index ) static const field_t label = make_bit_const( bit_index )
+inline size_t make_bit_const( size_t i ) { return ( i > 0 ) ? ( size_t(1) << ( ( i > 0 ) ? ( i - 1 ) : 0 ) ) : 0; }
+#define LOKI_BIT_CONST( field_t, label, bit_index ) static const field_t label = make_bit_const( bit_index )
#endif // LOKI_SAFE_BIT_FIELD
// The third macro helps to declare complex bit constants which are combination of several bits:
// LOKI_BIT_CONSTS( field_t, Label12 ) = Label_1 | Label_2;
#ifdef LOKI_SAFE_BIT_FIELD
- #define LOKI_BIT_CONSTS( field_t, label ) static const field_t::const_t label
+#define LOKI_BIT_CONSTS( field_t, label ) static const field_t::const_t label
#else
- #define LOKI_BIT_CONSTS( field_t, label ) static const field_t label
+#define LOKI_BIT_CONSTS( field_t, label ) static const field_t label
#endif // LOKI_SAFE_BIT_FIELD
// The fourth macro helps to declare the maximum number of bit constants for a given type:
// static const size_t count = LOKI_BIT_FIELD_COUNT( field_t );
// declared a variable "count" initialized to field_t::size()
#ifdef LOKI_SAFE_BIT_FIELD
- #define LOKI_BIT_FIELD_COUNT( field_t ) field_t::size()
+#define LOKI_BIT_FIELD_COUNT( field_t ) field_t::size()
#else
- #define LOKI_BIT_FIELD_COUNT( field_t ) ( 8 * sizeof(field_t) )
+#define LOKI_BIT_FIELD_COUNT( field_t ) ( 8 * sizeof(field_t) )
#endif // LOKI_SAFE_BIT_FIELD
} // namespace Loki
diff --git a/shared/loki/SafeFormat.h b/shared/loki/SafeFormat.h
index 9d948581..2734e972 100644
--- a/shared/loki/SafeFormat.h
+++ b/shared/loki/SafeFormat.h
@@ -5,8 +5,8 @@
// purpose is hereby granted without fee, provided that the above copyright
// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author makes no representations about the suitability of this software
-// for any purpose. It is provided "as is" without express or implied
+// The author makes no representations about the suitability of this software
+// for any purpose. It is provided "as is" without express or implied
// warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_SAFEFORMAT_INC_
@@ -16,8 +16,8 @@
////////////////////////////////////////////////////////////////////////////////
-// This file contains definitions for SafePrintf. SafeScanf coming soon (the
-// design is similar).
+// This file contains definitions for SafePrintf. SafeScanf coming soon (the
+// design is similar).
// See Alexandrescu, Andrei: Type-safe Formatting, C/C++ Users Journal, Aug 2005
////////////////////////////////////////////////////////////////////////////////
@@ -45,328 +45,375 @@
#endif
// Windows headers could have min/max defined
-#ifdef max
-# undef max
-#endif
-#ifdef min
-# undef min
-#endif
+#ifdef max
+# undef max
+#endif
+#ifdef min
+# undef min
+#endif
namespace Loki
{
- // Crude writing method: writes straight to the file, unbuffered
- // Must be combined with a buffer to work properly (and efficiently)
- LOKI_EXPORT
- void write(std::FILE* f, const char* from, const char* to);
-
- // Write to an ostream
- LOKI_EXPORT
- void write(std::ostream& f, const char* from, const char* to);
-
- // Write to a string
- LOKI_EXPORT
- void write(std::string& s, const char* from, const char* to);
-
- // Write to a fixed-size buffer
- template <class Char>
- void write(std::pair<Char*, std::size_t>& s, const Char* from, const Char* to) {
- assert(from <= to);
- if(from + s.second < to)
- throw std::overflow_error("");
- // s.first: position one past the final copied element
- s.first = std::copy(from, to, s.first);
- // remaining buffer size
- s.second -= to - from;
+// Crude writing method: writes straight to the file, unbuffered
+// Must be combined with a buffer to work properly (and efficiently)
+LOKI_EXPORT
+void write(std::FILE* f, const char* from, const char* to);
+
+// Write to an ostream
+LOKI_EXPORT
+void write(std::ostream& f, const char* from, const char* to);
+
+// Write to a string
+LOKI_EXPORT
+void write(std::string& s, const char* from, const char* to);
+
+// Write to a fixed-size buffer
+template <class Char>
+void write(std::pair<Char*, std::size_t>& s, const Char* from, const Char* to)
+{
+ assert(from <= to);
+ if(from + s.second < to)
+ throw std::overflow_error("");
+ // s.first: position one past the final copied element
+ s.first = std::copy(from, to, s.first);
+ // remaining buffer size
+ s.second -= to - from;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// PrintfState class template
+// Holds the formatting state, and implements operator() to format stuff
+// Todo: make sure errors are handled properly
+////////////////////////////////////////////////////////////////////////////////
+
+template <class Device, class Char>
+struct PrintfState
+{
+ PrintfState(Device dev, const Char* format)
+ : device_(dev)
+ , format_(format)
+ , width_(0)
+ , prec_(0)
+ , flags_(0)
+ , result_(0)
+ {
+ Advance();
}
- ////////////////////////////////////////////////////////////////////////////////
- // PrintfState class template
- // Holds the formatting state, and implements operator() to format stuff
- // Todo: make sure errors are handled properly
- ////////////////////////////////////////////////////////////////////////////////
-
- template <class Device, class Char>
- struct PrintfState {
- PrintfState(Device dev, const Char * format)
- : device_(dev)
- , format_(format)
- , width_(0)
- , prec_(0)
- , flags_(0)
- , result_(0) {
- Advance();
- }
-
- ~PrintfState() {
- }
+ ~PrintfState()
+ {
+ }
- #define LOKI_PRINTF_STATE_FORWARD(type) \
+#define LOKI_PRINTF_STATE_FORWARD(type) \
PrintfState& operator()(type par) {\
return (*this)(static_cast< LOKI_SAFEFORMAT_UNSIGNED_LONG >(par)); \
}
- LOKI_PRINTF_STATE_FORWARD(bool)
- LOKI_PRINTF_STATE_FORWARD(char)
- LOKI_PRINTF_STATE_FORWARD(signed char)
- LOKI_PRINTF_STATE_FORWARD(unsigned char)
- LOKI_PRINTF_STATE_FORWARD(signed short)
- LOKI_PRINTF_STATE_FORWARD(unsigned short)
- LOKI_PRINTF_STATE_FORWARD(signed int)
- LOKI_PRINTF_STATE_FORWARD(signed long)
+ LOKI_PRINTF_STATE_FORWARD(bool)
+ LOKI_PRINTF_STATE_FORWARD(char)
+ LOKI_PRINTF_STATE_FORWARD(signed char)
+ LOKI_PRINTF_STATE_FORWARD(unsigned char)
+ LOKI_PRINTF_STATE_FORWARD(signed short)
+ LOKI_PRINTF_STATE_FORWARD(unsigned short)
+ LOKI_PRINTF_STATE_FORWARD(signed int)
+ LOKI_PRINTF_STATE_FORWARD(signed long)
#if (defined(_WIN32) || defined(_WIN64))
- LOKI_PRINTF_STATE_FORWARD(unsigned long)
+ LOKI_PRINTF_STATE_FORWARD(unsigned long)
#else
- // on Windows already defined by uintptr_t
- LOKI_PRINTF_STATE_FORWARD(unsigned int)
+ // on Windows already defined by uintptr_t
+ LOKI_PRINTF_STATE_FORWARD(unsigned int)
#endif
- // Print (or gobble in case of the "*" specifier) an int
- PrintfState& operator()(LOKI_SAFEFORMAT_UNSIGNED_LONG i) {
- if (result_ == -1) return *this; // don't even bother
- // % [flags] [width] [.prec] [modifier] type_char
- // Fetch the flags
- ReadFlags();
- if (*format_ == '*') {
- // read the width and get out
- SetWidth(static_cast<size_t>(i));
- ++format_;
+ // Print (or gobble in case of the "*" specifier) an int
+ PrintfState& operator()(LOKI_SAFEFORMAT_UNSIGNED_LONG i)
+ {
+ if (result_ == -1) return *this; // don't even bother
+ // % [flags] [width] [.prec] [modifier] type_char
+ // Fetch the flags
+ ReadFlags();
+ if (*format_ == '*')
+ {
+ // read the width and get out
+ SetWidth(static_cast<size_t>(i));
+ ++format_;
+ return *this;
+ }
+ ReadWidth();
+ // precision
+ if (*format_ == '.')
+ {
+ // deal with precision
+ if (format_[1] == '*')
+ {
+ // read the precision and get out
+ SetPrec(static_cast<size_t>(i));
+ format_ += 2;
return *this;
}
- ReadWidth();
- // precision
- if (*format_ == '.') {
- // deal with precision
- if (format_[1] == '*') {
- // read the precision and get out
- SetPrec(static_cast<size_t>(i));
- format_ += 2;
- return *this;
- }
- ReadPrecision();
- }
- ReadModifiers();
- // input size modifier
- if (ForceShort()) {
- // short int
- const Char c = *format_;
- if (c == 'x' || c == 'X' || c == 'u' || c == 'o') {
- i = static_cast<LOKI_SAFEFORMAT_UNSIGNED_LONG>(static_cast<unsigned short>(i));
- }
+ ReadPrecision();
+ }
+ ReadModifiers();
+ // input size modifier
+ if (ForceShort())
+ {
+ // short int
+ const Char c = *format_;
+ if (c == 'x' || c == 'X' || c == 'u' || c == 'o')
+ {
+ i = static_cast<LOKI_SAFEFORMAT_UNSIGNED_LONG>(static_cast<unsigned short>(i));
}
- FormatWithCurrentFlags(i);
- return *this;
}
+ FormatWithCurrentFlags(i);
+ return *this;
+ }
- PrintfState& operator()(void* n) {
- if (result_ == -1) return *this; // don't even bother
- PrintUsing_snprintf(n,"p");
- return *this;
- }
-
- PrintfState& operator()(double n) {
- if (result_ == -1) return *this; // don't even bother
- PrintUsing_snprintf(n,"eEfgG");
- return *this;
- }
+ PrintfState& operator()(void* n)
+ {
+ if (result_ == -1) return *this; // don't even bother
+ PrintUsing_snprintf(n,"p");
+ return *this;
+ }
- PrintfState& operator()(long double n) {
- if (result_ == -1) return *this; // don't even bother
- PrintUsing_snprintf(n,"eEfgG");
- return *this;
- }
+ PrintfState& operator()(double n)
+ {
+ if (result_ == -1) return *this; // don't even bother
+ PrintUsing_snprintf(n,"eEfgG");
+ return *this;
+ }
- // Store the number of characters printed so far
- PrintfState& operator()(int * pi) {
- return StoreCountHelper(pi);
- }
-
- // Store the number of characters printed so far
- PrintfState& operator()(short * pi) {
- return StoreCountHelper(pi);
- }
-
- // Store the number of characters printed so far
- PrintfState& operator()(long * pi) {
- return StoreCountHelper(pi);
+ PrintfState& operator()(long double n)
+ {
+ if (result_ == -1) return *this; // don't even bother
+ PrintUsing_snprintf(n,"eEfgG");
+ return *this;
+ }
+
+ // Store the number of characters printed so far
+ PrintfState& operator()(int* pi)
+ {
+ return StoreCountHelper(pi);
+ }
+
+ // Store the number of characters printed so far
+ PrintfState& operator()(short* pi)
+ {
+ return StoreCountHelper(pi);
+ }
+
+ // Store the number of characters printed so far
+ PrintfState& operator()(long* pi)
+ {
+ return StoreCountHelper(pi);
+ }
+
+ PrintfState& operator()(const std::string& stdstr)
+ {
+ return operator()(stdstr.c_str());
+ }
+
+ PrintfState& operator()(const char* const s)
+ {
+ if (result_ == -1) return *this;
+ ReadLeaders();
+ const char fmt = *format_;
+ if (fmt == 'p')
+ {
+ FormatWithCurrentFlags(reinterpret_cast<LOKI_SAFEFORMAT_UNSIGNED_LONG>(s));
+ return *this;
}
-
- PrintfState& operator()(const std::string& stdstr) {
- return operator()(stdstr.c_str());
+ if (fmt != 's')
+ {
+ result_ = -1;
+ return *this;
}
-
- PrintfState& operator()(const char *const s) {
- if (result_ == -1) return *this;
- ReadLeaders();
- const char fmt = *format_;
- if (fmt == 'p') {
- FormatWithCurrentFlags(reinterpret_cast<LOKI_SAFEFORMAT_UNSIGNED_LONG>(s));
- return *this;
- }
- if (fmt != 's') {
- result_ = -1;
- return *this;
+ const size_t len = std::min(std::strlen(s), prec_);
+ if (width_ > len)
+ {
+ if (LeftJustify())
+ {
+ Write(s, s + len);
+ Fill(' ', width_ - len);
}
- const size_t len = std::min(std::strlen(s), prec_);
- if (width_ > len) {
- if (LeftJustify()) {
- Write(s, s + len);
- Fill(' ', width_ - len);
- } else {
- Fill(' ', width_ - len);
- Write(s, s + len);
- }
- } else {
+ else
+ {
+ Fill(' ', width_ - len);
Write(s, s + len);
}
- Next();
- return *this;
}
-
- PrintfState& operator()(const void *const p) {
- return (*this)(reinterpret_cast<LOKI_SAFEFORMAT_UNSIGNED_LONG>(p));
+ else
+ {
+ Write(s, s + len);
}
-
- // read the result
- operator int() const {
- return static_cast<int>(result_);
+ Next();
+ return *this;
+ }
+
+ PrintfState& operator()(const void* const p)
+ {
+ return (*this)(reinterpret_cast<LOKI_SAFEFORMAT_UNSIGNED_LONG>(p));
+ }
+
+ // read the result
+ operator int() const
+ {
+ return static_cast<int>(result_);
+ }
+
+private:
+ PrintfState& operator=(const PrintfState&);
+ template <typename T>
+ PrintfState& StoreCountHelper(T* const pi)
+ {
+ if (result_ == -1) return *this; // don't even bother
+ ReadLeaders();
+ const char fmt = *format_;
+ if (fmt == 'p') // pointer
+ {
+ FormatWithCurrentFlags(reinterpret_cast<LOKI_SAFEFORMAT_UNSIGNED_LONG>(pi));
+ return *this;
}
-
- private:
- PrintfState& operator=(const PrintfState&);
- template <typename T>
- PrintfState& StoreCountHelper(T *const pi) {
- if (result_ == -1) return *this; // don't even bother
- ReadLeaders();
- const char fmt = *format_;
- if (fmt == 'p') { // pointer
- FormatWithCurrentFlags(reinterpret_cast<LOKI_SAFEFORMAT_UNSIGNED_LONG>(pi));
- return *this;
- }
- if (fmt != 'n') {
- result_ = -1;
- return *this;
- }
- assert(pi != 0);
- *pi = result_;
- Next();
+ if (fmt != 'n')
+ {
+ result_ = -1;
return *this;
}
+ assert(pi != 0);
+ *pi = result_;
+ Next();
+ return *this;
+ }
- void FormatWithCurrentFlags(const LOKI_SAFEFORMAT_UNSIGNED_LONG i) {
- // look at the format character
- Char formatChar = *format_;
- bool isSigned = formatChar == 'd' || formatChar == 'i';
- if (formatChar == 'p') {
- formatChar = 'x'; // pointers go to hex
- SetAlternateForm(); // printed with '0x' in front
- isSigned = true; // that's what gcc does
- }
- if (!strchr("cdiuoxX", formatChar)) {
- result_ = -1;
- return;
- }
- Char buf[
- sizeof(LOKI_SAFEFORMAT_UNSIGNED_LONG) * 3 // digits
- + 1 // sign or ' '
- + 2 // 0x or 0X
- + 1]; // terminating zero
- const Char *const bufEnd = buf + (sizeof(buf) / sizeof(Char));
- Char * bufLast = buf + (sizeof(buf) / sizeof(Char) - 1);
- Char signChar = 0;
- unsigned int base = 10;
-
- if (formatChar == 'c') {
- // Format only one character
- // The 'fill with zeros' flag is ignored
- ResetFillZeros();
- *bufLast = static_cast<char>(i);
- } else {
- // TODO: inefficient code, refactor
- const bool negative = isSigned && static_cast<LOKI_SAFEFORMAT_SIGNED_LONG>(i) < 0;
- if (formatChar == 'o') base = 8;
- else if (formatChar == 'x' || formatChar == 'X') base = 16;
- bufLast = isSigned
- ? RenderWithoutSign(static_cast<LOKI_SAFEFORMAT_SIGNED_LONG>(i), bufLast, base,
- formatChar == 'X')
- : RenderWithoutSign(i, bufLast, base,
- formatChar == 'X');
- // Add the sign
- if (isSigned) {
- negative ? signChar = '-'
- : ShowSignAlways() ? signChar = '+'
- : Blank() ? signChar = ' '
- : 0;
- }
- }
- // precision
- size_t
- countDigits = bufEnd - bufLast,
- countZeros = prec_ != size_t(-1) && countDigits < prec_ &&
- formatChar != 'c'
- ? prec_ - countDigits
- : 0,
- countBase = base != 10 && AlternateForm() && i != 0
- ? (base == 16 ? 2 : countZeros > 0 ? 0 : 1)
- : 0,
- countSign = (signChar != 0),
- totalPrintable = countDigits + countZeros + countBase + countSign;
- size_t countPadLeft = 0, countPadRight = 0;
- if (width_ > totalPrintable) {
- if (LeftJustify()) {
- countPadRight = width_ - totalPrintable;
- countPadLeft = 0;
- } else {
- countPadLeft = width_ - totalPrintable;
- countPadRight = 0;
- }
+ void FormatWithCurrentFlags(const LOKI_SAFEFORMAT_UNSIGNED_LONG i)
+ {
+ // look at the format character
+ Char formatChar = *format_;
+ bool isSigned = formatChar == 'd' || formatChar == 'i';
+ if (formatChar == 'p')
+ {
+ formatChar = 'x'; // pointers go to hex
+ SetAlternateForm(); // printed with '0x' in front
+ isSigned = true; // that's what gcc does
+ }
+ if (!strchr("cdiuoxX", formatChar))
+ {
+ result_ = -1;
+ return;
+ }
+ Char buf[
+ sizeof(LOKI_SAFEFORMAT_UNSIGNED_LONG) * 3 // digits
+ + 1 // sign or ' '
+ + 2 // 0x or 0X
+ + 1]; // terminating zero
+ const Char* const bufEnd = buf + (sizeof(buf) / sizeof(Char));
+ Char* bufLast = buf + (sizeof(buf) / sizeof(Char) - 1);
+ Char signChar = 0;
+ unsigned int base = 10;
+
+ if (formatChar == 'c')
+ {
+ // Format only one character
+ // The 'fill with zeros' flag is ignored
+ ResetFillZeros();
+ *bufLast = static_cast<char>(i);
+ }
+ else
+ {
+ // TODO: inefficient code, refactor
+ const bool negative = isSigned && static_cast<LOKI_SAFEFORMAT_SIGNED_LONG>(i) < 0;
+ if (formatChar == 'o') base = 8;
+ else if (formatChar == 'x' || formatChar == 'X') base = 16;
+ bufLast = isSigned
+ ? RenderWithoutSign(static_cast<LOKI_SAFEFORMAT_SIGNED_LONG>(i), bufLast, base,
+ formatChar == 'X')
+ : RenderWithoutSign(i, bufLast, base,
+ formatChar == 'X');
+ // Add the sign
+ if (isSigned)
+ {
+ negative ? signChar = '-'
+ : ShowSignAlways() ? signChar = '+'
+ : Blank() ? signChar = ' '
+ : 0;
}
- if (FillZeros() && prec_ == size_t(-1)) {
- // pad with zeros and no precision - transfer padding to precision
- countZeros = countPadLeft;
+ }
+ // precision
+ size_t
+ countDigits = bufEnd - bufLast,
+ countZeros = prec_ != size_t(-1) && countDigits < prec_ &&
+ formatChar != 'c'
+ ? prec_ - countDigits
+ : 0,
+ countBase = base != 10 && AlternateForm() && i != 0
+ ? (base == 16 ? 2 : countZeros > 0 ? 0 : 1)
+ : 0,
+ countSign = (signChar != 0),
+ totalPrintable = countDigits + countZeros + countBase + countSign;
+ size_t countPadLeft = 0, countPadRight = 0;
+ if (width_ > totalPrintable)
+ {
+ if (LeftJustify())
+ {
+ countPadRight = width_ - totalPrintable;
countPadLeft = 0;
}
- // ok, all computed, ready to print to device
- Fill(' ', countPadLeft);
- if (signChar != 0) Write(&signChar, &signChar + 1);
- if (countBase > 0) Fill('0', 1);
- if (countBase == 2) Fill(formatChar, 1);
- Fill('0', countZeros);
- Write(bufLast, bufEnd);
- Fill(' ', countPadRight);
- // done, advance
- Next();
+ else
+ {
+ countPadLeft = width_ - totalPrintable;
+ countPadRight = 0;
+ }
}
-
- void Write(const Char* b, const Char* e) {
- if (result_ < 0) return;
- const LOKI_SAFEFORMAT_SIGNED_LONG x = e - b;
- write(device_, b, e);
- result_ += x;
+ if (FillZeros() && prec_ == size_t(-1))
+ {
+ // pad with zeros and no precision - transfer padding to precision
+ countZeros = countPadLeft;
+ countPadLeft = 0;
}
+ // ok, all computed, ready to print to device
+ Fill(' ', countPadLeft);
+ if (signChar != 0) Write(&signChar, &signChar + 1);
+ if (countBase > 0) Fill('0', 1);
+ if (countBase == 2) Fill(formatChar, 1);
+ Fill('0', countZeros);
+ Write(bufLast, bufEnd);
+ Fill(' ', countPadRight);
+ // done, advance
+ Next();
+ }
- template <class Value>
- void PrintUsing_snprintf(Value n, const char* check_fmt_char) {
- const Char *const fmt = format_ - 1;
- assert(*fmt == '%');
- // enforce format string validity
- ReadLeaders();
- // enforce format spec
- if (!strchr(check_fmt_char, *format_)) {
- result_ = -1;
- return;
- }
- // format char validated, copy it to a temp and use legacy sprintf
- ++format_;
- Char fmtBuf[128], resultBuf[1024];
- if (format_ >= fmt + sizeof(fmtBuf) / sizeof(Char)) {
- result_ = -1;
- return;
- }
- memcpy(fmtBuf, fmt, (format_ - fmt) * sizeof(Char));
- fmtBuf[format_ - fmt] = 0;
+ void Write(const Char* b, const Char* e)
+ {
+ if (result_ < 0) return;
+ const LOKI_SAFEFORMAT_SIGNED_LONG x = e - b;
+ write(device_, b, e);
+ result_ += x;
+ }
- const int stored =
+ template <class Value>
+ void PrintUsing_snprintf(Value n, const char* check_fmt_char)
+ {
+ const Char* const fmt = format_ - 1;
+ assert(*fmt == '%');
+ // enforce format string validity
+ ReadLeaders();
+ // enforce format spec
+ if (!strchr(check_fmt_char, *format_))
+ {
+ result_ = -1;
+ return;
+ }
+ // format char validated, copy it to a temp and use legacy sprintf
+ ++format_;
+ Char fmtBuf[128], resultBuf[1024];
+ if (format_ >= fmt + sizeof(fmtBuf) / sizeof(Char))
+ {
+ result_ = -1;
+ return;
+ }
+ memcpy(fmtBuf, fmt, (format_ - fmt) * sizeof(Char));
+ fmtBuf[format_ - fmt] = 0;
+
+ const int stored =
#ifdef _MSC_VER
#if _MSC_VER < 1400
_snprintf
@@ -374,214 +421,259 @@ namespace Loki
_snprintf_s
#endif
#else
- snprintf
-#endif
- (resultBuf, sizeof(resultBuf) / sizeof(Char), fmtBuf, n);
-
- if (stored < 0) {
- result_ = -1;
- return;
- }
- Write(resultBuf, resultBuf + strlen(resultBuf));
- Advance(); // output stuff to the next format directive
- }
+ snprintf
+#endif
+ (resultBuf, sizeof(resultBuf) / sizeof(Char), fmtBuf, n);
- void Fill(const Char c, size_t n) {
- for (; n > 0; --n) {
- Write(&c, &c + 1);
- }
+ if (stored < 0)
+ {
+ result_ = -1;
+ return;
}
-
- Char* RenderWithoutSign(LOKI_SAFEFORMAT_UNSIGNED_LONG n, char* bufLast,
- unsigned int base, bool uppercase) {
- const Char hex1st = uppercase ? 'A' : 'a';
- for (;;) {
- const LOKI_SAFEFORMAT_UNSIGNED_LONG next = n / base;
- Char c = static_cast<Char>(n - next * base);
- c = static_cast<Char>(c + (c <= 9 ? '0' : static_cast<Char>(hex1st - 10)));
- *bufLast = c;
- n = next;
- if (n == 0) break;
- --bufLast;
- }
- return bufLast;
+ Write(resultBuf, resultBuf + strlen(resultBuf));
+ Advance(); // output stuff to the next format directive
+ }
+
+ void Fill(const Char c, size_t n)
+ {
+ for (; n > 0; --n)
+ {
+ Write(&c, &c + 1);
}
+ }
- char* RenderWithoutSign(LOKI_SAFEFORMAT_SIGNED_LONG n, char* bufLast, unsigned int base,
- bool uppercase) {
- if (n != LONG_MIN) {
- return RenderWithoutSign(static_cast<LOKI_SAFEFORMAT_UNSIGNED_LONG>(n < 0 ? -n : n),
- bufLast, base, uppercase);
- }
- // annoying corner case
- char* save = bufLast;
- ++n;
- bufLast = RenderWithoutSign(static_cast<LOKI_SAFEFORMAT_UNSIGNED_LONG>(n),
- bufLast, base, uppercase);
- --(*save);
- return bufLast;
+ Char* RenderWithoutSign(LOKI_SAFEFORMAT_UNSIGNED_LONG n, char* bufLast,
+ unsigned int base, bool uppercase)
+ {
+ const Char hex1st = uppercase ? 'A' : 'a';
+ for (;;)
+ {
+ const LOKI_SAFEFORMAT_UNSIGNED_LONG next = n / base;
+ Char c = static_cast<Char>(n - next * base);
+ c = static_cast<Char>(c + (c <= 9 ? '0' : static_cast<Char>(hex1st - 10)));
+ *bufLast = c;
+ n = next;
+ if (n == 0) break;
+ --bufLast;
}
-
- void Next() {
- ++format_;
- Advance();
+ return bufLast;
+ }
+
+ char* RenderWithoutSign(LOKI_SAFEFORMAT_SIGNED_LONG n, char* bufLast, unsigned int base,
+ bool uppercase)
+ {
+ if (n != LONG_MIN)
+ {
+ return RenderWithoutSign(static_cast<LOKI_SAFEFORMAT_UNSIGNED_LONG>(n < 0 ? -n : n),
+ bufLast, base, uppercase);
}
-
- void Advance() {
- ResetAll();
- const Char* begin = format_;
- for (;;) {
- if (*format_ == '%') {
- if (format_[1] != '%') { // It's a format specifier
- Write(begin, format_);
- ++format_;
- break;
- }
- // It's a "%%"
- Write(begin, ++format_);
- begin = ++format_;
- continue;
- }
- if (*format_ == 0) {
+ // annoying corner case
+ char* save = bufLast;
+ ++n;
+ bufLast = RenderWithoutSign(static_cast<LOKI_SAFEFORMAT_UNSIGNED_LONG>(n),
+ bufLast, base, uppercase);
+ --(*save);
+ return bufLast;
+ }
+
+ void Next()
+ {
+ ++format_;
+ Advance();
+ }
+
+ void Advance()
+ {
+ ResetAll();
+ const Char* begin = format_;
+ for (;;)
+ {
+ if (*format_ == '%')
+ {
+ if (format_[1] != '%') // It's a format specifier
+ {
Write(begin, format_);
+ ++format_;
break;
}
- ++format_;
+ // It's a "%%"
+ Write(begin, ++format_);
+ begin = ++format_;
+ continue;
}
- }
-
- void ReadFlags() {
- for (;; ++format_) {
- switch (*format_) {
- case '-': SetLeftJustify(); break;
- case '+': SetShowSignAlways(); break;
- case ' ': SetBlank(); break;
- case '#': SetAlternateForm(); break;
- case '0': SetFillZeros(); break;
- default: return;
- }
+ if (*format_ == 0)
+ {
+ Write(begin, format_);
+ break;
}
- }
-
- void ParseDecimalSizeT(size_t& dest) {
- if (!std::isdigit(*format_, std::locale())) return;
- size_t r = 0;
- do {
- // TODO: inefficient - rewrite
- r *= 10;
- r += *format_ - '0';
- ++format_;
- } while (std::isdigit(*format_, std::locale()));
- dest = r;
- }
-
- void ReadWidth() {
- ParseDecimalSizeT(width_);
- }
-
- void ReadPrecision() {
- assert(*format_ == '.');
++format_;
- ParseDecimalSizeT(prec_);
- }
-
- void ReadModifiers() {
- switch (*format_) {
- case 'h': SetForceShort(); ++format_; break;
- case 'l': ++format_; break;
- // more (C99 and platform-specific modifiers) to come
+ }
+ }
+
+ void ReadFlags()
+ {
+ for (;; ++format_)
+ {
+ switch (*format_)
+ {
+ case '-':
+ SetLeftJustify();
+ break;
+ case '+':
+ SetShowSignAlways();
+ break;
+ case ' ':
+ SetBlank();
+ break;
+ case '#':
+ SetAlternateForm();
+ break;
+ case '0':
+ SetFillZeros();
+ break;
+ default:
+ return;
}
}
-
- void ReadLeaders() {
- ReadFlags();
- ReadWidth();
- if (*format_ == '.') ReadPrecision();
- ReadModifiers();
+ }
+
+ void ParseDecimalSizeT(size_t& dest)
+ {
+ if (!std::isdigit(*format_, std::locale())) return;
+ size_t r = 0;
+ do
+ {
+ // TODO: inefficient - rewrite
+ r *= 10;
+ r += *format_ - '0';
+ ++format_;
}
-
- enum {
- leftJustify = 1,
- showSignAlways = 2,
- blank = 4,
- alternateForm = 8,
- fillZeros = 16,
- forceShort = 32
- };
-
- bool LeftJustify() const { return (flags_ & leftJustify) != 0; }
- bool ShowSignAlways() const { return (flags_ & showSignAlways) != 0; }
- void SetWidth(size_t w) { width_ = w; }
- void SetLeftJustify() { flags_ |= leftJustify; }
- void SetShowSignAlways() { flags_ |= showSignAlways; }
- bool Blank() const { return (flags_ & blank) != 0; }
- bool AlternateForm() const { return (flags_ & alternateForm) != 0; }
- bool FillZeros() const { return (flags_ & fillZeros) != 0; }
- bool ForceShort() const { return (flags_ & forceShort) != 0; }
-
- void SetPrec(size_t p) { prec_ = p; }
- void SetBlank() { flags_ |= blank; }
- void SetAlternateForm() { flags_ |= alternateForm; }
- void SetFillZeros() { flags_ |= fillZeros; }
- void ResetFillZeros() { flags_ &= ~fillZeros; }
- void SetForceShort() { flags_ |= forceShort; }
-
- void ResetAll() {
- assert(result_ != EOF);
- width_ = 0;
- prec_ = size_t(-1);
- flags_ = 0;
+ while (std::isdigit(*format_, std::locale()));
+ dest = r;
+ }
+
+ void ReadWidth()
+ {
+ ParseDecimalSizeT(width_);
+ }
+
+ void ReadPrecision()
+ {
+ assert(*format_ == '.');
+ ++format_;
+ ParseDecimalSizeT(prec_);
+ }
+
+ void ReadModifiers()
+ {
+ switch (*format_)
+ {
+ case 'h':
+ SetForceShort();
+ ++format_;
+ break;
+ case 'l':
+ ++format_;
+ break;
+ // more (C99 and platform-specific modifiers) to come
}
+ }
+
+ void ReadLeaders()
+ {
+ ReadFlags();
+ ReadWidth();
+ if (*format_ == '.') ReadPrecision();
+ ReadModifiers();
+ }
- // state
- Device device_;
- const Char* format_;
- size_t width_;
- size_t prec_;
- unsigned int flags_;
- LOKI_SAFEFORMAT_SIGNED_LONG result_;
+ enum
+ {
+ leftJustify = 1,
+ showSignAlways = 2,
+ blank = 4,
+ alternateForm = 8,
+ fillZeros = 16,
+ forceShort = 32
};
- LOKI_EXPORT
- PrintfState<std::FILE*, char> Printf(const char* format);
+ bool LeftJustify() const { return (flags_ & leftJustify) != 0; }
+ bool ShowSignAlways() const { return (flags_ & showSignAlways) != 0; }
+ void SetWidth(size_t w) { width_ = w; }
+ void SetLeftJustify() { flags_ |= leftJustify; }
+ void SetShowSignAlways() { flags_ |= showSignAlways; }
+ bool Blank() const { return (flags_ & blank) != 0; }
+ bool AlternateForm() const { return (flags_ & alternateForm) != 0; }
+ bool FillZeros() const { return (flags_ & fillZeros) != 0; }
+ bool ForceShort() const { return (flags_ & forceShort) != 0; }
+
+ void SetPrec(size_t p) { prec_ = p; }
+ void SetBlank() { flags_ |= blank; }
+ void SetAlternateForm() { flags_ |= alternateForm; }
+ void SetFillZeros() { flags_ |= fillZeros; }
+ void ResetFillZeros() { flags_ &= ~fillZeros; }
+ void SetForceShort() { flags_ |= forceShort; }
+
+ void ResetAll()
+ {
+ assert(result_ != EOF);
+ width_ = 0;
+ prec_ = size_t(-1);
+ flags_ = 0;
+ }
- LOKI_EXPORT
- PrintfState<std::FILE*, char> Printf(const std::string& format);
+ // state
+ Device device_;
+ const Char* format_;
+ size_t width_;
+ size_t prec_;
+ unsigned int flags_;
+ LOKI_SAFEFORMAT_SIGNED_LONG result_;
+};
- LOKI_EXPORT
- PrintfState<std::FILE*, char> FPrintf(std::FILE* f, const char* format);
+LOKI_EXPORT
+PrintfState<std::FILE*, char> Printf(const char* format);
- LOKI_EXPORT
- PrintfState<std::FILE*, char> FPrintf(std::FILE* f, const std::string& format);
+LOKI_EXPORT
+PrintfState<std::FILE*, char> Printf(const std::string& format);
- LOKI_EXPORT
- PrintfState<std::ostream&, char> FPrintf(std::ostream& f, const char* format);
+LOKI_EXPORT
+PrintfState<std::FILE*, char> FPrintf(std::FILE* f, const char* format);
- LOKI_EXPORT
- PrintfState<std::ostream&, char> FPrintf(std::ostream& f, const std::string& format);
+LOKI_EXPORT
+PrintfState<std::FILE*, char> FPrintf(std::FILE* f, const std::string& format);
- LOKI_EXPORT
- PrintfState<std::string&, char> SPrintf(std::string& s, const char* format);
+LOKI_EXPORT
+PrintfState<std::ostream&, char> FPrintf(std::ostream& f, const char* format);
- LOKI_EXPORT
- PrintfState<std::string&, char> SPrintf(std::string& s, const std::string& format);
+LOKI_EXPORT
+PrintfState<std::ostream&, char> FPrintf(std::ostream& f, const std::string& format);
- template <class T, class Char>
- PrintfState<T&, Char> XPrintf(T& device, const Char* format) {
- return PrintfState<T&, Char>(device, format);
- }
+LOKI_EXPORT
+PrintfState<std::string&, char> SPrintf(std::string& s, const char* format);
- template <class T>
- PrintfState<T&, char> XPrintf(T& device, const std::string& format) {
- return PrintfState<T&, char>(device, format.c_str());
- }
+LOKI_EXPORT
+PrintfState<std::string&, char> SPrintf(std::string& s, const std::string& format);
- template <class Char, std::size_t N>
- PrintfState<std::pair<Char*, std::size_t>, Char>
- BufPrintf(Char (&buf)[N], const Char* format) {
- std::pair<Char*, std::size_t> temp(buf, N);
- return PrintfState<std::pair<Char*, std::size_t>, Char>(temp, format);
- }
+template <class T, class Char>
+PrintfState<T&, Char> XPrintf(T& device, const Char* format)
+{
+ return PrintfState<T&, Char>(device, format);
+}
+
+template <class T>
+PrintfState<T&, char> XPrintf(T& device, const std::string& format)
+{
+ return PrintfState<T&, char>(device, format.c_str());
+}
+
+template <class Char, std::size_t N>
+PrintfState<std::pair<Char*, std::size_t>, Char>
+BufPrintf(Char (&buf)[N], const Char* format)
+{
+ std::pair<Char*, std::size_t> temp(buf, N);
+ return PrintfState<std::pair<Char*, std::size_t>, Char>(temp, format);
+}
}// namespace Loki
diff --git a/shared/loki/ScopeGuard.h b/shared/loki/ScopeGuard.h
index b530068d..0b5445f5 100644
--- a/shared/loki/ScopeGuard.h
+++ b/shared/loki/ScopeGuard.h
@@ -4,12 +4,12 @@
// Copyright (c) 2000 Petru Marginean
// Copyright (c) 2005 Joshua Lehrer
//
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author makes no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author makes no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_SCOPEGUARD_INC_
@@ -25,634 +25,634 @@
namespace Loki
{
- ////////////////////////////////////////////////////////////////
- ///
- /// \class ScopeGuardImplBase
- /// \ingroup ExceptionGroup
- ///
- /// Base class used by all ScopeGuard implementations. All commonly used
- /// functions are in this class (e.g. - Dismiss and SafeExecute).
- ///
- /// See Andrei's and Petru Marginean's CUJ article
- /// http://www.cuj.com/documents/s=8000/cujcexp1812alexandr/alexandr.htm
- ///
- /// Changes to the original code by Joshua Lehrer:
- /// http://www.lehrerfamily.com/scopeguard.html
- ////////////////////////////////////////////////////////////////
-
- class ScopeGuardImplBase
- {
- /// Copy-assignment operator is not implemented and private.
- ScopeGuardImplBase& operator =(const ScopeGuardImplBase&);
-
- protected:
-
- ~ScopeGuardImplBase()
- {}
-
- /// Copy-constructor takes over responsibility from other ScopeGuard.
- ScopeGuardImplBase(const ScopeGuardImplBase& other) throw()
- : dismissed_(other.dismissed_)
- {
- other.Dismiss();
- }
-
- template <typename J>
- static void SafeExecute(J& j) throw()
- {
- if (!j.dismissed_)
- try
- {
- j.Execute();
- }
- catch(...)
+////////////////////////////////////////////////////////////////
+///
+/// \class ScopeGuardImplBase
+/// \ingroup ExceptionGroup
+///
+/// Base class used by all ScopeGuard implementations. All commonly used
+/// functions are in this class (e.g. - Dismiss and SafeExecute).
+///
+/// See Andrei's and Petru Marginean's CUJ article
+/// http://www.cuj.com/documents/s=8000/cujcexp1812alexandr/alexandr.htm
+///
+/// Changes to the original code by Joshua Lehrer:
+/// http://www.lehrerfamily.com/scopeguard.html
+////////////////////////////////////////////////////////////////
+
+class ScopeGuardImplBase
+{
+ /// Copy-assignment operator is not implemented and private.
+ ScopeGuardImplBase& operator =(const ScopeGuardImplBase&);
+
+protected:
+
+ ~ScopeGuardImplBase()
+ {}
+
+ /// Copy-constructor takes over responsibility from other ScopeGuard.
+ ScopeGuardImplBase(const ScopeGuardImplBase& other) throw()
+ : dismissed_(other.dismissed_)
+ {
+ other.Dismiss();
+ }
+
+ template <typename J>
+ static void SafeExecute(J& j) throw()
+ {
+ if (!j.dismissed_)
+ try
+ {
+ j.Execute();
+ }
+ catch(...)
{}
- }
-
- mutable bool dismissed_;
-
- public:
- ScopeGuardImplBase() throw() : dismissed_(false)
- {}
-
- void Dismiss() const throw()
- {
- dismissed_ = true;
- }
- };
-
- ////////////////////////////////////////////////////////////////
- ///
- /// \typedef typedef const ScopeGuardImplBase& ScopeGuard
- /// \ingroup ExceptionGroup
- ///
- ////////////////////////////////////////////////////////////////
-
- typedef const ScopeGuardImplBase& ScopeGuard;
-
- ////////////////////////////////////////////////////////////////
- ///
- /// \class ScopeGuardImpl0
- /// \ingroup ExceptionGroup
- ///
- /// Implementation class for a standalone function or class static function
- /// with no parameters. ScopeGuard ignores any value returned from the
- /// call within the Execute function.
- ///
- /// This class has a single standalone helper function, MakeGuard which
- /// creates and returns a ScopeGuard.
- ///
- ////////////////////////////////////////////////////////////////
-
- template <typename F>
- class ScopeGuardImpl0 : public ScopeGuardImplBase
- {
- public:
- static ScopeGuardImpl0<F> MakeGuard(F fun)
- {
- return ScopeGuardImpl0<F>(fun);
- }
-
- ~ScopeGuardImpl0() throw()
- {
- SafeExecute(*this);
- }
-
- void Execute()
- {
- fun_();
- }
-
- protected:
- ScopeGuardImpl0(F fun) : fun_(fun)
- {}
-
- F fun_;
- };
-
- template <typename F>
- inline ScopeGuardImpl0<F> MakeGuard(F fun)
- {
- return ScopeGuardImpl0<F>::MakeGuard(fun);
- }
-
- ////////////////////////////////////////////////////////////////
- ///
- /// \class ScopeGuardImpl1
- /// \ingroup ExceptionGroup
- ///
- /// Implementation class for a standalone function or class static function
- /// with one parameter. Each parameter is copied by value - use
- /// ::Loki::ByRef if you must use a reference instead. ScopeGuard ignores
- /// any value returned from the call within the Execute function.
- ///
- /// This class has a single standalone helper function, MakeGuard which
- /// creates and returns a ScopeGuard.
- ///
- ////////////////////////////////////////////////////////////////
-
- template <typename F, typename P1>
- class ScopeGuardImpl1 : public ScopeGuardImplBase
- {
- public:
- static ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
- {
- return ScopeGuardImpl1<F, P1>(fun, p1);
- }
-
- ~ScopeGuardImpl1() throw()
- {
- SafeExecute(*this);
- }
-
- void Execute()
- {
- fun_(p1_);
- }
-
- protected:
- ScopeGuardImpl1(F fun, P1 p1) : fun_(fun), p1_(p1)
- {}
-
- F fun_;
- const P1 p1_;
- };
-
- template <typename F, typename P1>
- inline ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
- {
- return ScopeGuardImpl1<F, P1>::MakeGuard(fun, p1);
- }
-
- ////////////////////////////////////////////////////////////////
- ///
- /// \class ScopeGuardImpl2
- /// \ingroup ExceptionGroup
- ///
- /// Implementation class for a standalone function or class static function
- /// with two parameters. Each parameter is copied by value - use
- /// ::Loki::ByRef if you must use a reference instead. ScopeGuard ignores
- /// any value returned from the call within the Execute function.
- ///
- /// This class has a single standalone helper function, MakeGuard which
- /// creates and returns a ScopeGuard.
- ///
- ////////////////////////////////////////////////////////////////
-
- template <typename F, typename P1, typename P2>
- class ScopeGuardImpl2: public ScopeGuardImplBase
- {
- public:
- static ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2)
- {
- return ScopeGuardImpl2<F, P1, P2>(fun, p1, p2);
- }
-
- ~ScopeGuardImpl2() throw()
- {
- SafeExecute(*this);
- }
-
- void Execute()
- {
- fun_(p1_, p2_);
- }
-
- protected:
- ScopeGuardImpl2(F fun, P1 p1, P2 p2) : fun_(fun), p1_(p1), p2_(p2)
- {}
-
- F fun_;
- const P1 p1_;
- const P2 p2_;
- };
-
- template <typename F, typename P1, typename P2>
- inline ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2)
- {
- return ScopeGuardImpl2<F, P1, P2>::MakeGuard(fun, p1, p2);
- }
-
- ////////////////////////////////////////////////////////////////
- ///
- /// \class ScopeGuardImpl3
- /// \ingroup ExceptionGroup
- ///
- /// Implementation class for a standalone function or class static function
- /// with three parameters. Each parameter is copied by value - use
- /// ::Loki::ByRef if you must use a reference instead. ScopeGuard ignores
- /// any value returned from the call within the Execute function.
- ///
- /// This class has a single standalone helper function, MakeGuard which
- /// creates and returns a ScopeGuard.
- ///
- ////////////////////////////////////////////////////////////////
-
- template <typename F, typename P1, typename P2, typename P3>
- class ScopeGuardImpl3 : public ScopeGuardImplBase
- {
- public:
- static ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
- {
- return ScopeGuardImpl3<F, P1, P2, P3>(fun, p1, p2, p3);
- }
-
- ~ScopeGuardImpl3() throw()
- {
- SafeExecute(*this);
- }
-
- void Execute()
- {
- fun_(p1_, p2_, p3_);
- }
-
- protected:
- ScopeGuardImpl3(F fun, P1 p1, P2 p2, P3 p3) : fun_(fun), p1_(p1), p2_(p2), p3_(p3)
- {}
-
- F fun_;
- const P1 p1_;
- const P2 p2_;
- const P3 p3_;
- };
-
- template <typename F, typename P1, typename P2, typename P3>
- inline ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
- {
- return ScopeGuardImpl3<F, P1, P2, P3>::MakeGuard(fun, p1, p2, p3);
- }
-
- ////////////////////////////////////////////////////////////////
- ///
- /// \class ScopeGuardImpl4
- /// \ingroup ExceptionGroup
- ///
- /// Implementation class for a standalone function or class static function
- /// with four parameters. Each parameter is copied by value - use
- /// ::Loki::ByRef if you must use a reference instead. ScopeGuard ignores
- /// any value returned from the call within the Execute function.
- ///
- /// This class has a single standalone helper function, MakeGuard which
- /// creates and returns a ScopeGuard.
- ///
- ////////////////////////////////////////////////////////////////
-
- template < typename F, typename P1, typename P2, typename P3, typename P4 >
- class ScopeGuardImpl4 : public ScopeGuardImplBase
- {
- public:
- static ScopeGuardImpl4< F, P1, P2, P3, P4 > MakeGuard(
- F fun, P1 p1, P2 p2, P3 p3, P4 p4 )
- {
- return ScopeGuardImpl4< F, P1, P2, P3, P4 >( fun, p1, p2, p3, p4 );
- }
-
- ~ScopeGuardImpl4() throw()
- {
- SafeExecute( *this );
- }
-
- void Execute()
- {
- fun_( p1_, p2_, p3_, p4_ );
- }
-
- protected:
- ScopeGuardImpl4( F fun, P1 p1, P2 p2, P3 p3, P4 p4 ) :
- fun_( fun ), p1_( p1 ), p2_( p2 ), p3_( p3 ), p4_( p4 )
- {}
-
- F fun_;
- const P1 p1_;
- const P2 p2_;
- const P3 p3_;
- const P4 p4_;
- };
-
- template < typename F, typename P1, typename P2, typename P3, typename P4 >
- inline ScopeGuardImpl4< F, P1, P2, P3, P4 > MakeGuard( F fun, P1 p1, P2 p2, P3 p3, P4 p4 )
- {
- return ScopeGuardImpl4< F, P1, P2, P3, P4 >::MakeGuard( fun, p1, p2, p3, p4 );
- }
-
- ////////////////////////////////////////////////////////////////
- ///
- /// \class ScopeGuardImpl5
- /// \ingroup ExceptionGroup
- ///
- /// Implementation class for a standalone function or class static function
- /// with five parameters. Each parameter is copied by value - use
- /// ::Loki::ByRef if you must use a reference instead. ScopeGuard ignores
- /// any value returned from the call within the Execute function.
- ///
- /// This class has a single standalone helper function, MakeGuard which
- /// creates and returns a ScopeGuard.
- ///
- ////////////////////////////////////////////////////////////////
-
- template < typename F, typename P1, typename P2, typename P3, typename P4, typename P5 >
- class ScopeGuardImpl5 : public ScopeGuardImplBase
- {
- public:
- static ScopeGuardImpl5< F, P1, P2, P3, P4, P5 > MakeGuard(
- F fun, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5 )
- {
- return ScopeGuardImpl5< F, P1, P2, P3, P4, P5 >( fun, p1, p2, p3, p4, p5 );
- }
-
- ~ScopeGuardImpl5() throw()
- {
- SafeExecute( *this );
- }
-
- void Execute()
- {
- fun_( p1_, p2_, p3_, p4_, p5_ );
- }
-
- protected:
- ScopeGuardImpl5( F fun, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5 ) :
- fun_( fun ), p1_( p1 ), p2_( p2 ), p3_( p3 ), p4_( p4 ), p5_( p5 )
- {}
-
- F fun_;
- const P1 p1_;
- const P2 p2_;
- const P3 p3_;
- const P4 p4_;
- const P5 p5_;
- };
-
- template < typename F, typename P1, typename P2, typename P3, typename P4, typename P5 >
- inline ScopeGuardImpl5< F, P1, P2, P3, P4, P5 > MakeGuard( F fun, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5 )
- {
- return ScopeGuardImpl5< F, P1, P2, P3, P4, P5 >::MakeGuard( fun, p1, p2, p3, p4, p5 );
- }
-
- ////////////////////////////////////////////////////////////////
- ///
- /// \class ObjScopeGuardImpl0
- /// \ingroup ExceptionGroup
- ///
- /// Implementation class for a class per-instance member function with no
- /// parameters. ScopeGuard ignores any value returned from the call within
- /// the Execute function.
- ///
- /// This class has 3 standalone helper functions which create a ScopeGuard.
- /// One is MakeObjGuard, which is deprecated but provided for older code.
- /// The other two are MakeGuard overloads, one which takes a pointer to an
- /// object, and the other which takes a reference.
- ///
- ////////////////////////////////////////////////////////////////
-
- template <class Obj, typename MemFun>
- class ObjScopeGuardImpl0 : public ScopeGuardImplBase
- {
- public:
- static ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun)
- {
- return ObjScopeGuardImpl0<Obj, MemFun>(obj, memFun);
- }
-
- ~ObjScopeGuardImpl0() throw()
- {
- SafeExecute(*this);
- }
-
- void Execute()
- {
- (obj_.*memFun_)();
- }
-
- protected:
- ObjScopeGuardImpl0(Obj& obj, MemFun memFun) : obj_(obj), memFun_(memFun)
- {}
-
- Obj& obj_;
- MemFun memFun_;
- };
-
- template <class Obj, typename MemFun>
- inline ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun)
- {
- return ObjScopeGuardImpl0<Obj, MemFun>::MakeObjGuard(obj, memFun);
- }
-
- template <typename Ret, class Obj1, class Obj2>
- inline ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()> MakeGuard(Ret(Obj2::*memFun)(), Obj1 &obj)
- {
- return ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()>::MakeObjGuard(obj,memFun);
- }
-
- template <typename Ret, class Obj1, class Obj2>
- inline ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()> MakeGuard(Ret(Obj2::*memFun)(), Obj1 *obj)
- {
- return ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()>::MakeObjGuard(*obj,memFun);
- }
-
- ////////////////////////////////////////////////////////////////
- ///
- /// \class ObjScopeGuardImpl1
- /// \ingroup ExceptionGroup
- ///
- /// Implementation class for a class per-instance member function with one
- /// parameter. The parameter is copied by value - use ::Loki::ByRef if you
- /// must use a reference instead. ScopeGuard ignores any value returned
- /// from the call within the Execute function.
- ///
- /// This class has 3 standalone helper functions which create a ScopeGuard.
- /// One is MakeObjGuard, which is deprecated but provided for older code.
- /// The other two are MakeGuard overloads, one which takes a pointer to an
- /// object, and the other which takes a reference.
- ///
- ////////////////////////////////////////////////////////////////
-
- template <class Obj, typename MemFun, typename P1>
- class ObjScopeGuardImpl1 : public ScopeGuardImplBase
- {
- public:
- static ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1)
- {
- return ObjScopeGuardImpl1<Obj, MemFun, P1>(obj, memFun, p1);
- }
+ }
+
+ mutable bool dismissed_;
+
+public:
+ ScopeGuardImplBase() throw() : dismissed_(false)
+ {}
+
+ void Dismiss() const throw()
+ {
+ dismissed_ = true;
+ }
+};
+
+////////////////////////////////////////////////////////////////
+///
+/// \typedef typedef const ScopeGuardImplBase& ScopeGuard
+/// \ingroup ExceptionGroup
+///
+////////////////////////////////////////////////////////////////
+
+typedef const ScopeGuardImplBase& ScopeGuard;
+
+////////////////////////////////////////////////////////////////
+///
+/// \class ScopeGuardImpl0
+/// \ingroup ExceptionGroup
+///
+/// Implementation class for a standalone function or class static function
+/// with no parameters. ScopeGuard ignores any value returned from the
+/// call within the Execute function.
+///
+/// This class has a single standalone helper function, MakeGuard which
+/// creates and returns a ScopeGuard.
+///
+////////////////////////////////////////////////////////////////
+
+template <typename F>
+class ScopeGuardImpl0 : public ScopeGuardImplBase
+{
+public:
+ static ScopeGuardImpl0<F> MakeGuard(F fun)
+ {
+ return ScopeGuardImpl0<F>(fun);
+ }
- ~ObjScopeGuardImpl1() throw()
- {
- SafeExecute(*this);
- }
+ ~ScopeGuardImpl0() throw()
+ {
+ SafeExecute(*this);
+ }
+
+ void Execute()
+ {
+ fun_();
+ }
- void Execute()
- {
- (obj_.*memFun_)(p1_);
- }
+protected:
+ ScopeGuardImpl0(F fun) : fun_(fun)
+ {}
- protected:
- ObjScopeGuardImpl1(Obj& obj, MemFun memFun, P1 p1) : obj_(obj), memFun_(memFun), p1_(p1)
- {}
-
- Obj& obj_;
- MemFun memFun_;
- const P1 p1_;
- };
-
- template <class Obj, typename MemFun, typename P1>
- inline ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1)
- {
- return ObjScopeGuardImpl1<Obj, MemFun, P1>::MakeObjGuard(obj, memFun, p1);
- }
-
- template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b>
- inline ObjScopeGuardImpl1<Obj1,Ret(Obj2::*)(P1a),P1b> MakeGuard(Ret(Obj2::*memFun)(P1a), Obj1 &obj, P1b p1)
+ F fun_;
+};
+
+template <typename F>
+inline ScopeGuardImpl0<F> MakeGuard(F fun)
+{
+ return ScopeGuardImpl0<F>::MakeGuard(fun);
+}
+
+////////////////////////////////////////////////////////////////
+///
+/// \class ScopeGuardImpl1
+/// \ingroup ExceptionGroup
+///
+/// Implementation class for a standalone function or class static function
+/// with one parameter. Each parameter is copied by value - use
+/// ::Loki::ByRef if you must use a reference instead. ScopeGuard ignores
+/// any value returned from the call within the Execute function.
+///
+/// This class has a single standalone helper function, MakeGuard which
+/// creates and returns a ScopeGuard.
+///
+////////////////////////////////////////////////////////////////
+
+template <typename F, typename P1>
+class ScopeGuardImpl1 : public ScopeGuardImplBase
+{
+public:
+ static ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
{
- return ObjScopeGuardImpl1<Obj1,Ret(Obj2::*)(P1a),P1b>::MakeObjGuard(obj,memFun,p1);
- }
-
- template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b>
- inline ObjScopeGuardImpl1<Obj1,Ret(Obj2::*)(P1a),P1b> MakeGuard(Ret(Obj2::*memFun)(P1a), Obj1 *obj, P1b p1)
- {
- return ObjScopeGuardImpl1<Obj1,Ret(Obj2::*)(P1a),P1b>::MakeObjGuard(*obj,memFun,p1);
- }
-
- ////////////////////////////////////////////////////////////////
- ///
- /// \class ObjScopeGuardImpl2
- /// \ingroup ExceptionGroup
- ///
- /// Implementation class for a class per-instance member function with two
- /// parameters. Each parameter is copied by value - use ::Loki::ByRef if you
- /// must use a reference instead. ScopeGuard ignores any value returned
- /// from the call within the Execute function.
- ///
- /// This class has 3 standalone helper functions which create a ScopeGuard.
- /// One is MakeObjGuard, which is deprecated but provided for older code.
- /// The other two are MakeGuard overloads, one which takes a pointer to an
- /// object, and the other which takes a reference.
- ///
- ////////////////////////////////////////////////////////////////
-
- template <class Obj, typename MemFun, typename P1, typename P2>
- class ObjScopeGuardImpl2 : public ScopeGuardImplBase
- {
- public:
- static ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2)
- {
- return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>(obj, memFun, p1, p2);
- }
-
- ~ObjScopeGuardImpl2() throw()
- {
- SafeExecute(*this);
- }
-
- void Execute()
- {
- (obj_.*memFun_)(p1_, p2_);
- }
-
- protected:
- ObjScopeGuardImpl2(Obj& obj, MemFun memFun, P1 p1, P2 p2) : obj_(obj), memFun_(memFun), p1_(p1), p2_(p2)
- {}
-
- Obj& obj_;
- MemFun memFun_;
- const P1 p1_;
- const P2 p2_;
- };
-
- template <class Obj, typename MemFun, typename P1, typename P2>
- inline ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2)
- {
- return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>::MakeObjGuard(obj, memFun, p1, p2);
- }
+ return ScopeGuardImpl1<F, P1>(fun, p1);
+ }
- template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b, typename P2a, typename P2b>
- inline ObjScopeGuardImpl2<Obj1,Ret(Obj2::*)(P1a,P2a),P1b,P2b> MakeGuard(Ret(Obj2::*memFun)(P1a,P2a), Obj1 &obj, P1b p1, P2b p2)
- {
- return ObjScopeGuardImpl2<Obj1,Ret(Obj2::*)(P1a,P2a),P1b,P2b>::MakeObjGuard(obj,memFun,p1,p2);
+ ~ScopeGuardImpl1() throw()
+ {
+ SafeExecute(*this);
}
-
- template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b, typename P2a, typename P2b>
- inline ObjScopeGuardImpl2<Obj1,Ret(Obj2::*)(P1a,P2a),P1b,P2b> MakeGuard(Ret(Obj2::*memFun)(P1a,P2a), Obj1 *obj, P1b p1, P2b p2)
+
+ void Execute()
{
- return ObjScopeGuardImpl2<Obj1,Ret(Obj2::*)(P1a,P2a),P1b,P2b>::MakeObjGuard(*obj,memFun,p1,p2);
+ fun_(p1_);
}
- ////////////////////////////////////////////////////////////////
- ///
- /// \class ObjScopeGuardImpl3
- /// \ingroup ExceptionGroup
- ///
- /// Implementation class for a class per-instance member function with three
- /// parameters. Each parameter is copied by value - use ::Loki::ByRef if you
- /// must use a reference instead. ScopeGuard ignores any value returned
- /// from the call within the Execute function.
- ///
- /// This class has 3 standalone helper functions which create a ScopeGuard.
- /// One is MakeObjGuard, which is deprecated but provided for older code.
- /// The other two are MakeGuard overloads, one which takes a pointer to an
- /// object, and the other which takes a reference.
- ///
- ////////////////////////////////////////////////////////////////
+protected:
+ ScopeGuardImpl1(F fun, P1 p1) : fun_(fun), p1_(p1)
+ {}
- template < class Obj, typename MemFun, typename P1, typename P2, typename P3 >
- class ObjScopeGuardImpl3 : public ScopeGuardImplBase
+ F fun_;
+ const P1 p1_;
+};
+
+template <typename F, typename P1>
+inline ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
+{
+ return ScopeGuardImpl1<F, P1>::MakeGuard(fun, p1);
+}
+
+////////////////////////////////////////////////////////////////
+///
+/// \class ScopeGuardImpl2
+/// \ingroup ExceptionGroup
+///
+/// Implementation class for a standalone function or class static function
+/// with two parameters. Each parameter is copied by value - use
+/// ::Loki::ByRef if you must use a reference instead. ScopeGuard ignores
+/// any value returned from the call within the Execute function.
+///
+/// This class has a single standalone helper function, MakeGuard which
+/// creates and returns a ScopeGuard.
+///
+////////////////////////////////////////////////////////////////
+
+template <typename F, typename P1, typename P2>
+class ScopeGuardImpl2: public ScopeGuardImplBase
+{
+public:
+ static ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2)
{
- public:
- static ObjScopeGuardImpl3< Obj, MemFun, P1, P2, P3 > MakeObjGuard(
- Obj & obj, MemFun memFun, P1 p1, P2 p2, P3 p3 )
- {
- return ObjScopeGuardImpl3< Obj, MemFun, P1, P2, P3 >( obj, memFun, p1, p2, p3 );
- }
+ return ScopeGuardImpl2<F, P1, P2>(fun, p1, p2);
+ }
- ~ObjScopeGuardImpl3() throw()
- {
- SafeExecute( *this );
- }
-
- void Execute()
- {
- ( obj_.*memFun_ )( p1_, p2_, p3_ );
- }
-
- protected:
- ObjScopeGuardImpl3( Obj & obj, MemFun memFun, P1 p1, P2 p2, P3 p3 ) :
- obj_( obj ), memFun_( memFun ), p1_( p1 ), p2_( p2 ), p3_( p3 )
- {}
-
- Obj& obj_;
- MemFun memFun_;
- const P1 p1_;
- const P2 p2_;
- const P3 p3_;
- };
+ ~ScopeGuardImpl2() throw()
+ {
+ SafeExecute(*this);
+ }
- template < class Obj, typename MemFun, typename P1, typename P2, typename P3 >
- inline ObjScopeGuardImpl3< Obj, MemFun, P1, P2, P3 > MakeObjGuard(
- Obj & obj, MemFun memFun, P1 p1, P2 p2, P3 p3 )
+ void Execute()
+ {
+ fun_(p1_, p2_);
+ }
+
+protected:
+ ScopeGuardImpl2(F fun, P1 p1, P2 p2) : fun_(fun), p1_(p1), p2_(p2)
+ {}
+
+ F fun_;
+ const P1 p1_;
+ const P2 p2_;
+};
+
+template <typename F, typename P1, typename P2>
+inline ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2)
+{
+ return ScopeGuardImpl2<F, P1, P2>::MakeGuard(fun, p1, p2);
+}
+
+////////////////////////////////////////////////////////////////
+///
+/// \class ScopeGuardImpl3
+/// \ingroup ExceptionGroup
+///
+/// Implementation class for a standalone function or class static function
+/// with three parameters. Each parameter is copied by value - use
+/// ::Loki::ByRef if you must use a reference instead. ScopeGuard ignores
+/// any value returned from the call within the Execute function.
+///
+/// This class has a single standalone helper function, MakeGuard which
+/// creates and returns a ScopeGuard.
+///
+////////////////////////////////////////////////////////////////
+
+template <typename F, typename P1, typename P2, typename P3>
+class ScopeGuardImpl3 : public ScopeGuardImplBase
+{
+public:
+ static ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
+ {
+ return ScopeGuardImpl3<F, P1, P2, P3>(fun, p1, p2, p3);
+ }
+
+ ~ScopeGuardImpl3() throw()
+ {
+ SafeExecute(*this);
+ }
+
+ void Execute()
+ {
+ fun_(p1_, p2_, p3_);
+ }
+
+protected:
+ ScopeGuardImpl3(F fun, P1 p1, P2 p2, P3 p3) : fun_(fun), p1_(p1), p2_(p2), p3_(p3)
+ {}
+
+ F fun_;
+ const P1 p1_;
+ const P2 p2_;
+ const P3 p3_;
+};
+
+template <typename F, typename P1, typename P2, typename P3>
+inline ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
+{
+ return ScopeGuardImpl3<F, P1, P2, P3>::MakeGuard(fun, p1, p2, p3);
+}
+
+////////////////////////////////////////////////////////////////
+///
+/// \class ScopeGuardImpl4
+/// \ingroup ExceptionGroup
+///
+/// Implementation class for a standalone function or class static function
+/// with four parameters. Each parameter is copied by value - use
+/// ::Loki::ByRef if you must use a reference instead. ScopeGuard ignores
+/// any value returned from the call within the Execute function.
+///
+/// This class has a single standalone helper function, MakeGuard which
+/// creates and returns a ScopeGuard.
+///
+////////////////////////////////////////////////////////////////
+
+template < typename F, typename P1, typename P2, typename P3, typename P4 >
+class ScopeGuardImpl4 : public ScopeGuardImplBase
+{
+public:
+ static ScopeGuardImpl4< F, P1, P2, P3, P4 > MakeGuard(
+ F fun, P1 p1, P2 p2, P3 p3, P4 p4 )
+ {
+ return ScopeGuardImpl4< F, P1, P2, P3, P4 >( fun, p1, p2, p3, p4 );
+ }
+
+ ~ScopeGuardImpl4() throw()
+ {
+ SafeExecute( *this );
+ }
+
+ void Execute()
+ {
+ fun_( p1_, p2_, p3_, p4_ );
+ }
+
+protected:
+ ScopeGuardImpl4( F fun, P1 p1, P2 p2, P3 p3, P4 p4 ) :
+ fun_( fun ), p1_( p1 ), p2_( p2 ), p3_( p3 ), p4_( p4 )
+ {}
+
+ F fun_;
+ const P1 p1_;
+ const P2 p2_;
+ const P3 p3_;
+ const P4 p4_;
+};
+
+template < typename F, typename P1, typename P2, typename P3, typename P4 >
+inline ScopeGuardImpl4< F, P1, P2, P3, P4 > MakeGuard( F fun, P1 p1, P2 p2, P3 p3, P4 p4 )
+{
+ return ScopeGuardImpl4< F, P1, P2, P3, P4 >::MakeGuard( fun, p1, p2, p3, p4 );
+}
+
+////////////////////////////////////////////////////////////////
+///
+/// \class ScopeGuardImpl5
+/// \ingroup ExceptionGroup
+///
+/// Implementation class for a standalone function or class static function
+/// with five parameters. Each parameter is copied by value - use
+/// ::Loki::ByRef if you must use a reference instead. ScopeGuard ignores
+/// any value returned from the call within the Execute function.
+///
+/// This class has a single standalone helper function, MakeGuard which
+/// creates and returns a ScopeGuard.
+///
+////////////////////////////////////////////////////////////////
+
+template < typename F, typename P1, typename P2, typename P3, typename P4, typename P5 >
+class ScopeGuardImpl5 : public ScopeGuardImplBase
+{
+public:
+ static ScopeGuardImpl5< F, P1, P2, P3, P4, P5 > MakeGuard(
+ F fun, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5 )
{
- return ObjScopeGuardImpl3< Obj, MemFun, P1, P2, P3 >::MakeObjGuard(
- obj, memFun, p1, p2, p3 );
+ return ScopeGuardImpl5< F, P1, P2, P3, P4, P5 >( fun, p1, p2, p3, p4, p5 );
}
- template < typename Ret, class Obj1, class Obj2, typename P1a, typename P1b,
- typename P2a, typename P2b, typename P3a, typename P3b >
- inline ObjScopeGuardImpl3< Obj1, Ret( Obj2::* )( P1a, P2a, P3a ), P1b, P2b, P3b >
- MakeGuard( Ret( Obj2::*memFun )( P1a, P2a, P3a ), Obj1 & obj, P1b p1, P2b p2, P3b p3 )
+ ~ScopeGuardImpl5() throw()
{
- return ObjScopeGuardImpl3< Obj1, Ret( Obj2::* )( P1a, P2a, P3a ), P1b, P2b, P3b >
- ::MakeObjGuard( obj, memFun, p1, p2, p3 );
+ SafeExecute( *this );
}
- template < typename Ret, class Obj1, class Obj2, typename P1a, typename P1b,
- typename P2a, typename P2b, typename P3a, typename P3b >
- inline ObjScopeGuardImpl3< Obj1, Ret( Obj2::* )( P1a, P2a, P3a ), P1b, P2b, P3b >
- MakeGuard( Ret( Obj2::*memFun )( P1a, P2a, P3a ), Obj1 * obj, P1b p1, P2b p2, P3b p3 )
+ void Execute()
{
- return ObjScopeGuardImpl3< Obj1, Ret( Obj2::* )( P1a, P2a, P3a ), P1b, P2b, P3b >
- ::MakeObjGuard( *obj, memFun, p1, p2, p3 );
+ fun_( p1_, p2_, p3_, p4_, p5_ );
}
+protected:
+ ScopeGuardImpl5( F fun, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5 ) :
+ fun_( fun ), p1_( p1 ), p2_( p2 ), p3_( p3 ), p4_( p4 ), p5_( p5 )
+ {}
+
+ F fun_;
+ const P1 p1_;
+ const P2 p2_;
+ const P3 p3_;
+ const P4 p4_;
+ const P5 p5_;
+};
+
+template < typename F, typename P1, typename P2, typename P3, typename P4, typename P5 >
+inline ScopeGuardImpl5< F, P1, P2, P3, P4, P5 > MakeGuard( F fun, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5 )
+{
+ return ScopeGuardImpl5< F, P1, P2, P3, P4, P5 >::MakeGuard( fun, p1, p2, p3, p4, p5 );
+}
+
+////////////////////////////////////////////////////////////////
+///
+/// \class ObjScopeGuardImpl0
+/// \ingroup ExceptionGroup
+///
+/// Implementation class for a class per-instance member function with no
+/// parameters. ScopeGuard ignores any value returned from the call within
+/// the Execute function.
+///
+/// This class has 3 standalone helper functions which create a ScopeGuard.
+/// One is MakeObjGuard, which is deprecated but provided for older code.
+/// The other two are MakeGuard overloads, one which takes a pointer to an
+/// object, and the other which takes a reference.
+///
+////////////////////////////////////////////////////////////////
+
+template <class Obj, typename MemFun>
+class ObjScopeGuardImpl0 : public ScopeGuardImplBase
+{
+public:
+ static ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun)
+ {
+ return ObjScopeGuardImpl0<Obj, MemFun>(obj, memFun);
+ }
+
+ ~ObjScopeGuardImpl0() throw()
+ {
+ SafeExecute(*this);
+ }
+
+ void Execute()
+ {
+ (obj_.*memFun_)();
+ }
+
+protected:
+ ObjScopeGuardImpl0(Obj& obj, MemFun memFun) : obj_(obj), memFun_(memFun)
+ {}
+
+ Obj& obj_;
+ MemFun memFun_;
+};
+
+template <class Obj, typename MemFun>
+inline ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun)
+{
+ return ObjScopeGuardImpl0<Obj, MemFun>::MakeObjGuard(obj, memFun);
+}
+
+template <typename Ret, class Obj1, class Obj2>
+inline ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()> MakeGuard(Ret(Obj2::*memFun)(), Obj1& obj)
+{
+ return ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()>::MakeObjGuard(obj,memFun);
+}
+
+template <typename Ret, class Obj1, class Obj2>
+inline ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()> MakeGuard(Ret(Obj2::*memFun)(), Obj1* obj)
+{
+ return ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()>::MakeObjGuard(*obj,memFun);
+}
+
+////////////////////////////////////////////////////////////////
+///
+/// \class ObjScopeGuardImpl1
+/// \ingroup ExceptionGroup
+///
+/// Implementation class for a class per-instance member function with one
+/// parameter. The parameter is copied by value - use ::Loki::ByRef if you
+/// must use a reference instead. ScopeGuard ignores any value returned
+/// from the call within the Execute function.
+///
+/// This class has 3 standalone helper functions which create a ScopeGuard.
+/// One is MakeObjGuard, which is deprecated but provided for older code.
+/// The other two are MakeGuard overloads, one which takes a pointer to an
+/// object, and the other which takes a reference.
+///
+////////////////////////////////////////////////////////////////
+
+template <class Obj, typename MemFun, typename P1>
+class ObjScopeGuardImpl1 : public ScopeGuardImplBase
+{
+public:
+ static ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1)
+ {
+ return ObjScopeGuardImpl1<Obj, MemFun, P1>(obj, memFun, p1);
+ }
+
+ ~ObjScopeGuardImpl1() throw()
+ {
+ SafeExecute(*this);
+ }
+
+ void Execute()
+ {
+ (obj_.*memFun_)(p1_);
+ }
+
+protected:
+ ObjScopeGuardImpl1(Obj& obj, MemFun memFun, P1 p1) : obj_(obj), memFun_(memFun), p1_(p1)
+ {}
+
+ Obj& obj_;
+ MemFun memFun_;
+ const P1 p1_;
+};
+
+template <class Obj, typename MemFun, typename P1>
+inline ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1)
+{
+ return ObjScopeGuardImpl1<Obj, MemFun, P1>::MakeObjGuard(obj, memFun, p1);
+}
+
+template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b>
+inline ObjScopeGuardImpl1<Obj1,Ret(Obj2::*)(P1a),P1b> MakeGuard(Ret(Obj2::*memFun)(P1a), Obj1& obj, P1b p1)
+{
+ return ObjScopeGuardImpl1<Obj1,Ret(Obj2::*)(P1a),P1b>::MakeObjGuard(obj,memFun,p1);
+}
+
+template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b>
+inline ObjScopeGuardImpl1<Obj1,Ret(Obj2::*)(P1a),P1b> MakeGuard(Ret(Obj2::*memFun)(P1a), Obj1* obj, P1b p1)
+{
+ return ObjScopeGuardImpl1<Obj1,Ret(Obj2::*)(P1a),P1b>::MakeObjGuard(*obj,memFun,p1);
+}
+
+////////////////////////////////////////////////////////////////
+///
+/// \class ObjScopeGuardImpl2
+/// \ingroup ExceptionGroup
+///
+/// Implementation class for a class per-instance member function with two
+/// parameters. Each parameter is copied by value - use ::Loki::ByRef if you
+/// must use a reference instead. ScopeGuard ignores any value returned
+/// from the call within the Execute function.
+///
+/// This class has 3 standalone helper functions which create a ScopeGuard.
+/// One is MakeObjGuard, which is deprecated but provided for older code.
+/// The other two are MakeGuard overloads, one which takes a pointer to an
+/// object, and the other which takes a reference.
+///
+////////////////////////////////////////////////////////////////
+
+template <class Obj, typename MemFun, typename P1, typename P2>
+class ObjScopeGuardImpl2 : public ScopeGuardImplBase
+{
+public:
+ static ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2)
+ {
+ return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>(obj, memFun, p1, p2);
+ }
+
+ ~ObjScopeGuardImpl2() throw()
+ {
+ SafeExecute(*this);
+ }
+
+ void Execute()
+ {
+ (obj_.*memFun_)(p1_, p2_);
+ }
+
+protected:
+ ObjScopeGuardImpl2(Obj& obj, MemFun memFun, P1 p1, P2 p2) : obj_(obj), memFun_(memFun), p1_(p1), p2_(p2)
+ {}
+
+ Obj& obj_;
+ MemFun memFun_;
+ const P1 p1_;
+ const P2 p2_;
+};
+
+template <class Obj, typename MemFun, typename P1, typename P2>
+inline ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2)
+{
+ return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>::MakeObjGuard(obj, memFun, p1, p2);
+}
+
+template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b, typename P2a, typename P2b>
+inline ObjScopeGuardImpl2<Obj1,Ret(Obj2::*)(P1a,P2a),P1b,P2b> MakeGuard(Ret(Obj2::*memFun)(P1a,P2a), Obj1& obj, P1b p1, P2b p2)
+{
+ return ObjScopeGuardImpl2<Obj1,Ret(Obj2::*)(P1a,P2a),P1b,P2b>::MakeObjGuard(obj,memFun,p1,p2);
+}
+
+template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b, typename P2a, typename P2b>
+inline ObjScopeGuardImpl2<Obj1,Ret(Obj2::*)(P1a,P2a),P1b,P2b> MakeGuard(Ret(Obj2::*memFun)(P1a,P2a), Obj1* obj, P1b p1, P2b p2)
+{
+ return ObjScopeGuardImpl2<Obj1,Ret(Obj2::*)(P1a,P2a),P1b,P2b>::MakeObjGuard(*obj,memFun,p1,p2);
+}
+
+////////////////////////////////////////////////////////////////
+///
+/// \class ObjScopeGuardImpl3
+/// \ingroup ExceptionGroup
+///
+/// Implementation class for a class per-instance member function with three
+/// parameters. Each parameter is copied by value - use ::Loki::ByRef if you
+/// must use a reference instead. ScopeGuard ignores any value returned
+/// from the call within the Execute function.
+///
+/// This class has 3 standalone helper functions which create a ScopeGuard.
+/// One is MakeObjGuard, which is deprecated but provided for older code.
+/// The other two are MakeGuard overloads, one which takes a pointer to an
+/// object, and the other which takes a reference.
+///
+////////////////////////////////////////////////////////////////
+
+template < class Obj, typename MemFun, typename P1, typename P2, typename P3 >
+class ObjScopeGuardImpl3 : public ScopeGuardImplBase
+{
+public:
+ static ObjScopeGuardImpl3< Obj, MemFun, P1, P2, P3 > MakeObjGuard(
+ Obj& obj, MemFun memFun, P1 p1, P2 p2, P3 p3 )
+ {
+ return ObjScopeGuardImpl3< Obj, MemFun, P1, P2, P3 >( obj, memFun, p1, p2, p3 );
+ }
+
+ ~ObjScopeGuardImpl3() throw()
+ {
+ SafeExecute( *this );
+ }
+
+ void Execute()
+ {
+ ( obj_.*memFun_ )( p1_, p2_, p3_ );
+ }
+
+protected:
+ ObjScopeGuardImpl3( Obj& obj, MemFun memFun, P1 p1, P2 p2, P3 p3 ) :
+ obj_( obj ), memFun_( memFun ), p1_( p1 ), p2_( p2 ), p3_( p3 )
+ {}
+
+ Obj& obj_;
+ MemFun memFun_;
+ const P1 p1_;
+ const P2 p2_;
+ const P3 p3_;
+};
+
+template < class Obj, typename MemFun, typename P1, typename P2, typename P3 >
+inline ObjScopeGuardImpl3< Obj, MemFun, P1, P2, P3 > MakeObjGuard(
+ Obj& obj, MemFun memFun, P1 p1, P2 p2, P3 p3 )
+{
+ return ObjScopeGuardImpl3< Obj, MemFun, P1, P2, P3 >::MakeObjGuard(
+ obj, memFun, p1, p2, p3 );
+}
+
+template < typename Ret, class Obj1, class Obj2, typename P1a, typename P1b,
+ typename P2a, typename P2b, typename P3a, typename P3b >
+inline ObjScopeGuardImpl3< Obj1, Ret( Obj2::* )( P1a, P2a, P3a ), P1b, P2b, P3b >
+MakeGuard( Ret( Obj2::*memFun )( P1a, P2a, P3a ), Obj1& obj, P1b p1, P2b p2, P3b p3 )
+{
+ return ObjScopeGuardImpl3< Obj1, Ret( Obj2::* )( P1a, P2a, P3a ), P1b, P2b, P3b >
+ ::MakeObjGuard( obj, memFun, p1, p2, p3 );
+}
+
+template < typename Ret, class Obj1, class Obj2, typename P1a, typename P1b,
+ typename P2a, typename P2b, typename P3a, typename P3b >
+inline ObjScopeGuardImpl3< Obj1, Ret( Obj2::* )( P1a, P2a, P3a ), P1b, P2b, P3b >
+MakeGuard( Ret( Obj2::*memFun )( P1a, P2a, P3a ), Obj1* obj, P1b p1, P2b p2, P3b p3 )
+{
+ return ObjScopeGuardImpl3< Obj1, Ret( Obj2::* )( P1a, P2a, P3a ), P1b, P2b, P3b >
+ ::MakeObjGuard( *obj, memFun, p1, p2, p3 );
+}
+
} // namespace Loki
#define LOKI_CONCATENATE_DIRECT(s1, s2) s1##s2
diff --git a/shared/loki/Sequence.h b/shared/loki/Sequence.h
index 4e5bd235..e8c8bd35 100644
--- a/shared/loki/Sequence.h
+++ b/shared/loki/Sequence.h
@@ -1,12 +1,12 @@
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2005 by Peter Kümmel
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author makes no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author makes no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_SEQUENCE_INC_
@@ -20,28 +20,28 @@
namespace Loki
{
- template
- <
- class T01=NullType,class T02=NullType,class T03=NullType,class T04=NullType,class T05=NullType,
- class T06=NullType,class T07=NullType,class T08=NullType,class T09=NullType,class T10=NullType,
- class T11=NullType,class T12=NullType,class T13=NullType,class T14=NullType,class T15=NullType,
- class T16=NullType,class T17=NullType,class T18=NullType,class T19=NullType,class T20=NullType
- >
- struct Seq
- {
- private:
- typedef typename Seq< T02, T03, T04, T05, T06, T07, T08, T09, T10,
- T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>::Type
- TailResult;
- public:
- typedef Typelist<T01, TailResult> Type;
- };
-
- template<>
- struct Seq<>
- {
- typedef NullType Type;
- };
+template
+<
+class T01=NullType,class T02=NullType,class T03=NullType,class T04=NullType,class T05=NullType,
+ class T06=NullType,class T07=NullType,class T08=NullType,class T09=NullType,class T10=NullType,
+ class T11=NullType,class T12=NullType,class T13=NullType,class T14=NullType,class T15=NullType,
+ class T16=NullType,class T17=NullType,class T18=NullType,class T19=NullType,class T20=NullType
+ >
+struct Seq
+{
+private:
+ typedef typename Seq< T02, T03, T04, T05, T06, T07, T08, T09, T10,
+ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>::Type
+ TailResult;
+public:
+ typedef Typelist<T01, TailResult> Type;
+};
+
+template<>
+struct Seq<>
+{
+ typedef NullType Type;
+};
} // namespace Loki
diff --git a/shared/loki/Singleton.h b/shared/loki/Singleton.h
index 42d6eb0d..40cc7550 100644
--- a/shared/loki/Singleton.h
+++ b/shared/loki/Singleton.h
@@ -2,14 +2,14 @@
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
-// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author or Addison-Wesley Longman make no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author or Addison-Wesley Longman make no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_SINGLETON_INC_
@@ -30,9 +30,9 @@
#include <memory>
#ifdef _MSC_VER
-#define LOKI_C_CALLING_CONVENTION_QUALIFIER __cdecl
+#define LOKI_C_CALLING_CONVENTION_QUALIFIER __cdecl
#else
-#define LOKI_C_CALLING_CONVENTION_QUALIFIER
+#define LOKI_C_CALLING_CONVENTION_QUALIFIER
#endif
/// \defgroup SingletonGroup Singleton
@@ -42,7 +42,7 @@
/// \ingroup SingletonGroup
/// The lifetimes of the singleton.
/// \par Special lifetime for SmallObjects
-/// When the holded object is a Small(Value)Object or the holded object
+/// When the holded object is a Small(Value)Object or the holded object
/// uses objects which are or inherit from Small(Value)Object
/// then you can't use the default lifetime: you must use the lifetime
/// \code Loki::LongevityLifetime::DieAsSmallObjectChild \endcode
@@ -52,820 +52,820 @@
namespace Loki
{
- typedef void (LOKI_C_CALLING_CONVENTION_QUALIFIER *atexit_pfn_t)();
+typedef void (LOKI_C_CALLING_CONVENTION_QUALIFIER* atexit_pfn_t)();
- namespace Private
- {
+namespace Private
+{
#ifndef LOKI_MAKE_DLL
- void LOKI_C_CALLING_CONVENTION_QUALIFIER AtExitFn(); // declaration needed below
+void LOKI_C_CALLING_CONVENTION_QUALIFIER AtExitFn(); // declaration needed below
#else
- void LOKI_EXPORT AtExitFn();
+void LOKI_EXPORT AtExitFn();
#endif
- class LifetimeTracker;
+class LifetimeTracker;
-#define LOKI_ENABLE_NEW_SETLONGLIVITY_HELPER_DATA_IMPL
+#define LOKI_ENABLE_NEW_SETLONGLIVITY_HELPER_DATA_IMPL
#ifdef LOKI_ENABLE_NEW_SETLONGLIVITY_HELPER_DATA_IMPL
- // Helper data
- // std::list because of the inserts
- typedef std::list<LifetimeTracker*> TrackerArray;
- extern LOKI_EXPORT TrackerArray* pTrackerArray;
+// Helper data
+// std::list because of the inserts
+typedef std::list<LifetimeTracker*> TrackerArray;
+extern LOKI_EXPORT TrackerArray* pTrackerArray;
#else
- // Helper data
- typedef LifetimeTracker** TrackerArray;
- extern TrackerArray pTrackerArray;
- extern unsigned int elements;
+// Helper data
+typedef LifetimeTracker** TrackerArray;
+extern TrackerArray pTrackerArray;
+extern unsigned int elements;
#endif
- ////////////////////////////////////////////////////////////////////////////////
- // class LifetimeTracker
- // Helper class for SetLongevity
- ////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+// class LifetimeTracker
+// Helper class for SetLongevity
+////////////////////////////////////////////////////////////////////////////////
- class LifetimeTracker
- {
- public:
- LifetimeTracker(unsigned int x) : longevity_(x)
- {}
-
- virtual ~LifetimeTracker() = 0;
-
- static bool Compare(const LifetimeTracker* lhs,
- const LifetimeTracker* rhs)
- {
- return lhs->longevity_ > rhs->longevity_;
- }
-
- private:
- unsigned int longevity_;
- };
-
- // Definition required
- inline LifetimeTracker::~LifetimeTracker() {}
+class LifetimeTracker
+{
+public:
+ LifetimeTracker(unsigned int x) : longevity_(x)
+ {}
- // Helper destroyer function
- template <typename T>
- struct Deleter
- {
- typedef void (*Type)(T*);
- static void Delete(T* pObj)
- { delete pObj; }
- };
+ virtual ~LifetimeTracker() = 0;
- // Concrete lifetime tracker for objects of type T
- template <typename T, typename Destroyer>
- class ConcreteLifetimeTracker : public LifetimeTracker
- {
- public:
- ConcreteLifetimeTracker(T* p,unsigned int longevity, Destroyer d)
- : LifetimeTracker(longevity)
- , pTracked_(p)
- , destroyer_(d)
- {}
-
- ~ConcreteLifetimeTracker()
- { destroyer_(pTracked_); }
-
- private:
- T* pTracked_;
- Destroyer destroyer_;
- };
+ static bool Compare(const LifetimeTracker* lhs,
+ const LifetimeTracker* rhs)
+ {
+ return lhs->longevity_ > rhs->longevity_;
+ }
- } // namespace Private
+private:
+ unsigned int longevity_;
+};
- ////////////////////////////////////////////////////////////////////////////////
- /// \ingroup LifetimeGroup
- ///
- /// Assigns an object a longevity; ensures ordered destructions of objects
- /// registered thusly during the exit sequence of the application
- ////////////////////////////////////////////////////////////////////////////////
+// Definition required
+inline LifetimeTracker::~LifetimeTracker() {}
+
+// Helper destroyer function
+template <typename T>
+struct Deleter
+{
+ typedef void (*Type)(T*);
+ static void Delete(T* pObj)
+ { delete pObj; }
+};
+
+// Concrete lifetime tracker for objects of type T
+template <typename T, typename Destroyer>
+class ConcreteLifetimeTracker : public LifetimeTracker
+{
+public:
+ ConcreteLifetimeTracker(T* p,unsigned int longevity, Destroyer d)
+ : LifetimeTracker(longevity)
+ , pTracked_(p)
+ , destroyer_(d)
+ {}
+
+ ~ConcreteLifetimeTracker()
+ { destroyer_(pTracked_); }
+
+private:
+ T* pTracked_;
+ Destroyer destroyer_;
+};
+
+} // namespace Private
+
+////////////////////////////////////////////////////////////////////////////////
+/// \ingroup LifetimeGroup
+///
+/// Assigns an object a longevity; ensures ordered destructions of objects
+/// registered thusly during the exit sequence of the application
+////////////////////////////////////////////////////////////////////////////////
#ifdef LOKI_ENABLE_NEW_SETLONGLIVITY_HELPER_DATA_IMPL
- template <typename T, typename Destroyer>
- void SetLongevity(T* pDynObject, unsigned int longevity,
- Destroyer d)
- {
- using namespace Private;
-
- // manage lifetime of stack manually
- if(pTrackerArray==0)
- pTrackerArray = new TrackerArray;
-
- // automatically delete the ConcreteLifetimeTracker object when a exception is thrown
- std::auto_ptr<LifetimeTracker>
- p( new ConcreteLifetimeTracker<T, Destroyer>(pDynObject, longevity, d) );
-
- // Find correct position
- TrackerArray::iterator pos = std::upper_bound(
- pTrackerArray->begin(),
- pTrackerArray->end(),
- p.get(),
- LifetimeTracker::Compare);
-
- // Insert the pointer to the ConcreteLifetimeTracker object into the queue
- pTrackerArray->insert(pos, p.get());
-
- // nothing has thrown: don't delete the ConcreteLifetimeTracker object
- p.release();
-
- // Register a call to AtExitFn
- std::atexit(Private::AtExitFn);
- }
+template <typename T, typename Destroyer>
+void SetLongevity(T* pDynObject, unsigned int longevity,
+ Destroyer d)
+{
+ using namespace Private;
+
+ // manage lifetime of stack manually
+ if(pTrackerArray==0)
+ pTrackerArray = new TrackerArray;
+
+ // automatically delete the ConcreteLifetimeTracker object when a exception is thrown
+ std::auto_ptr<LifetimeTracker>
+ p( new ConcreteLifetimeTracker<T, Destroyer>(pDynObject, longevity, d) );
+
+ // Find correct position
+ TrackerArray::iterator pos = std::upper_bound(
+ pTrackerArray->begin(),
+ pTrackerArray->end(),
+ p.get(),
+ LifetimeTracker::Compare);
+
+ // Insert the pointer to the ConcreteLifetimeTracker object into the queue
+ pTrackerArray->insert(pos, p.get());
+
+ // nothing has thrown: don't delete the ConcreteLifetimeTracker object
+ p.release();
+
+ // Register a call to AtExitFn
+ std::atexit(Private::AtExitFn);
+}
#else
-
- template <typename T, typename Destroyer>
- void SetLongevity(T* pDynObject, unsigned int longevity,
- Destroyer d)
- {
- using namespace Private;
-
- TrackerArray pNewArray = static_cast<TrackerArray>(
- std::realloc(pTrackerArray,
- sizeof(*pTrackerArray) * (elements + 1)));
- if (!pNewArray) throw std::bad_alloc();
-
- // Delayed assignment for exception safety
- pTrackerArray = pNewArray;
-
- LifetimeTracker* p = new ConcreteLifetimeTracker<T, Destroyer>(
- pDynObject, longevity, d);
-
- // Insert a pointer to the object into the queue
- TrackerArray pos = std::upper_bound(
- pTrackerArray,
- pTrackerArray + elements,
- p,
- LifetimeTracker::Compare);
- std::copy_backward(
- pos,
- pTrackerArray + elements,
- pTrackerArray + elements + 1);
- *pos = p;
- ++elements;
-
- // Register a call to AtExitFn
- std::atexit(Private::AtExitFn);
- }
+
+template <typename T, typename Destroyer>
+void SetLongevity(T* pDynObject, unsigned int longevity,
+ Destroyer d)
+{
+ using namespace Private;
+
+ TrackerArray pNewArray = static_cast<TrackerArray>(
+ std::realloc(pTrackerArray,
+ sizeof(*pTrackerArray) * (elements + 1)));
+ if (!pNewArray) throw std::bad_alloc();
+
+ // Delayed assignment for exception safety
+ pTrackerArray = pNewArray;
+
+ LifetimeTracker* p = new ConcreteLifetimeTracker<T, Destroyer>(
+ pDynObject, longevity, d);
+
+ // Insert a pointer to the object into the queue
+ TrackerArray pos = std::upper_bound(
+ pTrackerArray,
+ pTrackerArray + elements,
+ p,
+ LifetimeTracker::Compare);
+ std::copy_backward(
+ pos,
+ pTrackerArray + elements,
+ pTrackerArray + elements + 1);
+ *pos = p;
+ ++elements;
+
+ // Register a call to AtExitFn
+ std::atexit(Private::AtExitFn);
+}
#endif
- template <typename T>
- void SetLongevity(T* pDynObject, unsigned int longevity,
- typename Private::Deleter<T>::Type d = Private::Deleter<T>::Delete)
- {
- SetLongevity<T, typename Private::Deleter<T>::Type>(pDynObject, longevity, d);
- }
+template <typename T>
+void SetLongevity(T* pDynObject, unsigned int longevity,
+ typename Private::Deleter<T>::Type d = Private::Deleter<T>::Delete)
+{
+ SetLongevity<T, typename Private::Deleter<T>::Type>(pDynObject, longevity, d);
+}
- ////////////////////////////////////////////////////////////////////////////////
- /// \struct CreateUsingNew
- ///
- /// \ingroup CreationGroup
- /// Implementation of the CreationPolicy used by SingletonHolder
- /// Creates objects using a straight call to the new operator
- ////////////////////////////////////////////////////////////////////////////////
- template <class T> struct CreateUsingNew
- {
- static T* Create()
- { return new T; }
-
- static void Destroy(T* p)
- { delete p; }
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- /// \struct CreateUsing
- ///
- /// \ingroup CreationGroup
- /// Implementation of the CreationPolicy used by SingletonHolder
- /// Creates objects using a custom allocater.
- /// Usage: e.g. CreateUsing<std::allocator>::Allocator
- ////////////////////////////////////////////////////////////////////////////////
- template<template<class> class Alloc>
- struct CreateUsing
- {
- template <class T>
- struct Allocator
- {
- static Alloc<T> allocator;
+////////////////////////////////////////////////////////////////////////////////
+/// \struct CreateUsingNew
+///
+/// \ingroup CreationGroup
+/// Implementation of the CreationPolicy used by SingletonHolder
+/// Creates objects using a straight call to the new operator
+////////////////////////////////////////////////////////////////////////////////
+template <class T> struct CreateUsingNew
+{
+ static T* Create()
+ { return new T; }
- static T* Create()
- {
- return new (allocator.allocate(1)) T;
- }
+ static void Destroy(T* p)
+ { delete p; }
+};
- static void Destroy(T* p)
- {
- //allocator.destroy(p);
- p->~T();
- allocator.deallocate(p,1);
- }
- };
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- /// \struct CreateUsingMalloc
- ///
- /// \ingroup CreationGroup
- /// Implementation of the CreationPolicy used by SingletonHolder
- /// Creates objects using a call to std::malloc, followed by a call to the
- /// placement new operator
- ////////////////////////////////////////////////////////////////////////////////
- template <class T> struct CreateUsingMalloc
+////////////////////////////////////////////////////////////////////////////////
+/// \struct CreateUsing
+///
+/// \ingroup CreationGroup
+/// Implementation of the CreationPolicy used by SingletonHolder
+/// Creates objects using a custom allocater.
+/// Usage: e.g. CreateUsing<std::allocator>::Allocator
+////////////////////////////////////////////////////////////////////////////////
+template<template<class> class Alloc>
+struct CreateUsing
+{
+ template <class T>
+ struct Allocator
{
+ static Alloc<T> allocator;
+
static T* Create()
{
- void* p = std::malloc(sizeof(T));
- if (!p) return 0;
- return new(p) T;
+ return new (allocator.allocate(1)) T;
}
-
+
static void Destroy(T* p)
{
+ //allocator.destroy(p);
p->~T();
- std::free(p);
+ allocator.deallocate(p,1);
}
};
-
-
- ////////////////////////////////////////////////////////////////////////////////
- /// \struct CreateStatic
- ///
- /// \ingroup CreationGroup
- /// Implementation of the CreationPolicy used by SingletonHolder
- /// Creates an object in static memory
- /// Implementation is slightly nonportable because it uses the MaxAlign trick
- /// (an union of all types to ensure proper memory alignment). This trick is
- /// nonportable in theory but highly portable in practice.
- ////////////////////////////////////////////////////////////////////////////////
- template <class T> struct CreateStatic
+};
+
+////////////////////////////////////////////////////////////////////////////////
+/// \struct CreateUsingMalloc
+///
+/// \ingroup CreationGroup
+/// Implementation of the CreationPolicy used by SingletonHolder
+/// Creates objects using a call to std::malloc, followed by a call to the
+/// placement new operator
+////////////////////////////////////////////////////////////////////////////////
+template <class T> struct CreateUsingMalloc
+{
+ static T* Create()
{
-
+ void* p = std::malloc(sizeof(T));
+ if (!p) return 0;
+ return new(p) T;
+ }
+
+ static void Destroy(T* p)
+ {
+ p->~T();
+ std::free(p);
+ }
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+/// \struct CreateStatic
+///
+/// \ingroup CreationGroup
+/// Implementation of the CreationPolicy used by SingletonHolder
+/// Creates an object in static memory
+/// Implementation is slightly nonportable because it uses the MaxAlign trick
+/// (an union of all types to ensure proper memory alignment). This trick is
+/// nonportable in theory but highly portable in practice.
+////////////////////////////////////////////////////////////////////////////////
+template <class T> struct CreateStatic
+{
+
#ifdef _MSC_VER
-#pragma warning( push )
+#pragma warning( push )
#pragma warning( disable : 4121 )
-// alignment of a member was sensitive to packing
+ // alignment of a member was sensitive to packing
#endif // _MSC_VER
- union MaxAlign
- {
- char t_[sizeof(T)];
- short int shortInt_;
- int int_;
- long int longInt_;
- float float_;
- double double_;
- long double longDouble_;
- struct Test;
- int Test::* pMember_;
- int (Test::*pMemberFn_)(int);
- };
-
+ union MaxAlign
+ {
+ char t_[sizeof(T)];
+ short int shortInt_;
+ int int_;
+ long int longInt_;
+ float float_;
+ double double_;
+ long double longDouble_;
+ struct Test;
+ int Test::* pMember_;
+ int (Test::*pMemberFn_)(int);
+ };
+
#ifdef _MSC_VER
#pragma warning( pop )
#endif // _MSC_VER
-
- static T* Create()
- {
- static MaxAlign staticMemory_;
- return new(&staticMemory_) T;
- }
-
- static void Destroy(T* p)
- {
- p->~T();
- }
- };
- ////////////////////////////////////////////////////////////////////////////////
- /// \struct DefaultLifetime
- ///
- /// \ingroup LifetimeGroup
- /// Implementation of the LifetimePolicy used by SingletonHolder
- /// Schedules an object's destruction as per C++ rules
- /// Forwards to std::atexit
- ////////////////////////////////////////////////////////////////////////////////
- template <class T>
- struct DefaultLifetime
+ static T* Create()
{
- static void ScheduleDestruction(T*, atexit_pfn_t pFun)
- { std::atexit(pFun); }
-
- static void OnDeadReference()
- { throw std::logic_error("Dead Reference Detected"); }
- };
+ static MaxAlign staticMemory_;
+ return new(&staticMemory_) T;
+ }
- ////////////////////////////////////////////////////////////////////////////////
- /// \struct PhoenixSingleton
- ///
- /// \ingroup LifetimeGroup
- /// Implementation of the LifetimePolicy used by SingletonHolder
- /// Schedules an object's destruction as per C++ rules, and it allows object
- /// recreation by not throwing an exception from OnDeadReference
- ////////////////////////////////////////////////////////////////////////////////
- template <class T>
- class PhoenixSingleton
+ static void Destroy(T* p)
+ {
+ p->~T();
+ }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+/// \struct DefaultLifetime
+///
+/// \ingroup LifetimeGroup
+/// Implementation of the LifetimePolicy used by SingletonHolder
+/// Schedules an object's destruction as per C++ rules
+/// Forwards to std::atexit
+////////////////////////////////////////////////////////////////////////////////
+template <class T>
+struct DefaultLifetime
+{
+ static void ScheduleDestruction(T*, atexit_pfn_t pFun)
+ { std::atexit(pFun); }
+
+ static void OnDeadReference()
+ { throw std::logic_error("Dead Reference Detected"); }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+/// \struct PhoenixSingleton
+///
+/// \ingroup LifetimeGroup
+/// Implementation of the LifetimePolicy used by SingletonHolder
+/// Schedules an object's destruction as per C++ rules, and it allows object
+/// recreation by not throwing an exception from OnDeadReference
+////////////////////////////////////////////////////////////////////////////////
+template <class T>
+class PhoenixSingleton
+{
+public:
+ static void ScheduleDestruction(T*, atexit_pfn_t pFun)
{
- public:
- static void ScheduleDestruction(T*, atexit_pfn_t pFun)
- {
#ifndef ATEXIT_FIXED
- if (!destroyedOnce_)
+ if (!destroyedOnce_)
#endif
- std::atexit(pFun);
- }
-
- static void OnDeadReference()
- {
+ std::atexit(pFun);
+ }
+
+ static void OnDeadReference()
+ {
#ifndef ATEXIT_FIXED
- destroyedOnce_ = true;
+ destroyedOnce_ = true;
#endif
- }
-
- private:
+ }
+
+private:
#ifndef ATEXIT_FIXED
- static bool destroyedOnce_;
+ static bool destroyedOnce_;
#endif
- };
-
+};
+
#ifndef ATEXIT_FIXED
- template <class T> bool PhoenixSingleton<T>::destroyedOnce_ = false;
+template <class T> bool PhoenixSingleton<T>::destroyedOnce_ = false;
#endif
- ////////////////////////////////////////////////////////////////////////////////
- // Copyright (c) 2004 by Curtis Krauskopf - curtis@decompile.com
- ///
- /// \struct DeletableSingleton
- ///
- /// \ingroup LifetimeGroup
- ///
- /// A DeletableSingleton allows the instantiated singleton to be
- /// destroyed at any time. The singleton can be reinstantiated at
- /// any time, even during program termination.
- /// If the singleton exists when the program terminates, it will
- /// be automatically deleted.
- ///
- /// \par Usage:
- /// The singleton can be deleted manually:
- ///
- /// DeletableSingleton<MyClass>::GracefulDelete();
- ////////////////////////////////////////////////////////////////////////////////
- template <class T>
- class DeletableSingleton
- {
- public:
+////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2004 by Curtis Krauskopf - curtis@decompile.com
+///
+/// \struct DeletableSingleton
+///
+/// \ingroup LifetimeGroup
+///
+/// A DeletableSingleton allows the instantiated singleton to be
+/// destroyed at any time. The singleton can be reinstantiated at
+/// any time, even during program termination.
+/// If the singleton exists when the program terminates, it will
+/// be automatically deleted.
+///
+/// \par Usage:
+/// The singleton can be deleted manually:
+///
+/// DeletableSingleton<MyClass>::GracefulDelete();
+////////////////////////////////////////////////////////////////////////////////
+template <class T>
+class DeletableSingleton
+{
+public:
- static void ScheduleDestruction(T*, atexit_pfn_t pFun)
- {
- static bool firstPass = true;
- isDead = false;
- deleter = pFun;
- if (firstPass || needCallback)
- {
- std::atexit(atexitCallback);
- firstPass = false;
- needCallback = false;
- }
- }
-
- static void OnDeadReference()
- {
- }
- /// delete singleton object manually
- static void GracefulDelete()
+ static void ScheduleDestruction(T*, atexit_pfn_t pFun)
+ {
+ static bool firstPass = true;
+ isDead = false;
+ deleter = pFun;
+ if (firstPass || needCallback)
{
- if (isDead)
- return;
- isDead = true;
- deleter();
+ std::atexit(atexitCallback);
+ firstPass = false;
+ needCallback = false;
}
-
- protected:
- static atexit_pfn_t deleter;
- static bool isDead;
- static bool needCallback;
-
- static void atexitCallback()
- {
+ }
+
+ static void OnDeadReference()
+ {
+ }
+ /// delete singleton object manually
+ static void GracefulDelete()
+ {
+ if (isDead)
+ return;
+ isDead = true;
+ deleter();
+ }
+
+protected:
+ static atexit_pfn_t deleter;
+ static bool isDead;
+ static bool needCallback;
+
+ static void atexitCallback()
+ {
#ifdef ATEXIT_FIXED
- needCallback = true;
+ needCallback = true;
#else
- needCallback = false;
+ needCallback = false;
#endif
- GracefulDelete();
- }
- };
-
- template <class T>
- atexit_pfn_t DeletableSingleton<T>::deleter = 0;
-
- template <class T>
- bool DeletableSingleton<T>::isDead = true;
-
- template <class T>
- bool DeletableSingleton<T>::needCallback = true;
+ GracefulDelete();
+ }
+};
+
+template <class T>
+atexit_pfn_t DeletableSingleton<T>::deleter = 0;
+
+template <class T>
+bool DeletableSingleton<T>::isDead = true;
+
+template <class T>
+bool DeletableSingleton<T>::needCallback = true;
- ////////////////////////////////////////////////////////////////////////////////
- // class template Adapter
- // Helper for SingletonWithLongevity below
- ////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+// class template Adapter
+// Helper for SingletonWithLongevity below
+////////////////////////////////////////////////////////////////////////////////
+
+namespace Private
+{
+template <class T>
+struct Adapter
+{
+ void operator()(T*) { return pFun_(); }
+ atexit_pfn_t pFun_;
+};
+}
- namespace Private
+////////////////////////////////////////////////////////////////////////////////
+/// \struct SingletonWithLongevity
+///
+/// \ingroup LifetimeGroup
+/// Implementation of the LifetimePolicy used by SingletonHolder
+/// Schedules an object's destruction in order of their longevities
+/// Assumes a visible function GetLongevity(T*) that returns the longevity of the
+/// object.
+////////////////////////////////////////////////////////////////////////////////
+template <class T>
+class SingletonWithLongevity
+{
+public:
+ static void ScheduleDestruction(T* pObj, atexit_pfn_t pFun)
{
- template <class T>
- struct Adapter
- {
- void operator()(T*) { return pFun_(); }
- atexit_pfn_t pFun_;
- };
+ Private::Adapter<T> adapter = { pFun };
+ SetLongevity(pObj, GetLongevity(pObj), adapter);
}
- ////////////////////////////////////////////////////////////////////////////////
- /// \struct SingletonWithLongevity
- ///
- /// \ingroup LifetimeGroup
- /// Implementation of the LifetimePolicy used by SingletonHolder
- /// Schedules an object's destruction in order of their longevities
- /// Assumes a visible function GetLongevity(T*) that returns the longevity of the
- /// object.
- ////////////////////////////////////////////////////////////////////////////////
- template <class T>
- class SingletonWithLongevity
+ static void OnDeadReference()
+ { throw std::logic_error("Dead Reference Detected"); }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+/// \struct NoDestroy
+///
+/// \ingroup LifetimeGroup
+/// Implementation of the LifetimePolicy used by SingletonHolder
+/// Never destroys the object
+////////////////////////////////////////////////////////////////////////////////
+template <class T>
+struct NoDestroy
+{
+ static void ScheduleDestruction(T*, atexit_pfn_t)
+ {}
+
+ static void OnDeadReference()
+ {}
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+/// \defgroup LongevityLifetimeGroup LongevityLifetime
+/// \ingroup LifetimeGroup
+///
+/// \namespace LongevityLifetime
+///
+/// \ingroup LongevityLifetimeGroup
+/// \brief In this namespace are special lifetime policies to manage lifetime
+/// dependencies.
+////////////////////////////////////////////////////////////////////////////////
+namespace LongevityLifetime
+{
+////////////////////////////////////////////////////////////////////////////////
+/// \struct SingletonFixedLongevity
+///
+/// \ingroup LongevityLifetimeGroup
+/// Add your own lifetimes into the namespace 'LongevityLifetime'
+/// with your prefered lifetime by adding a struct like this:
+///
+/// template<class T>
+/// struct MyLifetime : SingletonFixedLongevity< MyLifetimeNumber ,T> {}
+////////////////////////////////////////////////////////////////////////////////
+template <unsigned int Longevity, class T>
+class SingletonFixedLongevity
+{
+public:
+ virtual ~SingletonFixedLongevity() {}
+
+ static void ScheduleDestruction(T* pObj, atexit_pfn_t pFun)
+ {
+ Private::Adapter<T> adapter = { pFun };
+ SetLongevity(pObj, Longevity , adapter);
+ }
+
+ static void OnDeadReference()
+ { throw std::logic_error("Dead Reference Detected"); }
+};
+
+/// \struct DieLast
+/// \ingroup LongevityLifetimeGroup
+/// \brief Longest possible SingletonWithLongevity lifetime: 0xFFFFFFFF
+template <class T>
+struct DieLast : SingletonFixedLongevity<0xFFFFFFFF ,T>
+ {};
+
+/// \struct DieDirectlyBeforeLast
+/// \ingroup LongevityLifetimeGroup
+/// \brief Lifetime is a one less than DieLast: 0xFFFFFFFF-1
+template <class T>
+struct DieDirectlyBeforeLast : SingletonFixedLongevity<0xFFFFFFFF-1 ,T>
+ {};
+
+/// \struct DieFirst
+/// \ingroup LongevityLifetimeGroup
+/// \brief Shortest possible SingletonWithLongevity lifetime: 0
+template <class T>
+struct DieFirst : SingletonFixedLongevity<0,T>
+ {};
+
+}//namespace LongevityLifetime
+
+////////////////////////////////////////////////////////////////////////////////
+/// \class FollowIntoDeath
+///
+/// \ingroup LifetimeGroup
+///
+/// Lifetime policyfor the SingletonHolder tempalte.
+/// Followers will die after the master dies Followers will not die, if
+/// - master never dies (NoDestroy policy)
+/// - master never created
+/// - master dies not in the function registered with atexit
+/// - master dies not by a call of a the atexit registerd function (DeletableSingleton::GracefulDelete)
+///
+/// \par Usage:
+///
+/// Lifetimes of the master and the follower singletons, e.g. with a M and a F class:
+/// \code SingletonHolder< M , FollowIntoDeath::With<DefaultLifetime>::AsMasterLifetime > MasterSingleton; \endcode
+/// \code SingletonHolder< F , CreateUsingNew, FollowIntoDeath::AfterMaster< MasterSingleton >::IsDestroyed > FollowerSingleton \endcode
+////////////////////////////////////////////////////////////////////////////////
+class FollowIntoDeath
+{
+ template<class T>
+ class Followers
{
+ typedef std::vector<atexit_pfn_t> Container;
+ typedef typename Container::iterator iterator;
+ static Container* followers_;
+
public:
- static void ScheduleDestruction(T* pObj, atexit_pfn_t pFun)
+ static void Init()
+ {
+ static bool done = false;
+ if(!done)
+ {
+ followers_ = new Container;
+ done = true;
+ }
+ }
+
+ static void AddFollower(atexit_pfn_t ae)
{
- Private::Adapter<T> adapter = { pFun };
- SetLongevity(pObj, GetLongevity(pObj), adapter);
+ Init();
+ followers_->push_back(ae);
}
-
- static void OnDeadReference()
- { throw std::logic_error("Dead Reference Detected"); }
- };
- ////////////////////////////////////////////////////////////////////////////////
- /// \struct NoDestroy
- ///
- /// \ingroup LifetimeGroup
- /// Implementation of the LifetimePolicy used by SingletonHolder
- /// Never destroys the object
- ////////////////////////////////////////////////////////////////////////////////
- template <class T>
- struct NoDestroy
- {
- static void ScheduleDestruction(T*, atexit_pfn_t)
- {}
-
- static void OnDeadReference()
- {}
+ static void DestroyFollowers()
+ {
+ Init();
+ for(iterator it = followers_->begin(); it != followers_->end(); ++it)
+ (*it)();
+ delete followers_;
+ }
};
-
-
- ////////////////////////////////////////////////////////////////////////////////
- /// \defgroup LongevityLifetimeGroup LongevityLifetime
- /// \ingroup LifetimeGroup
- ///
- /// \namespace LongevityLifetime
- ///
- /// \ingroup LongevityLifetimeGroup
- /// \brief In this namespace are special lifetime policies to manage lifetime
- /// dependencies.
- ////////////////////////////////////////////////////////////////////////////////
- namespace LongevityLifetime
+
+public:
+
+ /// \struct With
+ /// Template for the master
+ /// \param Lifetime Lifetime policy for the master
+ template<template <class> class Lifetime>
+ struct With
{
- ////////////////////////////////////////////////////////////////////////////////
- /// \struct SingletonFixedLongevity
- ///
- /// \ingroup LongevityLifetimeGroup
- /// Add your own lifetimes into the namespace 'LongevityLifetime'
- /// with your prefered lifetime by adding a struct like this:
- ///
- /// template<class T>
- /// struct MyLifetime : SingletonFixedLongevity< MyLifetimeNumber ,T> {}
- ////////////////////////////////////////////////////////////////////////////////
- template <unsigned int Longevity, class T>
- class SingletonFixedLongevity
+ /// \struct AsMasterLifetime
+ /// Policy for master
+ template<class Master>
+ struct AsMasterLifetime
{
- public:
- virtual ~SingletonFixedLongevity() {}
-
- static void ScheduleDestruction(T* pObj, atexit_pfn_t pFun)
+ static void ScheduleDestruction(Master* pObj, atexit_pfn_t pFun)
{
- Private::Adapter<T> adapter = { pFun };
- SetLongevity(pObj, Longevity , adapter);
+ Followers<Master>::Init();
+ Lifetime<Master>::ScheduleDestruction(pObj, pFun);
+
+ // use same policy for the followers and force a new
+ // template instantiation, this adds a additional atexit entry
+ // does not work with SetLonlevity, but there you can control
+ // the lifetime with the GetLongevity function.
+ Lifetime<Followers<Master> >::ScheduleDestruction(0,Followers<Master>::DestroyFollowers);
}
-
+
static void OnDeadReference()
- { throw std::logic_error("Dead Reference Detected"); }
+ {
+ throw std::logic_error("Dead Reference Detected");
+ }
};
+ };
- /// \struct DieLast
- /// \ingroup LongevityLifetimeGroup
- /// \brief Longest possible SingletonWithLongevity lifetime: 0xFFFFFFFF
- template <class T>
- struct DieLast : SingletonFixedLongevity<0xFFFFFFFF ,T>
- {};
-
- /// \struct DieDirectlyBeforeLast
- /// \ingroup LongevityLifetimeGroup
- /// \brief Lifetime is a one less than DieLast: 0xFFFFFFFF-1
- template <class T>
- struct DieDirectlyBeforeLast : SingletonFixedLongevity<0xFFFFFFFF-1 ,T>
- {};
-
- /// \struct DieFirst
- /// \ingroup LongevityLifetimeGroup
- /// \brief Shortest possible SingletonWithLongevity lifetime: 0
- template <class T>
- struct DieFirst : SingletonFixedLongevity<0,T>
- {};
-
- }//namespace LongevityLifetime
-
- ////////////////////////////////////////////////////////////////////////////////
- /// \class FollowIntoDeath
- ///
- /// \ingroup LifetimeGroup
- ///
- /// Lifetime policyfor the SingletonHolder tempalte.
- /// Followers will die after the master dies Followers will not die, if
- /// - master never dies (NoDestroy policy)
- /// - master never created
- /// - master dies not in the function registered with atexit
- /// - master dies not by a call of a the atexit registerd function (DeletableSingleton::GracefulDelete)
- ///
- /// \par Usage:
- ///
- /// Lifetimes of the master and the follower singletons, e.g. with a M and a F class:
- /// \code SingletonHolder< M , FollowIntoDeath::With<DefaultLifetime>::AsMasterLifetime > MasterSingleton; \endcode
- /// \code SingletonHolder< F , CreateUsingNew, FollowIntoDeath::AfterMaster< MasterSingleton >::IsDestroyed > FollowerSingleton \endcode
- ////////////////////////////////////////////////////////////////////////////////
- class FollowIntoDeath
+ /// \struct AfterMaster
+ /// Template for the follower
+ /// \param Master Master to follow into death
+ template<class Master>
+ struct AfterMaster
{
- template<class T>
- class Followers
+ /// \struct IsDestroyed
+ /// Policy for followers
+ template<class F>
+ struct IsDestroyed
{
- typedef std::vector<atexit_pfn_t> Container;
- typedef typename Container::iterator iterator;
- static Container* followers_;
-
- public:
- static void Init()
+ static void ScheduleDestruction(F*, atexit_pfn_t pFun)
{
- static bool done = false;
- if(!done)
- {
- followers_ = new Container;
- done = true;
- }
+ Followers<Master>::AddFollower(pFun);
}
- static void AddFollower(atexit_pfn_t ae)
- {
- Init();
- followers_->push_back(ae);
- }
-
- static void DestroyFollowers()
+ static void OnDeadReference()
{
- Init();
- for(iterator it = followers_->begin();it != followers_->end();++it)
- (*it)();
- delete followers_;
+ throw std::logic_error("Dead Reference Detected");
}
};
+ };
+};
- public:
+template<class T>
+typename FollowIntoDeath::Followers<T>::Container*
+FollowIntoDeath::Followers<T>::followers_ = 0;
- /// \struct With
- /// Template for the master
- /// \param Lifetime Lifetime policy for the master
- template<template <class> class Lifetime>
- struct With
- {
- /// \struct AsMasterLifetime
- /// Policy for master
- template<class Master>
- struct AsMasterLifetime
- {
- static void ScheduleDestruction(Master* pObj, atexit_pfn_t pFun)
- {
- Followers<Master>::Init();
- Lifetime<Master>::ScheduleDestruction(pObj, pFun);
-
- // use same policy for the followers and force a new
- // template instantiation, this adds a additional atexit entry
- // does not work with SetLonlevity, but there you can control
- // the lifetime with the GetLongevity function.
- Lifetime<Followers<Master> >::ScheduleDestruction(0,Followers<Master>::DestroyFollowers);
- }
-
- static void OnDeadReference()
- {
- throw std::logic_error("Dead Reference Detected");
- }
- };
- };
- /// \struct AfterMaster
- /// Template for the follower
- /// \param Master Master to follow into death
- template<class Master>
- struct AfterMaster
- {
- /// \struct IsDestroyed
- /// Policy for followers
- template<class F>
- struct IsDestroyed
- {
- static void ScheduleDestruction(F*, atexit_pfn_t pFun)
- {
- Followers<Master>::AddFollower(pFun);
- }
-
- static void OnDeadReference()
- {
- throw std::logic_error("Dead Reference Detected");
- }
- };
- };
- };
- template<class T>
- typename FollowIntoDeath::Followers<T>::Container*
- FollowIntoDeath::Followers<T>::followers_ = 0;
-
-
-
- ////////////////////////////////////////////////////////////////////////////////
- /// \class SingletonHolder
- ///
- /// \ingroup SingletonGroup
- ///
- /// Provides Singleton amenities for a type T
- /// To protect that type from spurious instantiations,
- /// you have to protect it yourself.
- ///
- /// \param CreationPolicy Creation policy, default: CreateUsingNew
- /// \param LifetimePolicy Lifetime policy, default: DefaultLifetime,
- /// \param ThreadingModel Threading policy,
- /// default: LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL
- ////////////////////////////////////////////////////////////////////////////////
- template
- <
- typename T,
- template <class> class CreationPolicy = CreateUsingNew,
- template <class> class LifetimePolicy = DefaultLifetime,
- template <class, class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL,
- class MutexPolicy = LOKI_DEFAULT_MUTEX
- >
- class SingletonHolder
- {
- public:
+////////////////////////////////////////////////////////////////////////////////
+/// \class SingletonHolder
+///
+/// \ingroup SingletonGroup
+///
+/// Provides Singleton amenities for a type T
+/// To protect that type from spurious instantiations,
+/// you have to protect it yourself.
+///
+/// \param CreationPolicy Creation policy, default: CreateUsingNew
+/// \param LifetimePolicy Lifetime policy, default: DefaultLifetime,
+/// \param ThreadingModel Threading policy,
+/// default: LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL
+////////////////////////////////////////////////////////////////////////////////
+template
+<
+typename T,
+ template <class> class CreationPolicy = CreateUsingNew,
+ template <class> class LifetimePolicy = DefaultLifetime,
+ template <class, class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL,
+ class MutexPolicy = LOKI_DEFAULT_MUTEX
+ >
+class SingletonHolder
+{
+public:
- /// Type of the singleton object
- typedef T ObjectType;
-
- /// Returns a reference to singleton object
- static T& Instance();
-
- private:
- // Helpers
- static void MakeInstance();
- static void LOKI_C_CALLING_CONVENTION_QUALIFIER DestroySingleton();
-
- // Protection
- SingletonHolder();
-
- // Data
- typedef typename ThreadingModel<T*,MutexPolicy>::VolatileType PtrInstanceType;
- static PtrInstanceType pInstance_;
- static bool destroyed_;
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- // SingletonHolder's data
- ////////////////////////////////////////////////////////////////////////////////
-
- template
- <
- class T,
- template <class> class C,
- template <class> class L,
- template <class, class> class M,
- class X
- >
- typename SingletonHolder<T, C, L, M, X>::PtrInstanceType
- SingletonHolder<T, C, L, M, X>::pInstance_ = 0;
-
- template
- <
- class T,
- template <class> class C,
- template <class> class L,
- template <class, class> class M,
- class X
- >
- bool SingletonHolder<T, C, L, M, X>::destroyed_ = false;
-
- ////////////////////////////////////////////////////////////////////////////////
- // SingletonHolder::Instance
- ////////////////////////////////////////////////////////////////////////////////
-
- template
- <
- class T,
- template <class> class CreationPolicy,
- template <class> class LifetimePolicy,
- template <class, class> class ThreadingModel,
- class MutexPolicy
- >
- inline T& SingletonHolder<T, CreationPolicy,
- LifetimePolicy, ThreadingModel, MutexPolicy>::Instance()
+ /// Type of the singleton object
+ typedef T ObjectType;
+
+ /// Returns a reference to singleton object
+ static T& Instance();
+
+private:
+ // Helpers
+ static void MakeInstance();
+ static void LOKI_C_CALLING_CONVENTION_QUALIFIER DestroySingleton();
+
+ // Protection
+ SingletonHolder();
+
+ // Data
+ typedef typename ThreadingModel<T*,MutexPolicy>::VolatileType PtrInstanceType;
+ static PtrInstanceType pInstance_;
+ static bool destroyed_;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// SingletonHolder's data
+////////////////////////////////////////////////////////////////////////////////
+
+template
+<
+class T,
+ template <class> class C,
+ template <class> class L,
+ template <class, class> class M,
+ class X
+ >
+typename SingletonHolder<T, C, L, M, X>::PtrInstanceType
+SingletonHolder<T, C, L, M, X>::pInstance_ = 0;
+
+template
+<
+class T,
+ template <class> class C,
+ template <class> class L,
+ template <class, class> class M,
+ class X
+ >
+bool SingletonHolder<T, C, L, M, X>::destroyed_ = false;
+
+////////////////////////////////////////////////////////////////////////////////
+// SingletonHolder::Instance
+////////////////////////////////////////////////////////////////////////////////
+
+template
+<
+class T,
+ template <class> class CreationPolicy,
+ template <class> class LifetimePolicy,
+ template <class, class> class ThreadingModel,
+ class MutexPolicy
+ >
+inline T& SingletonHolder<T, CreationPolicy,
+ LifetimePolicy, ThreadingModel, MutexPolicy>::Instance()
+{
+ if (!pInstance_)
{
- if (!pInstance_)
- {
- MakeInstance();
- }
- return *pInstance_;
+ MakeInstance();
}
+ return *pInstance_;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// SingletonHolder::MakeInstance (helper for Instance)
+////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////
- // SingletonHolder::MakeInstance (helper for Instance)
- ////////////////////////////////////////////////////////////////////////////////
-
- template
- <
- class T,
- template <class> class CreationPolicy,
- template <class> class LifetimePolicy,
- template <class, class> class ThreadingModel,
- class MutexPolicy
- >
- void SingletonHolder<T, CreationPolicy,
- LifetimePolicy, ThreadingModel, MutexPolicy>::MakeInstance()
+template
+<
+class T,
+template <class> class CreationPolicy,
+template <class> class LifetimePolicy,
+template <class, class> class ThreadingModel,
+class MutexPolicy
+>
+void SingletonHolder<T, CreationPolicy,
+ LifetimePolicy, ThreadingModel, MutexPolicy>::MakeInstance()
+{
+ typename ThreadingModel<SingletonHolder,MutexPolicy>::Lock guard;
+ (void)guard;
+
+ if (!pInstance_)
{
- typename ThreadingModel<SingletonHolder,MutexPolicy>::Lock guard;
- (void)guard;
-
- if (!pInstance_)
+ if (destroyed_)
{
- if (destroyed_)
- {
- destroyed_ = false;
- LifetimePolicy<T>::OnDeadReference();
- }
- pInstance_ = CreationPolicy<T>::Create();
- LifetimePolicy<T>::ScheduleDestruction(pInstance_,
- &DestroySingleton);
+ destroyed_ = false;
+ LifetimePolicy<T>::OnDeadReference();
}
+ pInstance_ = CreationPolicy<T>::Create();
+ LifetimePolicy<T>::ScheduleDestruction(pInstance_,
+ &DestroySingleton);
}
+}
- template
- <
- class T,
- template <class> class CreationPolicy,
- template <class> class L,
- template <class, class> class M,
- class X
- >
- void LOKI_C_CALLING_CONVENTION_QUALIFIER
- SingletonHolder<T, CreationPolicy, L, M, X>::DestroySingleton()
- {
- assert(!destroyed_);
- CreationPolicy<T>::Destroy(pInstance_);
- pInstance_ = 0;
- destroyed_ = true;
- }
+template
+<
+class T,
+template <class> class CreationPolicy,
+template <class> class L,
+template <class, class> class M,
+class X
+>
+void LOKI_C_CALLING_CONVENTION_QUALIFIER
+SingletonHolder<T, CreationPolicy, L, M, X>::DestroySingleton()
+{
+ assert(!destroyed_);
+ CreationPolicy<T>::Destroy(pInstance_);
+ pInstance_ = 0;
+ destroyed_ = true;
+}
- ////////////////////////////////////////////////////////////////////////////////
- /// \class Singleton
- ///
- /// \ingroup SingletonGroup
- ///
- /// Convenience template to implement a getter function for a singleton object.
- /// Often needed in a shared library which hosts singletons.
- ///
- /// \par Usage
- ///
- /// see test/SingletonDll
- ///
- ////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+/// \class Singleton
+///
+/// \ingroup SingletonGroup
+///
+/// Convenience template to implement a getter function for a singleton object.
+/// Often needed in a shared library which hosts singletons.
+///
+/// \par Usage
+///
+/// see test/SingletonDll
+///
+////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_SINGLETON_EXPORT
#define LOKI_SINGLETON_EXPORT
#endif
- template<class T>
- class LOKI_SINGLETON_EXPORT Singleton
- {
- public:
- static T& Instance();
- };
+template<class T>
+class LOKI_SINGLETON_EXPORT Singleton
+{
+public:
+ static T& Instance();
+};
} // namespace Loki
diff --git a/shared/loki/SmallObj.cpp b/shared/loki/SmallObj.cpp
index adb54c55..0d82c1bb 100644
--- a/shared/loki/SmallObj.cpp
+++ b/shared/loki/SmallObj.cpp
@@ -28,274 +28,274 @@
//#define LOKI_CHECK_FOR_CORRUPTION
#ifdef DO_EXTRA_LOKI_TESTS
- #include <iostream>
+#include <iostream>
#endif
namespace Loki
{
- /** @struct Chunk
- @ingroup SmallObjectGroupInternal
- Contains info about each allocated Chunk - which is a collection of
- contiguous blocks. Each block is the same size, as specified by the
- FixedAllocator. The number of blocks in a Chunk depends upon page size.
- This is a POD-style struct with value-semantics. All functions and data
- are private so that they can not be changed by anything other than the
- FixedAllocator which owns the Chunk.
-
- @par Minimal Interface
- For the sake of runtime efficiency, no constructor, destructor, or
- copy-assignment operator is defined. The inline functions made by the
- compiler should be sufficient, and perhaps faster than hand-crafted
- functions. The lack of these functions allows vector to create and copy
- Chunks as needed without overhead. The Init and Release functions do
- what the default constructor and destructor would do. A Chunk is not in
- a usable state after it is constructed and before calling Init. Nor is
- a Chunk usable after Release is called, but before the destructor.
-
- @par Efficiency
- Down near the lowest level of the allocator, runtime efficiencies trump
- almost all other considerations. Each function does the minimum required
- of it. All functions should execute in constant time to prevent higher-
- level code from unwittingly using a version of Shlemiel the Painter's
- Algorithm.
-
- @par Stealth Indexes
- The first char of each empty block contains the index of the next empty
- block. These stealth indexes form a singly-linked list within the blocks.
- A Chunk is corrupt if this singly-linked list has a loop or is shorter
- than blocksAvailable_. Much of the allocator's time and space efficiency
- comes from how these stealth indexes are implemented.
+/** @struct Chunk
+ @ingroup SmallObjectGroupInternal
+ Contains info about each allocated Chunk - which is a collection of
+ contiguous blocks. Each block is the same size, as specified by the
+ FixedAllocator. The number of blocks in a Chunk depends upon page size.
+ This is a POD-style struct with value-semantics. All functions and data
+ are private so that they can not be changed by anything other than the
+ FixedAllocator which owns the Chunk.
+
+ @par Minimal Interface
+ For the sake of runtime efficiency, no constructor, destructor, or
+ copy-assignment operator is defined. The inline functions made by the
+ compiler should be sufficient, and perhaps faster than hand-crafted
+ functions. The lack of these functions allows vector to create and copy
+ Chunks as needed without overhead. The Init and Release functions do
+ what the default constructor and destructor would do. A Chunk is not in
+ a usable state after it is constructed and before calling Init. Nor is
+ a Chunk usable after Release is called, but before the destructor.
+
+ @par Efficiency
+ Down near the lowest level of the allocator, runtime efficiencies trump
+ almost all other considerations. Each function does the minimum required
+ of it. All functions should execute in constant time to prevent higher-
+ level code from unwittingly using a version of Shlemiel the Painter's
+ Algorithm.
+
+ @par Stealth Indexes
+ The first char of each empty block contains the index of the next empty
+ block. These stealth indexes form a singly-linked list within the blocks.
+ A Chunk is corrupt if this singly-linked list has a loop or is shorter
+ than blocksAvailable_. Much of the allocator's time and space efficiency
+ comes from how these stealth indexes are implemented.
+ */
+class Chunk
+{
+private:
+ friend class FixedAllocator;
+
+ /** Initializes a just-constructed Chunk.
+ @param blockSize Number of bytes per block.
+ @param blocks Number of blocks per Chunk.
+ @return True for success, false for failure.
*/
- class Chunk
- {
- private:
- friend class FixedAllocator;
+ bool Init( std::size_t blockSize, unsigned char blocks );
- /** Initializes a just-constructed Chunk.
- @param blockSize Number of bytes per block.
- @param blocks Number of blocks per Chunk.
- @return True for success, false for failure.
- */
- bool Init( std::size_t blockSize, unsigned char blocks );
+ /** Allocate a block within the Chunk. Complexity is always O(1), and
+ this will never throw. Does not actually "allocate" by calling
+ malloc, new, or any other function, but merely adjusts some internal
+ indexes to indicate an already allocated block is no longer available.
+ @return Pointer to block within Chunk.
+ */
+ void* Allocate( std::size_t blockSize );
+
+ /** Deallocate a block within the Chunk. Complexity is always O(1), and
+ this will never throw. For efficiency, this assumes the address is
+ within the block and aligned along the correct byte boundary. An
+ assertion checks the alignment, and a call to HasBlock is done from
+ within VicinityFind. Does not actually "deallocate" by calling free,
+ delete, or other function, but merely adjusts some internal indexes to
+ indicate a block is now available.
+ */
+ void Deallocate( void* p, std::size_t blockSize );
- /** Allocate a block within the Chunk. Complexity is always O(1), and
- this will never throw. Does not actually "allocate" by calling
- malloc, new, or any other function, but merely adjusts some internal
- indexes to indicate an already allocated block is no longer available.
- @return Pointer to block within Chunk.
- */
- void * Allocate( std::size_t blockSize );
-
- /** Deallocate a block within the Chunk. Complexity is always O(1), and
- this will never throw. For efficiency, this assumes the address is
- within the block and aligned along the correct byte boundary. An
- assertion checks the alignment, and a call to HasBlock is done from
- within VicinityFind. Does not actually "deallocate" by calling free,
- delete, or other function, but merely adjusts some internal indexes to
- indicate a block is now available.
- */
- void Deallocate( void * p, std::size_t blockSize );
+ /** Resets the Chunk back to pristine values. The available count is
+ set back to zero, and the first available index is set to the zeroth
+ block. The stealth indexes inside each block are set to point to the
+ next block. This assumes the Chunk's data was already using Init.
+ */
+ void Reset( std::size_t blockSize, unsigned char blocks );
+
+ /// Releases the allocated block of memory.
+ void Release();
+
+ /** Determines if the Chunk has been corrupted.
+ @param numBlocks Total # of blocks in the Chunk.
+ @param blockSize # of bytes in each block.
+ @param checkIndexes True if caller wants to check indexes of available
+ blocks for corruption. If false, then caller wants to skip some
+ tests tests just to run faster. (Debug version does more checks, but
+ release version runs faster.)
+ @return True if Chunk is corrupt.
+ */
+ bool IsCorrupt( unsigned char numBlocks, std::size_t blockSize,
+ bool checkIndexes ) const;
+
+ /** Determines if block is available.
+ @param p Address of block managed by Chunk.
+ @param numBlocks Total # of blocks in the Chunk.
+ @param blockSize # of bytes in each block.
+ @return True if block is available, else false if allocated.
+ */
+ bool IsBlockAvailable( void* p, unsigned char numBlocks,
+ std::size_t blockSize ) const;
- /** Resets the Chunk back to pristine values. The available count is
- set back to zero, and the first available index is set to the zeroth
- block. The stealth indexes inside each block are set to point to the
- next block. This assumes the Chunk's data was already using Init.
- */
- void Reset( std::size_t blockSize, unsigned char blocks );
-
- /// Releases the allocated block of memory.
- void Release();
-
- /** Determines if the Chunk has been corrupted.
- @param numBlocks Total # of blocks in the Chunk.
- @param blockSize # of bytes in each block.
- @param checkIndexes True if caller wants to check indexes of available
- blocks for corruption. If false, then caller wants to skip some
- tests tests just to run faster. (Debug version does more checks, but
- release version runs faster.)
- @return True if Chunk is corrupt.
- */
- bool IsCorrupt( unsigned char numBlocks, std::size_t blockSize,
- bool checkIndexes ) const;
-
- /** Determines if block is available.
- @param p Address of block managed by Chunk.
- @param numBlocks Total # of blocks in the Chunk.
- @param blockSize # of bytes in each block.
- @return True if block is available, else false if allocated.
- */
- bool IsBlockAvailable( void * p, unsigned char numBlocks,
- std::size_t blockSize ) const;
+ /// Returns true if block at address P is inside this Chunk.
+ inline bool HasBlock( void* p, std::size_t chunkLength ) const
+ {
+ unsigned char* pc = static_cast< unsigned char* >( p );
+ return ( pData_ <= pc ) && ( pc < pData_ + chunkLength );
+ }
- /// Returns true if block at address P is inside this Chunk.
- inline bool HasBlock( void * p, std::size_t chunkLength ) const
- {
- unsigned char * pc = static_cast< unsigned char * >( p );
- return ( pData_ <= pc ) && ( pc < pData_ + chunkLength );
- }
+ inline bool HasAvailable( unsigned char numBlocks ) const
+ { return ( blocksAvailable_ == numBlocks ); }
+
+ inline bool IsFilled( void ) const
+ { return ( 0 == blocksAvailable_ ); }
+
+ /// Pointer to array of allocated blocks.
+ unsigned char* pData_;
+ /// Index of first empty block.
+ unsigned char firstAvailableBlock_;
+ /// Count of empty blocks.
+ unsigned char blocksAvailable_;
+};
+
+/** @class FixedAllocator
+ @ingroup SmallObjectGroupInternal
+ Offers services for allocating fixed-sized objects. It has a container
+ of "containers" of fixed-size blocks. The outer container has all the
+ Chunks. The inner container is a Chunk which owns some blocks.
+
+ @par Class Level Invariants
+ - There is always either zero or one Chunk which is empty.
+ - If this has no empty Chunk, then emptyChunk_ is NULL.
+ - If this has an empty Chunk, then emptyChunk_ points to it.
+ - If the Chunk container is empty, then deallocChunk_ and allocChunk_
+ are NULL.
+ - If the Chunk container is not-empty, then deallocChunk_ and allocChunk_
+ are either NULL or point to Chunks within the container.
+ - allocChunk_ will often point to the last Chunk in the container since
+ it was likely allocated most recently, and therefore likely to have an
+ available block.
+ */
+class FixedAllocator
+{
+private:
- inline bool HasAvailable( unsigned char numBlocks ) const
- { return ( blocksAvailable_ == numBlocks ); }
-
- inline bool IsFilled( void ) const
- { return ( 0 == blocksAvailable_ ); }
-
- /// Pointer to array of allocated blocks.
- unsigned char * pData_;
- /// Index of first empty block.
- unsigned char firstAvailableBlock_;
- /// Count of empty blocks.
- unsigned char blocksAvailable_;
- };
-
- /** @class FixedAllocator
- @ingroup SmallObjectGroupInternal
- Offers services for allocating fixed-sized objects. It has a container
- of "containers" of fixed-size blocks. The outer container has all the
- Chunks. The inner container is a Chunk which owns some blocks.
-
- @par Class Level Invariants
- - There is always either zero or one Chunk which is empty.
- - If this has no empty Chunk, then emptyChunk_ is NULL.
- - If this has an empty Chunk, then emptyChunk_ points to it.
- - If the Chunk container is empty, then deallocChunk_ and allocChunk_
- are NULL.
- - If the Chunk container is not-empty, then deallocChunk_ and allocChunk_
- are either NULL or point to Chunks within the container.
- - allocChunk_ will often point to the last Chunk in the container since
- it was likely allocated most recently, and therefore likely to have an
- available block.
+ /** Deallocates the block at address p, and then handles the internal
+ bookkeeping needed to maintain class invariants. This assumes that
+ deallocChunk_ points to the correct chunk.
*/
- class FixedAllocator
- {
- private:
-
- /** Deallocates the block at address p, and then handles the internal
- bookkeeping needed to maintain class invariants. This assumes that
- deallocChunk_ points to the correct chunk.
- */
- void DoDeallocate( void * p );
+ void DoDeallocate( void* p );
- /** Creates an empty Chunk and adds it to the end of the ChunkList.
- All calls to the lower-level memory allocation functions occur inside
- this function, and so the only try-catch block is inside here.
- @return true for success, false for failure.
- */
- bool MakeNewChunk( void );
-
- /** Finds the Chunk which owns the block at address p. It starts at
- deallocChunk_ and searches in both forwards and backwards directions
- from there until it finds the Chunk which owns p. This algorithm
- should find the Chunk quickly if it is deallocChunk_ or is close to it
- in the Chunks container. This goes both forwards and backwards since
- that works well for both same-order and opposite-order deallocations.
- (Same-order = objects are deallocated in the same order in which they
- were allocated. Opposite order = objects are deallocated in a last to
- first order. Complexity is O(C) where C is count of all Chunks. This
- never throws.
- @return Pointer to Chunk that owns p, or NULL if no owner found.
- */
- Chunk * VicinityFind( void * p ) const;
-
- /// Not implemented.
- FixedAllocator(const FixedAllocator&);
- /// Not implemented.
- FixedAllocator& operator=(const FixedAllocator&);
-
- /// Type of container used to hold Chunks.
- typedef std::vector< Chunk > Chunks;
- /// Iterator through container of Chunks.
- typedef Chunks::iterator ChunkIter;
- /// Iterator through const container of Chunks.
- typedef Chunks::const_iterator ChunkCIter;
-
- /// Fewest # of objects managed by a Chunk.
- static unsigned char MinObjectsPerChunk_;
-
- /// Most # of objects managed by a Chunk - never exceeds UCHAR_MAX.
- static unsigned char MaxObjectsPerChunk_;
-
- /// Number of bytes in a single block within a Chunk.
- std::size_t blockSize_;
- /// Number of blocks managed by each Chunk.
- unsigned char numBlocks_;
-
- /// Container of Chunks.
- Chunks chunks_;
- /// Pointer to Chunk used for last or next allocation.
- Chunk * allocChunk_;
- /// Pointer to Chunk used for last or next deallocation.
- Chunk * deallocChunk_;
- /// Pointer to the only empty Chunk if there is one, else NULL.
- Chunk * emptyChunk_;
-
- public:
- /// Create a FixedAllocator which manages blocks of 'blockSize' size.
- FixedAllocator();
-
- /// Destroy the FixedAllocator and release all its Chunks.
- ~FixedAllocator();
-
- /// Initializes a FixedAllocator by calculating # of blocks per Chunk.
- void Initialize( std::size_t blockSize, std::size_t pageSize );
-
- /** Returns pointer to allocated memory block of fixed size - or NULL
- if it failed to allocate.
- */
- void * Allocate( void );
+ /** Creates an empty Chunk and adds it to the end of the ChunkList.
+ All calls to the lower-level memory allocation functions occur inside
+ this function, and so the only try-catch block is inside here.
+ @return true for success, false for failure.
+ */
+ bool MakeNewChunk( void );
+
+ /** Finds the Chunk which owns the block at address p. It starts at
+ deallocChunk_ and searches in both forwards and backwards directions
+ from there until it finds the Chunk which owns p. This algorithm
+ should find the Chunk quickly if it is deallocChunk_ or is close to it
+ in the Chunks container. This goes both forwards and backwards since
+ that works well for both same-order and opposite-order deallocations.
+ (Same-order = objects are deallocated in the same order in which they
+ were allocated. Opposite order = objects are deallocated in a last to
+ first order. Complexity is O(C) where C is count of all Chunks. This
+ never throws.
+ @return Pointer to Chunk that owns p, or NULL if no owner found.
+ */
+ Chunk* VicinityFind( void* p ) const;
+
+ /// Not implemented.
+ FixedAllocator(const FixedAllocator&);
+ /// Not implemented.
+ FixedAllocator& operator=(const FixedAllocator&);
+
+ /// Type of container used to hold Chunks.
+ typedef std::vector< Chunk > Chunks;
+ /// Iterator through container of Chunks.
+ typedef Chunks::iterator ChunkIter;
+ /// Iterator through const container of Chunks.
+ typedef Chunks::const_iterator ChunkCIter;
+
+ /// Fewest # of objects managed by a Chunk.
+ static unsigned char MinObjectsPerChunk_;
+
+ /// Most # of objects managed by a Chunk - never exceeds UCHAR_MAX.
+ static unsigned char MaxObjectsPerChunk_;
+
+ /// Number of bytes in a single block within a Chunk.
+ std::size_t blockSize_;
+ /// Number of blocks managed by each Chunk.
+ unsigned char numBlocks_;
+
+ /// Container of Chunks.
+ Chunks chunks_;
+ /// Pointer to Chunk used for last or next allocation.
+ Chunk* allocChunk_;
+ /// Pointer to Chunk used for last or next deallocation.
+ Chunk* deallocChunk_;
+ /// Pointer to the only empty Chunk if there is one, else NULL.
+ Chunk* emptyChunk_;
+
+public:
+ /// Create a FixedAllocator which manages blocks of 'blockSize' size.
+ FixedAllocator();
+
+ /// Destroy the FixedAllocator and release all its Chunks.
+ ~FixedAllocator();
+
+ /// Initializes a FixedAllocator by calculating # of blocks per Chunk.
+ void Initialize( std::size_t blockSize, std::size_t pageSize );
+
+ /** Returns pointer to allocated memory block of fixed size - or NULL
+ if it failed to allocate.
+ */
+ void* Allocate( void );
- /** Deallocate a memory block previously allocated with Allocate. If
- the block is not owned by this FixedAllocator, it returns false so
- that SmallObjAllocator can call the default deallocator. If the
- block was found, this returns true.
- */
- bool Deallocate( void * p, Chunk * hint );
+ /** Deallocate a memory block previously allocated with Allocate. If
+ the block is not owned by this FixedAllocator, it returns false so
+ that SmallObjAllocator can call the default deallocator. If the
+ block was found, this returns true.
+ */
+ bool Deallocate( void* p, Chunk* hint );
- /// Returns block size with which the FixedAllocator was initialized.
- inline std::size_t BlockSize() const { return blockSize_; }
+ /// Returns block size with which the FixedAllocator was initialized.
+ inline std::size_t BlockSize() const { return blockSize_; }
- /** Releases the memory used by the empty Chunk. This will take
- constant time under any situation.
- @return True if empty chunk found and released, false if none empty.
- */
- bool TrimEmptyChunk( void );
+ /** Releases the memory used by the empty Chunk. This will take
+ constant time under any situation.
+ @return True if empty chunk found and released, false if none empty.
+ */
+ bool TrimEmptyChunk( void );
- /** Releases unused spots from ChunkList. This takes constant time
- with respect to # of Chunks, but actual time depends on underlying
- memory allocator.
- @return False if no unused spots, true if some found and released.
- */
- bool TrimChunkList( void );
+ /** Releases unused spots from ChunkList. This takes constant time
+ with respect to # of Chunks, but actual time depends on underlying
+ memory allocator.
+ @return False if no unused spots, true if some found and released.
+ */
+ bool TrimChunkList( void );
- /** Returns count of empty Chunks held by this allocator. Complexity
- is O(C) where C is the total number of Chunks - empty or used.
- */
- std::size_t CountEmptyChunks( void ) const;
+ /** Returns count of empty Chunks held by this allocator. Complexity
+ is O(C) where C is the total number of Chunks - empty or used.
+ */
+ std::size_t CountEmptyChunks( void ) const;
- /** Determines if FixedAllocator is corrupt. Checks data members to
- see if any have erroneous values, or violate class invariants. It
- also checks if any Chunk is corrupt. Complexity is O(C) where C is
- the number of Chunks. If any data is corrupt, this will return true
- in release mode, or assert in debug mode.
- */
- bool IsCorrupt( void ) const;
+ /** Determines if FixedAllocator is corrupt. Checks data members to
+ see if any have erroneous values, or violate class invariants. It
+ also checks if any Chunk is corrupt. Complexity is O(C) where C is
+ the number of Chunks. If any data is corrupt, this will return true
+ in release mode, or assert in debug mode.
+ */
+ bool IsCorrupt( void ) const;
- /** Returns true if the block at address p is within a Chunk owned by
- this FixedAllocator. Complexity is O(C) where C is the total number
- of Chunks - empty or used.
- */
- const Chunk * HasBlock( void * p ) const;
- inline Chunk * HasBlock( void * p )
- {
- return const_cast< Chunk * >(
- const_cast< const FixedAllocator * >( this )->HasBlock( p ) );
- }
+ /** Returns true if the block at address p is within a Chunk owned by
+ this FixedAllocator. Complexity is O(C) where C is the total number
+ of Chunks - empty or used.
+ */
+ const Chunk* HasBlock( void* p ) const;
+ inline Chunk* HasBlock( void* p )
+ {
+ return const_cast< Chunk* >(
+ const_cast< const FixedAllocator* >( this )->HasBlock( p ) );
+ }
- };
+};
- unsigned char FixedAllocator::MinObjectsPerChunk_ = 8;
- unsigned char FixedAllocator::MaxObjectsPerChunk_ = UCHAR_MAX;
+unsigned char FixedAllocator::MinObjectsPerChunk_ = 8;
+unsigned char FixedAllocator::MaxObjectsPerChunk_ = UCHAR_MAX;
// Chunk::Init ----------------------------------------------------------------
@@ -310,11 +310,11 @@ bool Chunk::Init( std::size_t blockSize, unsigned char blocks )
#ifdef USE_NEW_TO_ALLOCATE
// If this new operator fails, it will throw, and the exception will get
// caught one layer up.
- pData_ = static_cast< unsigned char * >( ::operator new ( allocSize ) );
+ pData_ = static_cast< unsigned char* >( ::operator new ( allocSize ) );
#else
// malloc can't throw, so its only way to indicate an error is to return
// a NULL pointer, so we have to check for that.
- pData_ = static_cast< unsigned char * >( ::std::malloc( allocSize ) );
+ pData_ = static_cast< unsigned char* >( ::std::malloc( allocSize ) );
if ( NULL == pData_ ) return false;
#endif
@@ -335,7 +335,7 @@ void Chunk::Reset(std::size_t blockSize, unsigned char blocks)
blocksAvailable_ = blocks;
unsigned char i = 0;
- for ( unsigned char * p = pData_; i != blocks; p += blockSize )
+ for ( unsigned char* p = pData_; i != blocks; p += blockSize )
{
*p = ++i;
}
@@ -349,7 +349,7 @@ void Chunk::Release()
#ifdef USE_NEW_TO_ALLOCATE
::operator delete ( pData_ );
#else
- ::std::free( static_cast< void * >( pData_ ) );
+ ::std::free( static_cast< void* >( pData_ ) );
#endif
}
@@ -360,8 +360,8 @@ void* Chunk::Allocate(std::size_t blockSize)
if ( IsFilled() ) return NULL;
assert((firstAvailableBlock_ * blockSize) / blockSize ==
- firstAvailableBlock_);
- unsigned char * pResult = pData_ + (firstAvailableBlock_ * blockSize);
+ firstAvailableBlock_);
+ unsigned char* pResult = pData_ + (firstAvailableBlock_ * blockSize);
firstAvailableBlock_ = *pResult;
--blocksAvailable_;
@@ -378,7 +378,7 @@ void Chunk::Deallocate(void* p, std::size_t blockSize)
// Alignment check
assert((toRelease - pData_) % blockSize == 0);
unsigned char index = static_cast< unsigned char >(
- ( toRelease - pData_ ) / blockSize);
+ ( toRelease - pData_ ) / blockSize);
#if defined(DEBUG) || defined(_DEBUG)
// Check if block was already deleted. Attempting to delete the same
@@ -399,7 +399,7 @@ void Chunk::Deallocate(void* p, std::size_t blockSize)
// Chunk::IsCorrupt -----------------------------------------------------------
bool Chunk::IsCorrupt( unsigned char numBlocks, std::size_t blockSize,
- bool checkIndexes ) const
+ bool checkIndexes ) const
{
if ( numBlocks < blocksAvailable_ )
@@ -428,7 +428,7 @@ bool Chunk::IsCorrupt( unsigned char numBlocks, std::size_t blockSize,
found on the linked-list.
*/
std::bitset< UCHAR_MAX > foundBlocks;
- unsigned char * nextBlock = NULL;
+ unsigned char* nextBlock = NULL;
/* The loop goes along singly linked-list of stealth indexes and makes sure
that each index is within bounds (0 <= index < numBlocks) and that the
@@ -499,19 +499,19 @@ bool Chunk::IsCorrupt( unsigned char numBlocks, std::size_t blockSize,
// Chunk::IsBlockAvailable ----------------------------------------------------
-bool Chunk::IsBlockAvailable( void * p, unsigned char numBlocks,
- std::size_t blockSize ) const
+bool Chunk::IsBlockAvailable( void* p, unsigned char numBlocks,
+ std::size_t blockSize ) const
{
(void) numBlocks;
if ( IsFilled() )
return false;
- unsigned char * place = static_cast< unsigned char * >( p );
+ unsigned char* place = static_cast< unsigned char* >( p );
// Alignment check
assert( ( place - pData_ ) % blockSize == 0 );
unsigned char blockIndex = static_cast< unsigned char >(
- ( place - pData_ ) / blockSize );
+ ( place - pData_ ) / blockSize );
unsigned char index = firstAvailableBlock_;
assert( numBlocks > index );
@@ -522,7 +522,7 @@ bool Chunk::IsBlockAvailable( void * p, unsigned char numBlocks,
found on the linked-list.
*/
std::bitset< UCHAR_MAX > foundBlocks;
- unsigned char * nextBlock = NULL;
+ unsigned char* nextBlock = NULL;
for ( unsigned char cc = 0; ; )
{
nextBlock = pData_ + ( index * blockSize );
@@ -562,7 +562,7 @@ FixedAllocator::~FixedAllocator()
assert( chunks_.empty() && "Memory leak detected!" );
#endif
for ( ChunkIter i( chunks_.begin() ); i != chunks_.end(); ++i )
- i->Release();
+ i->Release();
}
// FixedAllocator::Initialize -------------------------------------------------
@@ -592,7 +592,7 @@ std::size_t FixedAllocator::CountEmptyChunks( void ) const
std::size_t count = 0;
for ( ChunkCIter it( chunks_.begin() ); it != chunks_.end(); ++it )
{
- const Chunk & chunk = *it;
+ const Chunk& chunk = *it;
if ( chunk.HasAvailable( numBlocks_ ) )
++count;
}
@@ -642,8 +642,8 @@ bool FixedAllocator::IsCorrupt( void ) const
else
{
- const Chunk * front = &chunks_.front();
- const Chunk * back = &chunks_.back();
+ const Chunk* front = &chunks_.front();
+ const Chunk* back = &chunks_.back();
if ( start >= last )
{
assert( false );
@@ -708,7 +708,7 @@ bool FixedAllocator::IsCorrupt( void ) const
}
for ( ChunkCIter it( start ); it != last; ++it )
{
- const Chunk & chunk = *it;
+ const Chunk& chunk = *it;
if ( chunk.IsCorrupt( numBlocks_, blockSize_, true ) )
return true;
}
@@ -719,12 +719,12 @@ bool FixedAllocator::IsCorrupt( void ) const
// FixedAllocator::HasBlock ---------------------------------------------------
-const Chunk * FixedAllocator::HasBlock( void * p ) const
+const Chunk* FixedAllocator::HasBlock( void* p ) const
{
const std::size_t chunkLength = numBlocks_ * blockSize_;
for ( ChunkCIter it( chunks_.begin() ); it != chunks_.end(); ++it )
{
- const Chunk & chunk = *it;
+ const Chunk& chunk = *it;
if ( chunk.HasBlock( p, chunkLength ) )
return &chunk;
}
@@ -744,7 +744,7 @@ bool FixedAllocator::TrimEmptyChunk( void )
// And there should be exactly 1 empty Chunk.
assert( 1 == CountEmptyChunks() );
- Chunk * lastChunk = &chunks_.back();
+ Chunk* lastChunk = &chunks_.back();
if ( lastChunk != emptyChunk_ )
std::swap( *emptyChunk_, *lastChunk );
assert( lastChunk->HasAvailable( numBlocks_ ) );
@@ -828,7 +828,7 @@ bool FixedAllocator::MakeNewChunk( void )
// FixedAllocator::Allocate ---------------------------------------------------
-void * FixedAllocator::Allocate( void )
+void* FixedAllocator::Allocate( void )
{
// prove either emptyChunk_ points nowhere, or points to a truly empty Chunk.
assert( ( NULL == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) );
@@ -867,7 +867,7 @@ void * FixedAllocator::Allocate( void )
assert( allocChunk_ != NULL );
assert( !allocChunk_->IsFilled() );
- void * place = allocChunk_->Allocate( blockSize_ );
+ void* place = allocChunk_->Allocate( blockSize_ );
// prove either emptyChunk_ points nowhere, or points to a truly empty Chunk.
assert( ( NULL == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) );
@@ -885,7 +885,7 @@ void * FixedAllocator::Allocate( void )
// FixedAllocator::Deallocate -------------------------------------------------
-bool FixedAllocator::Deallocate( void * p, Chunk * hint )
+bool FixedAllocator::Deallocate( void* p, Chunk* hint )
{
assert(!chunks_.empty());
assert(&chunks_.front() <= deallocChunk_);
@@ -894,7 +894,7 @@ bool FixedAllocator::Deallocate( void * p, Chunk * hint )
assert( &chunks_.back() >= allocChunk_ );
assert( CountEmptyChunks() < 2 );
- Chunk * foundChunk = ( NULL == hint ) ? VicinityFind( p ) : hint;
+ Chunk* foundChunk = ( NULL == hint ) ? VicinityFind( p ) : hint;
if ( NULL == foundChunk )
return false;
@@ -920,16 +920,16 @@ bool FixedAllocator::Deallocate( void * p, Chunk * hint )
// FixedAllocator::VicinityFind -----------------------------------------------
-Chunk * FixedAllocator::VicinityFind( void * p ) const
+Chunk* FixedAllocator::VicinityFind( void* p ) const
{
if ( chunks_.empty() ) return NULL;
assert(deallocChunk_);
const std::size_t chunkLength = numBlocks_ * blockSize_;
- Chunk * lo = deallocChunk_;
- Chunk * hi = deallocChunk_ + 1;
- const Chunk * loBound = &chunks_.front();
- const Chunk * hiBound = &chunks_.back() + 1;
+ Chunk* lo = deallocChunk_;
+ Chunk* hi = deallocChunk_ + 1;
+ const Chunk* loBound = &chunks_.front();
+ const Chunk* hiBound = &chunks_.back() + 1;
// Special case: deallocChunk_ is the last in the array
if (hi == hiBound) hi = NULL;
@@ -989,7 +989,7 @@ void FixedAllocator::DoDeallocate(void* p)
// If last Chunk is empty, just change what deallocChunk_
// points to, and release the last. Otherwise, swap an empty
// Chunk with the last, and then release it.
- Chunk * lastChunk = &chunks_.back();
+ Chunk* lastChunk = &chunks_.back();
if ( lastChunk == deallocChunk_ )
deallocChunk_ = emptyChunk_;
else if ( lastChunk != emptyChunk_ )
@@ -1025,13 +1025,13 @@ inline std::size_t GetOffset( std::size_t numBytes, std::size_t alignment )
@param doThrow True if this function should throw an exception, or false if it
should indicate failure by returning a NULL pointer.
*/
-void * DefaultAllocator( std::size_t numBytes, bool doThrow )
+void* DefaultAllocator( std::size_t numBytes, bool doThrow )
{
#ifdef USE_NEW_TO_ALLOCATE
return doThrow ? ::operator new( numBytes ) :
- ::operator new( numBytes, std::nothrow_t() );
+ ::operator new( numBytes, std::nothrow_t() );
#else
- void * p = ::std::malloc( numBytes );
+ void* p = ::std::malloc( numBytes );
if ( doThrow && ( NULL == p ) )
throw std::bad_alloc();
return p;
@@ -1046,7 +1046,7 @@ void * DefaultAllocator( std::size_t numBytes, bool doThrow )
it matches malloc which is the preferred default allocator. SmallObjAllocator
will call this if an address was not found among any of its own blocks.
*/
-void DefaultDeallocator( void * p )
+void DefaultDeallocator( void* p )
{
#ifdef USE_NEW_TO_ALLOCATE
::operator delete( p );
@@ -1058,7 +1058,7 @@ void DefaultDeallocator( void * p )
// SmallObjAllocator::SmallObjAllocator ---------------------------------------
SmallObjAllocator::SmallObjAllocator( std::size_t pageSize,
- std::size_t maxObjectSize, std::size_t objectAlignSize ) :
+ std::size_t maxObjectSize, std::size_t objectAlignSize ) :
pool_( NULL ),
maxSmallObjectSize_( maxObjectSize ),
objectAlignSize_( objectAlignSize )
@@ -1106,7 +1106,7 @@ bool SmallObjAllocator::TrimExcessMemory( void )
// SmallObjAllocator::Allocate ------------------------------------------------
-void * SmallObjAllocator::Allocate( std::size_t numBytes, bool doThrow )
+void* SmallObjAllocator::Allocate( std::size_t numBytes, bool doThrow )
{
if ( numBytes > GetMaxObjectSize() )
return DefaultAllocator( numBytes, doThrow );
@@ -1118,10 +1118,10 @@ void * SmallObjAllocator::Allocate( std::size_t numBytes, bool doThrow )
(void) allocCount;
assert( index < allocCount );
- FixedAllocator & allocator = pool_[ index ];
+ FixedAllocator& allocator = pool_[ index ];
assert( allocator.BlockSize() >= numBytes );
assert( allocator.BlockSize() < numBytes + GetAlignment() );
- void * place = allocator.Allocate();
+ void* place = allocator.Allocate();
if ( ( NULL == place ) && TrimExcessMemory() )
place = allocator.Allocate();
@@ -1141,7 +1141,7 @@ void * SmallObjAllocator::Allocate( std::size_t numBytes, bool doThrow )
// SmallObjAllocator::Deallocate ----------------------------------------------
-void SmallObjAllocator::Deallocate( void * p, std::size_t numBytes )
+void SmallObjAllocator::Deallocate( void* p, std::size_t numBytes )
{
if ( NULL == p ) return;
if ( numBytes > GetMaxObjectSize() )
@@ -1155,7 +1155,7 @@ void SmallObjAllocator::Deallocate( void * p, std::size_t numBytes )
const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() );
(void) allocCount;
assert( index < allocCount );
- FixedAllocator & allocator = pool_[ index ];
+ FixedAllocator& allocator = pool_[ index ];
assert( allocator.BlockSize() >= numBytes );
assert( allocator.BlockSize() < numBytes + GetAlignment() );
const bool found = allocator.Deallocate( p, NULL );
@@ -1165,13 +1165,13 @@ void SmallObjAllocator::Deallocate( void * p, std::size_t numBytes )
// SmallObjAllocator::Deallocate ----------------------------------------------
-void SmallObjAllocator::Deallocate( void * p )
+void SmallObjAllocator::Deallocate( void* p )
{
if ( NULL == p ) return;
assert( NULL != pool_ );
- FixedAllocator * pAllocator = NULL;
+ FixedAllocator* pAllocator = NULL;
const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() );
- Chunk * chunk = NULL;
+ Chunk* chunk = NULL;
for ( std::size_t ii = 0; ii < allocCount; ++ii )
{
diff --git a/shared/loki/SmallObj.h b/shared/loki/SmallObj.h
index 65828bf2..8725b911 100644
--- a/shared/loki/SmallObj.h
+++ b/shared/loki/SmallObj.h
@@ -2,14 +2,14 @@
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
-// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author or Addison-Wesley Longman make no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author or Addison-Wesley Longman make no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_SMALLOBJ_INC_
@@ -53,590 +53,590 @@
namespace Loki
{
- namespace LongevityLifetime
- {
- /** @struct DieAsSmallObjectParent
- @ingroup SmallObjectGroup
- Lifetime policy to manage lifetime dependencies of
- SmallObject base and child classes.
- The Base class should have this lifetime
- */
- template <class T>
- struct DieAsSmallObjectParent : DieLast<T> {};
-
- /** @struct DieAsSmallObjectChild
- @ingroup SmallObjectGroup
- Lifetime policy to manage lifetime dependencies of
- SmallObject base and child classes.
- The Child class should have this lifetime
- */
- template <class T>
- struct DieAsSmallObjectChild : DieDirectlyBeforeLast<T> {};
-
- }
-
- class FixedAllocator;
-
- /** @class SmallObjAllocator
- @ingroup SmallObjectGroupInternal
- Manages pool of fixed-size allocators.
- Designed to be a non-templated base class of AllocatorSingleton so that
- implementation details can be safely hidden in the source code file.
+namespace LongevityLifetime
+{
+/** @struct DieAsSmallObjectParent
+ @ingroup SmallObjectGroup
+ Lifetime policy to manage lifetime dependencies of
+ SmallObject base and child classes.
+ The Base class should have this lifetime
+*/
+template <class T>
+struct DieAsSmallObjectParent : DieLast<T> {};
+
+/** @struct DieAsSmallObjectChild
+ @ingroup SmallObjectGroup
+ Lifetime policy to manage lifetime dependencies of
+ SmallObject base and child classes.
+ The Child class should have this lifetime
+*/
+template <class T>
+struct DieAsSmallObjectChild : DieDirectlyBeforeLast<T> {};
+
+}
+
+class FixedAllocator;
+
+/** @class SmallObjAllocator
+ @ingroup SmallObjectGroupInternal
+ Manages pool of fixed-size allocators.
+ Designed to be a non-templated base class of AllocatorSingleton so that
+ implementation details can be safely hidden in the source code file.
+ */
+class LOKI_EXPORT SmallObjAllocator
+{
+protected:
+ /** The only available constructor needs certain parameters in order to
+ initialize all the FixedAllocator's. This throws only if
+ @param pageSize # of bytes in a page of memory.
+ @param maxObjectSize Max # of bytes which this may allocate.
+ @param objectAlignSize # of bytes between alignment boundaries.
*/
- class LOKI_EXPORT SmallObjAllocator
- {
- protected:
- /** The only available constructor needs certain parameters in order to
- initialize all the FixedAllocator's. This throws only if
- @param pageSize # of bytes in a page of memory.
- @param maxObjectSize Max # of bytes which this may allocate.
- @param objectAlignSize # of bytes between alignment boundaries.
- */
- SmallObjAllocator( std::size_t pageSize, std::size_t maxObjectSize,
- std::size_t objectAlignSize );
-
- /** Destructor releases all blocks, all Chunks, and FixedAllocator's.
- Any outstanding blocks are unavailable, and should not be used after
- this destructor is called. The destructor is deliberately non-virtual
- because it is protected, not public.
- */
- ~SmallObjAllocator( void );
-
- public:
- /** Allocates a block of memory of requested size. Complexity is often
- constant-time, but might be O(C) where C is the number of Chunks in a
- FixedAllocator.
-
- @par Exception Safety Level
- Provides either strong-exception safety, or no-throw exception-safety
- level depending upon doThrow parameter. The reason it provides two
- levels of exception safety is because it is used by both the nothrow
- and throwing new operators. The underlying implementation will never
- throw of its own accord, but this can decide to throw if it does not
- allocate. The only exception it should emit is std::bad_alloc.
-
- @par Allocation Failure
- If it does not allocate, it will call TrimExcessMemory and attempt to
- allocate again, before it decides to throw or return NULL. Many
- allocators loop through several new_handler functions, and terminate
- if they can not allocate, but not this one. It only makes one attempt
- using its own implementation of the new_handler, and then returns NULL
- or throws so that the program can decide what to do at a higher level.
- (Side note: Even though the C++ Standard allows allocators and
- new_handlers to terminate if they fail, the Loki allocator does not do
- that since that policy is not polite to a host program.)
-
- @param size # of bytes needed for allocation.
- @param doThrow True if this should throw if unable to allocate, false
- if it should provide no-throw exception safety level.
- @return NULL if nothing allocated and doThrow is false. Else the
- pointer to an available block of memory.
- */
- void * Allocate( std::size_t size, bool doThrow );
-
- /** Deallocates a block of memory at a given place and of a specific
- size. Complexity is almost always constant-time, and is O(C) only if
- it has to search for which Chunk deallocates. This never throws.
- */
- void Deallocate( void * p, std::size_t size );
-
- /** Deallocates a block of memory at a given place but of unknown size
- size. Complexity is O(F + C) where F is the count of FixedAllocator's
- in the pool, and C is the number of Chunks in all FixedAllocator's. This
- does not throw exceptions. This overloaded version of Deallocate is
- called by the nothow delete operator - which is called when the nothrow
- new operator is used, but a constructor throws an exception.
- */
- void Deallocate( void * p );
-
- /// Returns max # of bytes which this can allocate.
- inline std::size_t GetMaxObjectSize() const
- { return maxSmallObjectSize_; }
-
- /// Returns # of bytes between allocation boundaries.
- inline std::size_t GetAlignment() const { return objectAlignSize_; }
-
- /** Releases empty Chunks from memory. Complexity is O(F + C) where F
- is the count of FixedAllocator's in the pool, and C is the number of
- Chunks in all FixedAllocator's. This will never throw. This is called
- by AllocatorSingleto::ClearExtraMemory, the new_handler function for
- Loki's allocator, and is called internally when an allocation fails.
- @return True if any memory released, or false if none released.
- */
- bool TrimExcessMemory( void );
-
- /** Returns true if anything in implementation is corrupt. Complexity
- is O(F + C + B) where F is the count of FixedAllocator's in the pool,
- C is the number of Chunks in all FixedAllocator's, and B is the number
- of blocks in all Chunks. If it determines any data is corrupted, this
- will return true in release version, but assert in debug version at
- the line where it detects the corrupted data. If it does not detect
- any corrupted data, it returns false.
- */
- bool IsCorrupt( void ) const;
-
- private:
- /// Default-constructor is not implemented.
- SmallObjAllocator( void );
- /// Copy-constructor is not implemented.
- SmallObjAllocator( const SmallObjAllocator & );
- /// Copy-assignment operator is not implemented.
- SmallObjAllocator & operator = ( const SmallObjAllocator & );
-
- /// Pointer to array of fixed-size allocators.
- Loki::FixedAllocator * pool_;
-
- /// Largest object size supported by allocators.
- const std::size_t maxSmallObjectSize_;
-
- /// Size of alignment boundaries.
- const std::size_t objectAlignSize_;
- };
-
-
- /** @class AllocatorSingleton
- @ingroup SmallObjectGroupInternal
- This template class is derived from
- SmallObjAllocator in order to pass template arguments into it, and still
- have a default constructor for the singleton. Each instance is a unique
- combination of all the template parameters, and hence is singleton only
- with respect to those parameters. The template parameters have default
- values and the class has typedefs identical to both SmallObject and
- SmallValueObject so that this class can be used directly instead of going
- through SmallObject or SmallValueObject. That design feature allows
- clients to use the new_handler without having the name of the new_handler
- function show up in classes derived from SmallObject or SmallValueObject.
- Thus, the only functions in the allocator which show up in SmallObject or
- SmallValueObject inheritance hierarchies are the new and delete
- operators.
- */
- template
- <
- template <class, class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL,
- std::size_t chunkSize = LOKI_DEFAULT_CHUNK_SIZE,
- std::size_t maxSmallObjectSize = LOKI_MAX_SMALL_OBJECT_SIZE,
- std::size_t objectAlignSize = LOKI_DEFAULT_OBJECT_ALIGNMENT,
- template <class> class LifetimePolicy = LOKI_DEFAULT_SMALLOBJ_LIFETIME,
- class MutexPolicy = LOKI_DEFAULT_MUTEX
- >
- class AllocatorSingleton : public SmallObjAllocator
- {
- public:
+ SmallObjAllocator( std::size_t pageSize, std::size_t maxObjectSize,
+ std::size_t objectAlignSize );
+
+ /** Destructor releases all blocks, all Chunks, and FixedAllocator's.
+ Any outstanding blocks are unavailable, and should not be used after
+ this destructor is called. The destructor is deliberately non-virtual
+ because it is protected, not public.
+ */
+ ~SmallObjAllocator( void );
+
+public:
+ /** Allocates a block of memory of requested size. Complexity is often
+ constant-time, but might be O(C) where C is the number of Chunks in a
+ FixedAllocator.
+
+ @par Exception Safety Level
+ Provides either strong-exception safety, or no-throw exception-safety
+ level depending upon doThrow parameter. The reason it provides two
+ levels of exception safety is because it is used by both the nothrow
+ and throwing new operators. The underlying implementation will never
+ throw of its own accord, but this can decide to throw if it does not
+ allocate. The only exception it should emit is std::bad_alloc.
+
+ @par Allocation Failure
+ If it does not allocate, it will call TrimExcessMemory and attempt to
+ allocate again, before it decides to throw or return NULL. Many
+ allocators loop through several new_handler functions, and terminate
+ if they can not allocate, but not this one. It only makes one attempt
+ using its own implementation of the new_handler, and then returns NULL
+ or throws so that the program can decide what to do at a higher level.
+ (Side note: Even though the C++ Standard allows allocators and
+ new_handlers to terminate if they fail, the Loki allocator does not do
+ that since that policy is not polite to a host program.)
+
+ @param size # of bytes needed for allocation.
+ @param doThrow True if this should throw if unable to allocate, false
+ if it should provide no-throw exception safety level.
+ @return NULL if nothing allocated and doThrow is false. Else the
+ pointer to an available block of memory.
+ */
+ void* Allocate( std::size_t size, bool doThrow );
+
+ /** Deallocates a block of memory at a given place and of a specific
+ size. Complexity is almost always constant-time, and is O(C) only if
+ it has to search for which Chunk deallocates. This never throws.
+ */
+ void Deallocate( void* p, std::size_t size );
+
+ /** Deallocates a block of memory at a given place but of unknown size
+ size. Complexity is O(F + C) where F is the count of FixedAllocator's
+ in the pool, and C is the number of Chunks in all FixedAllocator's. This
+ does not throw exceptions. This overloaded version of Deallocate is
+ called by the nothow delete operator - which is called when the nothrow
+ new operator is used, but a constructor throws an exception.
+ */
+ void Deallocate( void* p );
- /// Defines type of allocator.
- typedef AllocatorSingleton< ThreadingModel, chunkSize,
+ /// Returns max # of bytes which this can allocate.
+ inline std::size_t GetMaxObjectSize() const
+ { return maxSmallObjectSize_; }
+
+ /// Returns # of bytes between allocation boundaries.
+ inline std::size_t GetAlignment() const { return objectAlignSize_; }
+
+ /** Releases empty Chunks from memory. Complexity is O(F + C) where F
+ is the count of FixedAllocator's in the pool, and C is the number of
+ Chunks in all FixedAllocator's. This will never throw. This is called
+ by AllocatorSingleto::ClearExtraMemory, the new_handler function for
+ Loki's allocator, and is called internally when an allocation fails.
+ @return True if any memory released, or false if none released.
+ */
+ bool TrimExcessMemory( void );
+
+ /** Returns true if anything in implementation is corrupt. Complexity
+ is O(F + C + B) where F is the count of FixedAllocator's in the pool,
+ C is the number of Chunks in all FixedAllocator's, and B is the number
+ of blocks in all Chunks. If it determines any data is corrupted, this
+ will return true in release version, but assert in debug version at
+ the line where it detects the corrupted data. If it does not detect
+ any corrupted data, it returns false.
+ */
+ bool IsCorrupt( void ) const;
+
+private:
+ /// Default-constructor is not implemented.
+ SmallObjAllocator( void );
+ /// Copy-constructor is not implemented.
+ SmallObjAllocator( const SmallObjAllocator& );
+ /// Copy-assignment operator is not implemented.
+ SmallObjAllocator& operator = ( const SmallObjAllocator& );
+
+ /// Pointer to array of fixed-size allocators.
+ Loki::FixedAllocator* pool_;
+
+ /// Largest object size supported by allocators.
+ const std::size_t maxSmallObjectSize_;
+
+ /// Size of alignment boundaries.
+ const std::size_t objectAlignSize_;
+};
+
+
+/** @class AllocatorSingleton
+ @ingroup SmallObjectGroupInternal
+ This template class is derived from
+ SmallObjAllocator in order to pass template arguments into it, and still
+ have a default constructor for the singleton. Each instance is a unique
+ combination of all the template parameters, and hence is singleton only
+ with respect to those parameters. The template parameters have default
+ values and the class has typedefs identical to both SmallObject and
+ SmallValueObject so that this class can be used directly instead of going
+ through SmallObject or SmallValueObject. That design feature allows
+ clients to use the new_handler without having the name of the new_handler
+ function show up in classes derived from SmallObject or SmallValueObject.
+ Thus, the only functions in the allocator which show up in SmallObject or
+ SmallValueObject inheritance hierarchies are the new and delete
+ operators.
+*/
+template
+<
+template <class, class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL,
+ std::size_t chunkSize = LOKI_DEFAULT_CHUNK_SIZE,
+ std::size_t maxSmallObjectSize = LOKI_MAX_SMALL_OBJECT_SIZE,
+ std::size_t objectAlignSize = LOKI_DEFAULT_OBJECT_ALIGNMENT,
+ template <class> class LifetimePolicy = LOKI_DEFAULT_SMALLOBJ_LIFETIME,
+ class MutexPolicy = LOKI_DEFAULT_MUTEX
+ >
+class AllocatorSingleton : public SmallObjAllocator
+{
+public:
+
+ /// Defines type of allocator.
+ typedef AllocatorSingleton< ThreadingModel, chunkSize,
maxSmallObjectSize, objectAlignSize, LifetimePolicy > MyAllocator;
- /// Defines type for thread-safety locking mechanism.
- typedef ThreadingModel< MyAllocator, MutexPolicy > MyThreadingModel;
+ /// Defines type for thread-safety locking mechanism.
+ typedef ThreadingModel< MyAllocator, MutexPolicy > MyThreadingModel;
- /// Defines singleton made from allocator.
- typedef Loki::SingletonHolder< MyAllocator, Loki::CreateStatic,
+ /// Defines singleton made from allocator.
+ typedef Loki::SingletonHolder< MyAllocator, Loki::CreateStatic,
LifetimePolicy, ThreadingModel > MyAllocatorSingleton;
- /// Returns reference to the singleton.
- inline static AllocatorSingleton & Instance( void )
- {
- return MyAllocatorSingleton::Instance();
- }
-
- /// The default constructor is not meant to be called directly.
- inline AllocatorSingleton() :
- SmallObjAllocator( chunkSize, maxSmallObjectSize, objectAlignSize )
- {}
-
- /// The destructor is not meant to be called directly.
- inline ~AllocatorSingleton( void ) {}
-
- /** Clears any excess memory used by the allocator. Complexity is
- O(F + C) where F is the count of FixedAllocator's in the pool, and C
- is the number of Chunks in all FixedAllocator's. This never throws.
- @note This function can be used as a new_handler when Loki and other
- memory allocators can no longer allocate. Although the C++ Standard
- allows new_handler functions to terminate the program when they can
- not release any memory, this will not do so.
- */
- static void ClearExtraMemory( void );
-
- /** Returns true if anything in implementation is corrupt. Complexity
- is O(F + C + B) where F is the count of FixedAllocator's in the pool,
- C is the number of Chunks in all FixedAllocator's, and B is the number
- of blocks in all Chunks. If it determines any data is corrupted, this
- will return true in release version, but assert in debug version at
- the line where it detects the corrupted data. If it does not detect
- any corrupted data, it returns false.
- */
- static bool IsCorrupted( void );
-
- private:
- /// Copy-constructor is not implemented.
- AllocatorSingleton( const AllocatorSingleton & );
- /// Copy-assignment operator is not implemented.
- AllocatorSingleton & operator = ( const AllocatorSingleton & );
- };
-
- template
- <
- template <class, class> class T,
- std::size_t C,
- std::size_t M,
- std::size_t O,
- template <class> class L,
- class X
- >
- void AllocatorSingleton< T, C, M, O, L, X >::ClearExtraMemory( void )
+ /// Returns reference to the singleton.
+ inline static AllocatorSingleton& Instance( void )
+ {
+ return MyAllocatorSingleton::Instance();
+ }
+
+ /// The default constructor is not meant to be called directly.
+ inline AllocatorSingleton() :
+ SmallObjAllocator( chunkSize, maxSmallObjectSize, objectAlignSize )
+ {}
+
+ /// The destructor is not meant to be called directly.
+ inline ~AllocatorSingleton( void ) {}
+
+ /** Clears any excess memory used by the allocator. Complexity is
+ O(F + C) where F is the count of FixedAllocator's in the pool, and C
+ is the number of Chunks in all FixedAllocator's. This never throws.
+ @note This function can be used as a new_handler when Loki and other
+ memory allocators can no longer allocate. Although the C++ Standard
+ allows new_handler functions to terminate the program when they can
+ not release any memory, this will not do so.
+ */
+ static void ClearExtraMemory( void );
+
+ /** Returns true if anything in implementation is corrupt. Complexity
+ is O(F + C + B) where F is the count of FixedAllocator's in the pool,
+ C is the number of Chunks in all FixedAllocator's, and B is the number
+ of blocks in all Chunks. If it determines any data is corrupted, this
+ will return true in release version, but assert in debug version at
+ the line where it detects the corrupted data. If it does not detect
+ any corrupted data, it returns false.
+ */
+ static bool IsCorrupted( void );
+
+private:
+ /// Copy-constructor is not implemented.
+ AllocatorSingleton( const AllocatorSingleton& );
+ /// Copy-assignment operator is not implemented.
+ AllocatorSingleton& operator = ( const AllocatorSingleton& );
+};
+
+template
+<
+template <class, class> class T,
+ std::size_t C,
+ std::size_t M,
+ std::size_t O,
+ template <class> class L,
+ class X
+ >
+void AllocatorSingleton< T, C, M, O, L, X >::ClearExtraMemory( void )
+{
+ typename MyThreadingModel::Lock lock;
+ (void)lock; // get rid of warning
+ Instance().TrimExcessMemory();
+}
+
+template
+<
+template <class, class> class T,
+ std::size_t C,
+ std::size_t M,
+ std::size_t O,
+ template <class> class L,
+ class X
+ >
+bool AllocatorSingleton< T, C, M, O, L, X >::IsCorrupted( void )
+{
+ typename MyThreadingModel::Lock lock;
+ (void)lock; // get rid of warning
+ return Instance().IsCorrupt();
+}
+
+/** This standalone function provides the longevity level for Small-Object
+ Allocators which use the Loki::SingletonWithLongevity policy. The
+ SingletonWithLongevity class can find this function through argument-
+ dependent lookup.
+
+ @par Longevity Levels
+ No Small-Object Allocator depends on any other Small-Object allocator, so
+ this does not need to calculate dependency levels among allocators, and
+ it returns just a constant. All allocators must live longer than the
+ objects which use the allocators, it must return a longevity level higher
+ than any such object.
+ */
+template
+<
+template <class, class> class T,
+ std::size_t C,
+ std::size_t M,
+ std::size_t O,
+ template <class> class L,
+ class X
+ >
+inline unsigned int GetLongevity(
+ AllocatorSingleton< T, C, M, O, L, X > * )
+{
+ // Returns highest possible value.
+ return 0xFFFFFFFF;
+}
+
+
+/** @class SmallObjectBase
+ @ingroup SmallObjectGroup
+ Base class for small object allocation classes.
+ The shared implementation of the new and delete operators are here instead
+ of being duplicated in both SmallObject or SmallValueObject, later just
+ called Small-Objects. This class is not meant to be used directly by clients,
+ or derived from by clients. Class has no data members so compilers can
+ use Empty-Base-Optimization.
+
+ @par ThreadingModel
+ This class doesn't support ObjectLevelLockable policy for ThreadingModel.
+ The allocator is a singleton, so a per-instance mutex is not necessary.
+ Nor is using ObjectLevelLockable recommended with SingletonHolder since
+ the SingletonHolder::MakeInstance function requires a mutex that exists
+ prior to when the object is created - which is not possible if the mutex
+ is inside the object, such as required for ObjectLevelLockable. If you
+ attempt to use ObjectLevelLockable, the compiler will emit errors because
+ it can't use the default constructor in ObjectLevelLockable. If you need
+ a thread-safe allocator, use the ClassLevelLockable policy.
+
+ @par Lifetime Policy
+
+ The SmallObjectBase template needs a lifetime policy because it owns
+ a singleton of SmallObjAllocator which does all the low level functions.
+ When using a Small-Object in combination with the SingletonHolder template
+ you have to choose two lifetimes, that of the Small-Object and that of
+ the singleton. The rule is: The Small-Object lifetime must be greater than
+ the lifetime of the singleton hosting the Small-Object. Violating this rule
+ results in a crash on exit, because the hosting singleton tries to delete
+ the Small-Object which is then already destroyed.
+
+ The lifetime policies recommended for use with Small-Objects hosted
+ by a SingletonHolder template are
+ - LongevityLifetime::DieAsSmallObjectParent / LongevityLifetime::DieAsSmallObjectChild
+ - SingletonWithLongevity
+ - FollowIntoDeath (not supported by MSVC 7.1)
+ - NoDestroy
+
+ The default lifetime of Small-Objects is
+ LongevityLifetime::DieAsSmallObjectParent to
+ insure that memory is not released before a object with the lifetime
+ LongevityLifetime::DieAsSmallObjectChild using that
+ memory is destroyed. The LongevityLifetime::DieAsSmallObjectParent
+ lifetime has the highest possible value of a SetLongevity lifetime, so
+ you can use it in combination with your own lifetime not having also
+ the highest possible value.
+
+ The DefaultLifetime and PhoenixSingleton policies are *not* recommended
+ since they can cause the allocator to be destroyed and release memory
+ for singletons hosting a object which inherit from either SmallObject
+ or SmallValueObject.
+
+ @par Lifetime usage
+
+ - LongevityLifetime: The Small-Object has
+ LongevityLifetime::DieAsSmallObjectParent policy and the Singleton
+ hosting the Small-Object has LongevityLifetime::DieAsSmallObjectChild.
+ The child lifetime has a hard coded SetLongevity lifetime which is
+ shorter than the lifetime of the parent, thus the child dies
+ before the parent.
+
+ - Both Small-Object and Singleton use SingletonWithLongevity policy.
+ The longevity level for the singleton must be lower than that for the
+ Small-Object. This is why the AllocatorSingleton's GetLongevity function
+ returns the highest value.
+
+ - FollowIntoDeath lifetime: The Small-Object has
+ FollowIntoDeath::With<LIFETIME>::AsMasterLiftime
+ policy and the Singleton has
+ FollowIntoDeath::AfterMaster<MASTERSINGLETON>::IsDestroyed policy,
+ where you could choose the LIFETIME.
+
+ - Both Small-Object and Singleton use NoDestroy policy.
+ Since neither is ever destroyed, the destruction order does not matter.
+ Note: you will get memory leaks!
+
+ - The Small-Object has NoDestroy policy but the Singleton has
+ SingletonWithLongevity policy. Note: you will get memory leaks!
+
+
+ You should *not* use NoDestroy for the singleton, and then use
+ SingletonWithLongevity for the Small-Object.
+
+ @par Examples:
+
+ - test/SmallObj/SmallSingleton.cpp
+ - test/Singleton/Dependencies.cpp
+ */
+template
+<
+template <class, class> class ThreadingModel,
+ std::size_t chunkSize,
+ std::size_t maxSmallObjectSize,
+ std::size_t objectAlignSize,
+ template <class> class LifetimePolicy,
+ class MutexPolicy
+ >
+class SmallObjectBase
+{
+
+#if (LOKI_MAX_SMALL_OBJECT_SIZE != 0) && (LOKI_DEFAULT_CHUNK_SIZE != 0) && (LOKI_DEFAULT_OBJECT_ALIGNMENT != 0)
+
+public:
+ /// Defines type of allocator singleton, must be public
+ /// to handle singleton lifetime dependencies.
+ typedef AllocatorSingleton< ThreadingModel, chunkSize,
+ maxSmallObjectSize, objectAlignSize, LifetimePolicy > ObjAllocatorSingleton;
+
+private:
+
+ /// Defines type for thread-safety locking mechanism.
+ typedef ThreadingModel< ObjAllocatorSingleton, MutexPolicy > MyThreadingModel;
+
+ /// Use singleton defined in AllocatorSingleton.
+ typedef typename ObjAllocatorSingleton::MyAllocatorSingleton MyAllocatorSingleton;
+
+public:
+
+ /// Throwing single-object new throws bad_alloc when allocation fails.
+#ifdef _MSC_VER
+ /// @note MSVC complains about non-empty exception specification lists.
+ static void* operator new ( std::size_t size )
+#else
+ static void* operator new ( std::size_t size ) throw ( std::bad_alloc )
+#endif
{
typename MyThreadingModel::Lock lock;
(void)lock; // get rid of warning
- Instance().TrimExcessMemory();
+ return MyAllocatorSingleton::Instance().Allocate( size, true );
}
- template
- <
- template <class, class> class T,
- std::size_t C,
- std::size_t M,
- std::size_t O,
- template <class> class L,
- class X
- >
- bool AllocatorSingleton< T, C, M, O, L, X >::IsCorrupted( void )
+ /// Non-throwing single-object new returns NULL if allocation fails.
+ static void* operator new ( std::size_t size, const std::nothrow_t& ) throw ()
{
typename MyThreadingModel::Lock lock;
(void)lock; // get rid of warning
- return Instance().IsCorrupt();
+ return MyAllocatorSingleton::Instance().Allocate( size, false );
}
- /** This standalone function provides the longevity level for Small-Object
- Allocators which use the Loki::SingletonWithLongevity policy. The
- SingletonWithLongevity class can find this function through argument-
- dependent lookup.
-
- @par Longevity Levels
- No Small-Object Allocator depends on any other Small-Object allocator, so
- this does not need to calculate dependency levels among allocators, and
- it returns just a constant. All allocators must live longer than the
- objects which use the allocators, it must return a longevity level higher
- than any such object.
- */
- template
- <
- template <class, class> class T,
- std::size_t C,
- std::size_t M,
- std::size_t O,
- template <class> class L,
- class X
- >
- inline unsigned int GetLongevity(
- AllocatorSingleton< T, C, M, O, L, X > * )
+ /// Placement single-object new merely calls global placement new.
+ inline static void* operator new ( std::size_t size, void* place )
{
- // Returns highest possible value.
- return 0xFFFFFFFF;
+ return ::operator new( size, place );
}
+ /// Single-object delete.
+ static void operator delete ( void* p, std::size_t size ) throw ()
+ {
+ typename MyThreadingModel::Lock lock;
+ (void)lock; // get rid of warning
+ MyAllocatorSingleton::Instance().Deallocate( p, size );
+ }
- /** @class SmallObjectBase
- @ingroup SmallObjectGroup
- Base class for small object allocation classes.
- The shared implementation of the new and delete operators are here instead
- of being duplicated in both SmallObject or SmallValueObject, later just
- called Small-Objects. This class is not meant to be used directly by clients,
- or derived from by clients. Class has no data members so compilers can
- use Empty-Base-Optimization.
-
- @par ThreadingModel
- This class doesn't support ObjectLevelLockable policy for ThreadingModel.
- The allocator is a singleton, so a per-instance mutex is not necessary.
- Nor is using ObjectLevelLockable recommended with SingletonHolder since
- the SingletonHolder::MakeInstance function requires a mutex that exists
- prior to when the object is created - which is not possible if the mutex
- is inside the object, such as required for ObjectLevelLockable. If you
- attempt to use ObjectLevelLockable, the compiler will emit errors because
- it can't use the default constructor in ObjectLevelLockable. If you need
- a thread-safe allocator, use the ClassLevelLockable policy.
-
- @par Lifetime Policy
-
- The SmallObjectBase template needs a lifetime policy because it owns
- a singleton of SmallObjAllocator which does all the low level functions.
- When using a Small-Object in combination with the SingletonHolder template
- you have to choose two lifetimes, that of the Small-Object and that of
- the singleton. The rule is: The Small-Object lifetime must be greater than
- the lifetime of the singleton hosting the Small-Object. Violating this rule
- results in a crash on exit, because the hosting singleton tries to delete
- the Small-Object which is then already destroyed.
-
- The lifetime policies recommended for use with Small-Objects hosted
- by a SingletonHolder template are
- - LongevityLifetime::DieAsSmallObjectParent / LongevityLifetime::DieAsSmallObjectChild
- - SingletonWithLongevity
- - FollowIntoDeath (not supported by MSVC 7.1)
- - NoDestroy
-
- The default lifetime of Small-Objects is
- LongevityLifetime::DieAsSmallObjectParent to
- insure that memory is not released before a object with the lifetime
- LongevityLifetime::DieAsSmallObjectChild using that
- memory is destroyed. The LongevityLifetime::DieAsSmallObjectParent
- lifetime has the highest possible value of a SetLongevity lifetime, so
- you can use it in combination with your own lifetime not having also
- the highest possible value.
-
- The DefaultLifetime and PhoenixSingleton policies are *not* recommended
- since they can cause the allocator to be destroyed and release memory
- for singletons hosting a object which inherit from either SmallObject
- or SmallValueObject.
-
- @par Lifetime usage
-
- - LongevityLifetime: The Small-Object has
- LongevityLifetime::DieAsSmallObjectParent policy and the Singleton
- hosting the Small-Object has LongevityLifetime::DieAsSmallObjectChild.
- The child lifetime has a hard coded SetLongevity lifetime which is
- shorter than the lifetime of the parent, thus the child dies
- before the parent.
-
- - Both Small-Object and Singleton use SingletonWithLongevity policy.
- The longevity level for the singleton must be lower than that for the
- Small-Object. This is why the AllocatorSingleton's GetLongevity function
- returns the highest value.
-
- - FollowIntoDeath lifetime: The Small-Object has
- FollowIntoDeath::With<LIFETIME>::AsMasterLiftime
- policy and the Singleton has
- FollowIntoDeath::AfterMaster<MASTERSINGLETON>::IsDestroyed policy,
- where you could choose the LIFETIME.
-
- - Both Small-Object and Singleton use NoDestroy policy.
- Since neither is ever destroyed, the destruction order does not matter.
- Note: you will get memory leaks!
-
- - The Small-Object has NoDestroy policy but the Singleton has
- SingletonWithLongevity policy. Note: you will get memory leaks!
-
-
- You should *not* use NoDestroy for the singleton, and then use
- SingletonWithLongevity for the Small-Object.
-
- @par Examples:
-
- - test/SmallObj/SmallSingleton.cpp
- - test/Singleton/Dependencies.cpp
+ /** Non-throwing single-object delete is only called when nothrow
+ new operator is used, and the constructor throws an exception.
*/
- template
- <
- template <class, class> class ThreadingModel,
- std::size_t chunkSize,
- std::size_t maxSmallObjectSize,
- std::size_t objectAlignSize,
- template <class> class LifetimePolicy,
- class MutexPolicy
- >
- class SmallObjectBase
+ static void operator delete ( void* p, const std::nothrow_t& ) throw()
{
+ typename MyThreadingModel::Lock lock;
+ (void)lock; // get rid of warning
+ MyAllocatorSingleton::Instance().Deallocate( p );
+ }
-#if (LOKI_MAX_SMALL_OBJECT_SIZE != 0) && (LOKI_DEFAULT_CHUNK_SIZE != 0) && (LOKI_DEFAULT_OBJECT_ALIGNMENT != 0)
-
- public:
- /// Defines type of allocator singleton, must be public
- /// to handle singleton lifetime dependencies.
- typedef AllocatorSingleton< ThreadingModel, chunkSize,
- maxSmallObjectSize, objectAlignSize, LifetimePolicy > ObjAllocatorSingleton;
-
- private:
-
- /// Defines type for thread-safety locking mechanism.
- typedef ThreadingModel< ObjAllocatorSingleton, MutexPolicy > MyThreadingModel;
+ /// Placement single-object delete merely calls global placement delete.
+ inline static void operator delete ( void* p, void* place )
+ {
+ ::operator delete ( p, place );
+ }
- /// Use singleton defined in AllocatorSingleton.
- typedef typename ObjAllocatorSingleton::MyAllocatorSingleton MyAllocatorSingleton;
-
- public:
+#ifdef LOKI_SMALL_OBJECT_USE_NEW_ARRAY
- /// Throwing single-object new throws bad_alloc when allocation fails.
+ /// Throwing array-object new throws bad_alloc when allocation fails.
#ifdef _MSC_VER
- /// @note MSVC complains about non-empty exception specification lists.
- static void * operator new ( std::size_t size )
+ /// @note MSVC complains about non-empty exception specification lists.
+ static void* operator new [] ( std::size_t size )
#else
- static void * operator new ( std::size_t size ) throw ( std::bad_alloc )
+ static void* operator new [] ( std::size_t size )
+ throw ( std::bad_alloc )
#endif
- {
- typename MyThreadingModel::Lock lock;
- (void)lock; // get rid of warning
- return MyAllocatorSingleton::Instance().Allocate( size, true );
- }
-
- /// Non-throwing single-object new returns NULL if allocation fails.
- static void * operator new ( std::size_t size, const std::nothrow_t & ) throw ()
- {
- typename MyThreadingModel::Lock lock;
- (void)lock; // get rid of warning
- return MyAllocatorSingleton::Instance().Allocate( size, false );
- }
-
- /// Placement single-object new merely calls global placement new.
- inline static void * operator new ( std::size_t size, void * place )
- {
- return ::operator new( size, place );
- }
-
- /// Single-object delete.
- static void operator delete ( void * p, std::size_t size ) throw ()
- {
- typename MyThreadingModel::Lock lock;
- (void)lock; // get rid of warning
- MyAllocatorSingleton::Instance().Deallocate( p, size );
- }
-
- /** Non-throwing single-object delete is only called when nothrow
- new operator is used, and the constructor throws an exception.
- */
- static void operator delete ( void * p, const std::nothrow_t & ) throw()
- {
- typename MyThreadingModel::Lock lock;
- (void)lock; // get rid of warning
- MyAllocatorSingleton::Instance().Deallocate( p );
- }
-
- /// Placement single-object delete merely calls global placement delete.
- inline static void operator delete ( void * p, void * place )
- {
- ::operator delete ( p, place );
- }
+ {
+ typename MyThreadingModel::Lock lock;
+ (void)lock; // get rid of warning
+ return MyAllocatorSingleton::Instance().Allocate( size, true );
+ }
-#ifdef LOKI_SMALL_OBJECT_USE_NEW_ARRAY
+ /// Non-throwing array-object new returns NULL if allocation fails.
+ static void* operator new [] ( std::size_t size,
+ const std::nothrow_t& ) throw ()
+ {
+ typename MyThreadingModel::Lock lock;
+ (void)lock; // get rid of warning
+ return MyAllocatorSingleton::Instance().Allocate( size, false );
+ }
- /// Throwing array-object new throws bad_alloc when allocation fails.
-#ifdef _MSC_VER
- /// @note MSVC complains about non-empty exception specification lists.
- static void * operator new [] ( std::size_t size )
-#else
- static void * operator new [] ( std::size_t size )
- throw ( std::bad_alloc )
-#endif
- {
- typename MyThreadingModel::Lock lock;
- (void)lock; // get rid of warning
- return MyAllocatorSingleton::Instance().Allocate( size, true );
- }
-
- /// Non-throwing array-object new returns NULL if allocation fails.
- static void * operator new [] ( std::size_t size,
- const std::nothrow_t & ) throw ()
- {
- typename MyThreadingModel::Lock lock;
- (void)lock; // get rid of warning
- return MyAllocatorSingleton::Instance().Allocate( size, false );
- }
-
- /// Placement array-object new merely calls global placement new.
- inline static void * operator new [] ( std::size_t size, void * place )
- {
- return ::operator new( size, place );
- }
-
- /// Array-object delete.
- static void operator delete [] ( void * p, std::size_t size ) throw ()
- {
- typename MyThreadingModel::Lock lock;
- (void)lock; // get rid of warning
- MyAllocatorSingleton::Instance().Deallocate( p, size );
- }
-
- /** Non-throwing array-object delete is only called when nothrow
- new operator is used, and the constructor throws an exception.
- */
- static void operator delete [] ( void * p,
- const std::nothrow_t & ) throw()
- {
- typename MyThreadingModel::Lock lock;
- (void)lock; // get rid of warning
- MyAllocatorSingleton::Instance().Deallocate( p );
- }
-
- /// Placement array-object delete merely calls global placement delete.
- inline static void operator delete [] ( void * p, void * place )
- {
- ::operator delete ( p, place );
- }
-#endif // #if use new array functions.
+ /// Placement array-object new merely calls global placement new.
+ inline static void* operator new [] ( std::size_t size, void* place )
+ {
+ return ::operator new( size, place );
+ }
-#endif // #if default template parameters are not zero
+ /// Array-object delete.
+ static void operator delete [] ( void* p, std::size_t size ) throw ()
+ {
+ typename MyThreadingModel::Lock lock;
+ (void)lock; // get rid of warning
+ MyAllocatorSingleton::Instance().Deallocate( p, size );
+ }
- protected:
- inline SmallObjectBase( void ) {}
- inline SmallObjectBase( const SmallObjectBase & ) {}
- inline SmallObjectBase & operator = ( const SmallObjectBase & )
- { return *this; }
- inline ~SmallObjectBase() {}
- }; // end class SmallObjectBase
-
-
- /** @class SmallObject
- @ingroup SmallObjectGroup
- SmallObject Base class for polymorphic small objects, offers fast
- allocations & deallocations. Destructor is virtual and public. Default
- constructor is trivial. Copy-constructor and copy-assignment operator are
- not implemented since polymorphic classes almost always disable those
- operations. Class has no data members so compilers can use
- Empty-Base-Optimization.
+ /** Non-throwing array-object delete is only called when nothrow
+ new operator is used, and the constructor throws an exception.
*/
- template
- <
- template <class, class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL,
- std::size_t chunkSize = LOKI_DEFAULT_CHUNK_SIZE,
- std::size_t maxSmallObjectSize = LOKI_MAX_SMALL_OBJECT_SIZE,
- std::size_t objectAlignSize = LOKI_DEFAULT_OBJECT_ALIGNMENT,
- template <class> class LifetimePolicy = LOKI_DEFAULT_SMALLOBJ_LIFETIME,
- class MutexPolicy = LOKI_DEFAULT_MUTEX
- >
- class SmallObject : public SmallObjectBase< ThreadingModel, chunkSize,
- maxSmallObjectSize, objectAlignSize, LifetimePolicy, MutexPolicy >
+ static void operator delete [] ( void* p,
+ const std::nothrow_t& ) throw()
{
+ typename MyThreadingModel::Lock lock;
+ (void)lock; // get rid of warning
+ MyAllocatorSingleton::Instance().Deallocate( p );
+ }
- public:
- virtual ~SmallObject() {}
- protected:
- inline SmallObject( void ) {}
-
- private:
- /// Copy-constructor is not implemented.
- SmallObject( const SmallObject & );
- /// Copy-assignment operator is not implemented.
- SmallObject & operator = ( const SmallObject & );
- }; // end class SmallObject
-
-
- /** @class SmallValueObject
- @ingroup SmallObjectGroup
- SmallValueObject Base class for small objects with value-type
- semantics - offers fast allocations & deallocations. Destructor is
- non-virtual, inline, and protected to prevent unintentional destruction
- through base class. Default constructor is trivial. Copy-constructor
- and copy-assignment operator are trivial since value-types almost always
- need those operations. Class has no data members so compilers can use
- Empty-Base-Optimization.
- */
- template
- <
- template <class, class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL,
- std::size_t chunkSize = LOKI_DEFAULT_CHUNK_SIZE,
- std::size_t maxSmallObjectSize = LOKI_MAX_SMALL_OBJECT_SIZE,
- std::size_t objectAlignSize = LOKI_DEFAULT_OBJECT_ALIGNMENT,
- template <class> class LifetimePolicy = LOKI_DEFAULT_SMALLOBJ_LIFETIME,
- class MutexPolicy = LOKI_DEFAULT_MUTEX
- >
- class SmallValueObject : public SmallObjectBase< ThreadingModel, chunkSize,
- maxSmallObjectSize, objectAlignSize, LifetimePolicy, MutexPolicy >
+ /// Placement array-object delete merely calls global placement delete.
+ inline static void operator delete [] ( void* p, void* place )
{
- protected:
- inline SmallValueObject( void ) {}
- inline SmallValueObject( const SmallValueObject & ) {}
- inline SmallValueObject & operator = ( const SmallValueObject & )
- { return *this; }
- inline ~SmallValueObject() {}
- }; // end class SmallValueObject
+ ::operator delete ( p, place );
+ }
+#endif // #if use new array functions.
+
+#endif // #if default template parameters are not zero
+
+protected:
+ inline SmallObjectBase( void ) {}
+ inline SmallObjectBase( const SmallObjectBase& ) {}
+ inline SmallObjectBase& operator = ( const SmallObjectBase& )
+ { return *this; }
+ inline ~SmallObjectBase() {}
+}; // end class SmallObjectBase
+
+
+/** @class SmallObject
+ @ingroup SmallObjectGroup
+ SmallObject Base class for polymorphic small objects, offers fast
+ allocations & deallocations. Destructor is virtual and public. Default
+ constructor is trivial. Copy-constructor and copy-assignment operator are
+ not implemented since polymorphic classes almost always disable those
+ operations. Class has no data members so compilers can use
+ Empty-Base-Optimization.
+ */
+template
+<
+template <class, class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL,
+ std::size_t chunkSize = LOKI_DEFAULT_CHUNK_SIZE,
+ std::size_t maxSmallObjectSize = LOKI_MAX_SMALL_OBJECT_SIZE,
+ std::size_t objectAlignSize = LOKI_DEFAULT_OBJECT_ALIGNMENT,
+ template <class> class LifetimePolicy = LOKI_DEFAULT_SMALLOBJ_LIFETIME,
+ class MutexPolicy = LOKI_DEFAULT_MUTEX
+ >
+class SmallObject : public SmallObjectBase< ThreadingModel, chunkSize,
+ maxSmallObjectSize, objectAlignSize, LifetimePolicy, MutexPolicy >
+{
+
+public:
+ virtual ~SmallObject() {}
+protected:
+ inline SmallObject( void ) {}
+
+private:
+ /// Copy-constructor is not implemented.
+ SmallObject( const SmallObject& );
+ /// Copy-assignment operator is not implemented.
+ SmallObject& operator = ( const SmallObject& );
+}; // end class SmallObject
+
+
+/** @class SmallValueObject
+ @ingroup SmallObjectGroup
+ SmallValueObject Base class for small objects with value-type
+ semantics - offers fast allocations & deallocations. Destructor is
+ non-virtual, inline, and protected to prevent unintentional destruction
+ through base class. Default constructor is trivial. Copy-constructor
+ and copy-assignment operator are trivial since value-types almost always
+ need those operations. Class has no data members so compilers can use
+ Empty-Base-Optimization.
+ */
+template
+<
+template <class, class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL,
+ std::size_t chunkSize = LOKI_DEFAULT_CHUNK_SIZE,
+ std::size_t maxSmallObjectSize = LOKI_MAX_SMALL_OBJECT_SIZE,
+ std::size_t objectAlignSize = LOKI_DEFAULT_OBJECT_ALIGNMENT,
+ template <class> class LifetimePolicy = LOKI_DEFAULT_SMALLOBJ_LIFETIME,
+ class MutexPolicy = LOKI_DEFAULT_MUTEX
+ >
+class SmallValueObject : public SmallObjectBase< ThreadingModel, chunkSize,
+ maxSmallObjectSize, objectAlignSize, LifetimePolicy, MutexPolicy >
+{
+protected:
+ inline SmallValueObject( void ) {}
+ inline SmallValueObject( const SmallValueObject& ) {}
+ inline SmallValueObject& operator = ( const SmallValueObject& )
+ { return *this; }
+ inline ~SmallValueObject() {}
+}; // end class SmallValueObject
} // namespace Loki
diff --git a/shared/loki/SmartPtr.h b/shared/loki/SmartPtr.h
index df548553..fb14258e 100644
--- a/shared/loki/SmartPtr.h
+++ b/shared/loki/SmartPtr.h
@@ -67,78 +67,78 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
- template <class T>
- class HeapStorage
- {
- public:
- typedef T* StoredType; /// the type of the pointee_ object
- typedef T* InitPointerType; /// type used to declare OwnershipPolicy type.
- typedef T* PointerType; /// type returned by operator->
- typedef T& ReferenceType; /// type returned by operator*
+template <class T>
+class HeapStorage
+{
+public:
+ typedef T* StoredType; /// the type of the pointee_ object
+ typedef T* InitPointerType; /// type used to declare OwnershipPolicy type.
+ typedef T* PointerType; /// type returned by operator->
+ typedef T& ReferenceType; /// type returned by operator*
- HeapStorage() : pointee_(Default())
- {}
+ HeapStorage() : pointee_(Default())
+ {}
- // The storage policy doesn't initialize the stored pointer
- // which will be initialized by the OwnershipPolicy's Clone fn
- HeapStorage(const HeapStorage&) : pointee_(0)
- {}
+ // The storage policy doesn't initialize the stored pointer
+ // which will be initialized by the OwnershipPolicy's Clone fn
+ HeapStorage(const HeapStorage&) : pointee_(0)
+ {}
- template <class U>
- HeapStorage(const HeapStorage<U>&) : pointee_(0)
- {}
+ template <class U>
+ HeapStorage(const HeapStorage<U>&) : pointee_(0)
+ {}
- HeapStorage(const StoredType& p) : pointee_(p) {}
+ HeapStorage(const StoredType& p) : pointee_(p) {}
- PointerType operator->() const { return pointee_; }
+ PointerType operator->() const { return pointee_; }
- ReferenceType operator*() const { return *pointee_; }
+ ReferenceType operator*() const { return *pointee_; }
- void Swap(HeapStorage& rhs)
- { std::swap(pointee_, rhs.pointee_); }
+ void Swap(HeapStorage& rhs)
+ { std::swap(pointee_, rhs.pointee_); }
- // Accessors
- template <class F>
- friend typename HeapStorage<F>::PointerType GetImpl(const HeapStorage<F>& sp);
+ // Accessors
+ template <class F>
+ friend typename HeapStorage<F>::PointerType GetImpl(const HeapStorage<F>& sp);
- template <class F>
- friend const typename HeapStorage<F>::StoredType& GetImplRef(const HeapStorage<F>& sp);
+ template <class F>
+ friend const typename HeapStorage<F>::StoredType& GetImplRef(const HeapStorage<F>& sp);
- template <class F>
- friend typename HeapStorage<F>::StoredType& GetImplRef(HeapStorage<F>& sp);
+ template <class F>
+ friend typename HeapStorage<F>::StoredType& GetImplRef(HeapStorage<F>& sp);
- protected:
- // Destroys the data stored
- // (Destruction might be taken over by the OwnershipPolicy)
- void Destroy()
+protected:
+ // Destroys the data stored
+ // (Destruction might be taken over by the OwnershipPolicy)
+ void Destroy()
+ {
+ if ( 0 != pointee_ )
{
- if ( 0 != pointee_ )
- {
- pointee_->~T();
- ::free( pointee_ );
- }
+ pointee_->~T();
+ ::free( pointee_ );
}
+ }
- // Default value to initialize the pointer
- static StoredType Default()
- { return 0; }
+ // Default value to initialize the pointer
+ static StoredType Default()
+ { return 0; }
- private:
- // Data
- StoredType pointee_;
- };
+private:
+ // Data
+ StoredType pointee_;
+};
- template <class T>
- inline typename HeapStorage<T>::PointerType GetImpl(const HeapStorage<T>& sp)
- { return sp.pointee_; }
+template <class T>
+inline typename HeapStorage<T>::PointerType GetImpl(const HeapStorage<T>& sp)
+{ return sp.pointee_; }
- template <class T>
- inline const typename HeapStorage<T>::StoredType& GetImplRef(const HeapStorage<T>& sp)
- { return sp.pointee_; }
+template <class T>
+inline const typename HeapStorage<T>::StoredType& GetImplRef(const HeapStorage<T>& sp)
+{ return sp.pointee_; }
- template <class T>
- inline typename HeapStorage<T>::StoredType& GetImplRef(HeapStorage<T>& sp)
- { return sp.pointee_; }
+template <class T>
+inline typename HeapStorage<T>::StoredType& GetImplRef(HeapStorage<T>& sp)
+{ return sp.pointee_; }
////////////////////////////////////////////////////////////////////////////////
@@ -149,77 +149,77 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
- template <class T>
- class DefaultSPStorage
- {
- public:
- typedef T* StoredType; // the type of the pointee_ object
- typedef T* InitPointerType; /// type used to declare OwnershipPolicy type.
- typedef T* PointerType; // type returned by operator->
- typedef T& ReferenceType; // type returned by operator*
+template <class T>
+class DefaultSPStorage
+{
+public:
+ typedef T* StoredType; // the type of the pointee_ object
+ typedef T* InitPointerType; /// type used to declare OwnershipPolicy type.
+ typedef T* PointerType; // type returned by operator->
+ typedef T& ReferenceType; // type returned by operator*
- DefaultSPStorage() : pointee_(Default())
- {}
+ DefaultSPStorage() : pointee_(Default())
+ {}
- // The storage policy doesn't initialize the stored pointer
- // which will be initialized by the OwnershipPolicy's Clone fn
- DefaultSPStorage(const DefaultSPStorage&) : pointee_(0)
- {}
+ // The storage policy doesn't initialize the stored pointer
+ // which will be initialized by the OwnershipPolicy's Clone fn
+ DefaultSPStorage(const DefaultSPStorage&) : pointee_(0)
+ {}
- template <class U>
- DefaultSPStorage(const DefaultSPStorage<U>&) : pointee_(0)
- {}
+ template <class U>
+ DefaultSPStorage(const DefaultSPStorage<U>&) : pointee_(0)
+ {}
- DefaultSPStorage(const StoredType& p) : pointee_(p) {}
+ DefaultSPStorage(const StoredType& p) : pointee_(p) {}
- PointerType operator->() const { return pointee_; }
+ PointerType operator->() const { return pointee_; }
- ReferenceType operator*() const { return *pointee_; }
+ ReferenceType operator*() const { return *pointee_; }
- void Swap(DefaultSPStorage& rhs)
- { std::swap(pointee_, rhs.pointee_); }
+ void Swap(DefaultSPStorage& rhs)
+ { std::swap(pointee_, rhs.pointee_); }
- // Accessors
- template <class F>
- friend typename DefaultSPStorage<F>::PointerType GetImpl(const DefaultSPStorage<F>& sp);
+ // Accessors
+ template <class F>
+ friend typename DefaultSPStorage<F>::PointerType GetImpl(const DefaultSPStorage<F>& sp);
- template <class F>
- friend const typename DefaultSPStorage<F>::StoredType& GetImplRef(const DefaultSPStorage<F>& sp);
+ template <class F>
+ friend const typename DefaultSPStorage<F>::StoredType& GetImplRef(const DefaultSPStorage<F>& sp);
- template <class F>
- friend typename DefaultSPStorage<F>::StoredType& GetImplRef(DefaultSPStorage<F>& sp);
+ template <class F>
+ friend typename DefaultSPStorage<F>::StoredType& GetImplRef(DefaultSPStorage<F>& sp);
- protected:
- // Destroys the data stored
- // (Destruction might be taken over by the OwnershipPolicy)
- //
- // If your compiler gives you a warning in this area while
- // compiling the tests, it is on purpose, please ignore it.
- void Destroy()
- {
- delete pointee_;
- }
+protected:
+ // Destroys the data stored
+ // (Destruction might be taken over by the OwnershipPolicy)
+ //
+ // If your compiler gives you a warning in this area while
+ // compiling the tests, it is on purpose, please ignore it.
+ void Destroy()
+ {
+ delete pointee_;
+ }
- // Default value to initialize the pointer
- static StoredType Default()
- { return 0; }
+ // Default value to initialize the pointer
+ static StoredType Default()
+ { return 0; }
- private:
- // Data
- StoredType pointee_;
- };
+private:
+ // Data
+ StoredType pointee_;
+};
- template <class T>
- inline typename DefaultSPStorage<T>::PointerType GetImpl(const DefaultSPStorage<T>& sp)
- { return sp.pointee_; }
+template <class T>
+inline typename DefaultSPStorage<T>::PointerType GetImpl(const DefaultSPStorage<T>& sp)
+{ return sp.pointee_; }
- template <class T>
- inline const typename DefaultSPStorage<T>::StoredType& GetImplRef(const DefaultSPStorage<T>& sp)
- { return sp.pointee_; }
+template <class T>
+inline const typename DefaultSPStorage<T>::StoredType& GetImplRef(const DefaultSPStorage<T>& sp)
+{ return sp.pointee_; }
- template <class T>
- inline typename DefaultSPStorage<T>::StoredType& GetImplRef(DefaultSPStorage<T>& sp)
- { return sp.pointee_; }
+template <class T>
+inline typename DefaultSPStorage<T>::StoredType& GetImplRef(DefaultSPStorage<T>& sp)
+{ return sp.pointee_; }
////////////////////////////////////////////////////////////////////////////////
@@ -245,107 +245,107 @@ namespace Loki
/// LockedStorage which calls other functions to lock the object.
////////////////////////////////////////////////////////////////////////////////
- template <class T>
- class Locker
+template <class T>
+class Locker
+{
+public:
+ Locker( const T* p ) : pointee_( const_cast< T* >( p ) )
{
- public:
- Locker( const T * p ) : pointee_( const_cast< T * >( p ) )
- {
- if ( pointee_ != 0 )
- pointee_->Lock();
- }
+ if ( pointee_ != 0 )
+ pointee_->Lock();
+ }
- ~Locker( void )
- {
- if ( pointee_ != 0 )
- pointee_->Unlock();
- }
+ ~Locker( void )
+ {
+ if ( pointee_ != 0 )
+ pointee_->Unlock();
+ }
- operator T * ()
- {
- return pointee_;
- }
+ operator T* ()
+ {
+ return pointee_;
+ }
- T * operator->()
- {
- return pointee_;
- }
+ T* operator->()
+ {
+ return pointee_;
+ }
- private:
- Locker( void );
- Locker & operator = ( const Locker & );
- T * pointee_;
- };
+private:
+ Locker( void );
+ Locker& operator = ( const Locker& );
+ T* pointee_;
+};
- template <class T>
- class LockedStorage
- {
- public:
+template <class T>
+class LockedStorage
+{
+public:
- typedef T* StoredType; /// the type of the pointee_ object
- typedef T* InitPointerType; /// type used to declare OwnershipPolicy type.
- typedef Locker< T > PointerType; /// type returned by operator->
- typedef T& ReferenceType; /// type returned by operator*
+ typedef T* StoredType; /// the type of the pointee_ object
+ typedef T* InitPointerType; /// type used to declare OwnershipPolicy type.
+ typedef Locker< T > PointerType; /// type returned by operator->
+ typedef T& ReferenceType; /// type returned by operator*
- LockedStorage() : pointee_( Default() ) {}
+ LockedStorage() : pointee_( Default() ) {}
- ~LockedStorage( void ) {}
+ ~LockedStorage( void ) {}
- LockedStorage( const LockedStorage&) : pointee_( 0 ) {}
+ LockedStorage( const LockedStorage&) : pointee_( 0 ) {}
- LockedStorage( const StoredType & p ) : pointee_( p ) {}
+ LockedStorage( const StoredType& p ) : pointee_( p ) {}
- PointerType operator->()
- {
- return Locker< T >( pointee_ );
- }
+ PointerType operator->()
+ {
+ return Locker< T >( pointee_ );
+ }
- void Swap(LockedStorage& rhs)
- {
- std::swap( pointee_, rhs.pointee_ );
- }
+ void Swap(LockedStorage& rhs)
+ {
+ std::swap( pointee_, rhs.pointee_ );
+ }
- // Accessors
- template <class F>
- friend typename LockedStorage<F>::InitPointerType GetImpl(const LockedStorage<F>& sp);
+ // Accessors
+ template <class F>
+ friend typename LockedStorage<F>::InitPointerType GetImpl(const LockedStorage<F>& sp);
- template <class F>
- friend const typename LockedStorage<F>::StoredType& GetImplRef(const LockedStorage<F>& sp);
+ template <class F>
+ friend const typename LockedStorage<F>::StoredType& GetImplRef(const LockedStorage<F>& sp);
- template <class F>
- friend typename LockedStorage<F>::StoredType& GetImplRef(LockedStorage<F>& sp);
+ template <class F>
+ friend typename LockedStorage<F>::StoredType& GetImplRef(LockedStorage<F>& sp);
- protected:
- // Destroys the data stored
- // (Destruction might be taken over by the OwnershipPolicy)
- void Destroy()
- {
- delete pointee_;
- }
+protected:
+ // Destroys the data stored
+ // (Destruction might be taken over by the OwnershipPolicy)
+ void Destroy()
+ {
+ delete pointee_;
+ }
- // Default value to initialize the pointer
- static StoredType Default()
- { return 0; }
+ // Default value to initialize the pointer
+ static StoredType Default()
+ { return 0; }
- private:
- /// Dereference operator is not implemented.
- ReferenceType operator*();
+private:
+ /// Dereference operator is not implemented.
+ ReferenceType operator*();
- // Data
- StoredType pointee_;
- };
+ // Data
+ StoredType pointee_;
+};
- template <class T>
- inline typename LockedStorage<T>::InitPointerType GetImpl(const LockedStorage<T>& sp)
- { return sp.pointee_; }
+template <class T>
+inline typename LockedStorage<T>::InitPointerType GetImpl(const LockedStorage<T>& sp)
+{ return sp.pointee_; }
- template <class T>
- inline const typename LockedStorage<T>::StoredType& GetImplRef(const LockedStorage<T>& sp)
- { return sp.pointee_; }
+template <class T>
+inline const typename LockedStorage<T>::StoredType& GetImplRef(const LockedStorage<T>& sp)
+{ return sp.pointee_; }
- template <class T>
- inline typename LockedStorage<T>::StoredType& GetImplRef(LockedStorage<T>& sp)
- { return sp.pointee_; }
+template <class T>
+inline typename LockedStorage<T>::StoredType& GetImplRef(LockedStorage<T>& sp)
+{ return sp.pointee_; }
////////////////////////////////////////////////////////////////////////////////
@@ -356,72 +356,72 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
- template <class T>
- class ArrayStorage
- {
- public:
- typedef T* StoredType; // the type of the pointee_ object
- typedef T* InitPointerType; /// type used to declare OwnershipPolicy type.
- typedef T* PointerType; // type returned by operator->
- typedef T& ReferenceType; // type returned by operator*
+template <class T>
+class ArrayStorage
+{
+public:
+ typedef T* StoredType; // the type of the pointee_ object
+ typedef T* InitPointerType; /// type used to declare OwnershipPolicy type.
+ typedef T* PointerType; // type returned by operator->
+ typedef T& ReferenceType; // type returned by operator*
- ArrayStorage() : pointee_(Default())
- {}
+ ArrayStorage() : pointee_(Default())
+ {}
- // The storage policy doesn't initialize the stored pointer
- // which will be initialized by the OwnershipPolicy's Clone fn
- ArrayStorage(const ArrayStorage&) : pointee_(0)
- {}
+ // The storage policy doesn't initialize the stored pointer
+ // which will be initialized by the OwnershipPolicy's Clone fn
+ ArrayStorage(const ArrayStorage&) : pointee_(0)
+ {}
- template <class U>
- ArrayStorage(const ArrayStorage<U>&) : pointee_(0)
- {}
+ template <class U>
+ ArrayStorage(const ArrayStorage<U>&) : pointee_(0)
+ {}
- ArrayStorage(const StoredType& p) : pointee_(p) {}
+ ArrayStorage(const StoredType& p) : pointee_(p) {}
- PointerType operator->() const { return pointee_; }
+ PointerType operator->() const { return pointee_; }
- ReferenceType operator*() const { return *pointee_; }
+ ReferenceType operator*() const { return *pointee_; }
- void Swap(ArrayStorage& rhs)
- { std::swap(pointee_, rhs.pointee_); }
+ void Swap(ArrayStorage& rhs)
+ { std::swap(pointee_, rhs.pointee_); }
- // Accessors
- template <class F>
- friend typename ArrayStorage<F>::PointerType GetImpl(const ArrayStorage<F>& sp);
+ // Accessors
+ template <class F>
+ friend typename ArrayStorage<F>::PointerType GetImpl(const ArrayStorage<F>& sp);
- template <class F>
- friend const typename ArrayStorage<F>::StoredType& GetImplRef(const ArrayStorage<F>& sp);
+ template <class F>
+ friend const typename ArrayStorage<F>::StoredType& GetImplRef(const ArrayStorage<F>& sp);
- template <class F>
- friend typename ArrayStorage<F>::StoredType& GetImplRef(ArrayStorage<F>& sp);
+ template <class F>
+ friend typename ArrayStorage<F>::StoredType& GetImplRef(ArrayStorage<F>& sp);
- protected:
- // Destroys the data stored
- // (Destruction might be taken over by the OwnershipPolicy)
- void Destroy()
- { delete [] pointee_; }
+protected:
+ // Destroys the data stored
+ // (Destruction might be taken over by the OwnershipPolicy)
+ void Destroy()
+ { delete [] pointee_; }
- // Default value to initialize the pointer
- static StoredType Default()
- { return 0; }
+ // Default value to initialize the pointer
+ static StoredType Default()
+ { return 0; }
- private:
- // Data
- StoredType pointee_;
- };
+private:
+ // Data
+ StoredType pointee_;
+};
- template <class T>
- inline typename ArrayStorage<T>::PointerType GetImpl(const ArrayStorage<T>& sp)
- { return sp.pointee_; }
+template <class T>
+inline typename ArrayStorage<T>::PointerType GetImpl(const ArrayStorage<T>& sp)
+{ return sp.pointee_; }
- template <class T>
- inline const typename ArrayStorage<T>::StoredType& GetImplRef(const ArrayStorage<T>& sp)
- { return sp.pointee_; }
+template <class T>
+inline const typename ArrayStorage<T>::StoredType& GetImplRef(const ArrayStorage<T>& sp)
+{ return sp.pointee_; }
- template <class T>
- inline typename ArrayStorage<T>::StoredType& GetImplRef(ArrayStorage<T>& sp)
- { return sp.pointee_; }
+template <class T>
+inline typename ArrayStorage<T>::StoredType& GetImplRef(ArrayStorage<T>& sp)
+{ return sp.pointee_; }
////////////////////////////////////////////////////////////////////////////////
@@ -432,54 +432,54 @@ namespace Loki
/// Provides a classic external reference counting implementation
////////////////////////////////////////////////////////////////////////////////
- template <class P>
- class RefCounted
+template <class P>
+class RefCounted
+{
+public:
+ RefCounted()
+ : pCount_(static_cast<uintptr_t*>(
+ SmallObject<>::operator new(sizeof(uintptr_t))))
{
- public:
- RefCounted()
- : pCount_(static_cast<uintptr_t*>(
- SmallObject<>::operator new(sizeof(uintptr_t))))
- {
- assert(pCount_!=0);
- *pCount_ = 1;
- }
+ assert(pCount_!=0);
+ *pCount_ = 1;
+ }
- RefCounted(const RefCounted& rhs)
+ RefCounted(const RefCounted& rhs)
: pCount_(rhs.pCount_)
- {}
+ {}
- // MWCW lacks template friends, hence the following kludge
- template <typename P1>
- RefCounted(const RefCounted<P1>& rhs)
+ // MWCW lacks template friends, hence the following kludge
+ template <typename P1>
+ RefCounted(const RefCounted<P1>& rhs)
: pCount_(reinterpret_cast<const RefCounted&>(rhs).pCount_)
- {}
+ {}
- P Clone(const P& val)
- {
- ++*pCount_;
- return val;
- }
+ P Clone(const P& val)
+ {
+ ++*pCount_;
+ return val;
+ }
- bool Release(const P&)
+ bool Release(const P&)
+ {
+ if (!--*pCount_)
{
- if (!--*pCount_)
- {
- SmallObject<>::operator delete(pCount_, sizeof(uintptr_t));
- pCount_ = NULL;
- return true;
- }
- return false;
+ SmallObject<>::operator delete(pCount_, sizeof(uintptr_t));
+ pCount_ = NULL;
+ return true;
}
+ return false;
+ }
- void Swap(RefCounted& rhs)
- { std::swap(pCount_, rhs.pCount_); }
+ void Swap(RefCounted& rhs)
+ { std::swap(pCount_, rhs.pCount_); }
- enum { destructiveCopy = false };
+ enum { destructiveCopy = false };
- private:
- // Data
- uintptr_t* pCount_;
- };
+private:
+ // Data
+ uintptr_t* pCount_;
+};
////////////////////////////////////////////////////////////////////////////////
/// \struct RefCountedMT
@@ -500,68 +500,68 @@ namespace Loki
/// fixed at a higher design level, and no change to this class could fix it.
////////////////////////////////////////////////////////////////////////////////
- template <template <class, class> class ThreadingModel,
- class MX = LOKI_DEFAULT_MUTEX >
- struct RefCountedMTAdj
+template <template <class, class> class ThreadingModel,
+ class MX = LOKI_DEFAULT_MUTEX >
+struct RefCountedMTAdj
+{
+ template <class P>
+ class RefCountedMT : public ThreadingModel< RefCountedMT<P>, MX >
{
- template <class P>
- class RefCountedMT : public ThreadingModel< RefCountedMT<P>, MX >
- {
- typedef ThreadingModel< RefCountedMT<P>, MX > base_type;
- typedef typename base_type::IntType CountType;
- typedef volatile CountType *CountPtrType;
+ typedef ThreadingModel< RefCountedMT<P>, MX > base_type;
+ typedef typename base_type::IntType CountType;
+ typedef volatile CountType* CountPtrType;
- public:
- RefCountedMT()
- {
- pCount_ = static_cast<CountPtrType>(
- SmallObject<LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL>::operator new(
- sizeof(*pCount_)));
- assert(pCount_);
- //*pCount_ = 1;
- ThreadingModel<RefCountedMT, MX>::AtomicAssign(*pCount_, 1);
- }
+ public:
+ RefCountedMT()
+ {
+ pCount_ = static_cast<CountPtrType>(
+ SmallObject<LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL>::operator new(
+ sizeof(*pCount_)));
+ assert(pCount_);
+ //*pCount_ = 1;
+ ThreadingModel<RefCountedMT, MX>::AtomicAssign(*pCount_, 1);
+ }
- RefCountedMT(const RefCountedMT& rhs)
+ RefCountedMT(const RefCountedMT& rhs)
: pCount_(rhs.pCount_)
- {}
+ {}
- //MWCW lacks template friends, hence the following kludge
- template <typename P1>
- RefCountedMT(const RefCountedMT<P1>& rhs)
+ //MWCW lacks template friends, hence the following kludge
+ template <typename P1>
+ RefCountedMT(const RefCountedMT<P1>& rhs)
: pCount_(reinterpret_cast<const RefCountedMT<P>&>(rhs).pCount_)
- {}
+ {}
- P Clone(const P& val)
- {
- ThreadingModel<RefCountedMT, MX>::AtomicIncrement(*pCount_);
- return val;
- }
+ P Clone(const P& val)
+ {
+ ThreadingModel<RefCountedMT, MX>::AtomicIncrement(*pCount_);
+ return val;
+ }
- bool Release(const P&)
+ bool Release(const P&)
+ {
+ bool isZero = false;
+ ThreadingModel< RefCountedMT, MX >::AtomicDecrement( *pCount_, 0, isZero );
+ if ( isZero )
{
- bool isZero = false;
- ThreadingModel< RefCountedMT, MX >::AtomicDecrement( *pCount_, 0, isZero );
- if ( isZero )
- {
- SmallObject<LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL>::operator delete(
- const_cast<CountType *>(pCount_),
- sizeof(*pCount_));
- return true;
- }
- return false;
+ SmallObject<LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL>::operator delete(
+ const_cast<CountType*>(pCount_),
+ sizeof(*pCount_));
+ return true;
}
+ return false;
+ }
- void Swap(RefCountedMT& rhs)
- { std::swap(pCount_, rhs.pCount_); }
+ void Swap(RefCountedMT& rhs)
+ { std::swap(pCount_, rhs.pCount_); }
- enum { destructiveCopy = false };
+ enum { destructiveCopy = false };
- private:
- // Data
- CountPtrType pCount_;
- };
+ private:
+ // Data
+ CountPtrType pCount_;
};
+};
////////////////////////////////////////////////////////////////////////////////
/// \class COMRefCounted
@@ -571,36 +571,36 @@ namespace Loki
/// Adapts COM intrusive reference counting to OwnershipPolicy-specific syntax
////////////////////////////////////////////////////////////////////////////////
- template <class P>
- class COMRefCounted
- {
- public:
- COMRefCounted()
- {}
+template <class P>
+class COMRefCounted
+{
+public:
+ COMRefCounted()
+ {}
- template <class U>
- COMRefCounted(const COMRefCounted<U>&)
- {}
+ template <class U>
+ COMRefCounted(const COMRefCounted<U>&)
+ {}
- static P Clone(const P& val)
- {
- if(val!=0)
- val->AddRef();
- return val;
- }
+ static P Clone(const P& val)
+ {
+ if(val!=0)
+ val->AddRef();
+ return val;
+ }
- static bool Release(const P& val)
- {
- if(val!=0)
- val->Release();
- return false;
- }
+ static bool Release(const P& val)
+ {
+ if(val!=0)
+ val->Release();
+ return false;
+ }
- enum { destructiveCopy = false };
+ enum { destructiveCopy = false };
- static void Swap(COMRefCounted&)
- {}
- };
+ static void Swap(COMRefCounted&)
+ {}
+};
////////////////////////////////////////////////////////////////////////////////
/// \struct DeepCopy
@@ -611,27 +611,27 @@ namespace Loki
/// function of the pointee type
////////////////////////////////////////////////////////////////////////////////
- template <class P>
- struct DeepCopy
- {
- DeepCopy()
- {}
+template <class P>
+struct DeepCopy
+{
+ DeepCopy()
+ {}
- template <class P1>
- DeepCopy(const DeepCopy<P1>&)
- {}
+ template <class P1>
+ DeepCopy(const DeepCopy<P1>&)
+ {}
- static P Clone(const P& val)
- { return val->Clone(); }
+ static P Clone(const P& val)
+ { return val->Clone(); }
- static bool Release(const P&)
- { return true; }
+ static bool Release(const P&)
+ { return true; }
- static void Swap(DeepCopy&)
- {}
+ static void Swap(DeepCopy&)
+ {}
- enum { destructiveCopy = false };
- };
+ enum { destructiveCopy = false };
+};
////////////////////////////////////////////////////////////////////////////////
/// \class RefLinked
@@ -641,59 +641,59 @@ namespace Loki
/// Implements reference linking
////////////////////////////////////////////////////////////////////////////////
- namespace Private
- {
- class LOKI_EXPORT RefLinkedBase
- {
- public:
- RefLinkedBase()
- { prev_ = next_ = this; }
+namespace Private
+{
+class LOKI_EXPORT RefLinkedBase
+{
+public:
+ RefLinkedBase()
+ { prev_ = next_ = this; }
- RefLinkedBase(const RefLinkedBase& rhs);
+ RefLinkedBase(const RefLinkedBase& rhs);
- bool Release();
+ bool Release();
- void Swap(RefLinkedBase& rhs);
+ void Swap(RefLinkedBase& rhs);
- bool Merge( RefLinkedBase & rhs );
+ bool Merge( RefLinkedBase& rhs );
- enum { destructiveCopy = false };
+ enum { destructiveCopy = false };
- private:
- static unsigned int CountPrevCycle( const RefLinkedBase * pThis );
- static unsigned int CountNextCycle( const RefLinkedBase * pThis );
- bool HasPrevNode( const RefLinkedBase * p ) const;
- bool HasNextNode( const RefLinkedBase * p ) const;
+private:
+ static unsigned int CountPrevCycle( const RefLinkedBase* pThis );
+ static unsigned int CountNextCycle( const RefLinkedBase* pThis );
+ bool HasPrevNode( const RefLinkedBase* p ) const;
+ bool HasNextNode( const RefLinkedBase* p ) const;
- mutable const RefLinkedBase* prev_;
- mutable const RefLinkedBase* next_;
- };
- }
+ mutable const RefLinkedBase* prev_;
+ mutable const RefLinkedBase* next_;
+};
+}
- template <class P>
- class RefLinked : public Private::RefLinkedBase
- {
- public:
- RefLinked()
- {}
+template <class P>
+class RefLinked : public Private::RefLinkedBase
+{
+public:
+ RefLinked()
+ {}
- template <class P1>
- RefLinked(const RefLinked<P1>& rhs)
+ template <class P1>
+ RefLinked(const RefLinked<P1>& rhs)
: Private::RefLinkedBase(rhs)
- {}
+ {}
- static P Clone(const P& val)
- { return val; }
+ static P Clone(const P& val)
+ { return val; }
- bool Release(const P&)
- { return Private::RefLinkedBase::Release(); }
+ bool Release(const P&)
+ { return Private::RefLinkedBase::Release(); }
- template < class P1 >
- bool Merge( RefLinked< P1 > & rhs )
- {
- return Private::RefLinkedBase::Merge( rhs );
- }
- };
+ template < class P1 >
+ bool Merge( RefLinked< P1 > & rhs )
+ {
+ return Private::RefLinkedBase::Merge( rhs );
+ }
+};
////////////////////////////////////////////////////////////////////////////////
/// \class DestructiveCopy
@@ -703,33 +703,33 @@ namespace Loki
/// Implements destructive copy semantics (a la std::auto_ptr)
////////////////////////////////////////////////////////////////////////////////
- template <class P>
- class DestructiveCopy
- {
- public:
- DestructiveCopy()
- {}
+template <class P>
+class DestructiveCopy
+{
+public:
+ DestructiveCopy()
+ {}
- template <class P1>
- DestructiveCopy(const DestructiveCopy<P1>&)
- {}
+ template <class P1>
+ DestructiveCopy(const DestructiveCopy<P1>&)
+ {}
- template <class P1>
- static P Clone(P1& val)
- {
- P result(val);
- val = P1();
- return result;
- }
+ template <class P1>
+ static P Clone(P1& val)
+ {
+ P result(val);
+ val = P1();
+ return result;
+ }
- static bool Release(const P&)
- { return true; }
+ static bool Release(const P&)
+ { return true; }
- static void Swap(DestructiveCopy&)
- {}
+ static void Swap(DestructiveCopy&)
+ {}
- enum { destructiveCopy = true };
- };
+ enum { destructiveCopy = true };
+};
////////////////////////////////////////////////////////////////////////////////
/// \class NoCopy
@@ -739,33 +739,33 @@ namespace Loki
/// Implements a policy that doesn't allow copying objects
////////////////////////////////////////////////////////////////////////////////
- template <class P>
- class NoCopy
- {
- public:
- NoCopy()
- {}
+template <class P>
+class NoCopy
+{
+public:
+ NoCopy()
+ {}
- template <class P1>
- NoCopy(const NoCopy<P1>&)
- {}
+ template <class P1>
+ NoCopy(const NoCopy<P1>&)
+ {}
- static P Clone(const P&)
- {
- // Make it depended on template parameter
- static const bool DependedFalse = sizeof(P*) == 0;
+ static P Clone(const P&)
+ {
+ // Make it depended on template parameter
+ static const bool DependedFalse = sizeof(P*) == 0;
- LOKI_STATIC_CHECK(DependedFalse, This_Policy_Disallows_Value_Copying);
- }
+ LOKI_STATIC_CHECK(DependedFalse, This_Policy_Disallows_Value_Copying);
+ }
- static bool Release(const P&)
- { return true; }
+ static bool Release(const P&)
+ { return true; }
- static void Swap(NoCopy&)
- {}
+ static void Swap(NoCopy&)
+ {}
- enum { destructiveCopy = false };
- };
+ enum { destructiveCopy = false };
+};
////////////////////////////////////////////////////////////////////////////////
/// \struct AllowConversion
@@ -775,13 +775,13 @@ namespace Loki
/// Allows implicit conversion from SmartPtr to the pointee type
////////////////////////////////////////////////////////////////////////////////
- struct AllowConversion
- {
- enum { allow = true };
+struct AllowConversion
+{
+ enum { allow = true };
- void Swap(AllowConversion&)
- {}
- };
+ void Swap(AllowConversion&)
+ {}
+};
////////////////////////////////////////////////////////////////////////////////
/// \struct DisallowConversion
@@ -792,19 +792,19 @@ namespace Loki
/// You can initialize a DisallowConversion with an AllowConversion
////////////////////////////////////////////////////////////////////////////////
- struct DisallowConversion
- {
- DisallowConversion()
- {}
+struct DisallowConversion
+{
+ DisallowConversion()
+ {}
- DisallowConversion(const AllowConversion&)
- {}
+ DisallowConversion(const AllowConversion&)
+ {}
- enum { allow = false };
+ enum { allow = false };
- void Swap(DisallowConversion&)
- {}
- };
+ void Swap(DisallowConversion&)
+ {}
+};
////////////////////////////////////////////////////////////////////////////////
/// \struct NoCheck
@@ -814,28 +814,28 @@ namespace Loki
/// Well, it's clear what it does :o)
////////////////////////////////////////////////////////////////////////////////
- template <class P>
- struct NoCheck
- {
- NoCheck()
- {}
+template <class P>
+struct NoCheck
+{
+ NoCheck()
+ {}
- template <class P1>
- NoCheck(const NoCheck<P1>&)
- {}
+ template <class P1>
+ NoCheck(const NoCheck<P1>&)
+ {}
- static void OnDefault(const P&)
- {}
+ static void OnDefault(const P&)
+ {}
- static void OnInit(const P&)
- {}
+ static void OnInit(const P&)
+ {}
- static void OnDereference(const P&)
- {}
+ static void OnDereference(const P&)
+ {}
- static void Swap(NoCheck&)
- {}
- };
+ static void Swap(NoCheck&)
+ {}
+};
////////////////////////////////////////////////////////////////////////////////
@@ -846,32 +846,32 @@ namespace Loki
/// Checks the pointer before dereference
////////////////////////////////////////////////////////////////////////////////
- template <class P>
- struct AssertCheck
- {
- AssertCheck()
- {}
+template <class P>
+struct AssertCheck
+{
+ AssertCheck()
+ {}
- template <class P1>
- AssertCheck(const AssertCheck<P1>&)
- {}
+ template <class P1>
+ AssertCheck(const AssertCheck<P1>&)
+ {}
- template <class P1>
- AssertCheck(const NoCheck<P1>&)
- {}
+ template <class P1>
+ AssertCheck(const NoCheck<P1>&)
+ {}
- static void OnDefault(const P&)
- {}
+ static void OnDefault(const P&)
+ {}
- static void OnInit(const P&)
- {}
+ static void OnInit(const P&)
+ {}
- static void OnDereference(P val)
- { assert(val); (void)val; }
+ static void OnDereference(P val)
+ { assert(val); (void)val; }
- static void Swap(AssertCheck&)
- {}
- };
+ static void Swap(AssertCheck&)
+ {}
+};
////////////////////////////////////////////////////////////////////////////////
/// \struct AssertCheckStrict
@@ -882,36 +882,36 @@ namespace Loki
/// You can initialize an AssertCheckStrict with an AssertCheck
////////////////////////////////////////////////////////////////////////////////
- template <class P>
- struct AssertCheckStrict
- {
- AssertCheckStrict()
- {}
+template <class P>
+struct AssertCheckStrict
+{
+ AssertCheckStrict()
+ {}
- template <class U>
- AssertCheckStrict(const AssertCheckStrict<U>&)
- {}
+ template <class U>
+ AssertCheckStrict(const AssertCheckStrict<U>&)
+ {}
- template <class U>
- AssertCheckStrict(const AssertCheck<U>&)
- {}
+ template <class U>
+ AssertCheckStrict(const AssertCheck<U>&)
+ {}
- template <class P1>
- AssertCheckStrict(const NoCheck<P1>&)
- {}
+ template <class P1>
+ AssertCheckStrict(const NoCheck<P1>&)
+ {}
- static void OnDefault(P val)
- { assert(val); }
+ static void OnDefault(P val)
+ { assert(val); }
- static void OnInit(P val)
- { assert(val); }
+ static void OnInit(P val)
+ { assert(val); }
- static void OnDereference(P val)
- { assert(val); }
+ static void OnDereference(P val)
+ { assert(val); }
- static void Swap(AssertCheckStrict&)
- {}
- };
+ static void Swap(AssertCheckStrict&)
+ {}
+};
////////////////////////////////////////////////////////////////////////////////
/// \struct NullPointerException
@@ -920,13 +920,13 @@ namespace Loki
/// Used by some implementations of the CheckingPolicy used by SmartPtr
////////////////////////////////////////////////////////////////////////////////
- struct NullPointerException : public std::runtime_error
- {
- NullPointerException() : std::runtime_error(std::string(""))
- { }
- const char* what() const throw()
- { return "Null Pointer Exception"; }
- };
+struct NullPointerException : public std::runtime_error
+{
+ NullPointerException() : std::runtime_error(std::string(""))
+ { }
+ const char* what() const throw()
+ { return "Null Pointer Exception"; }
+};
////////////////////////////////////////////////////////////////////////////////
/// \struct RejectNullStatic
@@ -936,45 +936,45 @@ namespace Loki
/// Checks the pointer upon initialization and before dereference
////////////////////////////////////////////////////////////////////////////////
- template <class P>
- struct RejectNullStatic
- {
- RejectNullStatic()
- {}
+template <class P>
+struct RejectNullStatic
+{
+ RejectNullStatic()
+ {}
- template <class P1>
- RejectNullStatic(const RejectNullStatic<P1>&)
- {}
+ template <class P1>
+ RejectNullStatic(const RejectNullStatic<P1>&)
+ {}
- template <class P1>
- RejectNullStatic(const NoCheck<P1>&)
- {}
+ template <class P1>
+ RejectNullStatic(const NoCheck<P1>&)
+ {}
- template <class P1>
- RejectNullStatic(const AssertCheck<P1>&)
- {}
+ template <class P1>
+ RejectNullStatic(const AssertCheck<P1>&)
+ {}
- template <class P1>
- RejectNullStatic(const AssertCheckStrict<P1>&)
- {}
+ template <class P1>
+ RejectNullStatic(const AssertCheckStrict<P1>&)
+ {}
- static void OnDefault(const P&)
- {
- // Make it depended on template parameter
- static const bool DependedFalse = sizeof(P*) == 0;
+ static void OnDefault(const P&)
+ {
+ // Make it depended on template parameter
+ static const bool DependedFalse = sizeof(P*) == 0;
- LOKI_STATIC_CHECK(DependedFalse, ERROR_This_Policy_Does_Not_Allow_Default_Initialization);
- }
+ LOKI_STATIC_CHECK(DependedFalse, ERROR_This_Policy_Does_Not_Allow_Default_Initialization);
+ }
- static void OnInit(const P& val)
- { if (!val) throw NullPointerException(); }
+ static void OnInit(const P& val)
+ { if (!val) throw NullPointerException(); }
- static void OnDereference(const P& val)
- { if (!val) throw NullPointerException(); }
+ static void OnDereference(const P& val)
+ { if (!val) throw NullPointerException(); }
- static void Swap(RejectNullStatic&)
- {}
- };
+ static void Swap(RejectNullStatic&)
+ {}
+};
////////////////////////////////////////////////////////////////////////////////
/// \struct RejectNull
@@ -984,31 +984,31 @@ namespace Loki
/// Checks the pointer before dereference
////////////////////////////////////////////////////////////////////////////////
- template <class P>
- struct RejectNull
- {
- RejectNull()
- {}
+template <class P>
+struct RejectNull
+{
+ RejectNull()
+ {}
- template <class P1>
- RejectNull(const RejectNull<P1>&)
- {}
+ template <class P1>
+ RejectNull(const RejectNull<P1>&)
+ {}
- static void OnInit(P)
- {}
+ static void OnInit(P)
+ {}
- static void OnDefault(P)
- {}
+ static void OnDefault(P)
+ {}
- void OnDereference(P val)
- { if (!val) throw NullPointerException(); }
+ void OnDereference(P val)
+ { if (!val) throw NullPointerException(); }
- void OnDereference(P val) const
- { if (!val) throw NullPointerException(); }
+ void OnDereference(P val) const
+ { if (!val) throw NullPointerException(); }
- void Swap(RejectNull&)
- {}
- };
+ void Swap(RejectNull&)
+ {}
+};
////////////////////////////////////////////////////////////////////////////////
/// \struct RejectNullStrict
@@ -1018,32 +1018,32 @@ namespace Loki
/// Checks the pointer upon initialization and before dereference
////////////////////////////////////////////////////////////////////////////////
- template <class P>
- struct RejectNullStrict
- {
- RejectNullStrict()
- {}
+template <class P>
+struct RejectNullStrict
+{
+ RejectNullStrict()
+ {}
- template <class P1>
- RejectNullStrict(const RejectNullStrict<P1>&)
- {}
+ template <class P1>
+ RejectNullStrict(const RejectNullStrict<P1>&)
+ {}
- template <class P1>
- RejectNullStrict(const RejectNull<P1>&)
- {}
+ template <class P1>
+ RejectNullStrict(const RejectNull<P1>&)
+ {}
- static void OnInit(P val)
- { if (!val) throw NullPointerException(); }
+ static void OnInit(P val)
+ { if (!val) throw NullPointerException(); }
- void OnDereference(P val)
- { OnInit(val); }
+ void OnDereference(P val)
+ { OnInit(val); }
- void OnDereference(P val) const
- { OnInit(val); }
+ void OnDereference(P val) const
+ { OnInit(val); }
- void Swap(RejectNullStrict&)
- {}
- };
+ void Swap(RejectNullStrict&)
+ {}
+};
////////////////////////////////////////////////////////////////////////////////
@@ -1051,16 +1051,16 @@ namespace Loki
// The reason for all the fuss above
////////////////////////////////////////////////////////////////////////////////
- template
- <
- typename T,
- template <class> class OwnershipPolicy = RefCounted,
- class ConversionPolicy = DisallowConversion,
- template <class> class CheckingPolicy = AssertCheck,
- template <class> class StoragePolicy = DefaultSPStorage,
- template<class> class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS
- >
- class SmartPtr;
+template
+<
+typename T,
+ template <class> class OwnershipPolicy = RefCounted,
+ class ConversionPolicy = DisallowConversion,
+ template <class> class CheckingPolicy = AssertCheck,
+ template <class> class StoragePolicy = DefaultSPStorage,
+ template<class> class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS
+ >
+class SmartPtr;
////////////////////////////////////////////////////////////////////////////////
// class template SmartPtrDef (definition)
@@ -1068,28 +1068,28 @@ namespace Loki
// instead of writing SmartPtr<T,OP,CP,KP,SP> write SmartPtrDef<T,OP,CP,KP,SP>::type
////////////////////////////////////////////////////////////////////////////////
- template
+template
+<
+typename T,
+ template <class> class OwnershipPolicy = RefCounted,
+ class ConversionPolicy = DisallowConversion,
+ template <class> class CheckingPolicy = AssertCheck,
+ template <class> class StoragePolicy = DefaultSPStorage,
+ template<class> class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS
+ >
+struct SmartPtrDef
+{
+ typedef SmartPtr
<
- typename T,
- template <class> class OwnershipPolicy = RefCounted,
- class ConversionPolicy = DisallowConversion,
- template <class> class CheckingPolicy = AssertCheck,
- template <class> class StoragePolicy = DefaultSPStorage,
- template<class> class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS
+ T,
+ OwnershipPolicy,
+ ConversionPolicy,
+ CheckingPolicy,
+ StoragePolicy,
+ ConstnessPolicy
>
- struct SmartPtrDef
- {
- typedef SmartPtr
- <
- T,
- OwnershipPolicy,
- ConversionPolicy,
- CheckingPolicy,
- StoragePolicy,
- ConstnessPolicy
- >
- type;
- };
+ type;
+};
////////////////////////////////////////////////////////////////////////////////
/// \class SmartPtr
@@ -1110,368 +1110,368 @@ namespace Loki
/// - IsUnique() was removed
////////////////////////////////////////////////////////////////////////////////
- template
- <
- typename T,
- template <class> class OwnershipPolicy,
- class ConversionPolicy,
- template <class> class CheckingPolicy,
- template <class> class StoragePolicy,
- template <class> class ConstnessPolicy
- >
- class SmartPtr
- : public StoragePolicy<T>
- , public OwnershipPolicy<typename StoragePolicy<T>::InitPointerType>
- , public CheckingPolicy<typename StoragePolicy<T>::StoredType>
- , public ConversionPolicy
- {
- typedef StoragePolicy<T> SP;
- typedef OwnershipPolicy<typename StoragePolicy<T>::InitPointerType> OP;
- typedef CheckingPolicy<typename StoragePolicy<T>::StoredType> KP;
- typedef ConversionPolicy CP;
+template
+<
+typename T,
+ template <class> class OwnershipPolicy,
+ class ConversionPolicy,
+ template <class> class CheckingPolicy,
+ template <class> class StoragePolicy,
+ template <class> class ConstnessPolicy
+ >
+class SmartPtr
+ : public StoragePolicy<T>
+ , public OwnershipPolicy<typename StoragePolicy<T>::InitPointerType>
+ , public CheckingPolicy<typename StoragePolicy<T>::StoredType>
+ , public ConversionPolicy
+{
+ typedef StoragePolicy<T> SP;
+ typedef OwnershipPolicy<typename StoragePolicy<T>::InitPointerType> OP;
+ typedef CheckingPolicy<typename StoragePolicy<T>::StoredType> KP;
+ typedef ConversionPolicy CP;
- public:
- typedef typename ConstnessPolicy<T>::Type* ConstPointerType;
- typedef typename ConstnessPolicy<T>::Type& ConstReferenceType;
+public:
+ typedef typename ConstnessPolicy<T>::Type* ConstPointerType;
+ typedef typename ConstnessPolicy<T>::Type& ConstReferenceType;
- typedef typename SP::PointerType PointerType;
- typedef typename SP::StoredType StoredType;
- typedef typename SP::ReferenceType ReferenceType;
+ typedef typename SP::PointerType PointerType;
+ typedef typename SP::StoredType StoredType;
+ typedef typename SP::ReferenceType ReferenceType;
- typedef typename Select<OP::destructiveCopy,SmartPtr, const SmartPtr>::Result
- CopyArg;
+ typedef typename Select<OP::destructiveCopy,SmartPtr, const SmartPtr>::Result
+ CopyArg;
- private:
- struct NeverMatched {};
+private:
+ struct NeverMatched {};
#ifdef LOKI_SMARTPTR_CONVERSION_CONSTRUCTOR_POLICY
- typedef typename Select< CP::allow, const StoredType&, NeverMatched>::Result ImplicitArg;
- typedef typename Select<!CP::allow, const StoredType&, NeverMatched>::Result ExplicitArg;
+ typedef typename Select< CP::allow, const StoredType&, NeverMatched>::Result ImplicitArg;
+ typedef typename Select<!CP::allow, const StoredType&, NeverMatched>::Result ExplicitArg;
#else
- typedef const StoredType& ImplicitArg;
- typedef typename Select<false, const StoredType&, NeverMatched>::Result ExplicitArg;
+ typedef const StoredType& ImplicitArg;
+ typedef typename Select<false, const StoredType&, NeverMatched>::Result ExplicitArg;
#endif
- public:
+public:
- SmartPtr()
- {
- KP::OnDefault(GetImpl(*this));
- }
+ SmartPtr()
+ {
+ KP::OnDefault(GetImpl(*this));
+ }
- explicit
- SmartPtr(ExplicitArg p) : SP(p)
- {
- KP::OnInit(GetImpl(*this));
- }
+ explicit
+ SmartPtr(ExplicitArg p) : SP(p)
+ {
+ KP::OnInit(GetImpl(*this));
+ }
- SmartPtr(ImplicitArg p) : SP(p)
- {
- KP::OnInit(GetImpl(*this));
- }
+ SmartPtr(ImplicitArg p) : SP(p)
+ {
+ KP::OnInit(GetImpl(*this));
+ }
- SmartPtr(CopyArg& rhs) : SP(rhs), OP(rhs), KP(rhs), CP(rhs)
- {
- GetImplRef(*this) = OP::Clone(GetImplRef(rhs));
- }
+ SmartPtr(CopyArg& rhs) : SP(rhs), OP(rhs), KP(rhs), CP(rhs)
+ {
+ GetImplRef(*this) = OP::Clone(GetImplRef(rhs));
+ }
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- SmartPtr(const SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
+ template
+ <
+ typename T1,
+ template <class> class OP1,
+ class CP1,
+ template <class> class KP1,
+ template <class> class SP1,
+ template <class> class CNP1
+ >
+ SmartPtr(const SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
: SP(rhs), OP(rhs), KP(rhs), CP(rhs)
- { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); }
-
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- SmartPtr(SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
+ { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); }
+
+ template
+ <
+ typename T1,
+ template <class> class OP1,
+ class CP1,
+ template <class> class KP1,
+ template <class> class SP1,
+ template <class> class CNP1
+ >
+ SmartPtr(SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
: SP(rhs), OP(rhs), KP(rhs), CP(rhs)
- {
- GetImplRef(*this) = OP::Clone(GetImplRef(rhs));
- }
+ {
+ GetImplRef(*this) = OP::Clone(GetImplRef(rhs));
+ }
- SmartPtr(RefToValue<SmartPtr> rhs)
+ SmartPtr(RefToValue<SmartPtr> rhs)
: SP(rhs), OP(rhs), KP(rhs), CP(rhs)
- {}
+ {}
- operator RefToValue<SmartPtr>()
- { return RefToValue<SmartPtr>(*this); }
+ operator RefToValue<SmartPtr>()
+ { return RefToValue<SmartPtr>(*this); }
- SmartPtr& operator=(CopyArg& rhs)
- {
- SmartPtr temp(rhs);
- temp.Swap(*this);
- return *this;
- }
+ SmartPtr& operator=(CopyArg& rhs)
+ {
+ SmartPtr temp(rhs);
+ temp.Swap(*this);
+ return *this;
+ }
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- SmartPtr& operator=(const SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
- {
- SmartPtr temp(rhs);
- temp.Swap(*this);
- return *this;
- }
+ template
+ <
+ typename T1,
+ template <class> class OP1,
+ class CP1,
+ template <class> class KP1,
+ template <class> class SP1,
+ template <class> class CNP1
+ >
+ SmartPtr& operator=(const SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
+ {
+ SmartPtr temp(rhs);
+ temp.Swap(*this);
+ return *this;
+ }
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- SmartPtr& operator=(SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
- {
- SmartPtr temp(rhs);
- temp.Swap(*this);
- return *this;
- }
+ template
+ <
+ typename T1,
+ template <class> class OP1,
+ class CP1,
+ template <class> class KP1,
+ template <class> class SP1,
+ template <class> class CNP1
+ >
+ SmartPtr& operator=(SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
+ {
+ SmartPtr temp(rhs);
+ temp.Swap(*this);
+ return *this;
+ }
- void Swap(SmartPtr& rhs)
- {
- OP::Swap(rhs);
- CP::Swap(rhs);
- KP::Swap(rhs);
- SP::Swap(rhs);
- }
+ void Swap(SmartPtr& rhs)
+ {
+ OP::Swap(rhs);
+ CP::Swap(rhs);
+ KP::Swap(rhs);
+ SP::Swap(rhs);
+ }
- ~SmartPtr()
+ ~SmartPtr()
+ {
+ if (OP::Release(GetImpl(*static_cast<SP*>(this))))
{
- if (OP::Release(GetImpl(*static_cast<SP*>(this))))
- {
- SP::Destroy();
- }
+ SP::Destroy();
}
+ }
#ifdef LOKI_ENABLE_FRIEND_TEMPLATE_TEMPLATE_PARAMETER_WORKAROUND
- // old non standard in class definition of friends
- friend inline void Release(SmartPtr& sp, typename SP::StoredType& p)
- {
- p = GetImplRef(sp);
- GetImplRef(sp) = SP::Default();
- }
+ // old non standard in class definition of friends
+ friend inline void Release(SmartPtr& sp, typename SP::StoredType& p)
+ {
+ p = GetImplRef(sp);
+ GetImplRef(sp) = SP::Default();
+ }
- friend inline void Reset(SmartPtr& sp, typename SP::StoredType p)
- { SmartPtr(p).Swap(sp); }
+ friend inline void Reset(SmartPtr& sp, typename SP::StoredType p)
+ { SmartPtr(p).Swap(sp); }
#else
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- friend void Release(SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1>& sp,
- typename SP1<T1>::StoredType& p);
-
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- friend void Reset(SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1>& sp,
- typename SP1<T1>::StoredType p);
+ template
+ <
+ typename T1,
+ template <class> class OP1,
+ class CP1,
+ template <class> class KP1,
+ template <class> class SP1,
+ template <class> class CNP1
+ >
+ friend void Release(SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1>& sp,
+ typename SP1<T1>::StoredType& p);
+
+ template
+ <
+ typename T1,
+ template <class> class OP1,
+ class CP1,
+ template <class> class KP1,
+ template <class> class SP1,
+ template <class> class CNP1
+ >
+ friend void Reset(SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1>& sp,
+ typename SP1<T1>::StoredType p);
#endif
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- bool Merge( SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
+ template
+ <
+ typename T1,
+ template <class> class OP1,
+ class CP1,
+ template <class> class KP1,
+ template <class> class SP1,
+ template <class> class CNP1
+ >
+ bool Merge( SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
+ {
+ if ( GetImpl( *this ) != GetImpl( rhs ) )
{
- if ( GetImpl( *this ) != GetImpl( rhs ) )
- {
- return false;
- }
- return OP::template Merge( rhs );
+ return false;
}
+ return OP::template Merge( rhs );
+ }
- PointerType operator->()
- {
- KP::OnDereference(GetImplRef(*this));
- return SP::operator->();
- }
+ PointerType operator->()
+ {
+ KP::OnDereference(GetImplRef(*this));
+ return SP::operator->();
+ }
- ConstPointerType operator->() const
- {
- KP::OnDereference(GetImplRef(*this));
- return SP::operator->();
- }
+ ConstPointerType operator->() const
+ {
+ KP::OnDereference(GetImplRef(*this));
+ return SP::operator->();
+ }
- ReferenceType operator*()
- {
- KP::OnDereference(GetImplRef(*this));
- return SP::operator*();
- }
+ ReferenceType operator*()
+ {
+ KP::OnDereference(GetImplRef(*this));
+ return SP::operator*();
+ }
- ConstReferenceType operator*() const
- {
- KP::OnDereference(GetImplRef(*this));
- return SP::operator*();
- }
+ ConstReferenceType operator*() const
+ {
+ KP::OnDereference(GetImplRef(*this));
+ return SP::operator*();
+ }
- bool operator!() const // Enables "if (!sp) ..."
- { return GetImpl(*this) == 0; }
-
- static inline T * GetPointer( const SmartPtr & sp )
- { return GetImpl( sp ); }
-
- // Ambiguity buster
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- bool operator==(const SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs) const
- { return GetImpl(*this) == GetImpl(rhs); }
-
- // Ambiguity buster
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- bool operator!=(const SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs) const
- { return !(*this == rhs); }
-
- // Ambiguity buster
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- bool operator<(const SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs) const
- { return GetImpl(*this) < GetImpl(rhs); }
-
- // Ambiguity buster
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- inline bool operator > ( const SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
- {
- return ( GetImpl( rhs ) < GetImpl( *this ) );
- }
+ bool operator!() const // Enables "if (!sp) ..."
+ { return GetImpl(*this) == 0; }
- // Ambiguity buster
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- inline bool operator <= ( const SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
- {
- return !( GetImpl( rhs ) < GetImpl( *this ) );
- }
+ static inline T* GetPointer( const SmartPtr& sp )
+ { return GetImpl( sp ); }
- // Ambiguity buster
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- inline bool operator >= ( const SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
- {
- return !( GetImpl( *this ) < GetImpl( rhs ) );
- }
+ // Ambiguity buster
+ template
+ <
+ typename T1,
+ template <class> class OP1,
+ class CP1,
+ template <class> class KP1,
+ template <class> class SP1,
+ template <class> class CNP1
+ >
+ bool operator==(const SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs) const
+ { return GetImpl(*this) == GetImpl(rhs); }
+
+ // Ambiguity buster
+ template
+ <
+ typename T1,
+ template <class> class OP1,
+ class CP1,
+ template <class> class KP1,
+ template <class> class SP1,
+ template <class> class CNP1
+ >
+ bool operator!=(const SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs) const
+ { return !(*this == rhs); }
+
+ // Ambiguity buster
+ template
+ <
+ typename T1,
+ template <class> class OP1,
+ class CP1,
+ template <class> class KP1,
+ template <class> class SP1,
+ template <class> class CNP1
+ >
+ bool operator<(const SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs) const
+ { return GetImpl(*this) < GetImpl(rhs); }
+
+ // Ambiguity buster
+ template
+ <
+ typename T1,
+ template <class> class OP1,
+ class CP1,
+ template <class> class KP1,
+ template <class> class SP1,
+ template <class> class CNP1
+ >
+ inline bool operator > ( const SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
+ {
+ return ( GetImpl( rhs ) < GetImpl( *this ) );
+ }
- private:
- // Helper for enabling 'if (sp)'
- struct Tester
- {
- Tester(int) {}
- void dummy() {}
- };
+ // Ambiguity buster
+ template
+ <
+ typename T1,
+ template <class> class OP1,
+ class CP1,
+ template <class> class KP1,
+ template <class> class SP1,
+ template <class> class CNP1
+ >
+ inline bool operator <= ( const SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
+ {
+ return !( GetImpl( rhs ) < GetImpl( *this ) );
+ }
- typedef void (Tester::*unspecified_boolean_type_)();
+ // Ambiguity buster
+ template
+ <
+ typename T1,
+ template <class> class OP1,
+ class CP1,
+ template <class> class KP1,
+ template <class> class SP1,
+ template <class> class CNP1
+ >
+ inline bool operator >= ( const SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
+ {
+ return !( GetImpl( *this ) < GetImpl( rhs ) );
+ }
- typedef typename Select<CP::allow, Tester, unspecified_boolean_type_>::Result
- unspecified_boolean_type;
+private:
+ // Helper for enabling 'if (sp)'
+ struct Tester
+ {
+ Tester(int) {}
+ void dummy() {}
+ };
- public:
- // enable 'if (sp)'
- operator unspecified_boolean_type() const
- {
- return !*this ? 0 : &Tester::dummy;
- }
+ typedef void (Tester::*unspecified_boolean_type_)();
- private:
- // Helper for disallowing automatic conversion
- struct Insipid
- {
- Insipid(PointerType) {}
- };
+ typedef typename Select<CP::allow, Tester, unspecified_boolean_type_>::Result
+ unspecified_boolean_type;
- typedef typename Select<CP::allow, PointerType, Insipid>::Result
- AutomaticConversionResult;
+public:
+ // enable 'if (sp)'
+ operator unspecified_boolean_type() const
+ {
+ return !*this ? 0 : &Tester::dummy;
+ }
- public:
- operator AutomaticConversionResult() const
- { return GetImpl(*this); }
+private:
+ // Helper for disallowing automatic conversion
+ struct Insipid
+ {
+ Insipid(PointerType) {}
};
+ typedef typename Select<CP::allow, PointerType, Insipid>::Result
+ AutomaticConversionResult;
+
+public:
+ operator AutomaticConversionResult() const
+ { return GetImpl(*this); }
+};
+
////////////////////////////////////////////////////////////////////////////////
// friends
@@ -1479,34 +1479,34 @@ namespace Loki
#ifndef LOKI_ENABLE_FRIEND_TEMPLATE_TEMPLATE_PARAMETER_WORKAROUND
- template
- <
- typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP
- >
- inline void Release(SmartPtr<T, OP, CP, KP, SP, CNP>& sp,
- typename SP<T>::StoredType& p)
- {
- p = GetImplRef(sp);
- GetImplRef(sp) = SP<T>::Default();
- }
+template
+<
+typename T,
+ template <class> class OP,
+ class CP,
+ template <class> class KP,
+ template <class> class SP,
+ template <class> class CNP
+ >
+inline void Release(SmartPtr<T, OP, CP, KP, SP, CNP>& sp,
+ typename SP<T>::StoredType& p)
+{
+ p = GetImplRef(sp);
+ GetImplRef(sp) = SP<T>::Default();
+}
- template
- <
- typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP
- >
- inline void Reset(SmartPtr<T, OP, CP, KP, SP, CNP>& sp,
- typename SP<T>::StoredType p)
- { SmartPtr<T, OP, CP, KP, SP, CNP>(p).Swap(sp); }
+template
+<
+typename T,
+ template <class> class OP,
+ class CP,
+ template <class> class KP,
+ template <class> class SP,
+ template <class> class CNP
+ >
+inline void Reset(SmartPtr<T, OP, CP, KP, SP, CNP>& sp,
+ typename SP<T>::StoredType p)
+{ SmartPtr<T, OP, CP, KP, SP, CNP>(p).Swap(sp); }
#endif
@@ -1519,232 +1519,232 @@ namespace Loki
/// \ingroup SmartPointerGroup
////////////////////////////////////////////////////////////////////////////////
- template
- <
- typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP1,
- typename U
- >
- inline bool operator==(const SmartPtr<T, OP, CP, KP, SP, CNP1 >& lhs,
- U* rhs)
- { return GetImpl(lhs) == rhs; }
+template
+<
+typename T,
+ template <class> class OP,
+ class CP,
+ template <class> class KP,
+ template <class> class SP,
+ template <class> class CNP1,
+ typename U
+ >
+inline bool operator==(const SmartPtr<T, OP, CP, KP, SP, CNP1 >& lhs,
+ U* rhs)
+{ return GetImpl(lhs) == rhs; }
////////////////////////////////////////////////////////////////////////////////
/// operator== for lhs = raw pointer, rhs = SmartPtr
/// \ingroup SmartPointerGroup
////////////////////////////////////////////////////////////////////////////////
- template
- <
- typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP1,
- typename U
- >
- inline bool operator==(U* lhs,
- const SmartPtr<T, OP, CP, KP, SP, CNP1 >& rhs)
- { return rhs == lhs; }
+template
+<
+typename T,
+ template <class> class OP,
+ class CP,
+ template <class> class KP,
+ template <class> class SP,
+ template <class> class CNP1,
+ typename U
+ >
+inline bool operator==(U* lhs,
+ const SmartPtr<T, OP, CP, KP, SP, CNP1 >& rhs)
+{ return rhs == lhs; }
////////////////////////////////////////////////////////////////////////////////
/// operator!= for lhs = SmartPtr, rhs = raw pointer
/// \ingroup SmartPointerGroup
////////////////////////////////////////////////////////////////////////////////
- template
- <
- typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP,
- typename U
- >
- inline bool operator!=(const SmartPtr<T, OP, CP, KP, SP, CNP >& lhs,
- U* rhs)
- { return !(lhs == rhs); }
+template
+<
+typename T,
+ template <class> class OP,
+ class CP,
+ template <class> class KP,
+ template <class> class SP,
+ template <class> class CNP,
+ typename U
+ >
+inline bool operator!=(const SmartPtr<T, OP, CP, KP, SP, CNP >& lhs,
+ U* rhs)
+{ return !(lhs == rhs); }
////////////////////////////////////////////////////////////////////////////////
/// operator!= for lhs = raw pointer, rhs = SmartPtr
/// \ingroup SmartPointerGroup
////////////////////////////////////////////////////////////////////////////////
- template
- <
- typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP,
- typename U
- >
- inline bool operator!=(U* lhs,
- const SmartPtr<T, OP, CP, KP, SP, CNP >& rhs)
- { return rhs != lhs; }
+template
+<
+typename T,
+ template <class> class OP,
+ class CP,
+ template <class> class KP,
+ template <class> class SP,
+ template <class> class CNP,
+ typename U
+ >
+inline bool operator!=(U* lhs,
+ const SmartPtr<T, OP, CP, KP, SP, CNP >& rhs)
+{ return rhs != lhs; }
////////////////////////////////////////////////////////////////////////////////
/// operator< for lhs = SmartPtr, rhs = raw pointer
/// \ingroup SmartPointerGroup
////////////////////////////////////////////////////////////////////////////////
- template
- <
- typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP,
- typename U
- >
- inline bool operator<(const SmartPtr<T, OP, CP, KP, SP, CNP >& lhs,
- U* rhs)
- {
- return ( GetImpl( lhs ) < rhs );
- }
+template
+<
+typename T,
+ template <class> class OP,
+ class CP,
+ template <class> class KP,
+ template <class> class SP,
+ template <class> class CNP,
+ typename U
+ >
+inline bool operator<(const SmartPtr<T, OP, CP, KP, SP, CNP >& lhs,
+ U* rhs)
+{
+ return ( GetImpl( lhs ) < rhs );
+}
////////////////////////////////////////////////////////////////////////////////
/// operator< for lhs = raw pointer, rhs = SmartPtr
/// \ingroup SmartPointerGroup
////////////////////////////////////////////////////////////////////////////////
- template
- <
- typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP,
- typename U
- >
- inline bool operator<(U* lhs,
- const SmartPtr<T, OP, CP, KP, SP, CNP >& rhs)
- {
- return ( GetImpl( rhs ) < lhs );
- }
+template
+<
+typename T,
+ template <class> class OP,
+ class CP,
+ template <class> class KP,
+ template <class> class SP,
+ template <class> class CNP,
+ typename U
+ >
+inline bool operator<(U* lhs,
+ const SmartPtr<T, OP, CP, KP, SP, CNP >& rhs)
+{
+ return ( GetImpl( rhs ) < lhs );
+}
////////////////////////////////////////////////////////////////////////////////
// operator> for lhs = SmartPtr, rhs = raw pointer
/// \ingroup SmartPointerGroup
////////////////////////////////////////////////////////////////////////////////
- template
- <
- typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP,
- typename U
- >
- inline bool operator>(const SmartPtr<T, OP, CP, KP, SP, CNP >& lhs,
- U* rhs)
- { return rhs < lhs; }
+template
+<
+typename T,
+ template <class> class OP,
+ class CP,
+ template <class> class KP,
+ template <class> class SP,
+ template <class> class CNP,
+ typename U
+ >
+inline bool operator>(const SmartPtr<T, OP, CP, KP, SP, CNP >& lhs,
+ U* rhs)
+{ return rhs < lhs; }
////////////////////////////////////////////////////////////////////////////////
/// operator> for lhs = raw pointer, rhs = SmartPtr
/// \ingroup SmartPointerGroup
////////////////////////////////////////////////////////////////////////////////
- template
- <
- typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP,
- typename U
- >
- inline bool operator>(U* lhs,
- const SmartPtr<T, OP, CP, KP, SP, CNP >& rhs)
- { return rhs < lhs; }
+template
+<
+typename T,
+ template <class> class OP,
+ class CP,
+ template <class> class KP,
+ template <class> class SP,
+ template <class> class CNP,
+ typename U
+ >
+inline bool operator>(U* lhs,
+ const SmartPtr<T, OP, CP, KP, SP, CNP >& rhs)
+{ return rhs < lhs; }
////////////////////////////////////////////////////////////////////////////////
/// operator<= for lhs = SmartPtr, rhs = raw pointer
/// \ingroup SmartPointerGroup
////////////////////////////////////////////////////////////////////////////////
- template
- <
- typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP,
- typename U
- >
- inline bool operator<=(const SmartPtr<T, OP, CP, KP, SP, CNP >& lhs,
- U* rhs)
- { return !(rhs < lhs); }
+template
+<
+typename T,
+ template <class> class OP,
+ class CP,
+ template <class> class KP,
+ template <class> class SP,
+ template <class> class CNP,
+ typename U
+ >
+inline bool operator<=(const SmartPtr<T, OP, CP, KP, SP, CNP >& lhs,
+ U* rhs)
+{ return !(rhs < lhs); }
////////////////////////////////////////////////////////////////////////////////
/// operator<= for lhs = raw pointer, rhs = SmartPtr
/// \ingroup SmartPointerGroup
////////////////////////////////////////////////////////////////////////////////
- template
- <
- typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP,
- typename U
- >
- inline bool operator<=(U* lhs,
- const SmartPtr<T, OP, CP, KP, SP, CNP >& rhs)
- { return !(rhs < lhs); }
+template
+<
+typename T,
+ template <class> class OP,
+ class CP,
+ template <class> class KP,
+ template <class> class SP,
+ template <class> class CNP,
+ typename U
+ >
+inline bool operator<=(U* lhs,
+ const SmartPtr<T, OP, CP, KP, SP, CNP >& rhs)
+{ return !(rhs < lhs); }
////////////////////////////////////////////////////////////////////////////////
/// operator>= for lhs = SmartPtr, rhs = raw pointer
/// \ingroup SmartPointerGroup
////////////////////////////////////////////////////////////////////////////////
- template
- <
- typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP,
- typename U
- >
- inline bool operator>=(const SmartPtr<T, OP, CP, KP, SP, CNP >& lhs,
- U* rhs)
- { return !(lhs < rhs); }
+template
+<
+typename T,
+ template <class> class OP,
+ class CP,
+ template <class> class KP,
+ template <class> class SP,
+ template <class> class CNP,
+ typename U
+ >
+inline bool operator>=(const SmartPtr<T, OP, CP, KP, SP, CNP >& lhs,
+ U* rhs)
+{ return !(lhs < rhs); }
////////////////////////////////////////////////////////////////////////////////
/// operator>= for lhs = raw pointer, rhs = SmartPtr
/// \ingroup SmartPointerGroup
////////////////////////////////////////////////////////////////////////////////
- template
- <
- typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP,
- typename U
- >
- inline bool operator>=(U* lhs,
- const SmartPtr<T, OP, CP, KP, SP, CNP >& rhs)
- { return !(lhs < rhs); }
+template
+<
+typename T,
+ template <class> class OP,
+ class CP,
+ template <class> class KP,
+ template <class> class SP,
+ template <class> class CNP,
+ typename U
+ >
+inline bool operator>=(U* lhs,
+ const SmartPtr<T, OP, CP, KP, SP, CNP >& rhs)
+{ return !(lhs < rhs); }
} // namespace Loki
@@ -1755,23 +1755,23 @@ namespace Loki
namespace std
{
- template
- <
- typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP
- >
- struct less< Loki::SmartPtr<T, OP, CP, KP, SP, CNP > >
+template
+<
+typename T,
+ template <class> class OP,
+ class CP,
+ template <class> class KP,
+ template <class> class SP,
+ template <class> class CNP
+ >
+struct less< Loki::SmartPtr<T, OP, CP, KP, SP, CNP > >
: public binary_function<Loki::SmartPtr<T, OP, CP, KP, SP, CNP >,
- Loki::SmartPtr<T, OP, CP, KP, SP, CNP >, bool>
- {
- bool operator()(const Loki::SmartPtr<T, OP, CP, KP, SP, CNP >& lhs,
- const Loki::SmartPtr<T, OP, CP, KP, SP, CNP >& rhs) const
- { return less<T*>()(GetImpl(lhs), GetImpl(rhs)); }
- };
+ Loki::SmartPtr<T, OP, CP, KP, SP, CNP >, bool>
+{
+ bool operator()(const Loki::SmartPtr<T, OP, CP, KP, SP, CNP >& lhs,
+ const Loki::SmartPtr<T, OP, CP, KP, SP, CNP >& rhs) const
+ { return less<T*>()(GetImpl(lhs), GetImpl(rhs)); }
+};
}
#endif // end file guardian
diff --git a/shared/loki/StrongPtr.h b/shared/loki/StrongPtr.h
index 7ec9766f..23d70415 100644
--- a/shared/loki/StrongPtr.h
+++ b/shared/loki/StrongPtr.h
@@ -19,7 +19,7 @@
#include <loki/SmartPtr.h>
#if defined (LOKI_OBJECT_LEVEL_THREADING) || defined (LOKI_CLASS_LEVEL_THREADING)
- #include <loki/Threads.h>
+#include <loki/Threads.h>
#endif
@@ -127,7 +127,7 @@ template < class P >
class DeleteUsingFree
{
public:
- inline void static Delete( const P * p )
+ inline void static Delete( const P* p )
{
if ( 0 != p )
{
@@ -137,12 +137,12 @@ public:
}
/// Provides default value to initialize the pointer
- inline static P * Default( void )
+ inline static P* Default( void )
{
return 0;
}
- inline void Swap( DeleteUsingFree & ) {}
+ inline void Swap( DeleteUsingFree& ) {}
};
////////////////////////////////////////////////////////////////////////////////
@@ -158,17 +158,17 @@ template < class P >
class DeleteNothing
{
public:
- inline static void Delete( const P * )
+ inline static void Delete( const P* )
{
// Do nothing at all!
}
- inline static P * Default( void )
+ inline static P* Default( void )
{
return 0;
}
- inline void Swap( DeleteNothing & ) {}
+ inline void Swap( DeleteNothing& ) {}
};
////////////////////////////////////////////////////////////////////////////////
@@ -183,7 +183,7 @@ template < class P >
class DeleteSingle
{
public:
- inline static void Delete( const P * p )
+ inline static void Delete( const P* p )
{
/** @note If you see an error message about a negative subscript, that
means your are attempting to use Loki to delete an incomplete type.
@@ -194,12 +194,12 @@ public:
delete p;
}
- inline static P * Default( void )
+ inline static P* Default( void )
{
return 0;
}
- inline void Swap( DeleteSingle & ) {}
+ inline void Swap( DeleteSingle& ) {}
};
////////////////////////////////////////////////////////////////////////////////
@@ -214,7 +214,7 @@ template < class P >
class DeleteArray
{
public:
- inline static void Delete( const P * p )
+ inline static void Delete( const P* p )
{
/** @note If you see an error message about a negative subscript, that
means your are attempting to use Loki to delete an incomplete type.
@@ -225,12 +225,12 @@ public:
delete [] p;
}
- inline static P * Default( void )
+ inline static P* Default( void )
{
return 0;
}
- inline void Swap( DeleteArray & ) {}
+ inline void Swap( DeleteArray& ) {}
};
////////////////////////////////////////////////////////////////////////////////
@@ -326,7 +326,7 @@ public:
{
}
- inline TwoRefCountInfo( void * p, bool strong )
+ inline TwoRefCountInfo( void* p, bool strong )
: m_pointer( p )
, m_strongCount( strong ? 1 : 0 )
, m_weakCount( strong ? 0 : 1 )
@@ -378,28 +378,28 @@ public:
m_pointer = 0;
}
- void SetPointer( void * p )
+ void SetPointer( void* p )
{
m_pointer = p;
}
- inline void * GetPointer( void ) const
+ inline void* GetPointer( void ) const
{
return m_pointer;
}
- inline void * & GetPointerRef( void ) const
+ inline void*& GetPointerRef( void ) const
{
- return const_cast< void * & >( m_pointer );
+ return const_cast< void *& >( m_pointer );
}
private:
/// Copy-constructor not implemented.
- TwoRefCountInfo( const TwoRefCountInfo & );
+ TwoRefCountInfo( const TwoRefCountInfo& );
/// Copy-assignment operator not implemented.
- TwoRefCountInfo & operator = ( const TwoRefCountInfo & );
+ TwoRefCountInfo& operator = ( const TwoRefCountInfo& );
- void * m_pointer;
+ void* m_pointer;
unsigned int m_strongCount;
unsigned int m_weakCount;
};
@@ -435,7 +435,7 @@ public:
{
}
- LockableTwoRefCountInfo( void * p, bool strong )
+ LockableTwoRefCountInfo( void* p, bool strong )
: TwoRefCountInfo( p, strong )
, m_Mutex()
{
@@ -507,19 +507,19 @@ public:
m_Mutex.Unlock();
}
- void SetPointer( void * p )
+ void SetPointer( void* p )
{
m_Mutex.Lock();
TwoRefCountInfo::SetPointer( p );
m_Mutex.Unlock();
}
- inline void * GetPointer( void ) const
+ inline void* GetPointer( void ) const
{
return TwoRefCountInfo::GetPointer();
}
- inline void * & GetPointerRef( void ) const
+ inline void*& GetPointerRef( void ) const
{
return TwoRefCountInfo::GetPointerRef();
}
@@ -528,9 +528,9 @@ private:
/// Default constructor is not available.
LockableTwoRefCountInfo( void );
/// Copy constructor is not available.
- LockableTwoRefCountInfo( const LockableTwoRefCountInfo & );
+ LockableTwoRefCountInfo( const LockableTwoRefCountInfo& );
/// Copy-assignment operator is not available.
- LockableTwoRefCountInfo & operator = ( const LockableTwoRefCountInfo & );
+ LockableTwoRefCountInfo& operator = ( const LockableTwoRefCountInfo& );
mutable LOKI_DEFAULT_MUTEX m_Mutex;
};
@@ -556,9 +556,9 @@ protected:
explicit TwoRefCounts( bool strong );
- TwoRefCounts( const void * p, bool strong );
+ TwoRefCounts( const void* p, bool strong );
- TwoRefCounts( const TwoRefCounts & rhs, bool strong ) :
+ TwoRefCounts( const TwoRefCounts& rhs, bool strong ) :
m_counts( rhs.m_counts )
{
Increment( strong );
@@ -580,35 +580,35 @@ protected:
return m_counts->HasStrongPointer();
}
- void Swap( TwoRefCounts & rhs );
+ void Swap( TwoRefCounts& rhs );
- void SetPointer( void * p )
+ void SetPointer( void* p )
{
m_counts->SetPointer( p );
}
void ZapPointer( void );
- inline void * & GetPointerRef( void ) const
+ inline void*& GetPointerRef( void ) const
{
return m_counts->GetPointerRef();
}
- inline void * GetPointer( void ) const
+ inline void* GetPointer( void ) const
{
return m_counts->GetPointer();
}
private:
TwoRefCounts( void );
- TwoRefCounts & operator = ( const TwoRefCounts & );
+ TwoRefCounts& operator = ( const TwoRefCounts& );
void Increment( bool strong );
bool Decrement( bool strong );
/// Pointer to all shared data.
- Loki::Private::TwoRefCountInfo * m_counts;
+ Loki::Private::TwoRefCountInfo* m_counts;
};
////////////////////////////////////////////////////////////////////////////////
@@ -637,28 +637,28 @@ protected:
explicit LockableTwoRefCounts( bool strong )
: m_counts( NULL )
{
- void * temp = ThreadSafePointerAllocator::operator new(
- sizeof(Loki::Private::LockableTwoRefCountInfo) );
+ void* temp = ThreadSafePointerAllocator::operator new(
+ sizeof(Loki::Private::LockableTwoRefCountInfo) );
#ifdef DO_EXTRA_LOKI_TESTS
assert( temp != 0 );
#endif
m_counts = new ( temp ) Loki::Private::LockableTwoRefCountInfo( strong );
}
- LockableTwoRefCounts( const void * p, bool strong )
+ LockableTwoRefCounts( const void* p, bool strong )
: m_counts( NULL )
{
- void * temp = ThreadSafePointerAllocator::operator new(
- sizeof(Loki::Private::LockableTwoRefCountInfo) );
+ void* temp = ThreadSafePointerAllocator::operator new(
+ sizeof(Loki::Private::LockableTwoRefCountInfo) );
#ifdef DO_EXTRA_LOKI_TESTS
assert( temp != 0 );
#endif
- void * p2 = const_cast< void * >( p );
+ void* p2 = const_cast< void* >( p );
m_counts = new ( temp )
- Loki::Private::LockableTwoRefCountInfo( p2, strong );
+ Loki::Private::LockableTwoRefCountInfo( p2, strong );
}
- LockableTwoRefCounts( const LockableTwoRefCounts & rhs, bool strong ) :
+ LockableTwoRefCounts( const LockableTwoRefCounts& rhs, bool strong ) :
m_counts( rhs.m_counts )
{
Increment( strong );
@@ -717,12 +717,12 @@ protected:
return m_counts->HasStrongPointer();
}
- void Swap( LockableTwoRefCounts & rhs )
+ void Swap( LockableTwoRefCounts& rhs )
{
std::swap( m_counts, rhs.m_counts );
}
- void SetPointer( void * p )
+ void SetPointer( void* p )
{
m_counts->SetPointer( p );
}
@@ -739,27 +739,27 @@ protected:
else
{
ThreadSafePointerAllocator::operator delete ( m_counts,
- sizeof(Loki::Private::LockableTwoRefCountInfo) );
+ sizeof(Loki::Private::LockableTwoRefCountInfo) );
m_counts = NULL;
}
}
- inline void * GetPointer( void ) const
+ inline void* GetPointer( void ) const
{
return m_counts->GetPointer();
}
- inline void * & GetPointerRef( void ) const
+ inline void*& GetPointerRef( void ) const
{
return m_counts->GetPointerRef();
}
private:
LockableTwoRefCounts( void );
- LockableTwoRefCounts & operator = ( const LockableTwoRefCounts & );
+ LockableTwoRefCounts& operator = ( const LockableTwoRefCounts& );
/// Pointer to all shared data.
- Loki::Private::LockableTwoRefCountInfo * m_counts;
+ Loki::Private::LockableTwoRefCountInfo* m_counts;
};
#endif // if object-level-locking or class-level-locking
@@ -785,15 +785,15 @@ protected:
m_prev = m_next = this;
}
- TwoRefLinks( const void * p, bool strong );
+ TwoRefLinks( const void* p, bool strong );
- TwoRefLinks( const TwoRefLinks & rhs, bool strong );
+ TwoRefLinks( const TwoRefLinks& rhs, bool strong );
bool Release( bool strong );
- void Swap( TwoRefLinks & rhs );
+ void Swap( TwoRefLinks& rhs );
- bool Merge( TwoRefLinks & rhs );
+ bool Merge( TwoRefLinks& rhs );
bool HasStrongPointer( void ) const;
@@ -802,35 +802,35 @@ protected:
ZapAllNodes();
}
- void SetPointer( void * p );
+ void SetPointer( void* p );
- inline void * GetPointer( void ) const
+ inline void* GetPointer( void ) const
{
return m_pointer;
}
- inline void * & GetPointerRef( void ) const
+ inline void*& GetPointerRef( void ) const
{
- return const_cast< void * & >( m_pointer );
+ return const_cast< void *& >( m_pointer );
}
private:
- static unsigned int CountPrevCycle( const TwoRefLinks * pThis );
- static unsigned int CountNextCycle( const TwoRefLinks * pThis );
+ static unsigned int CountPrevCycle( const TwoRefLinks* pThis );
+ static unsigned int CountNextCycle( const TwoRefLinks* pThis );
/// Not implemented.
TwoRefLinks( void );
/// Not implemented.
- TwoRefLinks & operator = ( const TwoRefLinks & );
+ TwoRefLinks& operator = ( const TwoRefLinks& );
- bool HasPrevNode( const TwoRefLinks * p ) const;
- bool HasNextNode( const TwoRefLinks * p ) const;
+ bool HasPrevNode( const TwoRefLinks* p ) const;
+ bool HasNextNode( const TwoRefLinks* p ) const;
bool AllNodesHaveSamePointer( void ) const;
void ZapAllNodes( void );
- void * m_pointer;
- mutable TwoRefLinks * m_prev;
- mutable TwoRefLinks * m_next;
+ void* m_pointer;
+ mutable TwoRefLinks* m_prev;
+ mutable TwoRefLinks* m_next;
const bool m_strong;
};
@@ -850,24 +850,24 @@ private:
template
<
- typename T,
- bool Strong = true,
- class OwnershipPolicy = Loki::TwoRefCounts,
- class ConversionPolicy = Loki::DisallowConversion,
- template < class > class CheckingPolicy = Loki::AssertCheck,
- template < class > class ResetPolicy = Loki::CantResetWithStrong,
- template < class > class DeletePolicy = Loki::DeleteSingle,
- template < class > class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS
->
+typename T,
+ bool Strong = true,
+ class OwnershipPolicy = Loki::TwoRefCounts,
+ class ConversionPolicy = Loki::DisallowConversion,
+ template < class > class CheckingPolicy = Loki::AssertCheck,
+ template < class > class ResetPolicy = Loki::CantResetWithStrong,
+ template < class > class DeletePolicy = Loki::DeleteSingle,
+ template < class > class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS
+ >
class StrongPtr
: public OwnershipPolicy
, public ConversionPolicy
- , public CheckingPolicy< T * >
+ , public CheckingPolicy< T* >
, public ResetPolicy< T >
, public DeletePolicy< T >
{
typedef ConversionPolicy CP;
- typedef CheckingPolicy< T * > KP;
+ typedef CheckingPolicy< T* > KP;
typedef ResetPolicy< T > RP;
typedef DeletePolicy< T > DP;
@@ -875,12 +875,12 @@ public:
typedef OwnershipPolicy OP;
- typedef T * StoredType; // the type of the pointer
- typedef T * PointerType; // type returned by operator->
- typedef T & ReferenceType; // type returned by operator*
+ typedef T* StoredType; // the type of the pointer
+ typedef T* PointerType; // type returned by operator->
+ typedef T& ReferenceType; // type returned by operator*
- typedef typename ConstnessPolicy< T >::Type * ConstPointerType;
- typedef typename ConstnessPolicy< T >::Type & ConstReferenceType;
+ typedef typename ConstnessPolicy< T >::Type* ConstPointerType;
+ typedef typename ConstnessPolicy< T >::Type& ConstReferenceType;
private:
struct NeverMatched {};
@@ -910,22 +910,22 @@ public:
KP::OnInit( GetPointer() );
}
- StrongPtr( const StrongPtr & rhs )
+ StrongPtr( const StrongPtr& rhs )
: OP( rhs, Strong ), CP( rhs ), KP( rhs ), DP( rhs )
{
}
template
<
- typename T1,
- bool S1,
- class OP1,
- class CP1,
- template < class > class KP1,
- template < class > class RP1,
- template < class > class DP1,
- template < class > class CNP1
- >
+ typename T1,
+ bool S1,
+ class OP1,
+ class CP1,
+ template < class > class KP1,
+ template < class > class RP1,
+ template < class > class DP1,
+ template < class > class CNP1
+ >
StrongPtr(
const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs )
: OP( rhs, Strong )
@@ -934,15 +934,15 @@ public:
template
<
- typename T1,
- bool S1,
- class OP1,
- class CP1,
- template < class > class KP1,
- template < class > class RP1,
- template < class > class DP1,
- template < class > class CNP1
- >
+ typename T1,
+ bool S1,
+ class OP1,
+ class CP1,
+ template < class > class KP1,
+ template < class > class RP1,
+ template < class > class DP1,
+ template < class > class CNP1
+ >
StrongPtr(
StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs )
: OP( rhs, Strong )
@@ -959,7 +959,7 @@ public:
return RefToValue< StrongPtr >( *this );
}
- StrongPtr & operator = ( const StrongPtr & rhs )
+ StrongPtr& operator = ( const StrongPtr& rhs )
{
if ( GetPointer() != rhs.GetPointer() )
{
@@ -969,7 +969,7 @@ public:
return *this;
}
- StrongPtr & operator = ( T * p )
+ StrongPtr& operator = ( T* p )
{
if ( GetPointer() != p )
{
@@ -981,16 +981,16 @@ public:
template
<
- typename T1,
- bool S1,
- class OP1,
- class CP1,
- template < class > class KP1,
- template < class > class RP1,
- template < class > class DP1,
- template < class > class CNP1
- >
- StrongPtr & operator = (
+ typename T1,
+ bool S1,
+ class OP1,
+ class CP1,
+ template < class > class KP1,
+ template < class > class RP1,
+ template < class > class DP1,
+ template < class > class CNP1
+ >
+ StrongPtr& operator = (
const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs )
{
if ( !rhs.Equals( GetPointer() ) )
@@ -1006,7 +1006,7 @@ public:
return Strong;
}
- void Swap( StrongPtr & rhs )
+ void Swap( StrongPtr& rhs )
{
OP::Swap( rhs );
CP::Swap( rhs );
@@ -1023,7 +1023,7 @@ public:
// to deleting the shared object multiple times, which leads to
// undefined behavior. Therefore, this must get pointer before
// zapping it, and then delete the temp pointer.
- T * p = GetPointer();
+ T* p = GetPointer();
OP::ZapPointer();
if ( p != 0 )
{
@@ -1035,8 +1035,8 @@ public:
#ifdef LOKI_ENABLE_FRIEND_TEMPLATE_TEMPLATE_PARAMETER_WORKAROUND
// old non standard in class definition of friends
- friend bool ReleaseAll( StrongPtr & sp,
- typename StrongPtr::StoredType & p )
+ friend bool ReleaseAll( StrongPtr& sp,
+ typename StrongPtr::StoredType& p )
{
if ( !sp.RP::OnReleaseAll( sp.IsStrong() || sp.OP::HasStrongPointer() ) )
{
@@ -1047,8 +1047,8 @@ public:
return true;
}
- friend bool ResetAll( StrongPtr & sp,
- typename StrongPtr::StoredType p )
+ friend bool ResetAll( StrongPtr& sp,
+ typename StrongPtr::StoredType p )
{
if ( sp.OP::GetPointer() == p )
{
@@ -1067,32 +1067,32 @@ public:
template
<
- typename T1,
- bool S1,
- class OP1,
- class CP1,
- template < class > class KP1,
- template < class > class RP1,
- template < class > class DP1,
- template < class > class CNP1
- >
+ typename T1,
+ bool S1,
+ class OP1,
+ class CP1,
+ template < class > class KP1,
+ template < class > class RP1,
+ template < class > class DP1,
+ template < class > class CNP1
+ >
friend bool ReleaseAll( StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & sp,
- typename StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 >::StoredType & p );
+ typename StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 >::StoredType& p );
template
<
- typename T1,
- bool S1,
- class OP1,
- class CP1,
- template < class > class KP1,
- template < class > class RP1,
- template < class > class DP1,
- template < class > class CNP1
- >
+ typename T1,
+ bool S1,
+ class OP1,
+ class CP1,
+ template < class > class KP1,
+ template < class > class RP1,
+ template < class > class DP1,
+ template < class > class CNP1
+ >
friend bool ResetAll( StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & sp,
- typename StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 >::StoredType p );
+ typename StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 >::StoredType p );
#endif
@@ -1103,15 +1103,15 @@ public:
*/
template
<
- typename T1,
- bool S1,
- class OP1,
- class CP1,
- template < class > class KP1,
- template < class > class RP1,
- template < class > class DP1,
- template < class > class CNP1
- >
+ typename T1,
+ bool S1,
+ class OP1,
+ class CP1,
+ template < class > class KP1,
+ template < class > class RP1,
+ template < class > class DP1,
+ template < class > class CNP1
+ >
bool Merge( StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs )
{
if ( OP::GetPointer() != rhs.OP::GetPointer() )
@@ -1163,21 +1163,21 @@ public:
/// Helper function which can be called to avoid exposing GetPointer function.
template < class T1 >
- bool Equals( const T1 * p ) const
+ bool Equals( const T1* p ) const
{
return ( GetPointer() == p );
}
/// Helper function which can be called to avoid exposing GetPointer function.
template < class T1 >
- bool LessThan( const T1 * p ) const
+ bool LessThan( const T1* p ) const
{
return ( GetPointer() < p );
}
/// Helper function which can be called to avoid exposing GetPointer function.
template < class T1 >
- bool GreaterThan( const T1 * p ) const
+ bool GreaterThan( const T1* p ) const
{
return ( GetPointer() > p );
}
@@ -1185,15 +1185,15 @@ public:
/// Equality comparison operator is templated to handle ambiguity.
template
<
- typename T1,
- bool S1,
- class OP1,
- class CP1,
- template < class > class KP1,
- template < class > class RP1,
- template < class > class DP1,
- template < class > class CNP1
- >
+ typename T1,
+ bool S1,
+ class OP1,
+ class CP1,
+ template < class > class KP1,
+ template < class > class RP1,
+ template < class > class DP1,
+ template < class > class CNP1
+ >
bool operator == (
const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs ) const
{
@@ -1203,15 +1203,15 @@ public:
/// Inequality comparison operator is templated to handle ambiguity.
template
<
- typename T1,
- bool S1,
- class OP1,
- class CP1,
- template < class > class KP1,
- template < class > class RP1,
- template < class > class DP1,
- template < class > class CNP1
- >
+ typename T1,
+ bool S1,
+ class OP1,
+ class CP1,
+ template < class > class KP1,
+ template < class > class RP1,
+ template < class > class DP1,
+ template < class > class CNP1
+ >
bool operator != (
const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs ) const
{
@@ -1221,15 +1221,15 @@ public:
/// Less-than comparison operator is templated to handle ambiguity.
template
<
- typename T1,
- bool S1,
- class OP1,
- class CP1,
- template < class > class KP1,
- template < class > class RP1,
- template < class > class DP1,
- template < class > class CNP1
- >
+ typename T1,
+ bool S1,
+ class OP1,
+ class CP1,
+ template < class > class KP1,
+ template < class > class RP1,
+ template < class > class DP1,
+ template < class > class CNP1
+ >
bool operator < (
const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs ) const
{
@@ -1239,15 +1239,15 @@ public:
/// Greater-than comparison operator is templated to handle ambiguity.
template
<
- typename T1,
- bool S1,
- class OP1,
- class CP1,
- template < class > class KP1,
- template < class > class RP1,
- template < class > class DP1,
- template < class > class CNP1
- >
+ typename T1,
+ bool S1,
+ class OP1,
+ class CP1,
+ template < class > class KP1,
+ template < class > class RP1,
+ template < class > class DP1,
+ template < class > class CNP1
+ >
inline bool operator > (
const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs ) const
{
@@ -1257,15 +1257,15 @@ public:
/// Less-than-or-equal-to operator is templated to handle ambiguity.
template
<
- typename T1,
- bool S1,
- class OP1,
- class CP1,
- template < class > class KP1,
- template < class > class RP1,
- template < class > class DP1,
- template < class > class CNP1
- >
+ typename T1,
+ bool S1,
+ class OP1,
+ class CP1,
+ template < class > class KP1,
+ template < class > class RP1,
+ template < class > class DP1,
+ template < class > class CNP1
+ >
inline bool operator <= (
const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs ) const
{
@@ -1275,15 +1275,15 @@ public:
/// Greater-than-or-equal-to operator is templated to handle ambiguity.
template
<
- typename T1,
- bool S1,
- class OP1,
- class CP1,
- template < class > class KP1,
- template < class > class RP1,
- template < class > class DP1,
- template < class > class CNP1
- >
+ typename T1,
+ bool S1,
+ class OP1,
+ class CP1,
+ template < class > class KP1,
+ template < class > class RP1,
+ template < class > class DP1,
+ template < class > class CNP1
+ >
inline bool operator >= (
const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs ) const
{
@@ -1329,7 +1329,7 @@ private:
typedef void (Tester::*unspecified_boolean_type_)();
typedef typename Select< CP::allow, Tester, unspecified_boolean_type_ >::Result
- unspecified_boolean_type;
+ unspecified_boolean_type;
public:
// enable 'if (sp)'
@@ -1346,7 +1346,7 @@ private:
};
typedef typename Select< CP::allow, PointerType, Insipid >::Result
- AutomaticConversionResult;
+ AutomaticConversionResult;
public:
operator AutomaticConversionResult() const
@@ -1364,54 +1364,54 @@ public:
template
<
- typename U,
- typename T,
- bool S,
- class OP,
- class CP,
- template < class > class KP,
- template < class > class RP,
- template < class > class DP,
- template < class > class CNP
->
+typename U,
+ typename T,
+ bool S,
+ class OP,
+ class CP,
+ template < class > class KP,
+ template < class > class RP,
+ template < class > class DP,
+ template < class > class CNP
+ >
bool ReleaseAll( StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & sp,
- typename StrongPtr< T, S, OP, CP, KP, RP, DP, CNP >::StoredType & p )
+ typename StrongPtr< T, S, OP, CP, KP, RP, DP, CNP >::StoredType& p )
{
- if ( !sp.RP<T>::OnReleaseAll( sp.IsStrong() || sp.OP::HasStrongPointer() ) )
- {
- return false;
- }
- p = sp.GetPointer();
- sp.OP::SetPointer( sp.DP<T>::Default() );
- return true;
+ if ( !sp.RP<T>::OnReleaseAll( sp.IsStrong() || sp.OP::HasStrongPointer() ) )
+ {
+ return false;
+ }
+ p = sp.GetPointer();
+ sp.OP::SetPointer( sp.DP<T>::Default() );
+ return true;
}
template
<
- typename U,
- typename T,
- bool S,
- class OP,
- class CP,
- template < class > class KP,
- template < class > class RP,
- template < class > class DP,
- template < class > class CNP
->
+typename U,
+ typename T,
+ bool S,
+ class OP,
+ class CP,
+ template < class > class KP,
+ template < class > class RP,
+ template < class > class DP,
+ template < class > class CNP
+ >
bool ResetAll( StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & sp,
typename StrongPtr< T, S, OP, CP, KP, RP, DP, CNP >::StoredType p )
{
- if ( sp.OP::GetPointer() == p )
- {
+ if ( sp.OP::GetPointer() == p )
+ {
+ return true;
+ }
+ if ( !sp.RP<T>::OnResetAll( sp.IsStrong() || sp.OP::HasStrongPointer() ) )
+ {
+ return false;
+ }
+ sp.DP<T>::Delete( sp.GetPointer() );
+ sp.OP::SetPointer( p );
return true;
- }
- if ( !sp.RP<T>::OnResetAll( sp.IsStrong() || sp.OP::HasStrongPointer() ) )
- {
- return false;
- }
- sp.DP<T>::Delete( sp.GetPointer() );
- sp.OP::SetPointer( p );
- return true;
}
#endif
@@ -1422,18 +1422,18 @@ bool ResetAll( StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & sp,
/// \ingroup SmartPointerGroup
template
<
- typename U,
- typename T,
- bool S,
- class OP,
- class CP,
- template < class > class KP,
- template < class > class RP,
- template < class > class DP,
- template < class > class CNP
->
+typename U,
+ typename T,
+ bool S,
+ class OP,
+ class CP,
+ template < class > class KP,
+ template < class > class RP,
+ template < class > class DP,
+ template < class > class CNP
+ >
inline bool operator == (
- const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, U * rhs )
+ const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, U* rhs )
{
return ( lhs.Equals( rhs ) );
}
@@ -1442,18 +1442,18 @@ inline bool operator == (
/// \ingroup SmartPointerGroup
template
<
- typename U,
- typename T,
- bool S,
- class OP,
- class CP,
- template < class > class KP,
- template < class > class RP,
- template < class > class DP,
- template < class > class CNP
->
-inline bool operator == ( U * lhs,
- const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & rhs )
+typename U,
+ typename T,
+ bool S,
+ class OP,
+ class CP,
+ template < class > class KP,
+ template < class > class RP,
+ template < class > class DP,
+ template < class > class CNP
+ >
+inline bool operator == ( U* lhs,
+ const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & rhs )
{
return ( rhs.Equals( lhs ) );
}
@@ -1462,18 +1462,18 @@ inline bool operator == ( U * lhs,
/// \ingroup SmartPointerGroup
template
<
- typename U,
- typename T,
- bool S,
- class OP,
- class CP,
- template < class > class KP,
- template < class > class RP,
- template < class > class DP,
- template < class > class CNP
->
+typename U,
+ typename T,
+ bool S,
+ class OP,
+ class CP,
+ template < class > class KP,
+ template < class > class RP,
+ template < class > class DP,
+ template < class > class CNP
+ >
inline bool operator != (
- const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, U * rhs )
+ const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, U* rhs )
{
return !( lhs.Equals( rhs ) );
}
@@ -1482,18 +1482,18 @@ inline bool operator != (
/// \ingroup SmartPointerGroup
template
<
- typename U,
- typename T,
- bool S,
- class OP,
- class CP,
- template < class > class KP,
- template < class > class RP,
- template < class > class DP,
- template < class > class CNP
->
-inline bool operator != ( U * lhs,
- const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & rhs )
+typename U,
+ typename T,
+ bool S,
+ class OP,
+ class CP,
+ template < class > class KP,
+ template < class > class RP,
+ template < class > class DP,
+ template < class > class CNP
+ >
+inline bool operator != ( U* lhs,
+ const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & rhs )
{
return !( rhs.Equals( lhs ) );
}
@@ -1502,18 +1502,18 @@ inline bool operator != ( U * lhs,
/// \ingroup SmartPointerGroup
template
<
- typename U,
- typename T,
- bool S,
- class OP,
- class CP,
- template < class > class KP,
- template < class > class RP,
- template < class > class DP,
- template < class > class CNP
->
+typename U,
+ typename T,
+ bool S,
+ class OP,
+ class CP,
+ template < class > class KP,
+ template < class > class RP,
+ template < class > class DP,
+ template < class > class CNP
+ >
inline bool operator < (
- const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, U * rhs )
+ const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, U* rhs )
{
return ( lhs.LessThan( rhs ) );
}
@@ -1522,18 +1522,18 @@ inline bool operator < (
/// \ingroup SmartPointerGroup
template
<
- typename U,
- typename T,
- bool S,
- class OP,
- class CP,
- template < class > class KP,
- template < class > class RP,
- template < class > class DP,
- template < class > class CNP
->
-inline bool operator < ( U * lhs,
- const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & rhs )
+typename U,
+ typename T,
+ bool S,
+ class OP,
+ class CP,
+ template < class > class KP,
+ template < class > class RP,
+ template < class > class DP,
+ template < class > class CNP
+ >
+inline bool operator < ( U* lhs,
+ const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & rhs )
{
return ( rhs.GreaterThan( lhs ) );
}
@@ -1542,18 +1542,18 @@ inline bool operator < ( U * lhs,
/// \ingroup SmartPointerGroup
template
<
- typename U,
- typename T,
- bool S,
- class OP,
- class CP,
- template < class > class KP,
- template < class > class RP,
- template < class > class DP,
- template < class > class CNP
->
+typename U,
+ typename T,
+ bool S,
+ class OP,
+ class CP,
+ template < class > class KP,
+ template < class > class RP,
+ template < class > class DP,
+ template < class > class CNP
+ >
inline bool operator > (
- const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, U * rhs )
+ const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, U* rhs )
{
return ( lhs.GreaterThan( rhs ) );
}
@@ -1562,18 +1562,18 @@ inline bool operator > (
/// \ingroup SmartPointerGroup
template
<
- typename U,
- typename T,
- bool S,
- class OP,
- class CP,
- template < class > class KP,
- template < class > class RP,
- template < class > class DP,
- template < class > class CNP
->
-inline bool operator > ( U * lhs,
- const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & rhs )
+typename U,
+ typename T,
+ bool S,
+ class OP,
+ class CP,
+ template < class > class KP,
+ template < class > class RP,
+ template < class > class DP,
+ template < class > class CNP
+ >
+inline bool operator > ( U* lhs,
+ const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & rhs )
{
return ( rhs.LessThan( lhs ) );
}
@@ -1582,18 +1582,18 @@ inline bool operator > ( U * lhs,
/// \ingroup SmartPointerGroup
template
<
- typename U,
- typename T,
- bool S,
- class OP,
- class CP,
- template < class > class KP,
- template < class > class RP,
- template < class > class DP,
- template < class > class CNP
->
+typename U,
+ typename T,
+ bool S,
+ class OP,
+ class CP,
+ template < class > class KP,
+ template < class > class RP,
+ template < class > class DP,
+ template < class > class CNP
+ >
inline bool operator <= (
- const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, U * rhs )
+ const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, U* rhs )
{
return !( lhs.GreaterThan( rhs ) );
}
@@ -1602,18 +1602,18 @@ inline bool operator <= (
/// \ingroup SmartPointerGroup
template
<
- typename U,
- typename T,
- bool S,
- class OP,
- class CP,
- template < class > class KP,
- template < class > class RP,
- template < class > class DP,
- template < class > class CNP
->
-inline bool operator <= ( U * lhs,
- const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & rhs )
+typename U,
+ typename T,
+ bool S,
+ class OP,
+ class CP,
+ template < class > class KP,
+ template < class > class RP,
+ template < class > class DP,
+ template < class > class CNP
+ >
+inline bool operator <= ( U* lhs,
+ const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & rhs )
{
return !( rhs.LessThan( lhs ) );
}
@@ -1622,18 +1622,18 @@ inline bool operator <= ( U * lhs,
/// \ingroup SmartPointerGroup
template
<
- typename U,
- typename T,
- bool S,
- class OP,
- class CP,
- template < class > class KP,
- template < class > class RP,
- template < class > class DP,
- template < class > class CNP
->
+typename U,
+ typename T,
+ bool S,
+ class OP,
+ class CP,
+ template < class > class KP,
+ template < class > class RP,
+ template < class > class DP,
+ template < class > class CNP
+ >
inline bool operator >= (
- const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, U * rhs )
+ const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, U* rhs )
{
return !( lhs.LessThan( rhs ) );
}
@@ -1642,18 +1642,18 @@ inline bool operator >= (
/// \ingroup SmartPointerGroup
template
<
- typename U,
- typename T,
- bool S,
- class OP,
- class CP,
- template < class > class KP,
- template < class > class RP,
- template < class > class DP,
- template < class > class CNP
->
-inline bool operator >= ( U * lhs,
- const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & rhs )
+typename U,
+ typename T,
+ bool S,
+ class OP,
+ class CP,
+ template < class > class KP,
+ template < class > class RP,
+ template < class > class DP,
+ template < class > class CNP
+ >
+inline bool operator >= ( U* lhs,
+ const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & rhs )
{
return !( rhs.GreaterThan( lhs ) );
}
@@ -1662,33 +1662,33 @@ inline bool operator >= ( U * lhs,
namespace std
{
- ////////////////////////////////////////////////////////////////////////////////
- /// specialization of std::less for StrongPtr
- /// \ingroup SmartPointerGroup
- ////////////////////////////////////////////////////////////////////////////////
- template
- <
- typename T,
- bool S,
- class OP,
- class CP,
- template < class > class KP,
- template < class > class RP,
- template < class > class DP,
- template < class > class CNP
- >
- struct less< Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > >
+////////////////////////////////////////////////////////////////////////////////
+/// specialization of std::less for StrongPtr
+/// \ingroup SmartPointerGroup
+////////////////////////////////////////////////////////////////////////////////
+template
+<
+typename T,
+ bool S,
+ class OP,
+ class CP,
+ template < class > class KP,
+ template < class > class RP,
+ template < class > class DP,
+ template < class > class CNP
+ >
+struct less< Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > >
: public binary_function<
- Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP >,
- Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP >, bool >
+ Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP >,
+ Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP >, bool >
+{
+ bool operator () (
+ const Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs,
+ const Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & rhs ) const
{
- bool operator () (
- const Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs,
- const Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & rhs ) const
- {
- return ( lhs < rhs );
- }
- };
+ return ( lhs < rhs );
+ }
+};
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/shared/loki/Threads.h b/shared/loki/Threads.h
index cb44f094..8fb5d362 100644
--- a/shared/loki/Threads.h
+++ b/shared/loki/Threads.h
@@ -54,26 +54,26 @@
#if defined(LOKI_CLASS_LEVEL_THREADING) || defined(LOKI_OBJECT_LEVEL_THREADING)
- #define LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL ::Loki::ClassLevelLockable
-
- #if defined(LOKI_CLASS_LEVEL_THREADING) && !defined(LOKI_OBJECT_LEVEL_THREADING)
- #define LOKI_DEFAULT_THREADING ::Loki::ClassLevelLockable
- #else
- #define LOKI_DEFAULT_THREADING ::Loki::ObjectLevelLockable
- #endif
-
- #if defined(_WIN32) || defined(_WIN64)
- #include <windows.h>
- #define LOKI_WINDOWS_H
- #else
- #include <pthread.h>
- #define LOKI_PTHREAD_H
- #endif
+#define LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL ::Loki::ClassLevelLockable
+
+#if defined(LOKI_CLASS_LEVEL_THREADING) && !defined(LOKI_OBJECT_LEVEL_THREADING)
+#define LOKI_DEFAULT_THREADING ::Loki::ClassLevelLockable
+#else
+#define LOKI_DEFAULT_THREADING ::Loki::ObjectLevelLockable
+#endif
+
+#if defined(_WIN32) || defined(_WIN64)
+#include <windows.h>
+#define LOKI_WINDOWS_H
+#else
+#include <pthread.h>
+#define LOKI_PTHREAD_H
+#endif
#else
- #define LOKI_DEFAULT_THREADING ::Loki::SingleThreaded
- #define LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL ::Loki::SingleThreaded
+#define LOKI_DEFAULT_THREADING ::Loki::SingleThreaded
+#define LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL ::Loki::SingleThreaded
#endif
@@ -314,291 +314,291 @@
namespace Loki
{
- ////////////////////////////////////////////////////////////////////////////////
- /// \class Mutex
- //
- /// \ingroup ThreadingGroup
- /// A simple and portable Mutex. A default policy class for locking objects.
- ////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+/// \class Mutex
+//
+/// \ingroup ThreadingGroup
+/// A simple and portable Mutex. A default policy class for locking objects.
+////////////////////////////////////////////////////////////////////////////////
- class Mutex
+class Mutex
+{
+public:
+ Mutex() LOKI_THREADS_MUTEX_CTOR(mtx_)
{
- public:
- Mutex() LOKI_THREADS_MUTEX_CTOR(mtx_)
- {
- LOKI_THREADS_MUTEX_INIT(&mtx_);
- }
- ~Mutex()
- {
- LOKI_THREADS_MUTEX_DELETE(&mtx_);
- }
- void Lock()
- {
- LOKI_THREADS_MUTEX_LOCK(&mtx_);
- }
- void Unlock()
- {
- LOKI_THREADS_MUTEX_UNLOCK(&mtx_);
- }
- private:
- /// Copy-constructor not implemented.
- Mutex(const Mutex &);
- /// Copy-assignement operator not implemented.
- Mutex & operator = (const Mutex &);
- LOKI_THREADS_MUTEX(mtx_)
- };
+ LOKI_THREADS_MUTEX_INIT(&mtx_);
+ }
+ ~Mutex()
+ {
+ LOKI_THREADS_MUTEX_DELETE(&mtx_);
+ }
+ void Lock()
+ {
+ LOKI_THREADS_MUTEX_LOCK(&mtx_);
+ }
+ void Unlock()
+ {
+ LOKI_THREADS_MUTEX_UNLOCK(&mtx_);
+ }
+private:
+ /// Copy-constructor not implemented.
+ Mutex(const Mutex&);
+ /// Copy-assignement operator not implemented.
+ Mutex& operator = (const Mutex&);
+ LOKI_THREADS_MUTEX(mtx_)
+};
- ////////////////////////////////////////////////////////////////////////////////
- /// \class SingleThreaded
- ///
- /// \ingroup ThreadingGroup
- /// Implementation of the ThreadingModel policy used by various classes
- /// Implements a single-threaded model; no synchronization
- ////////////////////////////////////////////////////////////////////////////////
- template <class Host, class MutexPolicy = LOKI_DEFAULT_MUTEX>
- class SingleThreaded
+////////////////////////////////////////////////////////////////////////////////
+/// \class SingleThreaded
+///
+/// \ingroup ThreadingGroup
+/// Implementation of the ThreadingModel policy used by various classes
+/// Implements a single-threaded model; no synchronization
+////////////////////////////////////////////////////////////////////////////////
+template <class Host, class MutexPolicy = LOKI_DEFAULT_MUTEX>
+class SingleThreaded
+{
+public:
+ /// \struct Lock
+ /// Dummy Lock class
+ struct Lock
{
- public:
- /// \struct Lock
- /// Dummy Lock class
- struct Lock
- {
- Lock() {}
- explicit Lock(const SingleThreaded&) {}
- explicit Lock(const SingleThreaded*) {}
- };
+ Lock() {}
+ explicit Lock(const SingleThreaded&) {}
+ explicit Lock(const SingleThreaded*) {}
+ };
- typedef Host VolatileType;
+ typedef Host VolatileType;
- typedef int IntType;
+ typedef int IntType;
- static IntType AtomicAdd(volatile IntType& lval, const IntType val)
- { return lval += val; }
+ static IntType AtomicAdd(volatile IntType& lval, const IntType val)
+ { return lval += val; }
- static IntType AtomicSubtract(volatile IntType& lval, const IntType val)
- { return lval -= val; }
+ static IntType AtomicSubtract(volatile IntType& lval, const IntType val)
+ { return lval -= val; }
- static IntType AtomicMultiply(volatile IntType& lval, const IntType val)
- { return lval *= val; }
+ static IntType AtomicMultiply(volatile IntType& lval, const IntType val)
+ { return lval *= val; }
- static IntType AtomicDivide(volatile IntType& lval, const IntType val)
- { return lval /= val; }
+ static IntType AtomicDivide(volatile IntType& lval, const IntType val)
+ { return lval /= val; }
- static IntType AtomicIncrement(volatile IntType& lval)
- { return ++lval; }
+ static IntType AtomicIncrement(volatile IntType& lval)
+ { return ++lval; }
- static IntType AtomicDecrement(volatile IntType& lval)
- { return --lval; }
+ static IntType AtomicDecrement(volatile IntType& lval)
+ { return --lval; }
- static void AtomicAssign(volatile IntType & lval, const IntType val)
- { lval = val; }
+ static void AtomicAssign(volatile IntType& lval, const IntType val)
+ { lval = val; }
- static void AtomicAssign(IntType & lval, volatile IntType & val)
- { lval = val; }
+ static void AtomicAssign(IntType& lval, volatile IntType& val)
+ { lval = val; }
- static IntType AtomicAdd(volatile IntType& lval, const IntType val, const IntType compare, bool & matches )
- {
- lval += val;
- matches = ( lval == compare );
- return lval;
- }
+ static IntType AtomicAdd(volatile IntType& lval, const IntType val, const IntType compare, bool& matches )
+ {
+ lval += val;
+ matches = ( lval == compare );
+ return lval;
+ }
- static IntType AtomicSubtract(volatile IntType& lval, const IntType val, const IntType compare, bool & matches )
- {
- lval -= val;
- matches = ( lval == compare );
- return lval;
- }
+ static IntType AtomicSubtract(volatile IntType& lval, const IntType val, const IntType compare, bool& matches )
+ {
+ lval -= val;
+ matches = ( lval == compare );
+ return lval;
+ }
- static IntType AtomicMultiply(volatile IntType& lval, const IntType val, const IntType compare, bool & matches )
- {
- lval *= val;
- matches = ( lval == compare );
- return lval;
- }
+ static IntType AtomicMultiply(volatile IntType& lval, const IntType val, const IntType compare, bool& matches )
+ {
+ lval *= val;
+ matches = ( lval == compare );
+ return lval;
+ }
- static IntType AtomicDivide(volatile IntType& lval, const IntType val, const IntType compare, bool & matches )
- {
- lval /= val;
- matches = ( lval == compare );
- return lval;
- }
+ static IntType AtomicDivide(volatile IntType& lval, const IntType val, const IntType compare, bool& matches )
+ {
+ lval /= val;
+ matches = ( lval == compare );
+ return lval;
+ }
- static IntType AtomicIncrement(volatile IntType& lval, const IntType compare, bool & matches )
- {
- ++lval;
- matches = ( lval == compare );
- return lval;
- }
+ static IntType AtomicIncrement(volatile IntType& lval, const IntType compare, bool& matches )
+ {
+ ++lval;
+ matches = ( lval == compare );
+ return lval;
+ }
- static IntType AtomicDecrement(volatile IntType& lval, const IntType compare, bool & matches )
- {
- --lval;
- matches = ( lval == compare );
- return lval;
- }
+ static IntType AtomicDecrement(volatile IntType& lval, const IntType compare, bool& matches )
+ {
+ --lval;
+ matches = ( lval == compare );
+ return lval;
+ }
- };
+};
#if defined(LOKI_WINDOWS_H) || defined(LOKI_PTHREAD_H)
- ////////////////////////////////////////////////////////////////////////////////
- /// \class ObjectLevelLockable
- ///
- /// \ingroup ThreadingGroup
- /// Implementation of the ThreadingModel policy used by various classes
- /// Implements a object-level locking scheme
- ////////////////////////////////////////////////////////////////////////////////
- template < class Host, class MutexPolicy = LOKI_DEFAULT_MUTEX >
- class ObjectLevelLockable
- {
- mutable MutexPolicy mtx_;
+////////////////////////////////////////////////////////////////////////////////
+/// \class ObjectLevelLockable
+///
+/// \ingroup ThreadingGroup
+/// Implementation of the ThreadingModel policy used by various classes
+/// Implements a object-level locking scheme
+////////////////////////////////////////////////////////////////////////////////
+template < class Host, class MutexPolicy = LOKI_DEFAULT_MUTEX >
+class ObjectLevelLockable
+{
+ mutable MutexPolicy mtx_;
- public:
- ObjectLevelLockable() : mtx_() {}
+public:
+ ObjectLevelLockable() : mtx_() {}
- ObjectLevelLockable(const ObjectLevelLockable&) : mtx_() {}
+ ObjectLevelLockable(const ObjectLevelLockable&) : mtx_() {}
- ~ObjectLevelLockable() {}
+ ~ObjectLevelLockable() {}
- class Lock;
- friend class Lock;
+ class Lock;
+ friend class Lock;
- /// \struct Lock
- /// Lock class to lock on object level
- class Lock
- {
- public:
+ /// \struct Lock
+ /// Lock class to lock on object level
+ class Lock
+ {
+ public:
- /// Lock object
- explicit Lock(const ObjectLevelLockable& host) : host_(host)
- {
- host_.mtx_.Lock();
- }
+ /// Lock object
+ explicit Lock(const ObjectLevelLockable& host) : host_(host)
+ {
+ host_.mtx_.Lock();
+ }
- /// Lock object
- explicit Lock(const ObjectLevelLockable* host) : host_(*host)
- {
- host_.mtx_.Lock();
- }
+ /// Lock object
+ explicit Lock(const ObjectLevelLockable* host) : host_(*host)
+ {
+ host_.mtx_.Lock();
+ }
- /// Unlock object
- ~Lock()
- {
- host_.mtx_.Unlock();
- }
+ /// Unlock object
+ ~Lock()
+ {
+ host_.mtx_.Unlock();
+ }
- private:
- /// private by design of the object level threading
- Lock();
- Lock(const Lock&);
- Lock& operator=(const Lock&);
- const ObjectLevelLockable& host_;
- };
+ private:
+ /// private by design of the object level threading
+ Lock();
+ Lock(const Lock&);
+ Lock& operator=(const Lock&);
+ const ObjectLevelLockable& host_;
+ };
- typedef volatile Host VolatileType;
+ typedef volatile Host VolatileType;
- typedef LOKI_THREADS_LONG IntType;
+ typedef LOKI_THREADS_LONG IntType;
- LOKI_THREADS_ATOMIC_FUNCTIONS
+ LOKI_THREADS_ATOMIC_FUNCTIONS
- };
+};
#ifdef LOKI_PTHREAD_H
- template <class Host, class MutexPolicy>
- pthread_mutex_t ObjectLevelLockable<Host, MutexPolicy>::atomic_mutex_ = PTHREAD_MUTEX_INITIALIZER;
+template <class Host, class MutexPolicy>
+pthread_mutex_t ObjectLevelLockable<Host, MutexPolicy>::atomic_mutex_ = PTHREAD_MUTEX_INITIALIZER;
#endif
- ////////////////////////////////////////////////////////////////////////////////
- /// \class ClassLevelLockable
- ///
- /// \ingroup ThreadingGroup
- /// Implementation of the ThreadingModel policy used by various classes
- /// Implements a class-level locking scheme
- ////////////////////////////////////////////////////////////////////////////////
- template <class Host, class MutexPolicy = LOKI_DEFAULT_MUTEX >
- class ClassLevelLockable
+////////////////////////////////////////////////////////////////////////////////
+/// \class ClassLevelLockable
+///
+/// \ingroup ThreadingGroup
+/// Implementation of the ThreadingModel policy used by various classes
+/// Implements a class-level locking scheme
+////////////////////////////////////////////////////////////////////////////////
+template <class Host, class MutexPolicy = LOKI_DEFAULT_MUTEX >
+class ClassLevelLockable
+{
+ struct Initializer
{
- struct Initializer
+ bool init_;
+ MutexPolicy mtx_;
+
+ Initializer() : init_(false), mtx_()
+ {
+ init_ = true;
+ }
+
+ ~Initializer()
{
- bool init_;
- MutexPolicy mtx_;
+ assert(init_);
+ }
+ };
- Initializer() : init_(false), mtx_()
- {
- init_ = true;
- }
+ static Initializer initializer_;
- ~Initializer()
- {
- assert(init_);
- }
- };
+public:
- static Initializer initializer_;
+ class Lock;
+ friend class Lock;
+ /// \struct Lock
+ /// Lock class to lock on class level
+ class Lock
+ {
public:
- class Lock;
- friend class Lock;
+ /// Lock class
+ Lock()
+ {
+ assert(initializer_.init_);
+ initializer_.mtx_.Lock();
+ }
- /// \struct Lock
- /// Lock class to lock on class level
- class Lock
+ /// Lock class
+ explicit Lock(const ClassLevelLockable&)
{
- public:
-
- /// Lock class
- Lock()
- {
- assert(initializer_.init_);
- initializer_.mtx_.Lock();
- }
-
- /// Lock class
- explicit Lock(const ClassLevelLockable&)
- {
- assert(initializer_.init_);
- initializer_.mtx_.Lock();
- }
-
- /// Lock class
- explicit Lock(const ClassLevelLockable*)
- {
- assert(initializer_.init_);
- initializer_.mtx_.Lock();
- }
-
- /// Unlock class
- ~Lock()
- {
- assert(initializer_.init_);
- initializer_.mtx_.Unlock();
- }
-
- private:
- Lock(const Lock&);
- Lock& operator=(const Lock&);
- };
-
- typedef volatile Host VolatileType;
-
- typedef LOKI_THREADS_LONG IntType;
-
- LOKI_THREADS_ATOMIC_FUNCTIONS
+ assert(initializer_.init_);
+ initializer_.mtx_.Lock();
+ }
+ /// Lock class
+ explicit Lock(const ClassLevelLockable*)
+ {
+ assert(initializer_.init_);
+ initializer_.mtx_.Lock();
+ }
+
+ /// Unlock class
+ ~Lock()
+ {
+ assert(initializer_.init_);
+ initializer_.mtx_.Unlock();
+ }
+
+ private:
+ Lock(const Lock&);
+ Lock& operator=(const Lock&);
};
+ typedef volatile Host VolatileType;
+
+ typedef LOKI_THREADS_LONG IntType;
+
+ LOKI_THREADS_ATOMIC_FUNCTIONS
+
+};
+
#ifdef LOKI_PTHREAD_H
- template <class Host, class MutexPolicy>
- pthread_mutex_t ClassLevelLockable<Host, MutexPolicy>::atomic_mutex_ = PTHREAD_MUTEX_INITIALIZER;
+template <class Host, class MutexPolicy>
+pthread_mutex_t ClassLevelLockable<Host, MutexPolicy>::atomic_mutex_ = PTHREAD_MUTEX_INITIALIZER;
#endif
- template < class Host, class MutexPolicy >
- typename ClassLevelLockable< Host, MutexPolicy >::Initializer
- ClassLevelLockable< Host, MutexPolicy >::initializer_;
+template < class Host, class MutexPolicy >
+typename ClassLevelLockable< Host, MutexPolicy >::Initializer
+ClassLevelLockable< Host, MutexPolicy >::initializer_;
#endif // #if defined(LOKI_WINDOWS_H) || defined(LOKI_PTHREAD_H)
diff --git a/shared/loki/Tuple.h b/shared/loki/Tuple.h
index 47fc19e2..ec5ae213 100644
--- a/shared/loki/Tuple.h
+++ b/shared/loki/Tuple.h
@@ -2,14 +2,14 @@
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
-// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author or Addison-Wesley Longman make no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author or Addison-Wesley Longman make no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
@@ -18,5 +18,5 @@
////////////////////////////////////////////////////////////////////////////////
// This file is intentionally left empty
// Due to compiler limitations, its contents has been moved to
-// HierarchyGenerators.h
+// HierarchyGenerators.h
////////////////////////////////////////////////////////////////////////////////
diff --git a/shared/loki/TypeManip.h b/shared/loki/TypeManip.h
index e08b4e03..6b7f4ab8 100644
--- a/shared/loki/TypeManip.h
+++ b/shared/loki/TypeManip.h
@@ -2,14 +2,14 @@
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
-// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author or Addison-Welsey Longman make no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author or Addison-Welsey Longman make no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_TYPEMANIP_INC_
@@ -27,12 +27,12 @@ namespace Loki
// Defines 'value', an enum that evaluates to v
////////////////////////////////////////////////////////////////////////////////
- template <int v>
- struct Int2Type
- {
- enum { value = v };
- };
-
+template <int v>
+struct Int2Type
+{
+ enum { value = v };
+};
+
////////////////////////////////////////////////////////////////////////////////
// class template Type2Type
// Converts each type into a unique, insipid type
@@ -40,12 +40,12 @@ namespace Loki
// Defines the type OriginalType which maps back to T
////////////////////////////////////////////////////////////////////////////////
- template <typename T>
- struct Type2Type
- {
- typedef T OriginalType;
- };
-
+template <typename T>
+struct Type2Type
+{
+ typedef T OriginalType;
+};
+
////////////////////////////////////////////////////////////////////////////////
// class template Select
// Selects one of two types based upon a boolean constant
@@ -56,17 +56,17 @@ namespace Loki
// Result evaluates to T if flag is true, and to U otherwise.
////////////////////////////////////////////////////////////////////////////////
- template <bool flag, typename T, typename U>
- struct Select
- {
- typedef T Result;
- };
- template <typename T, typename U>
- struct Select<false, T, U>
- {
- typedef U Result;
- };
-
+template <bool flag, typename T, typename U>
+struct Select
+{
+ typedef T Result;
+};
+template <typename T, typename U>
+struct Select<false, T, U>
+{
+ typedef U Result;
+};
+
////////////////////////////////////////////////////////////////////////////////
// class template IsSameType
// Return true iff two given types are the same
@@ -76,34 +76,34 @@ namespace Loki
// Result evaluates to true iff U == T (types equal)
////////////////////////////////////////////////////////////////////////////////
- template <typename T, typename U>
- struct IsSameType
- {
- enum { value = false };
- };
-
- template <typename T>
- struct IsSameType<T,T>
- {
- enum { value = true };
- };
+template <typename T, typename U>
+struct IsSameType
+{
+ enum { value = false };
+};
+
+template <typename T>
+struct IsSameType<T,T>
+{
+ enum { value = true };
+};
////////////////////////////////////////////////////////////////////////////////
// Helper types Small and Big - guarantee that sizeof(Small) < sizeof(Big)
////////////////////////////////////////////////////////////////////////////////
- namespace Private
- {
- template <class T, class U>
- struct ConversionHelper
- {
- typedef char Small;
- struct Big { char dummy[2]; };
- static Big Test(...);
- static Small Test(U);
- static T MakeT();
- };
- }
+namespace Private
+{
+template <class T, class U>
+struct ConversionHelper
+{
+ typedef char Small;
+ struct Big { char dummy[2]; };
+ static Big Test(...);
+ static Small Test(U);
+ static T MakeT();
+};
+}
////////////////////////////////////////////////////////////////////////////////
// class template Conversion
@@ -121,48 +121,48 @@ namespace Loki
// Caveat: might not work if T and U are in a private inheritance hierarchy.
////////////////////////////////////////////////////////////////////////////////
- template <class T, class U>
- struct Conversion
- {
- typedef Private::ConversionHelper<T, U> H;
+template <class T, class U>
+struct Conversion
+{
+ typedef Private::ConversionHelper<T, U> H;
#ifndef __MWERKS__
- enum { exists = sizeof(typename H::Small) == sizeof((H::Test(H::MakeT()))) };
+ enum { exists = sizeof(typename H::Small) == sizeof((H::Test(H::MakeT()))) };
#else
- enum { exists = false };
+ enum { exists = false };
#endif
- enum { exists2Way = exists && Conversion<U, T>::exists };
- enum { sameType = false };
- };
-
- template <class T>
- struct Conversion<T, T>
- {
- enum { exists = 1, exists2Way = 1, sameType = 1 };
- };
-
- template <class T>
- struct Conversion<void, T>
- {
- enum { exists = 0, exists2Way = 0, sameType = 0 };
- };
-
- template <class T>
- struct Conversion<T, void>
- {
- enum { exists = 0, exists2Way = 0, sameType = 0 };
- };
-
- template <>
- struct Conversion<void, void>
- {
- public:
- enum { exists = 1, exists2Way = 1, sameType = 1 };
- };
+ enum { exists2Way = exists && Conversion<U, T>::exists };
+ enum { sameType = false };
+};
+
+template <class T>
+struct Conversion<T, T>
+{
+ enum { exists = 1, exists2Way = 1, sameType = 1 };
+};
+
+template <class T>
+struct Conversion<void, T>
+{
+ enum { exists = 0, exists2Way = 0, sameType = 0 };
+};
+
+template <class T>
+struct Conversion<T, void>
+{
+ enum { exists = 0, exists2Way = 0, sameType = 0 };
+};
+
+template <>
+struct Conversion<void, void>
+{
+public:
+ enum { exists = 1, exists2Way = 1, sameType = 1 };
+};
////////////////////////////////////////////////////////////////////////////////
// class template SuperSubclass
-// Invocation: SuperSubclass<B, D>::value where B and D are types.
-// Returns true if B is a public base of D, or if B and D are aliases of the
+// Invocation: SuperSubclass<B, D>::value where B and D are types.
+// Returns true if B is a public base of D, or if B and D are aliases of the
// same type.
//
// Caveat: might not work if T and U are in a private inheritance hierarchy.
@@ -172,41 +172,44 @@ template <class T, class U>
struct SuperSubclass
{
enum { value = (::Loki::Conversion<const volatile U*, const volatile T*>::exists &&
- !::Loki::Conversion<const volatile T*, const volatile void*>::sameType) };
-
+ !::Loki::Conversion<const volatile T*, const volatile void*>::sameType)
+ };
+
// Dummy enum to make sure that both classes are fully defined.
- enum{ dontUseWithIncompleteTypes = ( sizeof (T) == sizeof (U) ) };
+ enum { dontUseWithIncompleteTypes = ( sizeof (T) == sizeof (U) ) };
};
template <>
-struct SuperSubclass<void, void>
+struct SuperSubclass<void, void>
{
enum { value = false };
};
template <class U>
-struct SuperSubclass<void, U>
+struct SuperSubclass<void, U>
{
enum { value = (::Loki::Conversion<const volatile U*, const volatile void*>::exists &&
- !::Loki::Conversion<const volatile void*, const volatile void*>::sameType) };
-
+ !::Loki::Conversion<const volatile void*, const volatile void*>::sameType)
+ };
+
// Dummy enum to make sure that both classes are fully defined.
- enum{ dontUseWithIncompleteTypes = ( 0 == sizeof (U) ) };
+ enum { dontUseWithIncompleteTypes = ( 0 == sizeof (U) ) };
};
template <class T>
-struct SuperSubclass<T, void>
+struct SuperSubclass<T, void>
{
enum { value = (::Loki::Conversion<const volatile void*, const volatile T*>::exists &&
- !::Loki::Conversion<const volatile T*, const volatile void*>::sameType) };
-
+ !::Loki::Conversion<const volatile T*, const volatile void*>::sameType)
+ };
+
// Dummy enum to make sure that both classes are fully defined.
- enum{ dontUseWithIncompleteTypes = ( sizeof (T) == 0 ) };
+ enum { dontUseWithIncompleteTypes = ( sizeof (T) == 0 ) };
};
////////////////////////////////////////////////////////////////////////////////
// class template SuperSubclassStrict
-// Invocation: SuperSubclassStrict<B, D>::value where B and D are types.
+// Invocation: SuperSubclassStrict<B, D>::value where B and D are types.
// Returns true if B is a public base of D.
//
// Caveat: might not work if T and U are in a private inheritance hierarchy.
@@ -216,39 +219,42 @@ template<class T,class U>
struct SuperSubclassStrict
{
enum { value = (::Loki::Conversion<const volatile U*, const volatile T*>::exists &&
- !::Loki::Conversion<const volatile T*, const volatile void*>::sameType &&
- !::Loki::Conversion<const volatile T*, const volatile U*>::sameType) };
-
+ !::Loki::Conversion<const volatile T*, const volatile void*>::sameType &&
+ !::Loki::Conversion<const volatile T*, const volatile U*>::sameType)
+ };
+
// Dummy enum to make sure that both classes are fully defined.
- enum{ dontUseWithIncompleteTypes = ( sizeof (T) == sizeof (U) ) };
+ enum { dontUseWithIncompleteTypes = ( sizeof (T) == sizeof (U) ) };
};
template<>
-struct SuperSubclassStrict<void, void>
+struct SuperSubclassStrict<void, void>
{
enum { value = false };
};
template<class U>
-struct SuperSubclassStrict<void, U>
+struct SuperSubclassStrict<void, U>
{
enum { value = (::Loki::Conversion<const volatile U*, const volatile void*>::exists &&
- !::Loki::Conversion<const volatile void*, const volatile void*>::sameType &&
- !::Loki::Conversion<const volatile void*, const volatile U*>::sameType) };
-
+ !::Loki::Conversion<const volatile void*, const volatile void*>::sameType &&
+ !::Loki::Conversion<const volatile void*, const volatile U*>::sameType)
+ };
+
// Dummy enum to make sure that both classes are fully defined.
- enum{ dontUseWithIncompleteTypes = ( 0 == sizeof (U) ) };
+ enum { dontUseWithIncompleteTypes = ( 0 == sizeof (U) ) };
};
template<class T>
-struct SuperSubclassStrict<T, void>
+struct SuperSubclassStrict<T, void>
{
enum { value = (::Loki::Conversion<const volatile void*, const volatile T*>::exists &&
- !::Loki::Conversion<const volatile T*, const volatile void*>::sameType &&
- !::Loki::Conversion<const volatile T*, const volatile void*>::sameType) };
-
+ !::Loki::Conversion<const volatile T*, const volatile void*>::sameType &&
+ !::Loki::Conversion<const volatile T*, const volatile void*>::sameType)
+ };
+
// Dummy enum to make sure that both classes are fully defined.
- enum{ dontUseWithIncompleteTypes = ( sizeof (T) == 0 ) };
+ enum { dontUseWithIncompleteTypes = ( sizeof (T) == 0 ) };
};
@@ -256,8 +262,8 @@ struct SuperSubclassStrict<T, void>
////////////////////////////////////////////////////////////////////////////////
// macro SUPERSUBCLASS
-// Invocation: SUPERSUBCLASS(B, D) where B and D are types.
-// Returns true if B is a public base of D, or if B and D are aliases of the
+// Invocation: SUPERSUBCLASS(B, D) where B and D are types.
+// Returns true if B is a public base of D, or if B and D are aliases of the
// same type.
//
// Caveat: might not work if T and U are in a private inheritance hierarchy.
@@ -269,7 +275,7 @@ struct SuperSubclassStrict<T, void>
////////////////////////////////////////////////////////////////////////////////
// macro SUPERSUBCLASS_STRICT
-// Invocation: SUPERSUBCLASS(B, D) where B and D are types.
+// Invocation: SUPERSUBCLASS(B, D) where B and D are types.
// Returns true if B is a public base of D.
//
// Caveat: might not work if T and U are in a private inheritance hierarchy.
diff --git a/shared/loki/TypeTraits.h b/shared/loki/TypeTraits.h
index a592cab9..00ef069e 100644
--- a/shared/loki/TypeTraits.h
+++ b/shared/loki/TypeTraits.h
@@ -2,14 +2,14 @@
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
-// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author or Addison-Wesley Longman make no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author or Addison-Wesley Longman make no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_TYPETRAITS_INC_
@@ -27,7 +27,7 @@
#ifdef _MSC_VER
-#pragma warning( push )
+#pragma warning( push )
#pragma warning( disable : 4180 ) //qualifier applied to function type has no meaning; ignored
#endif
@@ -36,7 +36,7 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
// class template IsCustomUnsignedInt
// Offers a means to integrate nonstandard built-in unsigned integral types
-// (such as unsigned __int64 or unsigned long long int) with the TypeTraits
+// (such as unsigned __int64 or unsigned long long int) with the TypeTraits
// class template defined below.
// Invocation: IsCustomUnsignedInt<T> where T is any type
// Defines 'value', an enum that is 1 iff T is a custom built-in unsigned
@@ -45,16 +45,16 @@ namespace Loki
// and define value = 1 in those specializations
////////////////////////////////////////////////////////////////////////////////
- template <typename T>
- struct IsCustomUnsignedInt
- {
- enum { value = 0 };
- };
+template <typename T>
+struct IsCustomUnsignedInt
+{
+ enum { value = 0 };
+};
////////////////////////////////////////////////////////////////////////////////
// class template IsCustomSignedInt
// Offers a means to integrate nonstandard built-in unsigned integral types
-// (such as unsigned __int64 or unsigned long long int) with the TypeTraits
+// (such as unsigned __int64 or unsigned long long int) with the TypeTraits
// class template defined below.
// Invocation: IsCustomSignedInt<T> where T is any type
// Defines 'value', an enum that is 1 iff T is a custom built-in signed
@@ -63,11 +63,11 @@ namespace Loki
// and define value = 1 in those specializations
////////////////////////////////////////////////////////////////////////////////
- template <typename T>
- struct IsCustomSignedInt
- {
- enum { value = 0 };
- };
+template <typename T>
+struct IsCustomSignedInt
+{
+ enum { value = 0 };
+};
////////////////////////////////////////////////////////////////////////////////
// class template IsCustomFloat
@@ -80,1955 +80,1955 @@ namespace Loki
// and define value = 1 in those specializations
////////////////////////////////////////////////////////////////////////////////
- template <typename T>
- struct IsCustomFloat
- {
- enum { value = 0 };
- };
+template <typename T>
+struct IsCustomFloat
+{
+ enum { value = 0 };
+};
////////////////////////////////////////////////////////////////////////////////
// Helper types for class template TypeTraits defined below
////////////////////////////////////////////////////////////////////////////////
- namespace Private
- {
-#ifndef LOKI_DISABLE_TYPELIST_MACROS
- typedef LOKI_TYPELIST_4(unsigned char, unsigned short int,unsigned int, unsigned long int)
- StdUnsignedInts;
- typedef LOKI_TYPELIST_4(signed char, short int,int, long int)
- StdSignedInts;
- typedef LOKI_TYPELIST_3(bool, char, wchar_t)
- StdOtherInts;
- typedef LOKI_TYPELIST_3(float, double, long double)
- StdFloats;
+namespace Private
+{
+#ifndef LOKI_DISABLE_TYPELIST_MACROS
+typedef LOKI_TYPELIST_4(unsigned char, unsigned short int,unsigned int, unsigned long int)
+StdUnsignedInts;
+typedef LOKI_TYPELIST_4(signed char, short int,int, long int)
+StdSignedInts;
+typedef LOKI_TYPELIST_3(bool, char, wchar_t)
+StdOtherInts;
+typedef LOKI_TYPELIST_3(float, double, long double)
+StdFloats;
#else
- typedef Loki::Seq<unsigned char, unsigned short int,unsigned int, unsigned long int>::Type
- StdUnsignedInts;
- typedef Loki::Seq<signed char, short int,int, long int>::Type
- StdSignedInts;
- typedef Loki::Seq<bool, char, wchar_t>::Type
- StdOtherInts;
- typedef Loki::Seq<float, double, long double>::Type
- StdFloats;
-
-#endif
- template <typename U> struct AddPointer
- {
- typedef U* Result;
- };
-
- template <typename U> struct AddPointer<U&>
- {
- typedef U* Result;
- };
-
- template <class U> struct AddReference
- {
- typedef U & Result;
- };
-
- template <class U> struct AddReference<U &>
- {
- typedef U & Result;
- };
-
- template <> struct AddReference<void>
- {
- typedef NullType Result;
- };
-
- template <class U> struct AddParameterType
- {
- typedef const U & Result;
- };
-
- template <class U> struct AddParameterType<U &>
- {
- typedef U & Result;
- };
-
- template <> struct AddParameterType<void>
- {
- typedef NullType Result;
- };
-
- template <typename T>
- struct IsFunctionPointerRaw
- {enum{result = 0};};
-
- template <typename T>
- struct IsFunctionPointerRaw<T(*)()>
- {enum {result = 1};};
-
- template <typename T,
- typename P01>
- struct IsFunctionPointerRaw<T(*)(P01)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18, typename P19>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, P19)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18, typename P19, typename P20>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, P19, P20)>
- {enum {result = 1};};
-
- template <typename T>
- struct IsFunctionPointerRaw<T(*)(
- ...)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01>
- struct IsFunctionPointerRaw<T(*)(
- P01, ...)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, ...)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, ...)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, ...)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- ...)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, ...)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, ...)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, ...)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, ...)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- ...)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, ...)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, ...)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, ...)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, ...)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- ...)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, ...)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, ...)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, ...)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18, typename P19>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, P19, ...)>
- {enum {result = 1};};
-
- template <typename T,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18, typename P19, typename P20>
- struct IsFunctionPointerRaw<T(*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, P19, P20,
- ...)>
- {enum {result = 1};};
-
-
- template <typename T>
- struct IsMemberFunctionPointerRaw
- {enum{result = 0};};
-
- template <typename T, typename S>
- struct IsMemberFunctionPointerRaw<T (S::*)()>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01>
- struct IsMemberFunctionPointerRaw<T (S::*)(P01)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18, typename P19>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, P19)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18, typename P19, typename P20>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, P19, P20)>
- {enum {result = 1};};
-
- template <typename T, typename S>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- ...)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, ...)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, ...)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, ...)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, ...)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- ...)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, ...)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, ...)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, ...)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, ...)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- ...)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, ...)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, ...)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, ...)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, ...)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- ...)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, ...)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, ...)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, ...)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18, typename P19>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, P19, ...)>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18, typename P19, typename P20>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, P19, P20,
- ...)>
- {enum {result = 1};};
-
- // Const versions
-
- template <typename T, typename S>
- struct IsMemberFunctionPointerRaw<T (S::*)() const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01>
- struct IsMemberFunctionPointerRaw<T (S::*)(P01) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18, typename P19>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, P19) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18, typename P19, typename P20>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, P19, P20) const>
- {enum {result = 1};};
-
- template <typename T, typename S>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- ...) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, ...) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, ...) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, ...) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, ...) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- ...) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, ...) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, ...) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, ...) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, ...) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- ...) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, ...) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, ...) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, ...) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, ...) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- ...) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, ...) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, ...) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, ...) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18, typename P19>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, P19, ...) const>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18, typename P19, typename P20>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, P19, P20,
- ...) const>
- {enum {result = 1};};
-
- // Volatile versions
-
- template <typename T, typename S>
- struct IsMemberFunctionPointerRaw<T (S::*)() volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01>
- struct IsMemberFunctionPointerRaw<T (S::*)(P01) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18, typename P19>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, P19) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18, typename P19, typename P20>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, P19, P20) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- ...) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, ...) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, ...) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, ...) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, ...) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- ...) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, ...) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, ...) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, ...) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, ...) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- ...) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, ...) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, ...) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, ...) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, ...) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- ...) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, ...) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, ...) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, ...) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18, typename P19>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, P19, ...) volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18, typename P19, typename P20>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, P19, P20,
- ...) volatile>
- {enum {result = 1};};
-
- // Const volatile versions
-
- template <typename T, typename S>
- struct IsMemberFunctionPointerRaw<T (S::*)() const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01>
- struct IsMemberFunctionPointerRaw<T (S::*)(P01) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18, typename P19>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, P19) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18, typename P19, typename P20>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, P19, P20) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- ...) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, ...) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, ...) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, ...) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, ...) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- ...) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, ...) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, ...) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, ...) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, ...) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- ...) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, ...) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, ...) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, ...) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, ...) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- ...) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, ...) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, ...) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, ...) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18, typename P19>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, P19, ...) const volatile>
- {enum {result = 1};};
-
- template <typename T, typename S,
- typename P01, typename P02, typename P03, typename P04, typename P05,
- typename P06, typename P07, typename P08, typename P09, typename P10,
- typename P11, typename P12, typename P13, typename P14, typename P15,
- typename P16, typename P17, typename P18, typename P19, typename P20>
- struct IsMemberFunctionPointerRaw<T (S::*)(
- P01, P02, P03, P04, P05,
- P06, P07, P08, P09, P10,
- P11, P12, P13, P14, P15,
- P16, P17, P18, P19, P20,
- ...) const volatile>
- {enum {result = 1};};
-
- }// namespace Private
-
+typedef Loki::Seq<unsigned char, unsigned short int,unsigned int, unsigned long int>::Type
+StdUnsignedInts;
+typedef Loki::Seq<signed char, short int,int, long int>::Type
+StdSignedInts;
+typedef Loki::Seq<bool, char, wchar_t>::Type
+StdOtherInts;
+typedef Loki::Seq<float, double, long double>::Type
+StdFloats;
+
+#endif
+template <typename U> struct AddPointer
+{
+ typedef U* Result;
+};
+
+template <typename U> struct AddPointer<U&>
+{
+ typedef U* Result;
+};
+
+template <class U> struct AddReference
+{
+ typedef U& Result;
+};
+
+template <class U> struct AddReference<U&>
+{
+ typedef U& Result;
+};
+
+template <> struct AddReference<void>
+{
+ typedef NullType Result;
+};
+
+template <class U> struct AddParameterType
+{
+ typedef const U& Result;
+};
+
+template <class U> struct AddParameterType<U&>
+{
+ typedef U& Result;
+};
+
+template <> struct AddParameterType<void>
+{
+ typedef NullType Result;
+};
+
+template <typename T>
+struct IsFunctionPointerRaw
+ {enum {result = 0};};
+
+template <typename T>
+struct IsFunctionPointerRaw<T(*)()>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01>
+struct IsFunctionPointerRaw<T(*)(P01)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18, typename P19>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, P19)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18, typename P19, typename P20>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, P19, P20)>
+{enum {result = 1};};
+
+template <typename T>
+struct IsFunctionPointerRaw<T(*)(
+ ...)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01>
+struct IsFunctionPointerRaw<T(*)(
+ P01, ...)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, ...)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, ...)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, ...)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ ...)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, ...)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, ...)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, ...)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, ...)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ ...)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, ...)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, ...)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, ...)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, ...)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ ...)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, ...)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, ...)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, ...)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18, typename P19>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, P19, ...)>
+{enum {result = 1};};
+
+template <typename T,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18, typename P19, typename P20>
+struct IsFunctionPointerRaw<T(*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, P19, P20,
+ ...)>
+{enum {result = 1};};
+
+
+template <typename T>
+struct IsMemberFunctionPointerRaw
+ {enum {result = 0};};
+
+template <typename T, typename S>
+struct IsMemberFunctionPointerRaw<T (S::*)()>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01>
+struct IsMemberFunctionPointerRaw<T (S::*)(P01)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18, typename P19>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, P19)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18, typename P19, typename P20>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, P19, P20)>
+{enum {result = 1};};
+
+template <typename T, typename S>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ ...)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, ...)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, ...)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, ...)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, ...)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ ...)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, ...)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, ...)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, ...)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, ...)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ ...)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, ...)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, ...)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, ...)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, ...)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ ...)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, ...)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, ...)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, ...)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18, typename P19>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, P19, ...)>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18, typename P19, typename P20>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, P19, P20,
+ ...)>
+{enum {result = 1};};
+
+// Const versions
+
+template <typename T, typename S>
+struct IsMemberFunctionPointerRaw<T (S::*)() const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01>
+struct IsMemberFunctionPointerRaw<T (S::*)(P01) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18, typename P19>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, P19) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18, typename P19, typename P20>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, P19, P20) const>
+{enum {result = 1};};
+
+template <typename T, typename S>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ ...) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, ...) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, ...) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, ...) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, ...) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ ...) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, ...) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, ...) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, ...) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, ...) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ ...) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, ...) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, ...) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, ...) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, ...) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ ...) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, ...) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, ...) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, ...) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18, typename P19>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, P19, ...) const>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18, typename P19, typename P20>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, P19, P20,
+ ...) const>
+{enum {result = 1};};
+
+// Volatile versions
+
+template <typename T, typename S>
+struct IsMemberFunctionPointerRaw<T (S::*)() volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01>
+struct IsMemberFunctionPointerRaw<T (S::*)(P01) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18, typename P19>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, P19) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18, typename P19, typename P20>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, P19, P20) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ ...) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, ...) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, ...) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, ...) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, ...) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ ...) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, ...) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, ...) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, ...) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, ...) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ ...) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, ...) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, ...) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, ...) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, ...) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ ...) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, ...) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, ...) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, ...) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18, typename P19>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, P19, ...) volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18, typename P19, typename P20>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, P19, P20,
+ ...) volatile>
+{enum {result = 1};};
+
+// Const volatile versions
+
+template <typename T, typename S>
+struct IsMemberFunctionPointerRaw<T (S::*)() const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01>
+struct IsMemberFunctionPointerRaw<T (S::*)(P01) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18, typename P19>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, P19) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18, typename P19, typename P20>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, P19, P20) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ ...) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, ...) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, ...) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, ...) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, ...) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ ...) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, ...) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, ...) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, ...) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, ...) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ ...) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, ...) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, ...) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, ...) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, ...) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ ...) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, ...) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, ...) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, ...) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18, typename P19>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, P19, ...) const volatile>
+{enum {result = 1};};
+
+template <typename T, typename S,
+ typename P01, typename P02, typename P03, typename P04, typename P05,
+ typename P06, typename P07, typename P08, typename P09, typename P10,
+ typename P11, typename P12, typename P13, typename P14, typename P15,
+ typename P16, typename P17, typename P18, typename P19, typename P20>
+struct IsMemberFunctionPointerRaw<T (S::*)(
+ P01, P02, P03, P04, P05,
+ P06, P07, P08, P09, P10,
+ P11, P12, P13, P14, P15,
+ P16, P17, P18, P19, P20,
+ ...) const volatile>
+{enum {result = 1};};
+
+}// namespace Private
+
////////////////////////////////////////////////////////////////////////////////
// class template TypeTraits
//
@@ -2036,10 +2036,10 @@ namespace Loki
// Invocations (T is a type, TypeTraits<T>::Property):
//
// - isPointer : returns true if T is a pointer type
-// - PointeeType : returns the type to which T points if T is a pointer
+// - PointeeType : returns the type to which T points if T is a pointer
// type, NullType otherwise
// - isReference : returns true if T is a reference type
-// - ReferredType : returns the type to which T refers if T is a reference
+// - ReferredType : returns the type to which T refers if T is a reference
// type, NullType otherwise
// - isMemberPointer : returns true if T is a pointer to member type
// - isStdUnsignedInt: returns true if T is a standard unsigned integral type
@@ -2054,169 +2054,177 @@ namespace Loki
// - isFloat : returns true if T is a floating-point type
// - isArith : returns true if T is a arithmetic type
// - isFundamental : returns true if T is a fundamental type
-// - ParameterType : returns the optimal type to be used as a parameter for
+// - ParameterType : returns the optimal type to be used as a parameter for
// functions that take Ts
// - isConst : returns true if T is a const-qualified type
// - NonConstType : Type with removed 'const' qualifier from T, if any
// - isVolatile : returns true if T is a volatile-qualified type
// - NonVolatileType : Type with removed 'volatile' qualifier from T, if any
-// - UnqualifiedType : Type with removed 'const' and 'volatile' qualifiers from
+// - UnqualifiedType : Type with removed 'const' and 'volatile' qualifiers from
// T, if any
-// - ParameterType : returns the optimal type to be used as a parameter
+// - ParameterType : returns the optimal type to be used as a parameter
// for functions that take 'const T's
//
////////////////////////////////////////////////////////////////////////////////
- template <typename T>
- class TypeTraits
+template <typename T>
+class TypeTraits
+{
+private:
+
+ template <class U> struct ReferenceTraits
{
- private:
-
- template <class U> struct ReferenceTraits
- {
- enum { result = false };
- typedef U ReferredType;
- };
-
- template <class U> struct ReferenceTraits<U&>
- {
- enum { result = true };
- typedef U ReferredType;
- };
-
- template <class U> struct PointerTraits
- {
- enum { result = false };
- typedef NullType PointeeType;
- };
-
- template <class U> struct PointerTraits<U*>
- {
- enum { result = true };
- typedef U PointeeType;
- };
-
- template <class U> struct PointerTraits<U*&>
- {
- enum { result = true };
- typedef U PointeeType;
- };
-
- template <class U> struct PToMTraits
- {
- enum { result = false };
- };
-
- template <class U, class V> struct PToMTraits<U V::*>
- {
- enum { result = true };
- };
-
- template <class U, class V> struct PToMTraits<U V::*&>
- {
- enum { result = true };
- };
-
- template <class U> struct FunctionPointerTraits
- {
- enum{ result = Private::IsFunctionPointerRaw<U>::result };
- };
-
- template <typename U> struct PToMFunctionTraits
- {
- enum{ result = Private::IsMemberFunctionPointerRaw<U>::result };
- };
-
- template <class U> struct UnConst
- {
- typedef U Result;
- enum { isConst = 0 };
- };
-
- template <class U> struct UnConst<const U>
- {
- typedef U Result;
- enum { isConst = 1 };
- };
-
- template <class U> struct UnConst<const U&>
- {
- typedef U& Result;
- enum { isConst = 1 };
- };
-
- template <class U> struct UnVolatile
- {
- typedef U Result;
- enum { isVolatile = 0 };
- };
-
- template <class U> struct UnVolatile<volatile U>
- {
- typedef U Result;
- enum { isVolatile = 1 };
- };
-
- template <class U> struct UnVolatile<volatile U&>
- {
- typedef U& Result;
- enum { isVolatile = 1 };
- };
-
- public:
- typedef typename UnConst<T>::Result
- NonConstType;
- typedef typename UnVolatile<T>::Result
- NonVolatileType;
- typedef typename UnVolatile<typename UnConst<T>::Result>::Result
- UnqualifiedType;
- typedef typename PointerTraits<UnqualifiedType>::PointeeType
- PointeeType;
- typedef typename ReferenceTraits<T>::ReferredType
- ReferredType;
-
- enum { isConst = UnConst<T>::isConst };
- enum { isVolatile = UnVolatile<T>::isVolatile };
- enum { isReference = ReferenceTraits<UnqualifiedType>::result };
- enum { isFunction = FunctionPointerTraits<typename Private::AddPointer<T>::Result >::result };
- enum { isFunctionPointer= FunctionPointerTraits<
- typename ReferenceTraits<UnqualifiedType>::ReferredType >::result };
- enum { isMemberFunctionPointer= PToMFunctionTraits<
- typename ReferenceTraits<UnqualifiedType>::ReferredType >::result };
- enum { isMemberPointer = PToMTraits<
- typename ReferenceTraits<UnqualifiedType>::ReferredType >::result ||
- isMemberFunctionPointer };
- enum { isPointer = PointerTraits<
- typename ReferenceTraits<UnqualifiedType>::ReferredType >::result ||
- isFunctionPointer };
-
- enum { isStdUnsignedInt = TL::IndexOf<Private::StdUnsignedInts, UnqualifiedType>::value >= 0 ||
- TL::IndexOf<Private::StdUnsignedInts,
- typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0};
- enum { isStdSignedInt = TL::IndexOf<Private::StdSignedInts, UnqualifiedType>::value >= 0 ||
- TL::IndexOf<Private::StdSignedInts,
- typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0};
- enum { isStdIntegral = isStdUnsignedInt || isStdSignedInt ||
- TL::IndexOf<Private::StdOtherInts, UnqualifiedType>::value >= 0 ||
- TL::IndexOf<Private::StdOtherInts,
- typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0};
- enum { isStdFloat = TL::IndexOf<Private::StdFloats, UnqualifiedType>::value >= 0 ||
- TL::IndexOf<Private::StdFloats,
- typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0};
- enum { isStdArith = isStdIntegral || isStdFloat };
- enum { isStdFundamental = isStdArith || isStdFloat || Conversion<T, void>::sameType };
-
- enum { isUnsignedInt = isStdUnsignedInt || IsCustomUnsignedInt<UnqualifiedType>::value };
- enum { isSignedInt = isStdSignedInt || IsCustomSignedInt<UnqualifiedType>::value };
- enum { isIntegral = isStdIntegral || isUnsignedInt || isSignedInt };
- enum { isFloat = isStdFloat || IsCustomFloat<UnqualifiedType>::value };
- enum { isArith = isIntegral || isFloat };
- enum { isFundamental = isStdFundamental || isArith };
-
- typedef typename Select<isStdArith || isPointer || isMemberPointer, T,
- typename Private::AddParameterType<T>::Result>::Result
- ParameterType;
+ enum { result = false };
+ typedef U ReferredType;
+ };
+
+ template <class U> struct ReferenceTraits<U&>
+ {
+ enum { result = true };
+ typedef U ReferredType;
+ };
+
+ template <class U> struct PointerTraits
+ {
+ enum { result = false };
+ typedef NullType PointeeType;
+ };
+
+ template <class U> struct PointerTraits<U*>
+ {
+ enum { result = true };
+ typedef U PointeeType;
};
+
+ template <class U> struct PointerTraits<U*&>
+ {
+ enum { result = true };
+ typedef U PointeeType;
+ };
+
+ template <class U> struct PToMTraits
+ {
+ enum { result = false };
+ };
+
+ template <class U, class V> struct PToMTraits<U V::*>
+ {
+ enum { result = true };
+ };
+
+ template <class U, class V> struct PToMTraits<U V::*&>
+ {
+ enum { result = true };
+ };
+
+ template <class U> struct FunctionPointerTraits
+ {
+ enum { result = Private::IsFunctionPointerRaw<U>::result };
+ };
+
+ template <typename U> struct PToMFunctionTraits
+ {
+ enum { result = Private::IsMemberFunctionPointerRaw<U>::result };
+ };
+
+ template <class U> struct UnConst
+ {
+ typedef U Result;
+ enum { isConst = 0 };
+ };
+
+ template <class U> struct UnConst<const U>
+ {
+ typedef U Result;
+ enum { isConst = 1 };
+ };
+
+ template <class U> struct UnConst<const U&>
+ {
+ typedef U& Result;
+ enum { isConst = 1 };
+ };
+
+ template <class U> struct UnVolatile
+ {
+ typedef U Result;
+ enum { isVolatile = 0 };
+ };
+
+ template <class U> struct UnVolatile<volatile U>
+ {
+ typedef U Result;
+ enum { isVolatile = 1 };
+ };
+
+ template <class U> struct UnVolatile<volatile U&>
+ {
+ typedef U& Result;
+ enum { isVolatile = 1 };
+ };
+
+public:
+ typedef typename UnConst<T>::Result
+ NonConstType;
+ typedef typename UnVolatile<T>::Result
+ NonVolatileType;
+ typedef typename UnVolatile<typename UnConst<T>::Result>::Result
+ UnqualifiedType;
+ typedef typename PointerTraits<UnqualifiedType>::PointeeType
+ PointeeType;
+ typedef typename ReferenceTraits<T>::ReferredType
+ ReferredType;
+
+ enum { isConst = UnConst<T>::isConst };
+ enum { isVolatile = UnVolatile<T>::isVolatile };
+ enum { isReference = ReferenceTraits<UnqualifiedType>::result };
+ enum { isFunction = FunctionPointerTraits<typename Private::AddPointer<T>::Result >::result };
+ enum { isFunctionPointer= FunctionPointerTraits<
+ typename ReferenceTraits<UnqualifiedType>::ReferredType >::result
+ };
+ enum { isMemberFunctionPointer= PToMFunctionTraits<
+ typename ReferenceTraits<UnqualifiedType>::ReferredType >::result
+ };
+ enum { isMemberPointer = PToMTraits<
+ typename ReferenceTraits<UnqualifiedType>::ReferredType >::result ||
+ isMemberFunctionPointer
+ };
+ enum { isPointer = PointerTraits<
+ typename ReferenceTraits<UnqualifiedType>::ReferredType >::result ||
+ isFunctionPointer
+ };
+
+ enum { isStdUnsignedInt = TL::IndexOf<Private::StdUnsignedInts, UnqualifiedType>::value >= 0 ||
+ TL::IndexOf<Private::StdUnsignedInts,
+ typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0
+ };
+ enum { isStdSignedInt = TL::IndexOf<Private::StdSignedInts, UnqualifiedType>::value >= 0 ||
+ TL::IndexOf<Private::StdSignedInts,
+ typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0
+ };
+ enum { isStdIntegral = isStdUnsignedInt || isStdSignedInt ||
+ TL::IndexOf<Private::StdOtherInts, UnqualifiedType>::value >= 0 ||
+ TL::IndexOf<Private::StdOtherInts,
+ typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0
+ };
+ enum { isStdFloat = TL::IndexOf<Private::StdFloats, UnqualifiedType>::value >= 0 ||
+ TL::IndexOf<Private::StdFloats,
+ typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0
+ };
+ enum { isStdArith = isStdIntegral || isStdFloat };
+ enum { isStdFundamental = isStdArith || isStdFloat || Conversion<T, void>::sameType };
+
+ enum { isUnsignedInt = isStdUnsignedInt || IsCustomUnsignedInt<UnqualifiedType>::value };
+ enum { isSignedInt = isStdSignedInt || IsCustomSignedInt<UnqualifiedType>::value };
+ enum { isIntegral = isStdIntegral || isUnsignedInt || isSignedInt };
+ enum { isFloat = isStdFloat || IsCustomFloat<UnqualifiedType>::value };
+ enum { isArith = isIntegral || isFloat };
+ enum { isFundamental = isStdFundamental || isArith };
+
+ typedef typename Select<isStdArith || isPointer || isMemberPointer, T,
+ typename Private::AddParameterType<T>::Result>::Result
+ ParameterType;
+};
}
#ifdef _MSC_VER
diff --git a/shared/loki/Typelist.h b/shared/loki/Typelist.h
index 6a885927..ba18032f 100644
--- a/shared/loki/Typelist.h
+++ b/shared/loki/Typelist.h
@@ -2,14 +2,14 @@
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
-// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author or Addison-Welsey Longman make no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author or Addison-Welsey Longman make no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_TYPELIST_INC_
@@ -34,17 +34,17 @@ namespace Loki
// Tail (second element, can be another typelist)
////////////////////////////////////////////////////////////////////////////////
- template <class T, class U>
- struct Typelist
- {
- typedef T Head;
- typedef U Tail;
- };
+template <class T, class U>
+struct Typelist
+{
+ typedef T Head;
+ typedef U Tail;
+};
// Typelist utility algorithms
- namespace TL
- {
+namespace TL
+{
////////////////////////////////////////////////////////////////////////////////
// class template MakeTypelist
@@ -54,38 +54,38 @@ namespace Loki
// returns a typelist that is of T1, T2, ...
////////////////////////////////////////////////////////////////////////////////
- template
- <
- typename T1 = NullType, typename T2 = NullType, typename T3 = NullType,
- typename T4 = NullType, typename T5 = NullType, typename T6 = NullType,
- typename T7 = NullType, typename T8 = NullType, typename T9 = NullType,
- typename T10 = NullType, typename T11 = NullType, typename T12 = NullType,
- typename T13 = NullType, typename T14 = NullType, typename T15 = NullType,
- typename T16 = NullType, typename T17 = NullType, typename T18 = NullType
- >
- struct MakeTypelist
- {
- private:
- typedef typename MakeTypelist
- <
- T2 , T3 , T4 ,
- T5 , T6 , T7 ,
- T8 , T9 , T10,
- T11, T12, T13,
- T14, T15, T16,
- T17, T18
- >
- ::Result TailResult;
-
- public:
- typedef Typelist<T1, TailResult> Result;
- };
-
- template<>
- struct MakeTypelist<>
- {
- typedef NullType Result;
- };
+template
+<
+typename T1 = NullType, typename T2 = NullType, typename T3 = NullType,
+ typename T4 = NullType, typename T5 = NullType, typename T6 = NullType,
+ typename T7 = NullType, typename T8 = NullType, typename T9 = NullType,
+ typename T10 = NullType, typename T11 = NullType, typename T12 = NullType,
+ typename T13 = NullType, typename T14 = NullType, typename T15 = NullType,
+ typename T16 = NullType, typename T17 = NullType, typename T18 = NullType
+ >
+struct MakeTypelist
+{
+private:
+ typedef typename MakeTypelist
+ <
+ T2 , T3 , T4 ,
+ T5 , T6 , T7 ,
+ T8 , T9 , T10,
+ T11, T12, T13,
+ T14, T15, T16,
+ T17, T18
+ >
+ ::Result TailResult;
+
+public:
+ typedef Typelist<T1, TailResult> Result;
+};
+
+template<>
+struct MakeTypelist<>
+{
+ typedef NullType Result;
+};
////////////////////////////////////////////////////////////////////////////////
// class template Length
@@ -96,73 +96,73 @@ namespace Loki
// the end terminator (which by convention is NullType)
////////////////////////////////////////////////////////////////////////////////
- template <class TList> struct Length;
- template <> struct Length<NullType>
- {
- enum { value = 0 };
- };
-
- template <class T, class U>
- struct Length< Typelist<T, U> >
- {
- enum { value = 1 + Length<U>::value };
- };
+template <class TList> struct Length;
+template <> struct Length<NullType>
+{
+ enum { value = 0 };
+};
+
+template <class T, class U>
+struct Length< Typelist<T, U> >
+{
+ enum { value = 1 + Length<U>::value };
+};
////////////////////////////////////////////////////////////////////////////////
// class template TypeAt
// Finds the type at a given index in a typelist
-// Invocation (TList is a typelist and index is a compile-time integral
+// Invocation (TList is a typelist and index is a compile-time integral
// constant):
// TypeAt<TList, index>::Result
// returns the type in position 'index' in TList
// If you pass an out-of-bounds index, the result is a compile-time error
////////////////////////////////////////////////////////////////////////////////
- template <class TList, unsigned int index> struct TypeAt;
-
- template <class Head, class Tail>
- struct TypeAt<Typelist<Head, Tail>, 0>
- {
- typedef Head Result;
- };
+template <class TList, unsigned int index> struct TypeAt;
+
+template <class Head, class Tail>
+struct TypeAt<Typelist<Head, Tail>, 0>
+{
+ typedef Head Result;
+};
- template <class Head, class Tail, unsigned int i>
- struct TypeAt<Typelist<Head, Tail>, i>
- {
- typedef typename TypeAt<Tail, i - 1>::Result Result;
- };
+template <class Head, class Tail, unsigned int i>
+struct TypeAt<Typelist<Head, Tail>, i>
+{
+ typedef typename TypeAt<Tail, i - 1>::Result Result;
+};
////////////////////////////////////////////////////////////////////////////////
// class template TypeAtNonStrict
// Finds the type at a given index in a typelist
-// Invocations (TList is a typelist and index is a compile-time integral
+// Invocations (TList is a typelist and index is a compile-time integral
// constant):
// a) TypeAt<TList, index>::Result
-// returns the type in position 'index' in TList, or NullType if index is
+// returns the type in position 'index' in TList, or NullType if index is
// out-of-bounds
// b) TypeAt<TList, index, D>::Result
// returns the type in position 'index' in TList, or D if index is out-of-bounds
////////////////////////////////////////////////////////////////////////////////
- template <class TList, unsigned int index,
- typename DefaultType = NullType>
- struct TypeAtNonStrict
- {
- typedef DefaultType Result;
- };
-
- template <class Head, class Tail, typename DefaultType>
- struct TypeAtNonStrict<Typelist<Head, Tail>, 0, DefaultType>
- {
- typedef Head Result;
- };
-
- template <class Head, class Tail, unsigned int i, typename DefaultType>
- struct TypeAtNonStrict<Typelist<Head, Tail>, i, DefaultType>
- {
- typedef typename
- TypeAtNonStrict<Tail, i - 1, DefaultType>::Result Result;
- };
+template <class TList, unsigned int index,
+ typename DefaultType = NullType>
+struct TypeAtNonStrict
+{
+ typedef DefaultType Result;
+};
+
+template <class Head, class Tail, typename DefaultType>
+struct TypeAtNonStrict<Typelist<Head, Tail>, 0, DefaultType>
+{
+ typedef Head Result;
+};
+
+template <class Head, class Tail, unsigned int i, typename DefaultType>
+struct TypeAtNonStrict<Typelist<Head, Tail>, i, DefaultType>
+{
+ typedef typename
+ TypeAtNonStrict<Tail, i - 1, DefaultType>::Result Result;
+};
////////////////////////////////////////////////////////////////////////////////
// class template IndexOf
@@ -172,28 +172,28 @@ namespace Loki
// returns the position of T in TList, or NullType if T is not found in TList
////////////////////////////////////////////////////////////////////////////////
- template <class TList, class T> struct IndexOf;
-
- template <class T>
- struct IndexOf<NullType, T>
- {
- enum { value = -1 };
- };
-
- template <class T, class Tail>
- struct IndexOf<Typelist<T, Tail>, T>
- {
- enum { value = 0 };
- };
-
- template <class Head, class Tail, class T>
- struct IndexOf<Typelist<Head, Tail>, T>
- {
- private:
- enum { temp = IndexOf<Tail, T>::value };
- public:
- enum { value = (temp == -1 ? -1 : 1 + temp) };
- };
+template <class TList, class T> struct IndexOf;
+
+template <class T>
+struct IndexOf<NullType, T>
+{
+ enum { value = -1 };
+};
+
+template <class T, class Tail>
+struct IndexOf<Typelist<T, Tail>, T>
+{
+ enum { value = 0 };
+};
+
+template <class Head, class Tail, class T>
+struct IndexOf<Typelist<Head, Tail>, T>
+{
+private:
+ enum { temp = IndexOf<Tail, T>::value };
+public:
+ enum { value = (temp == -1 ? -1 : 1 + temp) };
+};
////////////////////////////////////////////////////////////////////////////////
// class template Append
@@ -203,32 +203,32 @@ namespace Loki
// returns a typelist that is TList followed by T and NullType-terminated
////////////////////////////////////////////////////////////////////////////////
- template <class TList, class T> struct Append;
-
- template <> struct Append<NullType, NullType>
- {
- typedef NullType Result;
- };
-
- template <class T> struct Append<NullType, T>
- {
- typedef Typelist<T,NullType> Result;
- };
-
- template <class Head, class Tail>
- struct Append<NullType, Typelist<Head, Tail> >
- {
- typedef Typelist<Head, Tail> Result;
- };
-
- template <class Head, class Tail, class T>
- struct Append<Typelist<Head, Tail>, T>
- {
- typedef Typelist<Head,
- typename Append<Tail, T>::Result>
- Result;
- };
-
+template <class TList, class T> struct Append;
+
+template <> struct Append<NullType, NullType>
+{
+ typedef NullType Result;
+};
+
+template <class T> struct Append<NullType, T>
+{
+ typedef Typelist<T,NullType> Result;
+};
+
+template <class Head, class Tail>
+struct Append<NullType, Typelist<Head, Tail> >
+{
+ typedef Typelist<Head, Tail> Result;
+};
+
+template <class Head, class Tail, class T>
+struct Append<Typelist<Head, Tail>, T>
+{
+ typedef Typelist<Head,
+ typename Append<Tail, T>::Result>
+ Result;
+};
+
////////////////////////////////////////////////////////////////////////////////
// class template Erase
// Erases the first occurence, if any, of a type in a typelist
@@ -237,27 +237,27 @@ namespace Loki
// returns a typelist that is TList without the first occurence of T
////////////////////////////////////////////////////////////////////////////////
- template <class TList, class T> struct Erase;
-
- template <class T> // Specialization 1
- struct Erase<NullType, T>
- {
- typedef NullType Result;
- };
+template <class TList, class T> struct Erase;
+
+template <class T> // Specialization 1
+struct Erase<NullType, T>
+{
+ typedef NullType Result;
+};
- template <class T, class Tail> // Specialization 2
- struct Erase<Typelist<T, Tail>, T>
- {
- typedef Tail Result;
- };
+template <class T, class Tail> // Specialization 2
+struct Erase<Typelist<T, Tail>, T>
+{
+ typedef Tail Result;
+};
- template <class Head, class Tail, class T> // Specialization 3
- struct Erase<Typelist<Head, Tail>, T>
- {
- typedef Typelist<Head,
- typename Erase<Tail, T>::Result>
- Result;
- };
+template <class Head, class Tail, class T> // Specialization 3
+struct Erase<Typelist<Head, Tail>, T>
+{
+ typedef Typelist<Head,
+ typename Erase<Tail, T>::Result>
+ Result;
+};
////////////////////////////////////////////////////////////////////////////////
// class template EraseAll
@@ -267,26 +267,26 @@ namespace Loki
// returns a typelist that is TList without any occurence of T
////////////////////////////////////////////////////////////////////////////////
- template <class TList, class T> struct EraseAll;
- template <class T>
- struct EraseAll<NullType, T>
- {
- typedef NullType Result;
- };
- template <class T, class Tail>
- struct EraseAll<Typelist<T, Tail>, T>
- {
- // Go all the way down the list removing the type
- typedef typename EraseAll<Tail, T>::Result Result;
- };
- template <class Head, class Tail, class T>
- struct EraseAll<Typelist<Head, Tail>, T>
- {
- // Go all the way down the list removing the type
- typedef Typelist<Head,
- typename EraseAll<Tail, T>::Result>
- Result;
- };
+template <class TList, class T> struct EraseAll;
+template <class T>
+struct EraseAll<NullType, T>
+{
+ typedef NullType Result;
+};
+template <class T, class Tail>
+struct EraseAll<Typelist<T, Tail>, T>
+{
+ // Go all the way down the list removing the type
+ typedef typename EraseAll<Tail, T>::Result Result;
+};
+template <class Head, class Tail, class T>
+struct EraseAll<Typelist<Head, Tail>, T>
+{
+ // Go all the way down the list removing the type
+ typedef Typelist<Head,
+ typename EraseAll<Tail, T>::Result>
+ Result;
+};
////////////////////////////////////////////////////////////////////////////////
// class template NoDuplicates
@@ -295,22 +295,22 @@ namespace Loki
// NoDuplicates<TList, T>::Result
////////////////////////////////////////////////////////////////////////////////
- template <class TList> struct NoDuplicates;
-
- template <> struct NoDuplicates<NullType>
- {
- typedef NullType Result;
- };
+template <class TList> struct NoDuplicates;
+
+template <> struct NoDuplicates<NullType>
+{
+ typedef NullType Result;
+};
- template <class Head, class Tail>
- struct NoDuplicates< Typelist<Head, Tail> >
- {
- private:
- typedef typename NoDuplicates<Tail>::Result L1;
- typedef typename Erase<L1, Head>::Result L2;
- public:
- typedef Typelist<Head, L2> Result;
- };
+template <class Head, class Tail>
+struct NoDuplicates< Typelist<Head, Tail> >
+{
+private:
+ typedef typename NoDuplicates<Tail>::Result L1;
+ typedef typename Erase<L1, Head>::Result L2;
+public:
+ typedef Typelist<Head, L2> Result;
+};
////////////////////////////////////////////////////////////////////////////////
// class template Replace
@@ -320,27 +320,27 @@ namespace Loki
// returns a typelist in which the first occurence of T is replaced with U
////////////////////////////////////////////////////////////////////////////////
- template <class TList, class T, class U> struct Replace;
-
- template <class T, class U>
- struct Replace<NullType, T, U>
- {
- typedef NullType Result;
- };
+template <class TList, class T, class U> struct Replace;
- template <class T, class Tail, class U>
- struct Replace<Typelist<T, Tail>, T, U>
- {
- typedef Typelist<U, Tail> Result;
- };
+template <class T, class U>
+struct Replace<NullType, T, U>
+{
+ typedef NullType Result;
+};
+
+template <class T, class Tail, class U>
+struct Replace<Typelist<T, Tail>, T, U>
+{
+ typedef Typelist<U, Tail> Result;
+};
- template <class Head, class Tail, class T, class U>
- struct Replace<Typelist<Head, Tail>, T, U>
- {
- typedef Typelist<Head,
- typename Replace<Tail, T, U>::Result>
- Result;
- };
+template <class Head, class Tail, class T, class U>
+struct Replace<Typelist<Head, Tail>, T, U>
+{
+ typedef Typelist<Head,
+ typename Replace<Tail, T, U>::Result>
+ Result;
+};
////////////////////////////////////////////////////////////////////////////////
// class template ReplaceAll
@@ -350,27 +350,27 @@ namespace Loki
// returns a typelist in which all occurences of T is replaced with U
////////////////////////////////////////////////////////////////////////////////
- template <class TList, class T, class U> struct ReplaceAll;
-
- template <class T, class U>
- struct ReplaceAll<NullType, T, U>
- {
- typedef NullType Result;
- };
-
- template <class T, class Tail, class U>
- struct ReplaceAll<Typelist<T, Tail>, T, U>
- {
- typedef Typelist<U, typename ReplaceAll<Tail, T, U>::Result> Result;
- };
-
- template <class Head, class Tail, class T, class U>
- struct ReplaceAll<Typelist<Head, Tail>, T, U>
- {
- typedef Typelist<Head,
- typename ReplaceAll<Tail, T, U>::Result>
- Result;
- };
+template <class TList, class T, class U> struct ReplaceAll;
+
+template <class T, class U>
+struct ReplaceAll<NullType, T, U>
+{
+ typedef NullType Result;
+};
+
+template <class T, class Tail, class U>
+struct ReplaceAll<Typelist<T, Tail>, T, U>
+{
+ typedef Typelist<U, typename ReplaceAll<Tail, T, U>::Result> Result;
+};
+
+template <class Head, class Tail, class T, class U>
+struct ReplaceAll<Typelist<Head, Tail>, T, U>
+{
+ typedef Typelist<Head,
+ typename ReplaceAll<Tail, T, U>::Result>
+ Result;
+};
////////////////////////////////////////////////////////////////////////////////
// class template Reverse
@@ -380,20 +380,20 @@ namespace Loki
// returns a typelist that is TList reversed
////////////////////////////////////////////////////////////////////////////////
- template <class TList> struct Reverse;
-
- template <>
- struct Reverse<NullType>
- {
- typedef NullType Result;
- };
-
- template <class Head, class Tail>
- struct Reverse< Typelist<Head, Tail> >
- {
- typedef typename Append<
- typename Reverse<Tail>::Result, Head>::Result Result;
- };
+template <class TList> struct Reverse;
+
+template <>
+struct Reverse<NullType>
+{
+ typedef NullType Result;
+};
+
+template <class Head, class Tail>
+struct Reverse< Typelist<Head, Tail> >
+{
+ typedef typename Append<
+ typename Reverse<Tail>::Result, Head>::Result Result;
+};
////////////////////////////////////////////////////////////////////////////////
// class template MostDerived
@@ -403,55 +403,55 @@ namespace Loki
// returns the type in TList that's the most derived from T
////////////////////////////////////////////////////////////////////////////////
- template <class TList, class T> struct MostDerived;
-
- template <class T>
- struct MostDerived<NullType, T>
- {
- typedef T Result;
- };
-
- template <class Head, class Tail, class T>
- struct MostDerived<Typelist<Head, Tail>, T>
- {
- private:
- typedef typename MostDerived<Tail, T>::Result Candidate;
- public:
- typedef typename Select<
- SuperSubclass<Candidate,Head>::value,
- Head, Candidate>::Result Result;
- };
+template <class TList, class T> struct MostDerived;
+
+template <class T>
+struct MostDerived<NullType, T>
+{
+ typedef T Result;
+};
+
+template <class Head, class Tail, class T>
+struct MostDerived<Typelist<Head, Tail>, T>
+{
+private:
+ typedef typename MostDerived<Tail, T>::Result Candidate;
+public:
+ typedef typename Select<
+ SuperSubclass<Candidate,Head>::value,
+ Head, Candidate>::Result Result;
+};
////////////////////////////////////////////////////////////////////////////////
// class template DerivedToFront
// Arranges the types in a typelist so that the most derived types appear first
// Invocation (TList is a typelist):
// DerivedToFront<TList>::Result
-// returns the reordered TList
-////////////////////////////////////////////////////////////////////////////////
-
- template <class TList> struct DerivedToFront;
-
- template <>
- struct DerivedToFront<NullType>
- {
- typedef NullType Result;
- };
-
- template <class Head, class Tail>
- struct DerivedToFront< Typelist<Head, Tail> >
- {
- private:
- typedef typename MostDerived<Tail, Head>::Result
- TheMostDerived;
- typedef typename Replace<Tail,
- TheMostDerived, Head>::Result Temp;
- typedef typename DerivedToFront<Temp>::Result L;
- public:
- typedef Typelist<TheMostDerived, L> Result;
- };
-
- } // namespace TL
+// returns the reordered TList
+////////////////////////////////////////////////////////////////////////////////
+
+template <class TList> struct DerivedToFront;
+
+template <>
+struct DerivedToFront<NullType>
+{
+ typedef NullType Result;
+};
+
+template <class Head, class Tail>
+struct DerivedToFront< Typelist<Head, Tail> >
+{
+private:
+ typedef typename MostDerived<Tail, Head>::Result
+ TheMostDerived;
+ typedef typename Replace<Tail,
+ TheMostDerived, Head>::Result Temp;
+ typedef typename DerivedToFront<Temp>::Result L;
+public:
+ typedef Typelist<TheMostDerived, L> Result;
+};
+
+} // namespace TL
} // namespace Loki
diff --git a/shared/loki/TypelistMacros.h b/shared/loki/TypelistMacros.h
index 6c14b348..1c3c3e63 100644
--- a/shared/loki/TypelistMacros.h
+++ b/shared/loki/TypelistMacros.h
@@ -2,14 +2,14 @@
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
-// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author or Addison-Welsey Longman make no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author or Addison-Welsey Longman make no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_TYPELISTMACROS_INC_
@@ -24,7 +24,7 @@
////////////////////////////////////////////////////////////////////////////////
// macros LOKI_TYPELIST_1, LOKI_TYPELIST_2, ... LOKI_TYPELIST_50
// Each takes a number of arguments equal to its numeric suffix
-// The arguments are type names. LOKI_TYPELIST_NN generates a typelist containing
+// The arguments are type names. LOKI_TYPELIST_NN generates a typelist containing
// all types passed as arguments, in that order.
// Example: LOKI_TYPELIST_2(char, int) generates a type containing char and int.
////////////////////////////////////////////////////////////////////////////////
diff --git a/shared/loki/Visitor.h b/shared/loki/Visitor.h
index 4425a9fa..f6b0ad81 100644
--- a/shared/loki/Visitor.h
+++ b/shared/loki/Visitor.h
@@ -2,14 +2,14 @@
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
-// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author or Addison-Wesley Longman make no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author or Addison-Wesley Longman make no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_VISITOR_INC_
@@ -28,17 +28,17 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
/// \class BaseVisitor
-///
+///
/// \ingroup VisitorGroup
/// The base class of any Acyclic Visitor
////////////////////////////////////////////////////////////////////////////////
- class BaseVisitor
- {
- public:
- virtual ~BaseVisitor() {}
- };
-
+class BaseVisitor
+{
+public:
+ virtual ~BaseVisitor() {}
+};
+
////////////////////////////////////////////////////////////////////////////////
/// \class Visitor
///
@@ -48,7 +48,7 @@ namespace Loki
/// \par Usage
///
/// Defining the visitable class:
-///
+///
/// \code
/// class RasterBitmap : public BaseVisitable<>
/// {
@@ -59,7 +59,7 @@ namespace Loki
///
/// Way 1 to define a visitor:
/// \code
-/// class SomeVisitor :
+/// class SomeVisitor :
/// public BaseVisitor // required
/// public Visitor<RasterBitmap>,
/// public Visitor<Paragraph>
@@ -72,7 +72,7 @@ namespace Loki
///
/// Way 2 to define the visitor:
/// \code
-/// class SomeVisitor :
+/// class SomeVisitor :
/// public BaseVisitor // required
/// public Visitor<LOKI_TYPELIST_2(RasterBitmap, Paragraph)>
/// {
@@ -84,7 +84,7 @@ namespace Loki
///
/// Way 3 to define the visitor:
/// \code
-/// class SomeVisitor :
+/// class SomeVisitor :
/// public BaseVisitor // required
/// public Visitor<Seq<RasterBitmap, Paragraph>::Type>
/// {
@@ -97,7 +97,7 @@ namespace Loki
/// \par Using const visit functions:
///
/// Defining the visitable class (true for const):
-///
+///
/// \code
/// class RasterBitmap : public BaseVisitable<void, DefaultCatchAll, true>
/// {
@@ -108,7 +108,7 @@ namespace Loki
///
/// Defining the visitor which only calls const member functions:
/// \code
-/// class SomeVisitor :
+/// class SomeVisitor :
/// public BaseVisitor // required
/// public Visitor<RasterBitmap, void, true>,
/// {
@@ -119,38 +119,38 @@ namespace Loki
///
/// \par Example:
///
-/// test/Visitor/main.cpp
+/// test/Visitor/main.cpp
////////////////////////////////////////////////////////////////////////////////
- template <class T, typename R = void, bool ConstVisit = false>
- class Visitor;
+template <class T, typename R = void, bool ConstVisit = false>
+class Visitor;
- template <class T, typename R>
- class Visitor<T, R, false>
- {
- public:
- typedef R ReturnType;
- typedef T ParamType;
- virtual ~Visitor() {}
- virtual ReturnType Visit(ParamType&) = 0;
- };
-
- template <class T, typename R>
- class Visitor<T, R, true>
- {
- public:
- typedef R ReturnType;
- typedef const T ParamType;
- virtual ~Visitor() {}
- virtual ReturnType Visit(ParamType&) = 0;
- };
+template <class T, typename R>
+class Visitor<T, R, false>
+{
+public:
+ typedef R ReturnType;
+ typedef T ParamType;
+ virtual ~Visitor() {}
+ virtual ReturnType Visit(ParamType&) = 0;
+};
+
+template <class T, typename R>
+class Visitor<T, R, true>
+{
+public:
+ typedef R ReturnType;
+ typedef const T ParamType;
+ virtual ~Visitor() {}
+ virtual ReturnType Visit(ParamType&) = 0;
+};
////////////////////////////////////////////////////////////////////////////////
// class template Visitor (specialization)
// This specialization is not present in the book. It makes it easier to define
// Visitors for multiple types in a shot by using a typelist. Example:
//
-// class SomeVisitor :
+// class SomeVisitor :
// public BaseVisitor // required
// public Visitor<LOKI_TYPELIST_2(RasterBitmap, Paragraph)>
// {
@@ -160,41 +160,41 @@ namespace Loki
// };
////////////////////////////////////////////////////////////////////////////////
- template <class Head, class Tail, typename R>
- class Visitor<Typelist<Head, Tail>, R, false>
- : public Visitor<Head, R, false>, public Visitor<Tail, R, false>
- {
- public:
- typedef R ReturnType;
- // using Visitor<Head, R>::Visit;
- // using Visitor<Tail, R>::Visit;
- };
-
- template <class Head, typename R>
- class Visitor<Typelist<Head, NullType>, R, false> : public Visitor<Head, R, false>
- {
- public:
- typedef R ReturnType;
- using Visitor<Head, R, false>::Visit;
- };
-
- template <class Head, class Tail, typename R>
- class Visitor<Typelist<Head, Tail>, R, true>
- : public Visitor<Head, R, true>, public Visitor<Tail, R, true>
- {
- public:
- typedef R ReturnType;
- // using Visitor<Head, R>::Visit;
- // using Visitor<Tail, R>::Visit;
- };
-
- template <class Head, typename R>
- class Visitor<Typelist<Head, NullType>, R, true> : public Visitor<Head, R, true>
- {
- public:
- typedef R ReturnType;
- using Visitor<Head, R, true>::Visit;
- };
+template <class Head, class Tail, typename R>
+class Visitor<Typelist<Head, Tail>, R, false>
+ : public Visitor<Head, R, false>, public Visitor<Tail, R, false>
+{
+public:
+ typedef R ReturnType;
+ // using Visitor<Head, R>::Visit;
+ // using Visitor<Tail, R>::Visit;
+};
+
+template <class Head, typename R>
+class Visitor<Typelist<Head, NullType>, R, false> : public Visitor<Head, R, false>
+{
+public:
+ typedef R ReturnType;
+ using Visitor<Head, R, false>::Visit;
+};
+
+template <class Head, class Tail, typename R>
+class Visitor<Typelist<Head, Tail>, R, true>
+ : public Visitor<Head, R, true>, public Visitor<Tail, R, true>
+{
+public:
+ typedef R ReturnType;
+ // using Visitor<Head, R>::Visit;
+ // using Visitor<Tail, R>::Visit;
+};
+
+template <class Head, typename R>
+class Visitor<Typelist<Head, NullType>, R, true> : public Visitor<Head, R, true>
+{
+public:
+ typedef R ReturnType;
+ using Visitor<Head, R, true>::Visit;
+};
////////////////////////////////////////////////////////////////////////////////
@@ -203,29 +203,29 @@ namespace Loki
// functions)
////////////////////////////////////////////////////////////////////////////////
- template <class TList, typename R = void> class BaseVisitorImpl;
+template <class TList, typename R = void> class BaseVisitorImpl;
+
+template <class Head, class Tail, typename R>
+class BaseVisitorImpl<Typelist<Head, Tail>, R>
+ : public Visitor<Head, R>
+ , public BaseVisitorImpl<Tail, R>
+{
+public:
+ // using BaseVisitorImpl<Tail, R>::Visit;
+
+ virtual R Visit(Head&)
+ { return R(); }
+};
+
+template <class Head, typename R>
+class BaseVisitorImpl<Typelist<Head, NullType>, R>
+ : public Visitor<Head, R>
+{
+public:
+ virtual R Visit(Head&)
+ { return R(); }
+};
- template <class Head, class Tail, typename R>
- class BaseVisitorImpl<Typelist<Head, Tail>, R>
- : public Visitor<Head, R>
- , public BaseVisitorImpl<Tail, R>
- {
- public:
- // using BaseVisitorImpl<Tail, R>::Visit;
-
- virtual R Visit(Head&)
- { return R(); }
- };
-
- template <class Head, typename R>
- class BaseVisitorImpl<Typelist<Head, NullType>, R>
- : public Visitor<Head, R>
- {
- public:
- virtual R Visit(Head&)
- { return R(); }
- };
-
////////////////////////////////////////////////////////////////////////////////
// class template BaseVisitable
////////////////////////////////////////////////////////////////////////////////
@@ -241,61 +241,61 @@ struct DefaultCatchAll
// class template BaseVisitable
////////////////////////////////////////////////////////////////////////////////
- template
- <
- typename R = void,
- template <typename, class> class CatchAll = DefaultCatchAll,
- bool ConstVisitable = false
- >
- class BaseVisitable;
+template
+<
+typename R = void,
+ template <typename, class> class CatchAll = DefaultCatchAll,
+ bool ConstVisitable = false
+ >
+class BaseVisitable;
- template<typename R,template <typename, class> class CatchAll>
- class BaseVisitable<R, CatchAll, false>
+template<typename R,template <typename, class> class CatchAll>
+class BaseVisitable<R, CatchAll, false>
+{
+public:
+ typedef R ReturnType;
+ virtual ~BaseVisitable() {}
+ virtual ReturnType Accept(BaseVisitor&) = 0;
+
+protected: // give access only to the hierarchy
+ template <class T>
+ static ReturnType AcceptImpl(T& visited, BaseVisitor& guest)
{
- public:
- typedef R ReturnType;
- virtual ~BaseVisitable() {}
- virtual ReturnType Accept(BaseVisitor&) = 0;
-
- protected: // give access only to the hierarchy
- template <class T>
- static ReturnType AcceptImpl(T& visited, BaseVisitor& guest)
+ // Apply the Acyclic Visitor
+ if (Visitor<T,R>* p = dynamic_cast<Visitor<T,R>*>(&guest))
{
- // Apply the Acyclic Visitor
- if (Visitor<T,R>* p = dynamic_cast<Visitor<T,R>*>(&guest))
- {
- return p->Visit(visited);
- }
- return CatchAll<R, T>::OnUnknownVisitor(visited, guest);
+ return p->Visit(visited);
}
- };
+ return CatchAll<R, T>::OnUnknownVisitor(visited, guest);
+ }
+};
- template<typename R,template <typename, class> class CatchAll>
- class BaseVisitable<R, CatchAll, true>
+template<typename R,template <typename, class> class CatchAll>
+class BaseVisitable<R, CatchAll, true>
+{
+public:
+ typedef R ReturnType;
+ virtual ~BaseVisitable() {}
+ virtual ReturnType Accept(BaseVisitor&) const = 0;
+
+protected: // give access only to the hierarchy
+ template <class T>
+ static ReturnType AcceptImpl(const T& visited, BaseVisitor& guest)
{
- public:
- typedef R ReturnType;
- virtual ~BaseVisitable() {}
- virtual ReturnType Accept(BaseVisitor&) const = 0;
-
- protected: // give access only to the hierarchy
- template <class T>
- static ReturnType AcceptImpl(const T& visited, BaseVisitor& guest)
+ // Apply the Acyclic Visitor
+ if (Visitor<T,R,true>* p = dynamic_cast<Visitor<T,R,true>*>(&guest))
{
- // Apply the Acyclic Visitor
- if (Visitor<T,R,true>* p = dynamic_cast<Visitor<T,R,true>*>(&guest))
- {
- return p->Visit(visited);
- }
- return CatchAll<R, T>::OnUnknownVisitor(const_cast<T&>(visited), guest);
+ return p->Visit(visited);
}
- };
+ return CatchAll<R, T>::OnUnknownVisitor(const_cast<T&>(visited), guest);
+ }
+};
////////////////////////////////////////////////////////////////////////////////
/// \def LOKI_DEFINE_VISITABLE()
/// \ingroup VisitorGroup
-/// Put it in every class that you want to make visitable
+/// Put it in every class that you want to make visitable
/// (in addition to deriving it from BaseVisitable<R>)
////////////////////////////////////////////////////////////////////////////////
@@ -306,7 +306,7 @@ struct DefaultCatchAll
////////////////////////////////////////////////////////////////////////////////
/// \def LOKI_DEFINE_CONST_VISITABLE()
/// \ingroup VisitorGroup
-/// Put it in every class that you want to make visitable by const member
+/// Put it in every class that you want to make visitable by const member
/// functions (in addition to deriving it from BaseVisitable<R>)
////////////////////////////////////////////////////////////////////////////////
@@ -318,25 +318,25 @@ struct DefaultCatchAll
/// \class CyclicVisitor
///
/// \ingroup VisitorGroup
-/// Put it in every class that you want to make visitable (in addition to
+/// Put it in every class that you want to make visitable (in addition to
/// deriving it from BaseVisitable<R>
////////////////////////////////////////////////////////////////////////////////
- template <typename R, class TList>
- class CyclicVisitor : public Visitor<TList, R>
+template <typename R, class TList>
+class CyclicVisitor : public Visitor<TList, R>
+{
+public:
+ typedef R ReturnType;
+ // using Visitor<TList, R>::Visit;
+
+ template <class Visited>
+ ReturnType GenericVisit(Visited& host)
{
- public:
- typedef R ReturnType;
- // using Visitor<TList, R>::Visit;
-
- template <class Visited>
- ReturnType GenericVisit(Visited& host)
- {
- Visitor<Visited, ReturnType>& subObj = *this;
- return subObj.Visit(host);
- }
- };
-
+ Visitor<Visited, ReturnType>& subObj = *this;
+ return subObj.Visit(host);
+ }
+};
+
////////////////////////////////////////////////////////////////////////////////
/// \def LOKI_DEFINE_CYCLIC_VISITABLE(SomeVisitor)
/// \ingroup VisitorGroup
diff --git a/shared/loki/static_check.h b/shared/loki/static_check.h
index 51ce389e..b4c455c9 100644
--- a/shared/loki/static_check.h
+++ b/shared/loki/static_check.h
@@ -2,14 +2,14 @@
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
-// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author or Addison-Wesley Longman make no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author or Addison-Wesley Longman make no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_STATIC_CHECK_INC_
@@ -24,8 +24,8 @@ namespace Loki
// Helper structure for the STATIC_CHECK macro
////////////////////////////////////////////////////////////////////////////////
- template<int> struct CompileTimeError;
- template<> struct CompileTimeError<true> {};
+template<int> struct CompileTimeError;
+template<> struct CompileTimeError<true> {};
}
////////////////////////////////////////////////////////////////////////////////
@@ -38,7 +38,7 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
#define LOKI_STATIC_CHECK(expr, msg) \
- { Loki::CompileTimeError<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; }
+ { Loki::CompileTimeError<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; }
#endif // end file guardian
diff --git a/shared/long_path_prefix.cpp b/shared/long_path_prefix.cpp
index 3fb0703d..dc249283 100644
--- a/shared/long_path_prefix.cpp
+++ b/shared/long_path_prefix.cpp
@@ -16,8 +16,8 @@ template <size_t max_path>
inline
Zstring applyLongPathPrefixImpl(const Zstring& path)
{
- if ( path.length() >= max_path && //maximum allowed path length without prefix is (MAX_PATH - 1)
- !path.StartsWith(LONG_PATH_PREFIX))
+ if (path.length() >= max_path && //maximum allowed path length without prefix is (MAX_PATH - 1)
+ !path.StartsWith(LONG_PATH_PREFIX))
{
if (path.StartsWith(Zstr("\\\\"))) //UNC-name, e.g. \\zenju-pc\Users
return LONG_PATH_PREFIX_UNC + path.AfterFirst(Zchar('\\')); //convert to \\?\UNC\zenju-pc\Users
@@ -47,12 +47,10 @@ Zstring ffs3::removeLongPathPrefix(const Zstring& path) //throw()
{
if (path.StartsWith(LONG_PATH_PREFIX))
{
- Zstring finalPath = path;
if (path.StartsWith(LONG_PATH_PREFIX_UNC)) //UNC-name
- finalPath.Replace(LONG_PATH_PREFIX_UNC, Zstr("\\"), false);
+ return Zstring(path).Replace(LONG_PATH_PREFIX_UNC, Zstr("\\"), false);
else
- finalPath.Replace(LONG_PATH_PREFIX, Zstr(""), false);
- return finalPath;
+ return Zstring(path).Replace(LONG_PATH_PREFIX, Zstr(""), false);
}
//fallback
diff --git a/shared/mouse_move_dlg.cpp b/shared/mouse_move_dlg.cpp
new file mode 100644
index 00000000..abaa7ead
--- /dev/null
+++ b/shared/mouse_move_dlg.cpp
@@ -0,0 +1,54 @@
+// **************************************************************************
+// * This file is part of the FreeFileSync project. It is distributed under *
+// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
+// **************************************************************************
+//
+#include "mouse_move_dlg.h"
+#include <vector>
+#include <wx/msw/wrapwin.h> //includes "windows.h"
+
+using namespace ffs3;
+
+
+MouseMoveWindow::MouseMoveWindow(wxWindow& parent,
+ wxWindow* child1,
+ wxWindow* child2,
+ wxWindow* child3,
+ wxWindow* child4,
+ wxWindow* child5,
+ wxWindow* child6) : wxWindow(&parent, wxID_ANY)
+{
+ std::vector<wxWindow*> windList;
+
+ if (child1) windList.push_back(child1);
+ if (child2) windList.push_back(child2);
+ if (child3) windList.push_back(child3);
+ if (child4) windList.push_back(child4);
+ if (child5) windList.push_back(child5);
+ if (child6) windList.push_back(child6);
+
+ for (std::vector<wxWindow*>::const_iterator i = windList.begin(); i != windList.end(); ++i)
+ (*i)->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(MouseMoveWindow::LeftButtonDown), NULL, this);
+
+ Hide(); //this is just a dummy window so that its parent can have ownership
+ Disable();
+}
+
+
+MouseMoveWindow::~MouseMoveWindow() {}
+
+
+void MouseMoveWindow::LeftButtonDown(wxMouseEvent& event)
+{
+ if (GetParent() && allowMove(event))
+ {
+ ::ReleaseCapture();
+ //::SendMessage(GetHwndOf(dialogToMove_), WM_NCLBUTTONDOWN, HTCAPTION, 0);
+ ::SendMessage(static_cast<HWND>(GetParent()->GetHWND()), WM_NCLBUTTONDOWN, HTCAPTION, 0);
+
+ return;
+ //event.Skip(); -> swallow event, to avoid other windows losing focus
+ }
+ event.Skip();
+}
diff --git a/shared/mouse_move_dlg.h b/shared/mouse_move_dlg.h
new file mode 100644
index 00000000..ccdf6c01
--- /dev/null
+++ b/shared/mouse_move_dlg.h
@@ -0,0 +1,40 @@
+// **************************************************************************
+// * This file is part of the FreeFileSync project. It is distributed under *
+// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
+// **************************************************************************
+//
+#ifndef MOUSEMOVEWINDOW_H_INCLUDED
+#define MOUSEMOVEWINDOW_H_INCLUDED
+
+#include <wx/window.h>
+
+namespace ffs3
+{
+
+//move main dialog by mouse-dragging contained sub-windows: just attach to parent via new in constructor: ownership passed!
+class MouseMoveWindow : public wxWindow //private wxEvtHandler
+{
+public:
+ MouseMoveWindow(wxWindow& parent,
+ wxWindow* child1,
+ wxWindow* child2 = NULL,
+ wxWindow* child3 = NULL,
+ wxWindow* child4 = NULL,
+ wxWindow* child5 = NULL,
+ wxWindow* child6 = NULL);
+
+ virtual ~MouseMoveWindow();
+
+ virtual bool allowMove(const wxMouseEvent& event)
+ {
+ return true;
+ }
+
+private:
+ void LeftButtonDown(wxMouseEvent& event);
+};
+}
+
+
+#endif // MOUSEMOVEWINDOW_H_INCLUDED
diff --git a/shared/perf.h b/shared/perf.h
index 4f955748..1ad4650d 100644
--- a/shared/perf.h
+++ b/shared/perf.h
@@ -7,22 +7,34 @@
#ifndef DEBUG_PERF_HEADER
#define DEBUG_PERF_HEADER
+#include <sstream>
//#define WIN32_LEAN_AND_MEAN -> not in a header
+/*
+#include <windows.h>
+#undef max
+#undef min
+*/
#include <wx/msw/wrapwin.h> //includes "windows.h"
-#include <sstream>
+
#ifdef __MINGW32__
- #define DEPRECATED(x) x __attribute__ ((deprecated))
+#define DEPRECATED(x) x __attribute__ ((deprecated))
#elif defined _MSC_VER
- #define DEPRECATED(x) __declspec(deprecated) x
+#define DEPRECATED(x) __declspec(deprecated) x
#endif
-class Performance
+class CpuTimer
{
public:
- DEPRECATED(Performance()) : resultWasShown(false), startTime(::GetTickCount()) {}
+ class TimerError {};
- ~Performance()
+ DEPRECATED(CpuTimer()) : resultWasShown(false), startTime(), frequency()
+ {
+ if (!::QueryPerformanceFrequency(&frequency)) throw TimerError();
+ if (!::QueryPerformanceCounter (&startTime)) throw TimerError();
+ }
+
+ ~CpuTimer()
{
if (!resultWasShown)
showResult();
@@ -30,23 +42,27 @@ public:
void showResult()
{
- const DWORD delta = ::GetTickCount() - startTime;
+ LARGE_INTEGER currentTime = {};
+ if (!::QueryPerformanceCounter(&currentTime)) throw TimerError();
+
+ const long delta = 1000.0 * (currentTime.QuadPart - startTime.QuadPart) / frequency.QuadPart;
std::ostringstream ss;
ss << delta << " ms";
-
+
::MessageBoxA(NULL, ss.str().c_str(), "Timer", 0);
resultWasShown = true;
- startTime = ::GetTickCount(); //don't include call to MessageBox()!
+ if (!::QueryPerformanceCounter(&startTime)) throw TimerError(); //don't include call to MessageBox()!
}
-
+
private:
bool resultWasShown;
- DWORD startTime;
+ LARGE_INTEGER startTime;
+ LARGE_INTEGER frequency;
};
//two macros for quick performance measurements
-#define PERF_START Performance a;
-#define PERF_STOP a.showResult();
+#define PERF_START CpuTimer perfTest;
+#define PERF_STOP perfTest.showResult();
-#endif //DEBUG_PERF_HEADER \ No newline at end of file
+#endif //DEBUG_PERF_HEADER
diff --git a/shared/privilege.cpp b/shared/privilege.cpp
index 16f9d385..00eb2855 100644
--- a/shared/privilege.cpp
+++ b/shared/privilege.cpp
@@ -1,7 +1,8 @@
#include "privilege.h"
#include <wx/intl.h>
#include "system_func.h"
-#include <boost/shared_ptr.hpp>
+//#include <boost/shared_ptr.hpp>
+#include "loki/ScopeGuard.h"
using namespace ffs3;
@@ -23,19 +24,21 @@ bool Privileges::privilegeIsActive(LPCTSTR privilege) //throw FileError()
const wxString errorMessage = wxString(_("Error setting privilege:")) + wxT(" \"") + privilege + wxT("\"") + wxT("\n\n");
throw FileError(errorMessage + ffs3::getLastErrorFormatted());
}
- boost::shared_ptr<void> dummy(hToken, ::CloseHandle);
+ Loki::ScopeGuard dummy = Loki::MakeGuard(::CloseHandle, hToken);
+ (void)dummy; //silence warning "unused variable"
- LUID luid = {0};
+
+ LUID luid = {};
if (!::LookupPrivilegeValue(
- NULL, //__in_opt LPCTSTR lpSystemName,
- privilege, //__in LPCTSTR lpName,
- &luid )) //__out PLUID lpLuid
+ NULL, //__in_opt LPCTSTR lpSystemName,
+ privilege, //__in LPCTSTR lpName,
+ &luid )) //__out PLUID lpLuid
{
const wxString errorMessage = wxString(_("Error setting privilege:")) + wxT(" \"") + privilege + wxT("\"") + wxT("\n\n");
throw FileError(errorMessage + ffs3::getLastErrorFormatted());
}
- PRIVILEGE_SET priv = {0};
+ PRIVILEGE_SET priv = {};
priv.PrivilegeCount = 1;
priv.Control = PRIVILEGE_SET_ALL_NECESSARY;
priv.Privilege[0].Luid = luid;
@@ -43,9 +46,9 @@ bool Privileges::privilegeIsActive(LPCTSTR privilege) //throw FileError()
BOOL alreadyGranted = FALSE;
if (!::PrivilegeCheck(
- hToken, //__in HANDLE ClientToken,
- &priv, //__inout PPRIVILEGE_SET RequiredPrivileges,
- &alreadyGranted)) //__out LPBOOL pfResult
+ hToken, //__in HANDLE ClientToken,
+ &priv, //__inout PPRIVILEGE_SET RequiredPrivileges,
+ &alreadyGranted)) //__out LPBOOL pfResult
{
const wxString errorMessage = wxString(_("Error setting privilege:")) + wxT(" \"") + privilege + wxT("\"") + wxT("\n\n");
throw FileError(errorMessage + ffs3::getLastErrorFormatted());
@@ -65,30 +68,31 @@ void Privileges::setPrivilege(LPCTSTR privilege, bool enable) //throw FileError(
const wxString errorMessage = wxString(_("Error setting privilege:")) + wxT(" \"") + privilege + wxT("\"") + wxT("\n\n");
throw FileError(errorMessage + ffs3::getLastErrorFormatted());
}
- boost::shared_ptr<void> dummy(hToken, ::CloseHandle);
+ Loki::ScopeGuard dummy = Loki::MakeGuard(::CloseHandle, hToken);
+ (void)dummy; //silence warning "unused variable"
- LUID luid = {0};
+ LUID luid = {};
if (!::LookupPrivilegeValue(
- NULL, //__in_opt LPCTSTR lpSystemName,
- privilege, //__in LPCTSTR lpName,
- &luid )) //__out PLUID lpLuid
+ NULL, //__in_opt LPCTSTR lpSystemName,
+ privilege, //__in LPCTSTR lpName,
+ &luid )) //__out PLUID lpLuid
{
const wxString errorMessage = wxString(_("Error setting privilege:")) + wxT(" \"") + privilege + wxT("\"") + wxT("\n\n");
throw FileError(errorMessage + ffs3::getLastErrorFormatted());
}
- TOKEN_PRIVILEGES tp = {0};
+ TOKEN_PRIVILEGES tp = {};
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
if (!::AdjustTokenPrivileges(
- hToken, //__in HANDLE TokenHandle,
- false, //__in BOOL DisableAllPrivileges,
- &tp, //__in_opt PTOKEN_PRIVILEGES NewState,
- 0, //__in DWORD BufferLength,
- NULL, //__out_opt PTOKEN_PRIVILEGES PreviousState,
- NULL)) //__out_opt PDWORD ReturnLength
+ hToken, //__in HANDLE TokenHandle,
+ false, //__in BOOL DisableAllPrivileges,
+ &tp, //__in_opt PTOKEN_PRIVILEGES NewState,
+ 0, //__in DWORD BufferLength,
+ NULL, //__out_opt PTOKEN_PRIVILEGES PreviousState,
+ NULL)) //__out_opt PDWORD ReturnLength
{
const wxString errorMessage = wxString(_("Error setting privilege:")) + wxT(" \"") + privilege + wxT("\"") + wxT("\n\n");
throw FileError(errorMessage + ffs3::getLastErrorFormatted());
diff --git a/shared/recycler.cpp b/shared/recycler.cpp
index 4a0d7290..4e9ce9a3 100644
--- a/shared/recycler.cpp
+++ b/shared/recycler.cpp
@@ -101,9 +101,9 @@ void moveToWindowsRecycler(const std::vector<Zstring>& filesToDelete) //throw (
wxString(_("Could not load a required DLL:")) + wxT(" \"") + getRecyclerDllName().c_str() + wxT("\""));
//#warning moving long file paths to recycler does not work! clarify!
-// std::vector<Zstring> temp;
-// std::transform(filesToDelete.begin(), filesToDelete.end(),
-// std::back_inserter(temp), std::ptr_fun(ffs3::removeLongPathPrefix)); //::IFileOperation() can't handle \\?\-prefix!
+ // std::vector<Zstring> temp;
+ // std::transform(filesToDelete.begin(), filesToDelete.end(),
+ // std::back_inserter(temp), std::ptr_fun(ffs3::removeLongPathPrefix)); //::IFileOperation() can't handle \\?\-prefix!
if (!moveToRecycler(&fileNames[0], //array must not be empty
fileNames.size()))
@@ -126,7 +126,7 @@ void moveToWindowsRecycler(const std::vector<Zstring>& filesToDelete) //throw (
filenameDoubleNull += Zchar(0);
}
- SHFILEOPSTRUCT fileOp;
+ SHFILEOPSTRUCT fileOp = {};
fileOp.hwnd = NULL;
fileOp.wFunc = FO_DELETE;
fileOp.pFrom = filenameDoubleNull.c_str();
diff --git a/shared/shadow.cpp b/shared/shadow.cpp
index 5a70bb6e..9dab1494 100644
--- a/shared/shadow.cpp
+++ b/shared/shadow.cpp
@@ -105,8 +105,8 @@ public:
releaseShadowCopy = util::getDllFun<ReleaseShadowCopyFct>(getShadowDllName(), releaseShadowCopyFctName);
//check if shadow copy dll was loaded correctly
- if ( createShadowCopy == NULL ||
- releaseShadowCopy == NULL)
+ if (createShadowCopy == NULL ||
+ releaseShadowCopy == NULL)
throw FileError(wxString(_("Error starting Volume Shadow Copy Service!")) + wxT("\n") +
_("Could not load a required DLL:") + wxT(" \"") + getShadowDllName().c_str() + wxT("\""));
@@ -117,18 +117,18 @@ public:
throw FileError(wxString(_("Error starting Volume Shadow Copy Service!")) + wxT("\n") +
_("Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version."));
-//---------------------------------------------------------------------------------------------------------
+ //---------------------------------------------------------------------------------------------------------
//start shadow volume copy service:
wchar_t shadowVolName[1000];
wchar_t errorMessage[1000];
if (!createShadowCopy(
- volumeNameFormatted.c_str(),
- shadowVolName,
- 1000,
- &backupHandle,
- errorMessage,
- 1000))
+ volumeNameFormatted.c_str(),
+ shadowVolName,
+ 1000,
+ &backupHandle,
+ errorMessage,
+ 1000))
throw FileError(wxString(_("Error starting Volume Shadow Copy Service!")) + wxT("\n") +
wxT("(") + errorMessage + wxT(" Volume: \"") + volumeNameFormatted.c_str() + wxT("\")"));
diff --git a/shared/symlink_target.h b/shared/symlink_target.h
index 358f2913..6dec85a0 100644
--- a/shared/symlink_target.h
+++ b/shared/symlink_target.h
@@ -7,7 +7,7 @@
#ifndef SYMLINK_WIN_H_INCLUDED
#define SYMLINK_WIN_H_INCLUDED
-#include <boost/shared_ptr.hpp>
+#include "loki/ScopeGuard.h"
#include <boost/scoped_array.hpp>
#include "system_func.h"
#include <wx/intl.h>
@@ -67,9 +67,9 @@ Zstring getSymlinkRawTargetString(const Zstring& linkPath) //throw (FileError)
using ffs3::zToWx;
using ffs3::FileError;
#ifdef FFS_WIN
-//FSCTL_GET_REPARSE_POINT: http://msdn.microsoft.com/en-us/library/aa364571(VS.85).aspx
+ //FSCTL_GET_REPARSE_POINT: http://msdn.microsoft.com/en-us/library/aa364571(VS.85).aspx
- try //setting privileges requires admin rights! This shall not cause an error in user mode!
+ try //reading certain symlinks requires admin rights! This shall not cause an error in user mode!
{
//allow access to certain symbolic links/junctions
ffs3::Privileges::getInstance().ensureActive(SE_BACKUP_NAME); //throw FileError()
@@ -88,7 +88,8 @@ Zstring getSymlinkRawTargetString(const Zstring& linkPath) //throw (FileError)
wxString errorMessage = wxString(_("Error resolving symbolic link:")) + wxT("\n\"") + ffs3::zToWx(linkPath) + wxT("\"");
throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
}
- boost::shared_ptr<void> dummy(hLink, ::CloseHandle);
+ Loki::ScopeGuard dummy = Loki::MakeGuard(::CloseHandle, hLink);
+ (void)dummy; //silence warning "unused variable"
//respect alignment issues...
const size_t bufferSize = REPARSE_DATA_BUFFER_HEADER_SIZE + MAXIMUM_REPARSE_DATA_BUFFER_SIZE;
diff --git a/shared/taskbar.cpp b/shared/taskbar.cpp
index 881a1570..5767f8c9 100644
--- a/shared/taskbar.cpp
+++ b/shared/taskbar.cpp
@@ -73,21 +73,21 @@ public:
TaskBarStatus tbSevenStatus = tbseven::STATUS_NORMAL;
switch (status)
{
- case TaskbarProgress::STATUS_NOPROGRESS:
- tbSevenStatus = tbseven::STATUS_NOPROGRESS;
- break;
- case TaskbarProgress::STATUS_INDETERMINATE:
- tbSevenStatus = tbseven::STATUS_INDETERMINATE;
- break;
- case TaskbarProgress::STATUS_NORMAL:
- tbSevenStatus = tbseven::STATUS_NORMAL;
- break;
- case TaskbarProgress::STATUS_ERROR:
- tbSevenStatus = tbseven::STATUS_ERROR;
- break;
- case TaskbarProgress::STATUS_PAUSED:
- tbSevenStatus = tbseven::STATUS_PAUSED;
- break;
+ case TaskbarProgress::STATUS_NOPROGRESS:
+ tbSevenStatus = tbseven::STATUS_NOPROGRESS;
+ break;
+ case TaskbarProgress::STATUS_INDETERMINATE:
+ tbSevenStatus = tbseven::STATUS_INDETERMINATE;
+ break;
+ case TaskbarProgress::STATUS_NORMAL:
+ tbSevenStatus = tbseven::STATUS_NORMAL;
+ break;
+ case TaskbarProgress::STATUS_ERROR:
+ tbSevenStatus = tbseven::STATUS_ERROR;
+ break;
+ case TaskbarProgress::STATUS_PAUSED:
+ tbSevenStatus = tbseven::STATUS_PAUSED;
+ break;
}
setStatus_(assocWindow, tbSevenStatus);
diff --git a/shared/tinyxml/tinystr.cpp b/shared/tinyxml/tinystr.cpp
index 2b9b5467..86377ad1 100644
--- a/shared/tinyxml/tinystr.cpp
+++ b/shared/tinyxml/tinystr.cpp
@@ -83,7 +83,7 @@ TiXmlString& TiXmlString::append(const char* str, size_type len)
}
-TiXmlString operator + (const TiXmlString & a, const TiXmlString & b)
+TiXmlString operator + (const TiXmlString& a, const TiXmlString& b)
{
TiXmlString tmp;
tmp.reserve(a.length() + b.length());
@@ -92,7 +92,7 @@ TiXmlString operator + (const TiXmlString & a, const TiXmlString & b)
return tmp;
}
-TiXmlString operator + (const TiXmlString & a, const char* b)
+TiXmlString operator + (const TiXmlString& a, const char* b)
{
TiXmlString tmp;
TiXmlString::size_type b_len = static_cast<TiXmlString::size_type>( strlen(b) );
@@ -102,7 +102,7 @@ TiXmlString operator + (const TiXmlString & a, const char* b)
return tmp;
}
-TiXmlString operator + (const char* a, const TiXmlString & b)
+TiXmlString operator + (const char* a, const TiXmlString& b)
{
TiXmlString tmp;
TiXmlString::size_type a_len = static_cast<TiXmlString::size_type>( strlen(a) );
diff --git a/shared/tinyxml/tinystr.h b/shared/tinyxml/tinystr.h
index 3c2aa9d5..b11407a4 100644
--- a/shared/tinyxml/tinystr.h
+++ b/shared/tinyxml/tinystr.h
@@ -47,13 +47,13 @@ distribution.
used. Be nice to old compilers and macro it here:
*/
#if defined(_MSC_VER) && (_MSC_VER >= 1200 )
- // Microsoft visual studio, version 6 and higher.
- #define TIXML_EXPLICIT explicit
+// Microsoft visual studio, version 6 and higher.
+#define TIXML_EXPLICIT explicit
#elif defined(__GNUC__) && (__GNUC__ >= 3 )
- // GCC version 3 and higher.s
- #define TIXML_EXPLICIT explicit
+// GCC version 3 and higher.s
+#define TIXML_EXPLICIT explicit
#else
- #define TIXML_EXPLICIT
+#define TIXML_EXPLICIT
#endif
@@ -66,229 +66,229 @@ distribution.
*/
class TiXmlString
{
- public :
- // The size type used
- typedef size_t size_type;
-
- // Error value for find primitive
- static const size_type npos; // = -1;
-
-
- // TiXmlString empty constructor
- TiXmlString () : rep_(&nullrep_)
- {
- }
-
- // TiXmlString copy constructor
- TiXmlString ( const TiXmlString & copy) : rep_(0)
- {
- init(copy.length());
- memcpy(start(), copy.data(), length());
- }
-
- // TiXmlString constructor, based on a string
- TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0)
- {
- init( static_cast<size_type>( strlen(copy) ));
- memcpy(start(), copy, length());
- }
-
- // TiXmlString constructor, based on a string
- TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0)
- {
- init(len);
- memcpy(start(), str, len);
- }
-
- // TiXmlString destructor
- ~TiXmlString ()
- {
- quit();
- }
-
- // = operator
- TiXmlString& operator = (const char * copy)
- {
- return assign( copy, (size_type)strlen(copy));
- }
-
- // = operator
- TiXmlString& operator = (const TiXmlString & copy)
- {
- return assign(copy.start(), copy.length());
- }
-
-
- // += operator. Maps to append
- TiXmlString& operator += (const char * suffix)
- {
- return append(suffix, static_cast<size_type>( strlen(suffix) ));
- }
-
- // += operator. Maps to append
- TiXmlString& operator += (char single)
- {
- return append(&single, 1);
- }
-
- // += operator. Maps to append
- TiXmlString& operator += (const TiXmlString & suffix)
- {
- return append(suffix.data(), suffix.length());
- }
-
-
- // Convert a TiXmlString into a null-terminated char *
- const char * c_str () const { return rep_->str; }
-
- // Convert a TiXmlString into a char * (need not be null terminated).
- const char * data () const { return rep_->str; }
-
- // Return the length of a TiXmlString
- size_type length () const { return rep_->size; }
-
- // Alias for length()
- size_type size () const { return rep_->size; }
-
- // Checks if a TiXmlString is empty
- bool empty () const { return rep_->size == 0; }
-
- // Return capacity of string
- size_type capacity () const { return rep_->capacity; }
-
-
- // single char extraction
- const char& at (size_type index) const
- {
- assert( index < length() );
- return rep_->str[ index ];
- }
-
- // [] operator
- char& operator [] (size_type index) const
- {
- assert( index < length() );
- return rep_->str[ index ];
- }
-
- // find a char in a string. Return TiXmlString::npos if not found
- size_type find (char lookup) const
- {
- return find(lookup, 0);
- }
-
- // find a char in a string from an offset. Return TiXmlString::npos if not found
- size_type find (char tofind, size_type offset) const
- {
- if (offset >= length()) return npos;
-
- for (const char* p = c_str() + offset; *p != '\0'; ++p)
- {
- if (*p == tofind) return static_cast< size_type >( p - c_str() );
- }
- return npos;
- }
-
- void clear ()
- {
- //Lee:
- //The original was just too strange, though correct:
- // TiXmlString().swap(*this);
- //Instead use the quit & re-init:
- quit();
- init(0,0);
- }
-
- /* Function to reserve a big amount of data when we know we'll need it. Be aware that this
- function DOES NOT clear the content of the TiXmlString if any exists.
- */
- void reserve (size_type cap);
-
- TiXmlString& assign (const char* str, size_type len);
-
- TiXmlString& append (const char* str, size_type len);
-
- void swap (TiXmlString& other)
- {
- Rep* r = rep_;
- rep_ = other.rep_;
- other.rep_ = r;
- }
-
- private:
-
- void init(size_type sz) { init(sz, sz); }
- void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; }
- char* start() const { return rep_->str; }
- char* finish() const { return rep_->str + rep_->size; }
-
- struct Rep
- {
- size_type size, capacity;
- char str[1];
- };
-
- void init(size_type sz, size_type cap)
- {
- if (cap)
- {
- // Lee: the original form:
- // rep_ = static_cast<Rep*>(operator new(sizeof(Rep) + cap));
- // doesn't work in some cases of new being overloaded. Switching
- // to the normal allocation, although use an 'int' for systems
- // that are overly picky about structure alignment.
- const size_type bytesNeeded = sizeof(Rep) + cap;
- const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int );
- rep_ = reinterpret_cast<Rep*>( new int[ intsNeeded ] );
-
- rep_->str[ rep_->size = sz ] = '\0';
- rep_->capacity = cap;
- }
- else
- {
- rep_ = &nullrep_;
- }
- }
-
- void quit()
- {
- if (rep_ != &nullrep_)
- {
- // The rep_ is really an array of ints. (see the allocator, above).
- // Cast it back before delete, so the compiler won't incorrectly call destructors.
- delete [] ( reinterpret_cast<int*>( rep_ ) );
- }
- }
-
- Rep * rep_;
- static Rep nullrep_;
+public :
+ // The size type used
+ typedef size_t size_type;
+
+ // Error value for find primitive
+ static const size_type npos; // = -1;
+
+
+ // TiXmlString empty constructor
+ TiXmlString () : rep_(&nullrep_)
+ {
+ }
+
+ // TiXmlString copy constructor
+ TiXmlString ( const TiXmlString& copy) : rep_(0)
+ {
+ init(copy.length());
+ memcpy(start(), copy.data(), length());
+ }
+
+ // TiXmlString constructor, based on a string
+ TIXML_EXPLICIT TiXmlString ( const char* copy) : rep_(0)
+ {
+ init( static_cast<size_type>( strlen(copy) ));
+ memcpy(start(), copy, length());
+ }
+
+ // TiXmlString constructor, based on a string
+ TIXML_EXPLICIT TiXmlString ( const char* str, size_type len) : rep_(0)
+ {
+ init(len);
+ memcpy(start(), str, len);
+ }
+
+ // TiXmlString destructor
+ ~TiXmlString ()
+ {
+ quit();
+ }
+
+ // = operator
+ TiXmlString& operator = (const char* copy)
+ {
+ return assign( copy, (size_type)strlen(copy));
+ }
+
+ // = operator
+ TiXmlString& operator = (const TiXmlString& copy)
+ {
+ return assign(copy.start(), copy.length());
+ }
+
+
+ // += operator. Maps to append
+ TiXmlString& operator += (const char* suffix)
+ {
+ return append(suffix, static_cast<size_type>( strlen(suffix) ));
+ }
+
+ // += operator. Maps to append
+ TiXmlString& operator += (char single)
+ {
+ return append(&single, 1);
+ }
+
+ // += operator. Maps to append
+ TiXmlString& operator += (const TiXmlString& suffix)
+ {
+ return append(suffix.data(), suffix.length());
+ }
+
+
+ // Convert a TiXmlString into a null-terminated char *
+ const char* c_str () const { return rep_->str; }
+
+ // Convert a TiXmlString into a char * (need not be null terminated).
+ const char* data () const { return rep_->str; }
+
+ // Return the length of a TiXmlString
+ size_type length () const { return rep_->size; }
+
+ // Alias for length()
+ size_type size () const { return rep_->size; }
+
+ // Checks if a TiXmlString is empty
+ bool empty () const { return rep_->size == 0; }
+
+ // Return capacity of string
+ size_type capacity () const { return rep_->capacity; }
+
+
+ // single char extraction
+ const char& at (size_type index) const
+ {
+ assert( index < length() );
+ return rep_->str[ index ];
+ }
+
+ // [] operator
+ char& operator [] (size_type index) const
+ {
+ assert( index < length() );
+ return rep_->str[ index ];
+ }
+
+ // find a char in a string. Return TiXmlString::npos if not found
+ size_type find (char lookup) const
+ {
+ return find(lookup, 0);
+ }
+
+ // find a char in a string from an offset. Return TiXmlString::npos if not found
+ size_type find (char tofind, size_type offset) const
+ {
+ if (offset >= length()) return npos;
+
+ for (const char* p = c_str() + offset; *p != '\0'; ++p)
+ {
+ if (*p == tofind) return static_cast< size_type >( p - c_str() );
+ }
+ return npos;
+ }
+
+ void clear ()
+ {
+ //Lee:
+ //The original was just too strange, though correct:
+ // TiXmlString().swap(*this);
+ //Instead use the quit & re-init:
+ quit();
+ init(0,0);
+ }
+
+ /* Function to reserve a big amount of data when we know we'll need it. Be aware that this
+ function DOES NOT clear the content of the TiXmlString if any exists.
+ */
+ void reserve (size_type cap);
+
+ TiXmlString& assign (const char* str, size_type len);
+
+ TiXmlString& append (const char* str, size_type len);
+
+ void swap (TiXmlString& other)
+ {
+ Rep* r = rep_;
+ rep_ = other.rep_;
+ other.rep_ = r;
+ }
+
+private:
+
+ void init(size_type sz) { init(sz, sz); }
+ void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; }
+ char* start() const { return rep_->str; }
+ char* finish() const { return rep_->str + rep_->size; }
+
+ struct Rep
+ {
+ size_type size, capacity;
+ char str[1];
+ };
+
+ void init(size_type sz, size_type cap)
+ {
+ if (cap)
+ {
+ // Lee: the original form:
+ // rep_ = static_cast<Rep*>(operator new(sizeof(Rep) + cap));
+ // doesn't work in some cases of new being overloaded. Switching
+ // to the normal allocation, although use an 'int' for systems
+ // that are overly picky about structure alignment.
+ const size_type bytesNeeded = sizeof(Rep) + cap;
+ const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int );
+ rep_ = reinterpret_cast<Rep*>( new int[ intsNeeded ] );
+
+ rep_->str[ rep_->size = sz ] = '\0';
+ rep_->capacity = cap;
+ }
+ else
+ {
+ rep_ = &nullrep_;
+ }
+ }
+
+ void quit()
+ {
+ if (rep_ != &nullrep_)
+ {
+ // The rep_ is really an array of ints. (see the allocator, above).
+ // Cast it back before delete, so the compiler won't incorrectly call destructors.
+ delete [] ( reinterpret_cast<int*>( rep_ ) );
+ }
+ }
+
+ Rep* rep_;
+ static Rep nullrep_;
} ;
-inline bool operator == (const TiXmlString & a, const TiXmlString & b)
+inline bool operator == (const TiXmlString& a, const TiXmlString& b)
{
- return ( a.length() == b.length() ) // optimization on some platforms
- && ( strcmp(a.c_str(), b.c_str()) == 0 ); // actual compare
+ return ( a.length() == b.length() ) // optimization on some platforms
+ && ( strcmp(a.c_str(), b.c_str()) == 0 ); // actual compare
}
-inline bool operator < (const TiXmlString & a, const TiXmlString & b)
+inline bool operator < (const TiXmlString& a, const TiXmlString& b)
{
- return strcmp(a.c_str(), b.c_str()) < 0;
+ return strcmp(a.c_str(), b.c_str()) < 0;
}
-inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); }
-inline bool operator > (const TiXmlString & a, const TiXmlString & b) { return b < a; }
-inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); }
-inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); }
+inline bool operator != (const TiXmlString& a, const TiXmlString& b) { return !(a == b); }
+inline bool operator > (const TiXmlString& a, const TiXmlString& b) { return b < a; }
+inline bool operator <= (const TiXmlString& a, const TiXmlString& b) { return !(b < a); }
+inline bool operator >= (const TiXmlString& a, const TiXmlString& b) { return !(a < b); }
-inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; }
-inline bool operator == (const char* a, const TiXmlString & b) { return b == a; }
-inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); }
-inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); }
+inline bool operator == (const TiXmlString& a, const char* b) { return strcmp(a.c_str(), b) == 0; }
+inline bool operator == (const char* a, const TiXmlString& b) { return b == a; }
+inline bool operator != (const TiXmlString& a, const char* b) { return !(a == b); }
+inline bool operator != (const char* a, const TiXmlString& b) { return !(b == a); }
-TiXmlString operator + (const TiXmlString & a, const TiXmlString & b);
-TiXmlString operator + (const TiXmlString & a, const char* b);
-TiXmlString operator + (const char* a, const TiXmlString & b);
+TiXmlString operator + (const TiXmlString& a, const TiXmlString& b);
+TiXmlString operator + (const TiXmlString& a, const char* b);
+TiXmlString operator + (const char* a, const TiXmlString& b);
/*
@@ -299,19 +299,19 @@ class TiXmlOutStream : public TiXmlString
{
public :
- // TiXmlOutStream << operator.
- TiXmlOutStream & operator << (const TiXmlString & in)
- {
- *this += in;
- return *this;
- }
-
- // TiXmlOutStream << operator.
- TiXmlOutStream & operator << (const char * in)
- {
- *this += in;
- return *this;
- }
+ // TiXmlOutStream << operator.
+ TiXmlOutStream& operator << (const TiXmlString& in)
+ {
+ *this += in;
+ return *this;
+ }
+
+ // TiXmlOutStream << operator.
+ TiXmlOutStream& operator << (const char* in)
+ {
+ *this += in;
+ return *this;
+ }
} ;
diff --git a/shared/tinyxml/tinyxml.cpp b/shared/tinyxml/tinyxml.cpp
index 9a13c32b..2b8f17a8 100644
--- a/shared/tinyxml/tinyxml.cpp
+++ b/shared/tinyxml/tinyxml.cpp
@@ -57,10 +57,10 @@ void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString )
{
unsigned char c = (unsigned char) str[i];
- if ( c == '&'
- && i < ( (int)str.length() - 2 )
- && str[i+1] == '#'
- && str[i+2] == 'x' )
+ if (c == '&'
+ && i < ( (int)str.length() - 2 )
+ && str[i+1] == '#'
+ && str[i+2] == 'x' )
{
// Hexadecimal character reference.
// Pass through unchanged.
@@ -358,7 +358,7 @@ bool TiXmlNode::RemoveChild( TiXmlNode* removeThis )
return true;
}
-const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const
+const TiXmlNode* TiXmlNode::FirstChild( const char* _value ) const
{
const TiXmlNode* node;
for ( node = firstChild; node; node = node->next )
@@ -370,7 +370,7 @@ const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const
}
-const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const
+const TiXmlNode* TiXmlNode::LastChild( const char* _value ) const
{
const TiXmlNode* node;
for ( node = lastChild; node; node = node->prev )
@@ -396,7 +396,7 @@ const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const
}
-const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const
+const TiXmlNode* TiXmlNode::IterateChildren( const char* val, const TiXmlNode* previous ) const
{
if ( !previous )
{
@@ -410,7 +410,7 @@ const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode*
}
-const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const
+const TiXmlNode* TiXmlNode::NextSibling( const char* _value ) const
{
const TiXmlNode* node;
for ( node = next; node; node = node->next )
@@ -422,7 +422,7 @@ const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const
}
-const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const
+const TiXmlNode* TiXmlNode::PreviousSibling( const char* _value ) const
{
const TiXmlNode* node;
for ( node = prev; node; node = node->prev )
@@ -434,7 +434,7 @@ const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const
}
-void TiXmlElement::RemoveAttribute( const char * name )
+void TiXmlElement::RemoveAttribute( const char* name )
{
#ifdef TIXML_USE_STL
TIXML_STRING str( name );
@@ -464,7 +464,7 @@ const TiXmlElement* TiXmlNode::FirstChildElement() const
}
-const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const
+const TiXmlElement* TiXmlNode::FirstChildElement( const char* _value ) const
{
const TiXmlNode* node;
@@ -494,7 +494,7 @@ const TiXmlElement* TiXmlNode::NextSiblingElement() const
}
-const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const
+const TiXmlElement* TiXmlNode::NextSiblingElement( const char* _value ) const
{
const TiXmlNode* node;
@@ -522,7 +522,7 @@ const TiXmlDocument* TiXmlNode::GetDocument() const
}
-TiXmlElement::TiXmlElement (const char * _value)
+TiXmlElement::TiXmlElement (const char* _value)
: TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
{
firstChild = lastChild = 0;
@@ -705,7 +705,7 @@ int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval )
#endif
-void TiXmlElement::SetAttribute( const char * name, int val )
+void TiXmlElement::SetAttribute( const char* name, int val )
{
TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
if ( attrib )
@@ -727,7 +727,7 @@ void TiXmlElement::SetAttribute( const std::string& name, int val )
#endif
-void TiXmlElement::SetDoubleAttribute( const char * name, double val )
+void TiXmlElement::SetDoubleAttribute( const char* name, double val )
{
TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
if ( attrib )
@@ -749,7 +749,7 @@ void TiXmlElement::SetDoubleAttribute( const std::string& name, double val )
#endif
-void TiXmlElement::SetAttribute( const char * cname, const char * cvalue )
+void TiXmlElement::SetAttribute( const char* cname, const char* cvalue )
{
TiXmlAttribute* attrib = attributeSet.FindOrCreate( cname );
if ( attrib )
@@ -895,7 +895,7 @@ TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
ClearError();
}
-TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
+TiXmlDocument::TiXmlDocument( const char* documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
{
tabsize = 4;
useMicrosoftBOM = false;
@@ -1063,7 +1063,7 @@ bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
}
-bool TiXmlDocument::SaveFile( const char * filename ) const
+bool TiXmlDocument::SaveFile( const char* filename ) const
{
// The old c stuff lives on...
FILE* fp = TiXmlFOpen( filename, "w" );
@@ -1370,9 +1370,9 @@ TiXmlNode* TiXmlText::Clone() const
}
-TiXmlDeclaration::TiXmlDeclaration( const char * _version,
- const char * _encoding,
- const char * _standalone )
+TiXmlDeclaration::TiXmlDeclaration( const char* _version,
+ const char* _encoding,
+ const char* _standalone )
: TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
{
version = _version;
@@ -1606,7 +1606,7 @@ TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const char* _name )
#ifdef TIXML_USE_STL
-std::istream& operator>> (std::istream & in, TiXmlNode & base)
+std::istream& operator>> (std::istream& in, TiXmlNode& base)
{
TIXML_STRING tag;
tag.reserve( 8 * 1000 );
@@ -1619,7 +1619,7 @@ std::istream& operator>> (std::istream & in, TiXmlNode & base)
#ifdef TIXML_USE_STL
-std::ostream& operator<< (std::ostream & out, const TiXmlNode & base)
+std::ostream& operator<< (std::ostream& out, const TiXmlNode& base)
{
TiXmlPrinter printer;
printer.SetStreamPrinting();
@@ -1654,7 +1654,7 @@ TiXmlHandle TiXmlHandle::FirstChild() const
}
-TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const
+TiXmlHandle TiXmlHandle::FirstChild( const char* value ) const
{
if ( node )
{
@@ -1678,7 +1678,7 @@ TiXmlHandle TiXmlHandle::FirstChildElement() const
}
-TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const
+TiXmlHandle TiXmlHandle::FirstChildElement( const char* value ) const
{
if ( node )
{
@@ -1796,9 +1796,9 @@ bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute
else
{
buffer += ">";
- if ( element.FirstChild()->ToText()
- && element.LastChild() == element.FirstChild()
- && element.FirstChild()->ToText()->CDATA() == false )
+ if (element.FirstChild()->ToText()
+ && element.LastChild() == element.FirstChild()
+ && element.FirstChild()->ToText()->CDATA() == false )
{
simpleTextPrint = true;
// no DoLineBreak()!
diff --git a/shared/tinyxml/tinyxml.h b/shared/tinyxml/tinyxml.h
index 01822911..226415c9 100644
--- a/shared/tinyxml/tinyxml.h
+++ b/shared/tinyxml/tinyxml.h
@@ -44,13 +44,13 @@ distribution.
#endif
#ifdef TIXML_USE_STL
- #include <string>
- #include <iostream>
- #include <sstream>
- #define TIXML_STRING std::string
+#include <string>
+#include <iostream>
+#include <sstream>
+#define TIXML_STRING std::string
#else
- #include "tinystr.h"
- #define TIXML_STRING TiXmlString
+#include "tinystr.h"
+#define TIXML_STRING TiXmlString
#endif
// Deprecated library function hell. Compilers want to use the
@@ -60,25 +60,25 @@ distribution.
#define TIXML_SAFE
#ifdef TIXML_SAFE
- #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
- // Microsoft visual studio, version 2005 and higher.
- #define TIXML_SNPRINTF _snprintf_s
- #define TIXML_SSCANF sscanf_s
- #elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
- // Microsoft visual studio, version 6 and higher.
- //#pragma message( "Using _sn* functions." )
- #define TIXML_SNPRINTF _snprintf
- #define TIXML_SSCANF sscanf
- #elif defined(__GNUC__) && (__GNUC__ >= 3 )
- // GCC version 3 and higher.s
- //#warning( "Using sn* functions." )
- #define TIXML_SNPRINTF snprintf
- #define TIXML_SSCANF sscanf
- #else
- #define TIXML_SNPRINTF snprintf
- #define TIXML_SSCANF sscanf
- #endif
-#endif
+#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
+// Microsoft visual studio, version 2005 and higher.
+#define TIXML_SNPRINTF _snprintf_s
+#define TIXML_SSCANF sscanf_s
+#elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
+// Microsoft visual studio, version 6 and higher.
+//#pragma message( "Using _sn* functions." )
+#define TIXML_SNPRINTF _snprintf
+#define TIXML_SSCANF sscanf
+#elif defined(__GNUC__) && (__GNUC__ >= 3 )
+// GCC version 3 and higher.s
+//#warning( "Using sn* functions." )
+#define TIXML_SNPRINTF snprintf
+#define TIXML_SSCANF sscanf
+#else
+#define TIXML_SNPRINTF snprintf
+#define TIXML_SSCANF sscanf
+#endif
+#endif
class TiXmlDocument;
class TiXmlElement;
@@ -93,16 +93,16 @@ const int TIXML_MAJOR_VERSION = 2;
const int TIXML_MINOR_VERSION = 6;
const int TIXML_PATCH_VERSION = 1;
-/* Internal structure for tracking location of items
+/* Internal structure for tracking location of items
in the XML file.
*/
struct TiXmlCursor
{
- TiXmlCursor() { Clear(); }
- void Clear() { row = col = -1; }
+ TiXmlCursor() { Clear(); }
+ void Clear() { row = col = -1; }
- int row; // 0 based.
- int col; // 0 based.
+ int row; // 0 based.
+ int col; // 0 based.
};
@@ -116,7 +116,7 @@ struct TiXmlCursor
If you return 'true' from a Visit method, recursive parsing will continue. If you return
false, <b>no children of this node or its sibilings</b> will be Visited.
- All flavors of Visit methods have a default implementation that returns 'true' (continue
+ All flavors of Visit methods have a default implementation that returns 'true' (continue
visiting). You need to only override methods that are interesting to you.
Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting.
@@ -128,43 +128,43 @@ struct TiXmlCursor
class TiXmlVisitor
{
public:
- virtual ~TiXmlVisitor() {}
-
- /// Visit a document.
- virtual bool VisitEnter( const TiXmlDocument& /*doc*/ ) { return true; }
- /// Visit a document.
- virtual bool VisitExit( const TiXmlDocument& /*doc*/ ) { return true; }
-
- /// Visit an element.
- virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ ) { return true; }
- /// Visit an element.
- virtual bool VisitExit( const TiXmlElement& /*element*/ ) { return true; }
-
- /// Visit a declaration
- virtual bool Visit( const TiXmlDeclaration& /*declaration*/ ) { return true; }
- /// Visit a text node
- virtual bool Visit( const TiXmlText& /*text*/ ) { return true; }
- /// Visit a comment node
- virtual bool Visit( const TiXmlComment& /*comment*/ ) { return true; }
- /// Visit an unknow node
- virtual bool Visit( const TiXmlUnknown& /*unknown*/ ) { return true; }
+ virtual ~TiXmlVisitor() {}
+
+ /// Visit a document.
+ virtual bool VisitEnter( const TiXmlDocument& /*doc*/ ) { return true; }
+ /// Visit a document.
+ virtual bool VisitExit( const TiXmlDocument& /*doc*/ ) { return true; }
+
+ /// Visit an element.
+ virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ ) { return true; }
+ /// Visit an element.
+ virtual bool VisitExit( const TiXmlElement& /*element*/ ) { return true; }
+
+ /// Visit a declaration
+ virtual bool Visit( const TiXmlDeclaration& /*declaration*/ ) { return true; }
+ /// Visit a text node
+ virtual bool Visit( const TiXmlText& /*text*/ ) { return true; }
+ /// Visit a comment node
+ virtual bool Visit( const TiXmlComment& /*comment*/ ) { return true; }
+ /// Visit an unknow node
+ virtual bool Visit( const TiXmlUnknown& /*unknown*/ ) { return true; }
};
// Only used by Attribute::Query functions
-enum
-{
- TIXML_SUCCESS,
- TIXML_NO_ATTRIBUTE,
- TIXML_WRONG_TYPE
+enum
+{
+ TIXML_SUCCESS,
+ TIXML_NO_ATTRIBUTE,
+ TIXML_WRONG_TYPE
};
// Used by the parsing routines.
enum TiXmlEncoding
{
- TIXML_ENCODING_UNKNOWN,
- TIXML_ENCODING_UTF8,
- TIXML_ENCODING_LEGACY
+ TIXML_ENCODING_UNKNOWN,
+ TIXML_ENCODING_UTF8,
+ TIXML_ENCODING_LEGACY
};
const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
@@ -193,224 +193,225 @@ const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
*/
class TiXmlBase
{
- friend class TiXmlNode;
- friend class TiXmlElement;
- friend class TiXmlDocument;
+ friend class TiXmlNode;
+ friend class TiXmlElement;
+ friend class TiXmlDocument;
public:
- TiXmlBase() : userData(0) {}
- virtual ~TiXmlBase() {}
-
- /** All TinyXml classes can print themselves to a filestream
- or the string class (TiXmlString in non-STL mode, std::string
- in STL mode.) Either or both cfile and str can be null.
-
- This is a formatted print, and will insert
- tabs and newlines.
-
- (For an unformatted stream, use the << operator.)
- */
- virtual void Print( FILE* cfile, int depth ) const = 0;
-
- /** The world does not agree on whether white space should be kept or
- not. In order to make everyone happy, these global, static functions
- are provided to set whether or not TinyXml will condense all white space
- into a single space or not. The default is to condense. Note changing this
- value is not thread safe.
- */
- static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; }
-
- /// Return the current white space setting.
- static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; }
-
- /** Return the position, in the original source file, of this node or attribute.
- The row and column are 1-based. (That is the first row and first column is
- 1,1). If the returns values are 0 or less, then the parser does not have
- a row and column value.
-
- Generally, the row and column value will be set when the TiXmlDocument::Load(),
- TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set
- when the DOM was created from operator>>.
-
- The values reflect the initial load. Once the DOM is modified programmatically
- (by adding or changing nodes and attributes) the new values will NOT update to
- reflect changes in the document.
-
- There is a minor performance cost to computing the row and column. Computation
- can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value.
-
- @sa TiXmlDocument::SetTabSize()
- */
- int Row() const { return location.row + 1; }
- int Column() const { return location.col + 1; } ///< See Row()
-
- void SetUserData( void* user ) { userData = user; } ///< Set a pointer to arbitrary user data.
- void* GetUserData() { return userData; } ///< Get a pointer to arbitrary user data.
- const void* GetUserData() const { return userData; } ///< Get a pointer to arbitrary user data.
-
- // Table that returs, for a given lead byte, the total number of bytes
- // in the UTF-8 sequence.
- static const int utf8ByteTable[256];
-
- virtual const char* Parse( const char* p,
- TiXmlParsingData* data,
- TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
-
- /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc,
- or they will be transformed into entities!
- */
- static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out );
-
- enum
- {
- TIXML_NO_ERROR = 0,
- TIXML_ERROR,
- TIXML_ERROR_OPENING_FILE,
- TIXML_ERROR_PARSING_ELEMENT,
- TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
- TIXML_ERROR_READING_ELEMENT_VALUE,
- TIXML_ERROR_READING_ATTRIBUTES,
- TIXML_ERROR_PARSING_EMPTY,
- TIXML_ERROR_READING_END_TAG,
- TIXML_ERROR_PARSING_UNKNOWN,
- TIXML_ERROR_PARSING_COMMENT,
- TIXML_ERROR_PARSING_DECLARATION,
- TIXML_ERROR_DOCUMENT_EMPTY,
- TIXML_ERROR_EMBEDDED_NULL,
- TIXML_ERROR_PARSING_CDATA,
- TIXML_ERROR_DOCUMENT_TOP_ONLY,
-
- TIXML_ERROR_STRING_COUNT
- };
+ TiXmlBase() : userData(0) {}
+ virtual ~TiXmlBase() {}
+
+ /** All TinyXml classes can print themselves to a filestream
+ or the string class (TiXmlString in non-STL mode, std::string
+ in STL mode.) Either or both cfile and str can be null.
+
+ This is a formatted print, and will insert
+ tabs and newlines.
+
+ (For an unformatted stream, use the << operator.)
+ */
+ virtual void Print( FILE* cfile, int depth ) const = 0;
+
+ /** The world does not agree on whether white space should be kept or
+ not. In order to make everyone happy, these global, static functions
+ are provided to set whether or not TinyXml will condense all white space
+ into a single space or not. The default is to condense. Note changing this
+ value is not thread safe.
+ */
+ static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; }
+
+ /// Return the current white space setting.
+ static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; }
+
+ /** Return the position, in the original source file, of this node or attribute.
+ The row and column are 1-based. (That is the first row and first column is
+ 1,1). If the returns values are 0 or less, then the parser does not have
+ a row and column value.
+
+ Generally, the row and column value will be set when the TiXmlDocument::Load(),
+ TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set
+ when the DOM was created from operator>>.
+
+ The values reflect the initial load. Once the DOM is modified programmatically
+ (by adding or changing nodes and attributes) the new values will NOT update to
+ reflect changes in the document.
+
+ There is a minor performance cost to computing the row and column. Computation
+ can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value.
+
+ @sa TiXmlDocument::SetTabSize()
+ */
+ int Row() const { return location.row + 1; }
+ int Column() const { return location.col + 1; } ///< See Row()
+
+ void SetUserData( void* user ) { userData = user; } ///< Set a pointer to arbitrary user data.
+ void* GetUserData() { return userData; } ///< Get a pointer to arbitrary user data.
+ const void* GetUserData() const { return userData; } ///< Get a pointer to arbitrary user data.
+
+ // Table that returs, for a given lead byte, the total number of bytes
+ // in the UTF-8 sequence.
+ static const int utf8ByteTable[256];
+
+ virtual const char* Parse( const char* p,
+ TiXmlParsingData* data,
+ TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
+
+ /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc,
+ or they will be transformed into entities!
+ */
+ static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out );
+
+ enum
+ {
+ TIXML_NO_ERROR = 0,
+ TIXML_ERROR,
+ TIXML_ERROR_OPENING_FILE,
+ TIXML_ERROR_PARSING_ELEMENT,
+ TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
+ TIXML_ERROR_READING_ELEMENT_VALUE,
+ TIXML_ERROR_READING_ATTRIBUTES,
+ TIXML_ERROR_PARSING_EMPTY,
+ TIXML_ERROR_READING_END_TAG,
+ TIXML_ERROR_PARSING_UNKNOWN,
+ TIXML_ERROR_PARSING_COMMENT,
+ TIXML_ERROR_PARSING_DECLARATION,
+ TIXML_ERROR_DOCUMENT_EMPTY,
+ TIXML_ERROR_EMBEDDED_NULL,
+ TIXML_ERROR_PARSING_CDATA,
+ TIXML_ERROR_DOCUMENT_TOP_ONLY,
+
+ TIXML_ERROR_STRING_COUNT
+ };
protected:
- static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
+ static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
- inline static bool IsWhiteSpace( char c )
- {
- return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' );
- }
- inline static bool IsWhiteSpace( int c )
- {
- if ( c < 256 )
- return IsWhiteSpace( (char) c );
- return false; // Again, only truly correct for English/Latin...but usually works.
- }
+ inline static bool IsWhiteSpace( char c )
+ {
+ return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' );
+ }
+ inline static bool IsWhiteSpace( int c )
+ {
+ if ( c < 256 )
+ return IsWhiteSpace( (char) c );
+ return false; // Again, only truly correct for English/Latin...but usually works.
+ }
- #ifdef TIXML_USE_STL
- static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag );
- static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag );
- #endif
-
- /* Reads an XML name into the string provided. Returns
- a pointer just past the last character of the name,
- or 0 if the function has an error.
- */
- static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
-
- /* Reads text. Returns a pointer past the given end tag.
- Wickedly complex options, but it keeps the (sensitive) code in one place.
- */
- static const char* ReadText( const char* in, // where to start
- TIXML_STRING* text, // the string read
- bool ignoreWhiteSpace, // whether to keep the white space
- const char* endTag, // what ends this text
- bool ignoreCase, // whether to ignore case in the end tag
- TiXmlEncoding encoding ); // the current encoding
-
- // If an entity has been found, transform it into a character.
- static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
-
- // Get a character, while interpreting entities.
- // The length can be from 0 to 4 bytes.
- inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )
- {
- assert( p );
- if ( encoding == TIXML_ENCODING_UTF8 )
- {
- *length = utf8ByteTable[ *((const unsigned char*)p) ];
- assert( *length >= 0 && *length < 5 );
- }
- else
- {
- *length = 1;
- }
-
- if ( *length == 1 )
- {
- if ( *p == '&' )
- return GetEntity( p, _value, length, encoding );
- *_value = *p;
- return p+1;
- }
- else if ( *length )
- {
- //strncpy( _value, p, *length ); // lots of compilers don't like this function (unsafe),
- // and the null terminator isn't needed
- for( int i=0; p[i] && i<*length; ++i ) {
- _value[i] = p[i];
- }
- return p + (*length);
- }
- else
- {
- // Not valid text.
- return 0;
- }
- }
-
- // Return true if the next characters in the stream are any of the endTag sequences.
- // Ignore case only works for english, and should only be relied on when comparing
- // to English words: StringEqual( p, "version", true ) is fine.
- static bool StringEqual( const char* p,
- const char* endTag,
- bool ignoreCase,
- TiXmlEncoding encoding );
-
- static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
+#ifdef TIXML_USE_STL
+ static bool StreamWhiteSpace( std::istream* in, TIXML_STRING* tag );
+ static bool StreamTo( std::istream* in, int character, TIXML_STRING* tag );
+#endif
- TiXmlCursor location;
+ /* Reads an XML name into the string provided. Returns
+ a pointer just past the last character of the name,
+ or 0 if the function has an error.
+ */
+ static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
+
+ /* Reads text. Returns a pointer past the given end tag.
+ Wickedly complex options, but it keeps the (sensitive) code in one place.
+ */
+ static const char* ReadText( const char* in, // where to start
+ TIXML_STRING* text, // the string read
+ bool ignoreWhiteSpace, // whether to keep the white space
+ const char* endTag, // what ends this text
+ bool ignoreCase, // whether to ignore case in the end tag
+ TiXmlEncoding encoding ); // the current encoding
+
+ // If an entity has been found, transform it into a character.
+ static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
+
+ // Get a character, while interpreting entities.
+ // The length can be from 0 to 4 bytes.
+ inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )
+ {
+ assert( p );
+ if ( encoding == TIXML_ENCODING_UTF8 )
+ {
+ *length = utf8ByteTable[ *((const unsigned char*)p) ];
+ assert( *length >= 0 && *length < 5 );
+ }
+ else
+ {
+ *length = 1;
+ }
+
+ if ( *length == 1 )
+ {
+ if ( *p == '&' )
+ return GetEntity( p, _value, length, encoding );
+ *_value = *p;
+ return p+1;
+ }
+ else if ( *length )
+ {
+ //strncpy( _value, p, *length ); // lots of compilers don't like this function (unsafe),
+ // and the null terminator isn't needed
+ for( int i=0; p[i] && i<*length; ++i )
+ {
+ _value[i] = p[i];
+ }
+ return p + (*length);
+ }
+ else
+ {
+ // Not valid text.
+ return 0;
+ }
+ }
+
+ // Return true if the next characters in the stream are any of the endTag sequences.
+ // Ignore case only works for english, and should only be relied on when comparing
+ // to English words: StringEqual( p, "version", true ) is fine.
+ static bool StringEqual( const char* p,
+ const char* endTag,
+ bool ignoreCase,
+ TiXmlEncoding encoding );
+
+ static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
+
+ TiXmlCursor location;
/// Field containing a generic user pointer
- void* userData;
-
- // None of these methods are reliable for any language except English.
- // Good for approximation, not great for accuracy.
- static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
- static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
- inline static int ToLower( int v, TiXmlEncoding encoding )
- {
- if ( encoding == TIXML_ENCODING_UTF8 )
- {
- if ( v < 128 ) return tolower( v );
- return v;
- }
- else
- {
- return tolower( v );
- }
- }
- static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
+ void* userData;
+
+ // None of these methods are reliable for any language except English.
+ // Good for approximation, not great for accuracy.
+ static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
+ static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
+ inline static int ToLower( int v, TiXmlEncoding encoding )
+ {
+ if ( encoding == TIXML_ENCODING_UTF8 )
+ {
+ if ( v < 128 ) return tolower( v );
+ return v;
+ }
+ else
+ {
+ return tolower( v );
+ }
+ }
+ static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
private:
- TiXmlBase( const TiXmlBase& ); // not implemented.
- void operator=( const TiXmlBase& base ); // not allowed.
-
- struct Entity
- {
- const char* str;
- unsigned int strLength;
- char chr;
- };
- enum
- {
- NUM_ENTITY = 5,
- MAX_ENTITY_LENGTH = 6
-
- };
- static Entity entity[ NUM_ENTITY ];
- static bool condenseWhiteSpace;
+ TiXmlBase( const TiXmlBase& ); // not implemented.
+ void operator=( const TiXmlBase& base ); // not allowed.
+
+ struct Entity
+ {
+ const char* str;
+ unsigned int strLength;
+ char chr;
+ };
+ enum
+ {
+ NUM_ENTITY = 5,
+ MAX_ENTITY_LENGTH = 6
+
+ };
+ static Entity entity[ NUM_ENTITY ];
+ static bool condenseWhiteSpace;
};
@@ -422,350 +423,361 @@ private:
*/
class TiXmlNode : public TiXmlBase
{
- friend class TiXmlDocument;
- friend class TiXmlElement;
+ friend class TiXmlDocument;
+ friend class TiXmlElement;
public:
- #ifdef TIXML_USE_STL
-
- /** An input stream operator, for every class. Tolerant of newlines and
- formatting, but doesn't expect them.
- */
- friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
-
- /** An output stream operator, for every class. Note that this outputs
- without any newlines or formatting, as opposed to Print(), which
- includes tabs and new lines.
-
- The operator<< and operator>> are not completely symmetric. Writing
- a node to a stream is very well defined. You'll get a nice stream
- of output, without any extra whitespace or newlines.
-
- But reading is not as well defined. (As it always is.) If you create
- a TiXmlElement (for example) and read that from an input stream,
- the text needs to define an element or junk will result. This is
- true of all input streams, but it's worth keeping in mind.
-
- A TiXmlDocument will read nodes until it reads a root element, and
- all the children of that root element.
- */
- friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
-
- /// Appends the XML node or attribute to a std::string.
- friend std::string& operator<< (std::string& out, const TiXmlNode& base );
-
- #endif
-
- /** The types of XML nodes supported by TinyXml. (All the
- unsupported types are picked up by UNKNOWN.)
- */
- enum NodeType
- {
- TINYXML_DOCUMENT,
- TINYXML_ELEMENT,
- TINYXML_COMMENT,
- TINYXML_UNKNOWN,
- TINYXML_TEXT,
- TINYXML_DECLARATION,
- TINYXML_TYPECOUNT
- };
-
- virtual ~TiXmlNode();
-
- /** The meaning of 'value' changes for the specific type of
- TiXmlNode.
- @verbatim
- Document: filename of the xml file
- Element: name of the element
- Comment: the comment text
- Unknown: the tag contents
- Text: the text string
- @endverbatim
-
- The subclasses will wrap this function.
- */
- const char *Value() const { return value.c_str (); }
-
- #ifdef TIXML_USE_STL
- /** Return Value() as a std::string. If you only use STL,
- this is more efficient than calling Value().
- Only available in STL mode.
- */
- const std::string& ValueStr() const { return value; }
- #endif
-
- const TIXML_STRING& ValueTStr() const { return value; }
-
- /** Changes the value of the node. Defined as:
- @verbatim
- Document: filename of the xml file
- Element: name of the element
- Comment: the comment text
- Unknown: the tag contents
- Text: the text string
- @endverbatim
- */
- void SetValue(const char * _value) { value = _value;}
-
- #ifdef TIXML_USE_STL
- /// STL std::string form.
- void SetValue( const std::string& _value ) { value = _value; }
- #endif
-
- /// Delete all the children of this node. Does not affect 'this'.
- void Clear();
-
- /// One step up the DOM.
- TiXmlNode* Parent() { return parent; }
- const TiXmlNode* Parent() const { return parent; }
-
- const TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children.
- TiXmlNode* FirstChild() { return firstChild; }
- const TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found.
- /// The first child of this node with the matching 'value'. Will be null if none found.
- TiXmlNode* FirstChild( const char * _value ) {
- // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe)
- // call the method, cast the return back to non-const.
- return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value ));
- }
- const TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children.
- TiXmlNode* LastChild() { return lastChild; }
-
- const TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children.
- TiXmlNode* LastChild( const char * _value ) {
- return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value ));
- }
+#ifdef TIXML_USE_STL
- #ifdef TIXML_USE_STL
- const TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::string form.
- TiXmlNode* FirstChild( const std::string& _value ) { return FirstChild (_value.c_str ()); } ///< STL std::string form.
- const TiXmlNode* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); } ///< STL std::string form.
- TiXmlNode* LastChild( const std::string& _value ) { return LastChild (_value.c_str ()); } ///< STL std::string form.
- #endif
-
- /** An alternate way to walk the children of a node.
- One way to iterate over nodes is:
- @verbatim
- for( child = parent->FirstChild(); child; child = child->NextSibling() )
- @endverbatim
-
- IterateChildren does the same thing with the syntax:
- @verbatim
- child = 0;
- while( child = parent->IterateChildren( child ) )
- @endverbatim
-
- IterateChildren takes the previous child as input and finds
- the next one. If the previous child is null, it returns the
- first. IterateChildren will return null when done.
- */
- const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
- TiXmlNode* IterateChildren( const TiXmlNode* previous ) {
- return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) );
- }
+ /** An input stream operator, for every class. Tolerant of newlines and
+ formatting, but doesn't expect them.
+ */
+ friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
- /// This flavor of IterateChildren searches for children with a particular 'value'
- const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
- TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) {
- return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) );
- }
+ /** An output stream operator, for every class. Note that this outputs
+ without any newlines or formatting, as opposed to Print(), which
+ includes tabs and new lines.
- #ifdef TIXML_USE_STL
- const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form.
- TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form.
- #endif
+ The operator<< and operator>> are not completely symmetric. Writing
+ a node to a stream is very well defined. You'll get a nice stream
+ of output, without any extra whitespace or newlines.
- /** Add a new node related to this. Adds a child past the LastChild.
- Returns a pointer to the new object or NULL if an error occured.
- */
- TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
+ But reading is not as well defined. (As it always is.) If you create
+ a TiXmlElement (for example) and read that from an input stream,
+ the text needs to define an element or junk will result. This is
+ true of all input streams, but it's worth keeping in mind.
+ A TiXmlDocument will read nodes until it reads a root element, and
+ all the children of that root element.
+ */
+ friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
- /** Add a new node related to this. Adds a child past the LastChild.
+ /// Appends the XML node or attribute to a std::string.
+ friend std::string& operator<< (std::string& out, const TiXmlNode& base );
- NOTE: the node to be added is passed by pointer, and will be
- henceforth owned (and deleted) by tinyXml. This method is efficient
- and avoids an extra copy, but should be used with care as it
- uses a different memory model than the other insert functions.
+#endif
- @sa InsertEndChild
- */
- TiXmlNode* LinkEndChild( TiXmlNode* addThis );
+ /** The types of XML nodes supported by TinyXml. (All the
+ unsupported types are picked up by UNKNOWN.)
+ */
+ enum NodeType
+ {
+ TINYXML_DOCUMENT,
+ TINYXML_ELEMENT,
+ TINYXML_COMMENT,
+ TINYXML_UNKNOWN,
+ TINYXML_TEXT,
+ TINYXML_DECLARATION,
+ TINYXML_TYPECOUNT
+ };
+
+ virtual ~TiXmlNode();
+
+ /** The meaning of 'value' changes for the specific type of
+ TiXmlNode.
+ @verbatim
+ Document: filename of the xml file
+ Element: name of the element
+ Comment: the comment text
+ Unknown: the tag contents
+ Text: the text string
+ @endverbatim
+
+ The subclasses will wrap this function.
+ */
+ const char* Value() const { return value.c_str (); }
- /** Add a new node related to this. Adds a child before the specified child.
- Returns a pointer to the new object or NULL if an error occured.
- */
- TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
+#ifdef TIXML_USE_STL
+ /** Return Value() as a std::string. If you only use STL,
+ this is more efficient than calling Value().
+ Only available in STL mode.
+ */
+ const std::string& ValueStr() const { return value; }
+#endif
- /** Add a new node related to this. Adds a child after the specified child.
- Returns a pointer to the new object or NULL if an error occured.
- */
- TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis );
+ const TIXML_STRING& ValueTStr() const { return value; }
- /** Replace a child of this node.
- Returns a pointer to the new object or NULL if an error occured.
- */
- TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
+ /** Changes the value of the node. Defined as:
+ @verbatim
+ Document: filename of the xml file
+ Element: name of the element
+ Comment: the comment text
+ Unknown: the tag contents
+ Text: the text string
+ @endverbatim
+ */
+ void SetValue(const char* _value) { value = _value;}
- /// Delete a child of this node.
- bool RemoveChild( TiXmlNode* removeThis );
+#ifdef TIXML_USE_STL
+ /// STL std::string form.
+ void SetValue( const std::string& _value ) { value = _value; }
+#endif
- /// Navigate to a sibling node.
- const TiXmlNode* PreviousSibling() const { return prev; }
- TiXmlNode* PreviousSibling() { return prev; }
+ /// Delete all the children of this node. Does not affect 'this'.
+ void Clear();
+
+ /// One step up the DOM.
+ TiXmlNode* Parent() { return parent; }
+ const TiXmlNode* Parent() const { return parent; }
+
+ const TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children.
+ TiXmlNode* FirstChild() { return firstChild; }
+ const TiXmlNode* FirstChild( const char* value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found.
+ /// The first child of this node with the matching 'value'. Will be null if none found.
+ TiXmlNode* FirstChild( const char* _value )
+ {
+ // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe)
+ // call the method, cast the return back to non-const.
+ return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value ));
+ }
+ const TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children.
+ TiXmlNode* LastChild() { return lastChild; }
+
+ const TiXmlNode* LastChild( const char* value ) const; /// The last child of this node matching 'value'. Will be null if there are no children.
+ TiXmlNode* LastChild( const char* _value )
+ {
+ return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value ));
+ }
- /// Navigate to a sibling node.
- const TiXmlNode* PreviousSibling( const char * ) const;
- TiXmlNode* PreviousSibling( const char *_prev ) {
- return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) );
- }
+#ifdef TIXML_USE_STL
+ const TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::string form.
+ TiXmlNode* FirstChild( const std::string& _value ) { return FirstChild (_value.c_str ()); } ///< STL std::string form.
+ const TiXmlNode* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); } ///< STL std::string form.
+ TiXmlNode* LastChild( const std::string& _value ) { return LastChild (_value.c_str ()); } ///< STL std::string form.
+#endif
- #ifdef TIXML_USE_STL
- const TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::string form.
- TiXmlNode* PreviousSibling( const std::string& _value ) { return PreviousSibling (_value.c_str ()); } ///< STL std::string form.
- const TiXmlNode* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); } ///< STL std::string form.
- TiXmlNode* NextSibling( const std::string& _value) { return NextSibling (_value.c_str ()); } ///< STL std::string form.
- #endif
-
- /// Navigate to a sibling node.
- const TiXmlNode* NextSibling() const { return next; }
- TiXmlNode* NextSibling() { return next; }
-
- /// Navigate to a sibling node with the given 'value'.
- const TiXmlNode* NextSibling( const char * ) const;
- TiXmlNode* NextSibling( const char* _next ) {
- return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) );
- }
+ /** An alternate way to walk the children of a node.
+ One way to iterate over nodes is:
+ @verbatim
+ for( child = parent->FirstChild(); child; child = child->NextSibling() )
+ @endverbatim
+
+ IterateChildren does the same thing with the syntax:
+ @verbatim
+ child = 0;
+ while( child = parent->IterateChildren( child ) )
+ @endverbatim
+
+ IterateChildren takes the previous child as input and finds
+ the next one. If the previous child is null, it returns the
+ first. IterateChildren will return null when done.
+ */
+ const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
+ TiXmlNode* IterateChildren( const TiXmlNode* previous )
+ {
+ return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) );
+ }
+
+ /// This flavor of IterateChildren searches for children with a particular 'value'
+ const TiXmlNode* IterateChildren( const char* value, const TiXmlNode* previous ) const;
+ TiXmlNode* IterateChildren( const char* _value, const TiXmlNode* previous )
+ {
+ return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) );
+ }
- /** Convenience function to get through elements.
- Calls NextSibling and ToElement. Will skip all non-Element
- nodes. Returns 0 if there is not another element.
- */
- const TiXmlElement* NextSiblingElement() const;
- TiXmlElement* NextSiblingElement() {
- return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() );
- }
+#ifdef TIXML_USE_STL
+ const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form.
+ TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form.
+#endif
- /** Convenience function to get through elements.
- Calls NextSibling and ToElement. Will skip all non-Element
- nodes. Returns 0 if there is not another element.
- */
- const TiXmlElement* NextSiblingElement( const char * ) const;
- TiXmlElement* NextSiblingElement( const char *_next ) {
- return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) );
- }
+ /** Add a new node related to this. Adds a child past the LastChild.
+ Returns a pointer to the new object or NULL if an error occured.
+ */
+ TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
- #ifdef TIXML_USE_STL
- const TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form.
- TiXmlElement* NextSiblingElement( const std::string& _value) { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form.
- #endif
- /// Convenience function to get through elements.
- const TiXmlElement* FirstChildElement() const;
- TiXmlElement* FirstChildElement() {
- return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() );
- }
+ /** Add a new node related to this. Adds a child past the LastChild.
- /// Convenience function to get through elements.
- const TiXmlElement* FirstChildElement( const char * _value ) const;
- TiXmlElement* FirstChildElement( const char * _value ) {
- return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) );
- }
+ NOTE: the node to be added is passed by pointer, and will be
+ henceforth owned (and deleted) by tinyXml. This method is efficient
+ and avoids an extra copy, but should be used with care as it
+ uses a different memory model than the other insert functions.
- #ifdef TIXML_USE_STL
- const TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::string form.
- TiXmlElement* FirstChildElement( const std::string& _value ) { return FirstChildElement (_value.c_str ()); } ///< STL std::string form.
- #endif
-
- /** Query the type (as an enumerated value, above) of this node.
- The possible types are: DOCUMENT, ELEMENT, COMMENT,
- UNKNOWN, TEXT, and DECLARATION.
- */
- int Type() const { return type; }
-
- /** Return a pointer to the Document this node lives in.
- Returns null if not in a document.
- */
- const TiXmlDocument* GetDocument() const;
- TiXmlDocument* GetDocument() {
- return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() );
- }
+ @sa InsertEndChild
+ */
+ TiXmlNode* LinkEndChild( TiXmlNode* addThis );
- /// Returns true if this node has no children.
- bool NoChildren() const { return !firstChild; }
+ /** Add a new node related to this. Adds a child before the specified child.
+ Returns a pointer to the new object or NULL if an error occured.
+ */
+ TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
- virtual const TiXmlDocument* ToDocument() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
- virtual const TiXmlElement* ToElement() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
- virtual const TiXmlComment* ToComment() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
- virtual const TiXmlUnknown* ToUnknown() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
- virtual const TiXmlText* ToText() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
- virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+ /** Add a new node related to this. Adds a child after the specified child.
+ Returns a pointer to the new object or NULL if an error occured.
+ */
+ TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis );
- virtual TiXmlDocument* ToDocument() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
- virtual TiXmlElement* ToElement() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
- virtual TiXmlComment* ToComment() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
- virtual TiXmlUnknown* ToUnknown() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
- virtual TiXmlText* ToText() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
- virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+ /** Replace a child of this node.
+ Returns a pointer to the new object or NULL if an error occured.
+ */
+ TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
- /** Create an exact duplicate of this node and return it. The memory must be deleted
- by the caller.
- */
- virtual TiXmlNode* Clone() const = 0;
+ /// Delete a child of this node.
+ bool RemoveChild( TiXmlNode* removeThis );
- /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the
- XML tree will be conditionally visited and the host will be called back
- via the TiXmlVisitor interface.
+ /// Navigate to a sibling node.
+ const TiXmlNode* PreviousSibling() const { return prev; }
+ TiXmlNode* PreviousSibling() { return prev; }
- This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse
- the XML for the callbacks, so the performance of TinyXML is unchanged by using this
- interface versus any other.)
+ /// Navigate to a sibling node.
+ const TiXmlNode* PreviousSibling( const char* ) const;
+ TiXmlNode* PreviousSibling( const char* _prev )
+ {
+ return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) );
+ }
- The interface has been based on ideas from:
+#ifdef TIXML_USE_STL
+ const TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::string form.
+ TiXmlNode* PreviousSibling( const std::string& _value ) { return PreviousSibling (_value.c_str ()); } ///< STL std::string form.
+ const TiXmlNode* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); } ///< STL std::string form.
+ TiXmlNode* NextSibling( const std::string& _value) { return NextSibling (_value.c_str ()); } ///< STL std::string form.
+#endif
- - http://www.saxproject.org/
- - http://c2.com/cgi/wiki?HierarchicalVisitorPattern
+ /// Navigate to a sibling node.
+ const TiXmlNode* NextSibling() const { return next; }
+ TiXmlNode* NextSibling() { return next; }
+
+ /// Navigate to a sibling node with the given 'value'.
+ const TiXmlNode* NextSibling( const char* ) const;
+ TiXmlNode* NextSibling( const char* _next )
+ {
+ return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) );
+ }
+
+ /** Convenience function to get through elements.
+ Calls NextSibling and ToElement. Will skip all non-Element
+ nodes. Returns 0 if there is not another element.
+ */
+ const TiXmlElement* NextSiblingElement() const;
+ TiXmlElement* NextSiblingElement()
+ {
+ return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() );
+ }
+
+ /** Convenience function to get through elements.
+ Calls NextSibling and ToElement. Will skip all non-Element
+ nodes. Returns 0 if there is not another element.
+ */
+ const TiXmlElement* NextSiblingElement( const char* ) const;
+ TiXmlElement* NextSiblingElement( const char* _next )
+ {
+ return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) );
+ }
- Which are both good references for "visiting".
+#ifdef TIXML_USE_STL
+ const TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form.
+ TiXmlElement* NextSiblingElement( const std::string& _value) { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form.
+#endif
+
+ /// Convenience function to get through elements.
+ const TiXmlElement* FirstChildElement() const;
+ TiXmlElement* FirstChildElement()
+ {
+ return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() );
+ }
- An example of using Accept():
- @verbatim
- TiXmlPrinter printer;
- tinyxmlDoc.Accept( &printer );
- const char* xmlcstr = printer.CStr();
- @endverbatim
- */
- virtual bool Accept( TiXmlVisitor* visitor ) const = 0;
+ /// Convenience function to get through elements.
+ const TiXmlElement* FirstChildElement( const char* _value ) const;
+ TiXmlElement* FirstChildElement( const char* _value )
+ {
+ return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) );
+ }
+
+#ifdef TIXML_USE_STL
+ const TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::string form.
+ TiXmlElement* FirstChildElement( const std::string& _value ) { return FirstChildElement (_value.c_str ()); } ///< STL std::string form.
+#endif
+
+ /** Query the type (as an enumerated value, above) of this node.
+ The possible types are: DOCUMENT, ELEMENT, COMMENT,
+ UNKNOWN, TEXT, and DECLARATION.
+ */
+ int Type() const { return type; }
+
+ /** Return a pointer to the Document this node lives in.
+ Returns null if not in a document.
+ */
+ const TiXmlDocument* GetDocument() const;
+ TiXmlDocument* GetDocument()
+ {
+ return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() );
+ }
+
+ /// Returns true if this node has no children.
+ bool NoChildren() const { return !firstChild; }
+
+ virtual const TiXmlDocument* ToDocument() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+ virtual const TiXmlElement* ToElement() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+ virtual const TiXmlComment* ToComment() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+ virtual const TiXmlUnknown* ToUnknown() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+ virtual const TiXmlText* ToText() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+ virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+
+ virtual TiXmlDocument* ToDocument() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+ virtual TiXmlElement* ToElement() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+ virtual TiXmlComment* ToComment() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+ virtual TiXmlUnknown* ToUnknown() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+ virtual TiXmlText* ToText() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+ virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+
+ /** Create an exact duplicate of this node and return it. The memory must be deleted
+ by the caller.
+ */
+ virtual TiXmlNode* Clone() const = 0;
+
+ /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the
+ XML tree will be conditionally visited and the host will be called back
+ via the TiXmlVisitor interface.
+
+ This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse
+ the XML for the callbacks, so the performance of TinyXML is unchanged by using this
+ interface versus any other.)
+
+ The interface has been based on ideas from:
+
+ - http://www.saxproject.org/
+ - http://c2.com/cgi/wiki?HierarchicalVisitorPattern
+
+ Which are both good references for "visiting".
+
+ An example of using Accept():
+ @verbatim
+ TiXmlPrinter printer;
+ tinyxmlDoc.Accept( &printer );
+ const char* xmlcstr = printer.CStr();
+ @endverbatim
+ */
+ virtual bool Accept( TiXmlVisitor* visitor ) const = 0;
protected:
- TiXmlNode( NodeType _type );
+ TiXmlNode( NodeType _type );
- // Copy to the allocated object. Shared functionality between Clone, Copy constructor,
- // and the assignment operator.
- void CopyTo( TiXmlNode* target ) const;
+ // Copy to the allocated object. Shared functionality between Clone, Copy constructor,
+ // and the assignment operator.
+ void CopyTo( TiXmlNode* target ) const;
- #ifdef TIXML_USE_STL
- // The real work of the input operator.
- virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0;
- #endif
+#ifdef TIXML_USE_STL
+ // The real work of the input operator.
+ virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0;
+#endif
- // Figure out what is at *p, and parse it. Returns null if it is not an xml node.
- TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
+ // Figure out what is at *p, and parse it. Returns null if it is not an xml node.
+ TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
- TiXmlNode* parent;
- NodeType type;
+ TiXmlNode* parent;
+ NodeType type;
- TiXmlNode* firstChild;
- TiXmlNode* lastChild;
+ TiXmlNode* firstChild;
+ TiXmlNode* lastChild;
- TIXML_STRING value;
+ TIXML_STRING value;
- TiXmlNode* prev;
- TiXmlNode* next;
+ TiXmlNode* prev;
+ TiXmlNode* next;
private:
- TiXmlNode( const TiXmlNode& ); // not implemented.
- void operator=( const TiXmlNode& base ); // not allowed.
+ TiXmlNode( const TiXmlNode& ); // not implemented.
+ void operator=( const TiXmlNode& base ); // not allowed.
};
@@ -778,119 +790,122 @@ private:
*/
class TiXmlAttribute : public TiXmlBase
{
- friend class TiXmlAttributeSet;
+ friend class TiXmlAttributeSet;
public:
- /// Construct an empty attribute.
- TiXmlAttribute() : TiXmlBase()
- {
- document = 0;
- prev = next = 0;
- }
+ /// Construct an empty attribute.
+ TiXmlAttribute() : TiXmlBase()
+ {
+ document = 0;
+ prev = next = 0;
+ }
- #ifdef TIXML_USE_STL
- /// std::string constructor.
- TiXmlAttribute( const std::string& _name, const std::string& _value )
- {
- name = _name;
- value = _value;
- document = 0;
- prev = next = 0;
- }
- #endif
+#ifdef TIXML_USE_STL
+ /// std::string constructor.
+ TiXmlAttribute( const std::string& _name, const std::string& _value )
+ {
+ name = _name;
+ value = _value;
+ document = 0;
+ prev = next = 0;
+ }
+#endif
- /// Construct an attribute with a name and value.
- TiXmlAttribute( const char * _name, const char * _value )
- {
- name = _name;
- value = _value;
- document = 0;
- prev = next = 0;
- }
+ /// Construct an attribute with a name and value.
+ TiXmlAttribute( const char* _name, const char* _value )
+ {
+ name = _name;
+ value = _value;
+ document = 0;
+ prev = next = 0;
+ }
+
+ const char* Name() const { return name.c_str(); } ///< Return the name of this attribute.
+ const char* Value() const { return value.c_str(); } ///< Return the value of this attribute.
+#ifdef TIXML_USE_STL
+ const std::string& ValueStr() const { return value; } ///< Return the value of this attribute.
+#endif
+ int IntValue() const; ///< Return the value of this attribute, converted to an integer.
+ double DoubleValue() const; ///< Return the value of this attribute, converted to a double.
- const char* Name() const { return name.c_str(); } ///< Return the name of this attribute.
- const char* Value() const { return value.c_str(); } ///< Return the value of this attribute.
- #ifdef TIXML_USE_STL
- const std::string& ValueStr() const { return value; } ///< Return the value of this attribute.
- #endif
- int IntValue() const; ///< Return the value of this attribute, converted to an integer.
- double DoubleValue() const; ///< Return the value of this attribute, converted to a double.
-
- // Get the tinyxml string representation
- const TIXML_STRING& NameTStr() const { return name; }
-
- /** QueryIntValue examines the value string. It is an alternative to the
- IntValue() method with richer error checking.
- If the value is an integer, it is stored in 'value' and
- the call returns TIXML_SUCCESS. If it is not
- an integer, it returns TIXML_WRONG_TYPE.
-
- A specialized but useful call. Note that for success it returns 0,
- which is the opposite of almost all other TinyXml calls.
- */
- int QueryIntValue( int* _value ) const;
- /// QueryDoubleValue examines the value string. See QueryIntValue().
- int QueryDoubleValue( double* _value ) const;
-
- void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute.
- void SetValue( const char* _value ) { value = _value; } ///< Set the value.
-
- void SetIntValue( int _value ); ///< Set the value from an integer.
- void SetDoubleValue( double _value ); ///< Set the value from a double.
-
- #ifdef TIXML_USE_STL
- /// STL std::string form.
- void SetName( const std::string& _name ) { name = _name; }
- /// STL std::string form.
- void SetValue( const std::string& _value ) { value = _value; }
- #endif
-
- /// Get the next sibling attribute in the DOM. Returns null at end.
- const TiXmlAttribute* Next() const;
- TiXmlAttribute* Next() {
- return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() );
- }
+ // Get the tinyxml string representation
+ const TIXML_STRING& NameTStr() const { return name; }
- /// Get the previous sibling attribute in the DOM. Returns null at beginning.
- const TiXmlAttribute* Previous() const;
- TiXmlAttribute* Previous() {
- return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() );
- }
+ /** QueryIntValue examines the value string. It is an alternative to the
+ IntValue() method with richer error checking.
+ If the value is an integer, it is stored in 'value' and
+ the call returns TIXML_SUCCESS. If it is not
+ an integer, it returns TIXML_WRONG_TYPE.
- bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
- bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; }
- bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; }
+ A specialized but useful call. Note that for success it returns 0,
+ which is the opposite of almost all other TinyXml calls.
+ */
+ int QueryIntValue( int* _value ) const;
+ /// QueryDoubleValue examines the value string. See QueryIntValue().
+ int QueryDoubleValue( double* _value ) const;
- /* Attribute parsing starts: first letter of the name
- returns: the next char after the value end quote
- */
- virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+ void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute.
+ void SetValue( const char* _value ) { value = _value; } ///< Set the value.
- // Prints this Attribute to a FILE stream.
- virtual void Print( FILE* cfile, int depth ) const {
- Print( cfile, depth, 0 );
- }
- void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
+ void SetIntValue( int _value ); ///< Set the value from an integer.
+ void SetDoubleValue( double _value ); ///< Set the value from a double.
- // [internal use]
- // Set the document pointer so the attribute can report errors.
- void SetDocument( TiXmlDocument* doc ) { document = doc; }
+#ifdef TIXML_USE_STL
+ /// STL std::string form.
+ void SetName( const std::string& _name ) { name = _name; }
+ /// STL std::string form.
+ void SetValue( const std::string& _value ) { value = _value; }
+#endif
+
+ /// Get the next sibling attribute in the DOM. Returns null at end.
+ const TiXmlAttribute* Next() const;
+ TiXmlAttribute* Next()
+ {
+ return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() );
+ }
+
+ /// Get the previous sibling attribute in the DOM. Returns null at beginning.
+ const TiXmlAttribute* Previous() const;
+ TiXmlAttribute* Previous()
+ {
+ return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() );
+ }
+
+ bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
+ bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; }
+ bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; }
+
+ /* Attribute parsing starts: first letter of the name
+ returns: the next char after the value end quote
+ */
+ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+ // Prints this Attribute to a FILE stream.
+ virtual void Print( FILE* cfile, int depth ) const
+ {
+ Print( cfile, depth, 0 );
+ }
+ void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
+
+ // [internal use]
+ // Set the document pointer so the attribute can report errors.
+ void SetDocument( TiXmlDocument* doc ) { document = doc; }
private:
- TiXmlAttribute( const TiXmlAttribute& ); // not implemented.
- void operator=( const TiXmlAttribute& base ); // not allowed.
-
- TiXmlDocument* document; // A pointer back to a document, for error reporting.
- TIXML_STRING name;
- TIXML_STRING value;
- TiXmlAttribute* prev;
- TiXmlAttribute* next;
+ TiXmlAttribute( const TiXmlAttribute& ); // not implemented.
+ void operator=( const TiXmlAttribute& base ); // not allowed.
+
+ TiXmlDocument* document; // A pointer back to a document, for error reporting.
+ TIXML_STRING name;
+ TIXML_STRING value;
+ TiXmlAttribute* prev;
+ TiXmlAttribute* next;
};
/* A class used to manage a group of attributes.
It is only used internally, both by the ELEMENT and the DECLARATION.
-
+
The set can be changed transparent to the Element and Declaration
classes that use it, but NOT transparent to the Attribute
which has to implement a next() and previous() method. Which makes
@@ -903,33 +918,33 @@ private:
class TiXmlAttributeSet
{
public:
- TiXmlAttributeSet();
- ~TiXmlAttributeSet();
+ TiXmlAttributeSet();
+ ~TiXmlAttributeSet();
- void Add( TiXmlAttribute* attribute );
- void Remove( TiXmlAttribute* attribute );
+ void Add( TiXmlAttribute* attribute );
+ void Remove( TiXmlAttribute* attribute );
- const TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
- TiXmlAttribute* First() { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
- const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
- TiXmlAttribute* Last() { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
+ const TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
+ TiXmlAttribute* First() { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
+ const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
+ TiXmlAttribute* Last() { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
- TiXmlAttribute* Find( const char* _name ) const;
- TiXmlAttribute* FindOrCreate( const char* _name );
+ TiXmlAttribute* Find( const char* _name ) const;
+ TiXmlAttribute* FindOrCreate( const char* _name );
# ifdef TIXML_USE_STL
- TiXmlAttribute* Find( const std::string& _name ) const;
- TiXmlAttribute* FindOrCreate( const std::string& _name );
+ TiXmlAttribute* Find( const std::string& _name ) const;
+ TiXmlAttribute* FindOrCreate( const std::string& _name );
# endif
private:
- //*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
- //*ME: this class must be also use a hidden/disabled copy-constructor !!!
- TiXmlAttributeSet( const TiXmlAttributeSet& ); // not allowed
- void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute)
+ //*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
+ //*ME: this class must be also use a hidden/disabled copy-constructor !!!
+ TiXmlAttributeSet( const TiXmlAttributeSet& ); // not allowed
+ void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute)
- TiXmlAttribute sentinel;
+ TiXmlAttribute sentinel;
};
@@ -940,213 +955,217 @@ private:
class TiXmlElement : public TiXmlNode
{
public:
- /// Construct an element.
- TiXmlElement (const char * in_value);
-
- #ifdef TIXML_USE_STL
- /// std::string constructor.
- TiXmlElement( const std::string& _value );
- #endif
-
- TiXmlElement( const TiXmlElement& );
-
- void operator=( const TiXmlElement& base );
-
- virtual ~TiXmlElement();
-
- /** Given an attribute name, Attribute() returns the value
- for the attribute of that name, or null if none exists.
- */
- const char* Attribute( const char* name ) const;
-
- /** Given an attribute name, Attribute() returns the value
- for the attribute of that name, or null if none exists.
- If the attribute exists and can be converted to an integer,
- the integer value will be put in the return 'i', if 'i'
- is non-null.
- */
- const char* Attribute( const char* name, int* i ) const;
-
- /** Given an attribute name, Attribute() returns the value
- for the attribute of that name, or null if none exists.
- If the attribute exists and can be converted to an double,
- the double value will be put in the return 'd', if 'd'
- is non-null.
- */
- const char* Attribute( const char* name, double* d ) const;
-
- /** QueryIntAttribute examines the attribute - it is an alternative to the
- Attribute() method with richer error checking.
- If the attribute is an integer, it is stored in 'value' and
- the call returns TIXML_SUCCESS. If it is not
- an integer, it returns TIXML_WRONG_TYPE. If the attribute
- does not exist, then TIXML_NO_ATTRIBUTE is returned.
- */
- int QueryIntAttribute( const char* name, int* _value ) const;
- /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
- int QueryDoubleAttribute( const char* name, double* _value ) const;
- /// QueryFloatAttribute examines the attribute - see QueryIntAttribute().
- int QueryFloatAttribute( const char* name, float* _value ) const {
- double d;
- int result = QueryDoubleAttribute( name, &d );
- if ( result == TIXML_SUCCESS ) {
- *_value = (float)d;
- }
- return result;
- }
+ /// Construct an element.
+ TiXmlElement (const char* in_value);
- #ifdef TIXML_USE_STL
- /// QueryStringAttribute examines the attribute - see QueryIntAttribute().
- int QueryStringAttribute( const char* name, std::string* _value ) const {
- const char* cstr = Attribute( name );
- if ( cstr ) {
- *_value = std::string( cstr );
- return TIXML_SUCCESS;
- }
- return TIXML_NO_ATTRIBUTE;
- }
+#ifdef TIXML_USE_STL
+ /// std::string constructor.
+ TiXmlElement( const std::string& _value );
+#endif
- /** Template form of the attribute query which will try to read the
- attribute into the specified type. Very easy, very powerful, but
- be careful to make sure to call this with the correct type.
-
- NOTE: This method doesn't work correctly for 'string' types that contain spaces.
+ TiXmlElement( const TiXmlElement& );
+
+ void operator=( const TiXmlElement& base );
+
+ virtual ~TiXmlElement();
+
+ /** Given an attribute name, Attribute() returns the value
+ for the attribute of that name, or null if none exists.
+ */
+ const char* Attribute( const char* name ) const;
+
+ /** Given an attribute name, Attribute() returns the value
+ for the attribute of that name, or null if none exists.
+ If the attribute exists and can be converted to an integer,
+ the integer value will be put in the return 'i', if 'i'
+ is non-null.
+ */
+ const char* Attribute( const char* name, int* i ) const;
+
+ /** Given an attribute name, Attribute() returns the value
+ for the attribute of that name, or null if none exists.
+ If the attribute exists and can be converted to an double,
+ the double value will be put in the return 'd', if 'd'
+ is non-null.
+ */
+ const char* Attribute( const char* name, double* d ) const;
+
+ /** QueryIntAttribute examines the attribute - it is an alternative to the
+ Attribute() method with richer error checking.
+ If the attribute is an integer, it is stored in 'value' and
+ the call returns TIXML_SUCCESS. If it is not
+ an integer, it returns TIXML_WRONG_TYPE. If the attribute
+ does not exist, then TIXML_NO_ATTRIBUTE is returned.
+ */
+ int QueryIntAttribute( const char* name, int* _value ) const;
+ /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
+ int QueryDoubleAttribute( const char* name, double* _value ) const;
+ /// QueryFloatAttribute examines the attribute - see QueryIntAttribute().
+ int QueryFloatAttribute( const char* name, float* _value ) const
+ {
+ double d;
+ int result = QueryDoubleAttribute( name, &d );
+ if ( result == TIXML_SUCCESS )
+ {
+ *_value = (float)d;
+ }
+ return result;
+ }
- @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE
- */
- template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const
- {
- const TiXmlAttribute* node = attributeSet.Find( name );
- if ( !node )
- return TIXML_NO_ATTRIBUTE;
-
- std::stringstream sstream( node->ValueStr() );
- sstream >> *outValue;
- if ( !sstream.fail() )
- return TIXML_SUCCESS;
- return TIXML_WRONG_TYPE;
- }
+#ifdef TIXML_USE_STL
+ /// QueryStringAttribute examines the attribute - see QueryIntAttribute().
+ int QueryStringAttribute( const char* name, std::string* _value ) const
+ {
+ const char* cstr = Attribute( name );
+ if ( cstr )
+ {
+ *_value = std::string( cstr );
+ return TIXML_SUCCESS;
+ }
+ return TIXML_NO_ATTRIBUTE;
+ }
+
+ /** Template form of the attribute query which will try to read the
+ attribute into the specified type. Very easy, very powerful, but
+ be careful to make sure to call this with the correct type.
+
+ NOTE: This method doesn't work correctly for 'string' types that contain spaces.
+
+ @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE
+ */
+ template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const
+ {
+ const TiXmlAttribute* node = attributeSet.Find( name );
+ if ( !node )
+ return TIXML_NO_ATTRIBUTE;
+
+ std::stringstream sstream( node->ValueStr() );
+ sstream >> *outValue;
+ if ( !sstream.fail() )
+ return TIXML_SUCCESS;
+ return TIXML_WRONG_TYPE;
+ }
+
+ int QueryValueAttribute( const std::string& name, std::string* outValue ) const
+ {
+ const TiXmlAttribute* node = attributeSet.Find( name );
+ if ( !node )
+ return TIXML_NO_ATTRIBUTE;
+ *outValue = node->ValueStr();
+ return TIXML_SUCCESS;
+ }
+#endif
- int QueryValueAttribute( const std::string& name, std::string* outValue ) const
- {
- const TiXmlAttribute* node = attributeSet.Find( name );
- if ( !node )
- return TIXML_NO_ATTRIBUTE;
- *outValue = node->ValueStr();
- return TIXML_SUCCESS;
- }
- #endif
-
- /** Sets an attribute of name to a given value. The attribute
- will be created if it does not exist, or changed if it does.
- */
- void SetAttribute( const char* name, const char * _value );
-
- #ifdef TIXML_USE_STL
- const std::string* Attribute( const std::string& name ) const;
- const std::string* Attribute( const std::string& name, int* i ) const;
- const std::string* Attribute( const std::string& name, double* d ) const;
- int QueryIntAttribute( const std::string& name, int* _value ) const;
- int QueryDoubleAttribute( const std::string& name, double* _value ) const;
-
- /// STL std::string form.
- void SetAttribute( const std::string& name, const std::string& _value );
- ///< STL std::string form.
- void SetAttribute( const std::string& name, int _value );
- ///< STL std::string form.
- void SetDoubleAttribute( const std::string& name, double value );
- #endif
-
- /** Sets an attribute of name to a given value. The attribute
- will be created if it does not exist, or changed if it does.
- */
- void SetAttribute( const char * name, int value );
-
- /** Sets an attribute of name to a given value. The attribute
- will be created if it does not exist, or changed if it does.
- */
- void SetDoubleAttribute( const char * name, double value );
-
- /** Deletes an attribute with the given name.
- */
- void RemoveAttribute( const char * name );
- #ifdef TIXML_USE_STL
- void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); } ///< STL std::string form.
- #endif
-
- const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element.
- TiXmlAttribute* FirstAttribute() { return attributeSet.First(); }
- const TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element.
- TiXmlAttribute* LastAttribute() { return attributeSet.Last(); }
-
- /** Convenience function for easy access to the text inside an element. Although easy
- and concise, GetText() is limited compared to getting the TiXmlText child
- and accessing it directly.
-
- If the first child of 'this' is a TiXmlText, the GetText()
- returns the character string of the Text node, else null is returned.
-
- This is a convenient method for getting the text of simple contained text:
- @verbatim
- <foo>This is text</foo>
- const char* str = fooElement->GetText();
- @endverbatim
-
- 'str' will be a pointer to "This is text".
-
- Note that this function can be misleading. If the element foo was created from
- this XML:
- @verbatim
- <foo><b>This is text</b></foo>
- @endverbatim
-
- then the value of str would be null. The first child node isn't a text node, it is
- another element. From this XML:
- @verbatim
- <foo>This is <b>text</b></foo>
- @endverbatim
- GetText() will return "This is ".
-
- WARNING: GetText() accesses a child node - don't become confused with the
- similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are
- safe type casts on the referenced node.
- */
- const char* GetText() const;
-
- /// Creates a new Element and returns it - the returned element is a copy.
- virtual TiXmlNode* Clone() const;
- // Print the Element to a FILE stream.
- virtual void Print( FILE* cfile, int depth ) const;
-
- /* Attribtue parsing starts: next char past '<'
- returns: next char past '>'
- */
- virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
-
- virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
- virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
-
- /** Walk the XML tree visiting this node and all of its children.
- */
- virtual bool Accept( TiXmlVisitor* visitor ) const;
+ /** Sets an attribute of name to a given value. The attribute
+ will be created if it does not exist, or changed if it does.
+ */
+ void SetAttribute( const char* name, const char* _value );
+
+#ifdef TIXML_USE_STL
+ const std::string* Attribute( const std::string& name ) const;
+ const std::string* Attribute( const std::string& name, int* i ) const;
+ const std::string* Attribute( const std::string& name, double* d ) const;
+ int QueryIntAttribute( const std::string& name, int* _value ) const;
+ int QueryDoubleAttribute( const std::string& name, double* _value ) const;
+
+ /// STL std::string form.
+ void SetAttribute( const std::string& name, const std::string& _value );
+ ///< STL std::string form.
+ void SetAttribute( const std::string& name, int _value );
+ ///< STL std::string form.
+ void SetDoubleAttribute( const std::string& name, double value );
+#endif
+
+ /** Sets an attribute of name to a given value. The attribute
+ will be created if it does not exist, or changed if it does.
+ */
+ void SetAttribute( const char* name, int value );
+
+ /** Sets an attribute of name to a given value. The attribute
+ will be created if it does not exist, or changed if it does.
+ */
+ void SetDoubleAttribute( const char* name, double value );
+
+ /** Deletes an attribute with the given name.
+ */
+ void RemoveAttribute( const char* name );
+#ifdef TIXML_USE_STL
+ void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); } ///< STL std::string form.
+#endif
+
+ const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element.
+ TiXmlAttribute* FirstAttribute() { return attributeSet.First(); }
+ const TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element.
+ TiXmlAttribute* LastAttribute() { return attributeSet.Last(); }
+
+ /** Convenience function for easy access to the text inside an element. Although easy
+ and concise, GetText() is limited compared to getting the TiXmlText child
+ and accessing it directly.
+
+ If the first child of 'this' is a TiXmlText, the GetText()
+ returns the character string of the Text node, else null is returned.
+
+ This is a convenient method for getting the text of simple contained text:
+ @verbatim
+ <foo>This is text</foo>
+ const char* str = fooElement->GetText();
+ @endverbatim
+
+ 'str' will be a pointer to "This is text".
+
+ Note that this function can be misleading. If the element foo was created from
+ this XML:
+ @verbatim
+ <foo><b>This is text</b></foo>
+ @endverbatim
+
+ then the value of str would be null. The first child node isn't a text node, it is
+ another element. From this XML:
+ @verbatim
+ <foo>This is <b>text</b></foo>
+ @endverbatim
+ GetText() will return "This is ".
+
+ WARNING: GetText() accesses a child node - don't become confused with the
+ similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are
+ safe type casts on the referenced node.
+ */
+ const char* GetText() const;
+
+ /// Creates a new Element and returns it - the returned element is a copy.
+ virtual TiXmlNode* Clone() const;
+ // Print the Element to a FILE stream.
+ virtual void Print( FILE* cfile, int depth ) const;
+
+ /* Attribtue parsing starts: next char past '<'
+ returns: next char past '>'
+ */
+ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+ virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+ virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+ /** Walk the XML tree visiting this node and all of its children.
+ */
+ virtual bool Accept( TiXmlVisitor* visitor ) const;
protected:
- void CopyTo( TiXmlElement* target ) const;
- void ClearThis(); // like clear, but initializes 'this' object as well
+ void CopyTo( TiXmlElement* target ) const;
+ void ClearThis(); // like clear, but initializes 'this' object as well
- // Used to be public [internal use]
- #ifdef TIXML_USE_STL
- virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
- #endif
- /* [internal use]
- Reads the "value" of the element -- another element, or text.
- This should terminate with the current end tag.
- */
- const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
+ // Used to be public [internal use]
+#ifdef TIXML_USE_STL
+ virtual void StreamIn( std::istream* in, TIXML_STRING* tag );
+#endif
+ /* [internal use]
+ Reads the "value" of the element -- another element, or text.
+ This should terminate with the current end tag.
+ */
+ const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
private:
- TiXmlAttributeSet attributeSet;
+ TiXmlAttributeSet attributeSet;
};
@@ -1155,110 +1174,111 @@ private:
class TiXmlComment : public TiXmlNode
{
public:
- /// Constructs an empty comment.
- TiXmlComment() : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {}
- /// Construct a comment from text.
- TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {
- SetValue( _value );
- }
- TiXmlComment( const TiXmlComment& );
- void operator=( const TiXmlComment& base );
-
- virtual ~TiXmlComment() {}
-
- /// Returns a copy of this Comment.
- virtual TiXmlNode* Clone() const;
- // Write this Comment to a FILE stream.
- virtual void Print( FILE* cfile, int depth ) const;
-
- /* Attribtue parsing starts: at the ! of the !--
- returns: next char past '>'
- */
- virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
-
- virtual const TiXmlComment* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
- virtual TiXmlComment* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
-
- /** Walk the XML tree visiting this node and all of its children.
- */
- virtual bool Accept( TiXmlVisitor* visitor ) const;
+ /// Constructs an empty comment.
+ TiXmlComment() : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {}
+ /// Construct a comment from text.
+ TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT )
+ {
+ SetValue( _value );
+ }
+ TiXmlComment( const TiXmlComment& );
+ void operator=( const TiXmlComment& base );
+
+ virtual ~TiXmlComment() {}
+
+ /// Returns a copy of this Comment.
+ virtual TiXmlNode* Clone() const;
+ // Write this Comment to a FILE stream.
+ virtual void Print( FILE* cfile, int depth ) const;
+
+ /* Attribtue parsing starts: at the ! of the !--
+ returns: next char past '>'
+ */
+ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+ virtual const TiXmlComment* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+ virtual TiXmlComment* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+ /** Walk the XML tree visiting this node and all of its children.
+ */
+ virtual bool Accept( TiXmlVisitor* visitor ) const;
protected:
- void CopyTo( TiXmlComment* target ) const;
+ void CopyTo( TiXmlComment* target ) const;
- // used to be public
- #ifdef TIXML_USE_STL
- virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
- #endif
-// virtual void StreamOut( TIXML_OSTREAM * out ) const;
+ // used to be public
+#ifdef TIXML_USE_STL
+ virtual void StreamIn( std::istream* in, TIXML_STRING* tag );
+#endif
+ // virtual void StreamOut( TIXML_OSTREAM * out ) const;
private:
};
-/** XML text. A text node can have 2 ways to output the next. "normal" output
+/** XML text. A text node can have 2 ways to output the next. "normal" output
and CDATA. It will default to the mode it was parsed from the XML file and
- you generally want to leave it alone, but you can change the output mode with
+ you generally want to leave it alone, but you can change the output mode with
SetCDATA() and query it with CDATA().
*/
class TiXmlText : public TiXmlNode
{
- friend class TiXmlElement;
+ friend class TiXmlElement;
public:
- /** Constructor for text element. By default, it is treated as
- normal, encoded text. If you want it be output as a CDATA text
- element, set the parameter _cdata to 'true'
- */
- TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
- {
- SetValue( initValue );
- cdata = false;
- }
- virtual ~TiXmlText() {}
+ /** Constructor for text element. By default, it is treated as
+ normal, encoded text. If you want it be output as a CDATA text
+ element, set the parameter _cdata to 'true'
+ */
+ TiXmlText (const char* initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
+ {
+ SetValue( initValue );
+ cdata = false;
+ }
+ virtual ~TiXmlText() {}
- #ifdef TIXML_USE_STL
- /// Constructor.
- TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
- {
- SetValue( initValue );
- cdata = false;
- }
- #endif
+#ifdef TIXML_USE_STL
+ /// Constructor.
+ TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
+ {
+ SetValue( initValue );
+ cdata = false;
+ }
+#endif
- TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TINYXML_TEXT ) { copy.CopyTo( this ); }
- void operator=( const TiXmlText& base ) { base.CopyTo( this ); }
+ TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TINYXML_TEXT ) { copy.CopyTo( this ); }
+ void operator=( const TiXmlText& base ) { base.CopyTo( this ); }
- // Write this text object to a FILE stream.
- virtual void Print( FILE* cfile, int depth ) const;
+ // Write this text object to a FILE stream.
+ virtual void Print( FILE* cfile, int depth ) const;
- /// Queries whether this represents text using a CDATA section.
- bool CDATA() const { return cdata; }
- /// Turns on or off a CDATA representation of text.
- void SetCDATA( bool _cdata ) { cdata = _cdata; }
+ /// Queries whether this represents text using a CDATA section.
+ bool CDATA() const { return cdata; }
+ /// Turns on or off a CDATA representation of text.
+ void SetCDATA( bool _cdata ) { cdata = _cdata; }
- virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
- virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
- virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+ virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+ virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
- /** Walk the XML tree visiting this node and all of its children.
- */
- virtual bool Accept( TiXmlVisitor* content ) const;
+ /** Walk the XML tree visiting this node and all of its children.
+ */
+ virtual bool Accept( TiXmlVisitor* content ) const;
protected :
- /// [internal use] Creates a new Element and returns it.
- virtual TiXmlNode* Clone() const;
- void CopyTo( TiXmlText* target ) const;
+ /// [internal use] Creates a new Element and returns it.
+ virtual TiXmlNode* Clone() const;
+ void CopyTo( TiXmlText* target ) const;
- bool Blank() const; // returns true if all white space and new lines
- // [internal use]
- #ifdef TIXML_USE_STL
- virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
- #endif
+ bool Blank() const; // returns true if all white space and new lines
+ // [internal use]
+#ifdef TIXML_USE_STL
+ virtual void StreamIn( std::istream* in, TIXML_STRING* tag );
+#endif
private:
- bool cdata; // true if this should be input and output as a CDATA style text element
+ bool cdata; // true if this should be input and output as a CDATA style text element
};
@@ -1278,62 +1298,63 @@ private:
class TiXmlDeclaration : public TiXmlNode
{
public:
- /// Construct an empty declaration.
- TiXmlDeclaration() : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) {}
+ /// Construct an empty declaration.
+ TiXmlDeclaration() : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) {}
#ifdef TIXML_USE_STL
- /// Constructor.
- TiXmlDeclaration( const std::string& _version,
- const std::string& _encoding,
- const std::string& _standalone );
+ /// Constructor.
+ TiXmlDeclaration( const std::string& _version,
+ const std::string& _encoding,
+ const std::string& _standalone );
#endif
- /// Construct.
- TiXmlDeclaration( const char* _version,
- const char* _encoding,
- const char* _standalone );
-
- TiXmlDeclaration( const TiXmlDeclaration& copy );
- void operator=( const TiXmlDeclaration& copy );
-
- virtual ~TiXmlDeclaration() {}
-
- /// Version. Will return an empty string if none was found.
- const char *Version() const { return version.c_str (); }
- /// Encoding. Will return an empty string if none was found.
- const char *Encoding() const { return encoding.c_str (); }
- /// Is this a standalone document?
- const char *Standalone() const { return standalone.c_str (); }
-
- /// Creates a copy of this Declaration and returns it.
- virtual TiXmlNode* Clone() const;
- // Print this declaration to a FILE stream.
- virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
- virtual void Print( FILE* cfile, int depth ) const {
- Print( cfile, depth, 0 );
- }
+ /// Construct.
+ TiXmlDeclaration( const char* _version,
+ const char* _encoding,
+ const char* _standalone );
+
+ TiXmlDeclaration( const TiXmlDeclaration& copy );
+ void operator=( const TiXmlDeclaration& copy );
- virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+ virtual ~TiXmlDeclaration() {}
- virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
- virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+ /// Version. Will return an empty string if none was found.
+ const char* Version() const { return version.c_str (); }
+ /// Encoding. Will return an empty string if none was found.
+ const char* Encoding() const { return encoding.c_str (); }
+ /// Is this a standalone document?
+ const char* Standalone() const { return standalone.c_str (); }
- /** Walk the XML tree visiting this node and all of its children.
- */
- virtual bool Accept( TiXmlVisitor* visitor ) const;
+ /// Creates a copy of this Declaration and returns it.
+ virtual TiXmlNode* Clone() const;
+ // Print this declaration to a FILE stream.
+ virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
+ virtual void Print( FILE* cfile, int depth ) const
+ {
+ Print( cfile, depth, 0 );
+ }
+
+ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+ virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+ virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+ /** Walk the XML tree visiting this node and all of its children.
+ */
+ virtual bool Accept( TiXmlVisitor* visitor ) const;
protected:
- void CopyTo( TiXmlDeclaration* target ) const;
- // used to be public
- #ifdef TIXML_USE_STL
- virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
- #endif
+ void CopyTo( TiXmlDeclaration* target ) const;
+ // used to be public
+#ifdef TIXML_USE_STL
+ virtual void StreamIn( std::istream* in, TIXML_STRING* tag );
+#endif
private:
- TIXML_STRING version;
- TIXML_STRING encoding;
- TIXML_STRING standalone;
+ TIXML_STRING version;
+ TIXML_STRING encoding;
+ TIXML_STRING standalone;
};
@@ -1347,32 +1368,32 @@ private:
class TiXmlUnknown : public TiXmlNode
{
public:
- TiXmlUnknown() : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) {}
- virtual ~TiXmlUnknown() {}
+ TiXmlUnknown() : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) {}
+ virtual ~TiXmlUnknown() {}
- TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) { copy.CopyTo( this ); }
- void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); }
+ TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) { copy.CopyTo( this ); }
+ void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); }
- /// Creates a copy of this Unknown and returns it.
- virtual TiXmlNode* Clone() const;
- // Print this Unknown to a FILE stream.
- virtual void Print( FILE* cfile, int depth ) const;
+ /// Creates a copy of this Unknown and returns it.
+ virtual TiXmlNode* Clone() const;
+ // Print this Unknown to a FILE stream.
+ virtual void Print( FILE* cfile, int depth ) const;
- virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
- virtual const TiXmlUnknown* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
- virtual TiXmlUnknown* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+ virtual const TiXmlUnknown* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+ virtual TiXmlUnknown* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
- /** Walk the XML tree visiting this node and all of its children.
- */
- virtual bool Accept( TiXmlVisitor* content ) const;
+ /** Walk the XML tree visiting this node and all of its children.
+ */
+ virtual bool Accept( TiXmlVisitor* content ) const;
protected:
- void CopyTo( TiXmlUnknown* target ) const;
+ void CopyTo( TiXmlUnknown* target ) const;
- #ifdef TIXML_USE_STL
- virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
- #endif
+#ifdef TIXML_USE_STL
+ virtual void StreamIn( std::istream* in, TIXML_STRING* tag );
+#endif
private:
@@ -1386,165 +1407,167 @@ private:
class TiXmlDocument : public TiXmlNode
{
public:
- /// Create an empty document, that has no name.
- TiXmlDocument();
- /// Create a document with a name. The name of the document is also the filename of the xml.
- TiXmlDocument( const char * documentName );
-
- #ifdef TIXML_USE_STL
- /// Constructor.
- TiXmlDocument( const std::string& documentName );
- #endif
-
- TiXmlDocument( const TiXmlDocument& copy );
- void operator=( const TiXmlDocument& copy );
-
- virtual ~TiXmlDocument() {}
-
- /** Load a file using the current document value.
- Returns true if successful. Will delete any existing
- document data before loading.
- */
- bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
- /// Save a file using the current document value. Returns true if successful.
- bool SaveFile() const;
- /// Load a file using the given filename. Returns true if successful.
- bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
- /// Save a file using the given filename. Returns true if successful.
- bool SaveFile( const char * filename ) const;
- /** Load a file using the given FILE*. Returns true if successful. Note that this method
- doesn't stream - the entire object pointed at by the FILE*
- will be interpreted as an XML file. TinyXML doesn't stream in XML from the current
- file location. Streaming may be added in the future.
- */
- bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
- /// Save a file using the given FILE*. Returns true if successful.
- bool SaveFile( FILE* ) const;
-
- #ifdef TIXML_USE_STL
- bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version.
- {
- return LoadFile( filename.c_str(), encoding );
- }
- bool SaveFile( const std::string& filename ) const ///< STL std::string version.
- {
- return SaveFile( filename.c_str() );
- }
- #endif
-
- /** Parse the given null terminated block of xml data. Passing in an encoding to this
- method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml
- to use that encoding, regardless of what TinyXml might otherwise try to detect.
- */
- virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
-
- /** Get the root element -- the only top level element -- of the document.
- In well formed XML, there should only be one. TinyXml is tolerant of
- multiple elements at the document level.
- */
- const TiXmlElement* RootElement() const { return FirstChildElement(); }
- TiXmlElement* RootElement() { return FirstChildElement(); }
-
- /** If an error occurs, Error will be set to true. Also,
- - The ErrorId() will contain the integer identifier of the error (not generally useful)
- - The ErrorDesc() method will return the name of the error. (very useful)
- - The ErrorRow() and ErrorCol() will return the location of the error (if known)
- */
- bool Error() const { return error; }
-
- /// Contains a textual (english) description of the error if one occurs.
- const char * ErrorDesc() const { return errorDesc.c_str (); }
-
- /** Generally, you probably want the error string ( ErrorDesc() ). But if you
- prefer the ErrorId, this function will fetch it.
- */
- int ErrorId() const { return errorId; }
-
- /** Returns the location (if known) of the error. The first column is column 1,
- and the first row is row 1. A value of 0 means the row and column wasn't applicable
- (memory errors, for example, have no row/column) or the parser lost the error. (An
- error in the error reporting, in that case.)
-
- @sa SetTabSize, Row, Column
- */
- int ErrorRow() const { return errorLocation.row+1; }
- int ErrorCol() const { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow()
-
- /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol())
- to report the correct values for row and column. It does not change the output
- or input in any way.
-
- By calling this method, with a tab size
- greater than 0, the row and column of each node and attribute is stored
- when the file is loaded. Very useful for tracking the DOM back in to
- the source file.
-
- The tab size is required for calculating the location of nodes. If not
- set, the default of 4 is used. The tabsize is set per document. Setting
- the tabsize to 0 disables row/column tracking.
-
- Note that row and column tracking is not supported when using operator>>.
-
- The tab size needs to be enabled before the parse or load. Correct usage:
- @verbatim
- TiXmlDocument doc;
- doc.SetTabSize( 8 );
- doc.Load( "myfile.xml" );
- @endverbatim
-
- @sa Row, Column
- */
- void SetTabSize( int _tabsize ) { tabsize = _tabsize; }
-
- int TabSize() const { return tabsize; }
-
- /** If you have handled the error, it can be reset with this call. The error
- state is automatically cleared if you Parse a new XML block.
- */
- void ClearError() { error = false;
- errorId = 0;
- errorDesc = "";
- errorLocation.row = errorLocation.col = 0;
- //errorLocation.last = 0;
- }
-
- /** Write the document to standard out using formatted printing ("pretty print"). */
- void Print() const { Print( stdout, 0 ); }
-
- /* Write the document to a string using formatted printing ("pretty print"). This
- will allocate a character array (new char[]) and return it as a pointer. The
- calling code pust call delete[] on the return char* to avoid a memory leak.
- */
- //char* PrintToMemory() const;
-
- /// Print this Document to a FILE stream.
- virtual void Print( FILE* cfile, int depth = 0 ) const;
- // [internal use]
- void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
-
- virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
- virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
-
- /** Walk the XML tree visiting this node and all of its children.
- */
- virtual bool Accept( TiXmlVisitor* content ) const;
+ /// Create an empty document, that has no name.
+ TiXmlDocument();
+ /// Create a document with a name. The name of the document is also the filename of the xml.
+ TiXmlDocument( const char* documentName );
+
+#ifdef TIXML_USE_STL
+ /// Constructor.
+ TiXmlDocument( const std::string& documentName );
+#endif
+
+ TiXmlDocument( const TiXmlDocument& copy );
+ void operator=( const TiXmlDocument& copy );
+
+ virtual ~TiXmlDocument() {}
+
+ /** Load a file using the current document value.
+ Returns true if successful. Will delete any existing
+ document data before loading.
+ */
+ bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+ /// Save a file using the current document value. Returns true if successful.
+ bool SaveFile() const;
+ /// Load a file using the given filename. Returns true if successful.
+ bool LoadFile( const char* filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+ /// Save a file using the given filename. Returns true if successful.
+ bool SaveFile( const char* filename ) const;
+ /** Load a file using the given FILE*. Returns true if successful. Note that this method
+ doesn't stream - the entire object pointed at by the FILE*
+ will be interpreted as an XML file. TinyXML doesn't stream in XML from the current
+ file location. Streaming may be added in the future.
+ */
+ bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+ /// Save a file using the given FILE*. Returns true if successful.
+ bool SaveFile( FILE* ) const;
+
+#ifdef TIXML_USE_STL
+ bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version.
+ {
+ return LoadFile( filename.c_str(), encoding );
+ }
+ bool SaveFile( const std::string& filename ) const ///< STL std::string version.
+ {
+ return SaveFile( filename.c_str() );
+ }
+#endif
+
+ /** Parse the given null terminated block of xml data. Passing in an encoding to this
+ method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml
+ to use that encoding, regardless of what TinyXml might otherwise try to detect.
+ */
+ virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+
+ /** Get the root element -- the only top level element -- of the document.
+ In well formed XML, there should only be one. TinyXml is tolerant of
+ multiple elements at the document level.
+ */
+ const TiXmlElement* RootElement() const { return FirstChildElement(); }
+ TiXmlElement* RootElement() { return FirstChildElement(); }
+
+ /** If an error occurs, Error will be set to true. Also,
+ - The ErrorId() will contain the integer identifier of the error (not generally useful)
+ - The ErrorDesc() method will return the name of the error. (very useful)
+ - The ErrorRow() and ErrorCol() will return the location of the error (if known)
+ */
+ bool Error() const { return error; }
+
+ /// Contains a textual (english) description of the error if one occurs.
+ const char* ErrorDesc() const { return errorDesc.c_str (); }
+
+ /** Generally, you probably want the error string ( ErrorDesc() ). But if you
+ prefer the ErrorId, this function will fetch it.
+ */
+ int ErrorId() const { return errorId; }
+
+ /** Returns the location (if known) of the error. The first column is column 1,
+ and the first row is row 1. A value of 0 means the row and column wasn't applicable
+ (memory errors, for example, have no row/column) or the parser lost the error. (An
+ error in the error reporting, in that case.)
+
+ @sa SetTabSize, Row, Column
+ */
+ int ErrorRow() const { return errorLocation.row+1; }
+ int ErrorCol() const { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow()
+
+ /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol())
+ to report the correct values for row and column. It does not change the output
+ or input in any way.
+
+ By calling this method, with a tab size
+ greater than 0, the row and column of each node and attribute is stored
+ when the file is loaded. Very useful for tracking the DOM back in to
+ the source file.
+
+ The tab size is required for calculating the location of nodes. If not
+ set, the default of 4 is used. The tabsize is set per document. Setting
+ the tabsize to 0 disables row/column tracking.
+
+ Note that row and column tracking is not supported when using operator>>.
+
+ The tab size needs to be enabled before the parse or load. Correct usage:
+ @verbatim
+ TiXmlDocument doc;
+ doc.SetTabSize( 8 );
+ doc.Load( "myfile.xml" );
+ @endverbatim
+
+ @sa Row, Column
+ */
+ void SetTabSize( int _tabsize ) { tabsize = _tabsize; }
+
+ int TabSize() const { return tabsize; }
+
+ /** If you have handled the error, it can be reset with this call. The error
+ state is automatically cleared if you Parse a new XML block.
+ */
+ void ClearError()
+ {
+ error = false;
+ errorId = 0;
+ errorDesc = "";
+ errorLocation.row = errorLocation.col = 0;
+ //errorLocation.last = 0;
+ }
+
+ /** Write the document to standard out using formatted printing ("pretty print"). */
+ void Print() const { Print( stdout, 0 ); }
+
+ /* Write the document to a string using formatted printing ("pretty print"). This
+ will allocate a character array (new char[]) and return it as a pointer. The
+ calling code pust call delete[] on the return char* to avoid a memory leak.
+ */
+ //char* PrintToMemory() const;
+
+ /// Print this Document to a FILE stream.
+ virtual void Print( FILE* cfile, int depth = 0 ) const;
+ // [internal use]
+ void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
+
+ virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+ virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+ /** Walk the XML tree visiting this node and all of its children.
+ */
+ virtual bool Accept( TiXmlVisitor* content ) const;
protected :
- // [internal use]
- virtual TiXmlNode* Clone() const;
- #ifdef TIXML_USE_STL
- virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
- #endif
+ // [internal use]
+ virtual TiXmlNode* Clone() const;
+#ifdef TIXML_USE_STL
+ virtual void StreamIn( std::istream* in, TIXML_STRING* tag );
+#endif
private:
- void CopyTo( TiXmlDocument* target ) const;
-
- bool error;
- int errorId;
- TIXML_STRING errorDesc;
- int tabsize;
- TiXmlCursor errorLocation;
- bool useMicrosoftBOM; // the UTF-8 BOM were found when read. Note this, and try to write.
+ void CopyTo( TiXmlDocument* target ) const;
+
+ bool error;
+ int errorId;
+ TIXML_STRING errorDesc;
+ int tabsize;
+ TiXmlCursor errorLocation;
+ bool useMicrosoftBOM; // the UTF-8 BOM were found when read. Note this, and try to write.
};
@@ -1563,7 +1586,7 @@ private:
<Document>
@endverbatim
- Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
+ Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
easy to write a *lot* of code that looks like:
@verbatim
@@ -1583,7 +1606,7 @@ private:
@endverbatim
And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity
- of such code. A TiXmlHandle checks for null pointers so it is perfectly safe
+ of such code. A TiXmlHandle checks for null pointers so it is perfectly safe
and correct to use:
@verbatim
@@ -1604,7 +1627,7 @@ private:
What they should not be used for is iteration:
@verbatim
- int i=0;
+ int i=0;
while ( true )
{
TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement();
@@ -1615,8 +1638,8 @@ private:
}
@endverbatim
- It seems reasonable, but it is in fact two embedded while loops. The Child method is
- a linear walk to find the element, so this code would iterate much more than it needs
+ It seems reasonable, but it is in fact two embedded while loops. The Child method is
+ a linear walk to find the element, so this code would iterate much more than it needs
to. Instead, prefer:
@verbatim
@@ -1631,80 +1654,80 @@ private:
class TiXmlHandle
{
public:
- /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
- TiXmlHandle( TiXmlNode* _node ) { this->node = _node; }
- /// Copy constructor
- TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; }
- TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; }
-
- /// Return a handle to the first child node.
- TiXmlHandle FirstChild() const;
- /// Return a handle to the first child node with the given name.
- TiXmlHandle FirstChild( const char * value ) const;
- /// Return a handle to the first child element.
- TiXmlHandle FirstChildElement() const;
- /// Return a handle to the first child element with the given name.
- TiXmlHandle FirstChildElement( const char * value ) const;
-
- /** Return a handle to the "index" child with the given name.
- The first child is 0, the second 1, etc.
- */
- TiXmlHandle Child( const char* value, int index ) const;
- /** Return a handle to the "index" child.
- The first child is 0, the second 1, etc.
- */
- TiXmlHandle Child( int index ) const;
- /** Return a handle to the "index" child element with the given name.
- The first child element is 0, the second 1, etc. Note that only TiXmlElements
- are indexed: other types are not counted.
- */
- TiXmlHandle ChildElement( const char* value, int index ) const;
- /** Return a handle to the "index" child element.
- The first child element is 0, the second 1, etc. Note that only TiXmlElements
- are indexed: other types are not counted.
- */
- TiXmlHandle ChildElement( int index ) const;
-
- #ifdef TIXML_USE_STL
- TiXmlHandle FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); }
- TiXmlHandle FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); }
-
- TiXmlHandle Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); }
- TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); }
- #endif
-
- /** Return the handle as a TiXmlNode. This may return null.
- */
- TiXmlNode* ToNode() const { return node; }
- /** Return the handle as a TiXmlElement. This may return null.
- */
- TiXmlElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
- /** Return the handle as a TiXmlText. This may return null.
- */
- TiXmlText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
- /** Return the handle as a TiXmlUnknown. This may return null.
- */
- TiXmlUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
-
- /** @deprecated use ToNode.
- Return the handle as a TiXmlNode. This may return null.
- */
- TiXmlNode* Node() const { return ToNode(); }
- /** @deprecated use ToElement.
- Return the handle as a TiXmlElement. This may return null.
- */
- TiXmlElement* Element() const { return ToElement(); }
- /** @deprecated use ToText()
- Return the handle as a TiXmlText. This may return null.
- */
- TiXmlText* Text() const { return ToText(); }
- /** @deprecated use ToUnknown()
- Return the handle as a TiXmlUnknown. This may return null.
- */
- TiXmlUnknown* Unknown() const { return ToUnknown(); }
+ /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
+ TiXmlHandle( TiXmlNode* _node ) { this->node = _node; }
+ /// Copy constructor
+ TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; }
+ TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; }
+
+ /// Return a handle to the first child node.
+ TiXmlHandle FirstChild() const;
+ /// Return a handle to the first child node with the given name.
+ TiXmlHandle FirstChild( const char* value ) const;
+ /// Return a handle to the first child element.
+ TiXmlHandle FirstChildElement() const;
+ /// Return a handle to the first child element with the given name.
+ TiXmlHandle FirstChildElement( const char* value ) const;
+
+ /** Return a handle to the "index" child with the given name.
+ The first child is 0, the second 1, etc.
+ */
+ TiXmlHandle Child( const char* value, int index ) const;
+ /** Return a handle to the "index" child.
+ The first child is 0, the second 1, etc.
+ */
+ TiXmlHandle Child( int index ) const;
+ /** Return a handle to the "index" child element with the given name.
+ The first child element is 0, the second 1, etc. Note that only TiXmlElements
+ are indexed: other types are not counted.
+ */
+ TiXmlHandle ChildElement( const char* value, int index ) const;
+ /** Return a handle to the "index" child element.
+ The first child element is 0, the second 1, etc. Note that only TiXmlElements
+ are indexed: other types are not counted.
+ */
+ TiXmlHandle ChildElement( int index ) const;
+
+#ifdef TIXML_USE_STL
+ TiXmlHandle FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); }
+ TiXmlHandle FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); }
+
+ TiXmlHandle Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); }
+ TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); }
+#endif
+
+ /** Return the handle as a TiXmlNode. This may return null.
+ */
+ TiXmlNode* ToNode() const { return node; }
+ /** Return the handle as a TiXmlElement. This may return null.
+ */
+ TiXmlElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
+ /** Return the handle as a TiXmlText. This may return null.
+ */
+ TiXmlText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
+ /** Return the handle as a TiXmlUnknown. This may return null.
+ */
+ TiXmlUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
+
+ /** @deprecated use ToNode.
+ Return the handle as a TiXmlNode. This may return null.
+ */
+ TiXmlNode* Node() const { return ToNode(); }
+ /** @deprecated use ToElement.
+ Return the handle as a TiXmlElement. This may return null.
+ */
+ TiXmlElement* Element() const { return ToElement(); }
+ /** @deprecated use ToText()
+ Return the handle as a TiXmlText. This may return null.
+ */
+ TiXmlText* Text() const { return ToText(); }
+ /** @deprecated use ToUnknown()
+ Return the handle as a TiXmlUnknown. This may return null.
+ */
+ TiXmlUnknown* Unknown() const { return ToUnknown(); }
private:
- TiXmlNode* node;
+ TiXmlNode* node;
};
@@ -1730,64 +1753,68 @@ private:
class TiXmlPrinter : public TiXmlVisitor
{
public:
- TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),
- buffer(), indent( " " ), lineBreak( "\n" ) {}
-
- virtual bool VisitEnter( const TiXmlDocument& doc );
- virtual bool VisitExit( const TiXmlDocument& doc );
-
- virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
- virtual bool VisitExit( const TiXmlElement& element );
-
- virtual bool Visit( const TiXmlDeclaration& declaration );
- virtual bool Visit( const TiXmlText& text );
- virtual bool Visit( const TiXmlComment& comment );
- virtual bool Visit( const TiXmlUnknown& unknown );
-
- /** Set the indent characters for printing. By default 4 spaces
- but tab (\t) is also useful, or null/empty string for no indentation.
- */
- void SetIndent( const char* _indent ) { indent = _indent ? _indent : "" ; }
- /// Query the indention string.
- const char* Indent() { return indent.c_str(); }
- /** Set the line breaking string. By default set to newline (\n).
- Some operating systems prefer other characters, or can be
- set to the null/empty string for no indenation.
- */
- void SetLineBreak( const char* _lineBreak ) { lineBreak = _lineBreak ? _lineBreak : ""; }
- /// Query the current line breaking string.
- const char* LineBreak() { return lineBreak.c_str(); }
-
- /** Switch over to "stream printing" which is the most dense formatting without
- linebreaks. Common when the XML is needed for network transmission.
- */
- void SetStreamPrinting() { indent = "";
- lineBreak = "";
- }
- /// Return the result.
- const char* CStr() { return buffer.c_str(); }
- /// Return the length of the result string.
- size_t Size() { return buffer.size(); }
-
- #ifdef TIXML_USE_STL
- /// Return the result.
- const std::string& Str() { return buffer; }
- #endif
+ TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),
+ buffer(), indent( " " ), lineBreak( "\n" ) {}
+
+ virtual bool VisitEnter( const TiXmlDocument& doc );
+ virtual bool VisitExit( const TiXmlDocument& doc );
+
+ virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
+ virtual bool VisitExit( const TiXmlElement& element );
+
+ virtual bool Visit( const TiXmlDeclaration& declaration );
+ virtual bool Visit( const TiXmlText& text );
+ virtual bool Visit( const TiXmlComment& comment );
+ virtual bool Visit( const TiXmlUnknown& unknown );
+
+ /** Set the indent characters for printing. By default 4 spaces
+ but tab (\t) is also useful, or null/empty string for no indentation.
+ */
+ void SetIndent( const char* _indent ) { indent = _indent ? _indent : "" ; }
+ /// Query the indention string.
+ const char* Indent() { return indent.c_str(); }
+ /** Set the line breaking string. By default set to newline (\n).
+ Some operating systems prefer other characters, or can be
+ set to the null/empty string for no indenation.
+ */
+ void SetLineBreak( const char* _lineBreak ) { lineBreak = _lineBreak ? _lineBreak : ""; }
+ /// Query the current line breaking string.
+ const char* LineBreak() { return lineBreak.c_str(); }
+
+ /** Switch over to "stream printing" which is the most dense formatting without
+ linebreaks. Common when the XML is needed for network transmission.
+ */
+ void SetStreamPrinting()
+ {
+ indent = "";
+ lineBreak = "";
+ }
+ /// Return the result.
+ const char* CStr() { return buffer.c_str(); }
+ /// Return the length of the result string.
+ size_t Size() { return buffer.size(); }
-private:
- void DoIndent() {
- for( int i=0; i<depth; ++i )
- buffer += indent;
- }
- void DoLineBreak() {
- buffer += lineBreak;
- }
+#ifdef TIXML_USE_STL
+ /// Return the result.
+ const std::string& Str() { return buffer; }
+#endif
- int depth;
- bool simpleTextPrint;
- TIXML_STRING buffer;
- TIXML_STRING indent;
- TIXML_STRING lineBreak;
+private:
+ void DoIndent()
+ {
+ for( int i=0; i<depth; ++i )
+ buffer += indent;
+ }
+ void DoLineBreak()
+ {
+ buffer += lineBreak;
+ }
+
+ int depth;
+ bool simpleTextPrint;
+ TIXML_STRING buffer;
+ TIXML_STRING indent;
+ TIXML_STRING lineBreak;
};
diff --git a/shared/tinyxml/tinyxmlparser.cpp b/shared/tinyxml/tinyxmlparser.cpp
index 92bee64d..ea691fd4 100644
--- a/shared/tinyxml/tinyxmlparser.cpp
+++ b/shared/tinyxml/tinyxmlparser.cpp
@@ -110,21 +110,21 @@ void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* leng
// Scary scary fall throughs.
switch (*length)
{
- case 4:
- --output;
- *output = (char)((input | BYTE_MARK) & BYTE_MASK);
- input >>= 6;
- case 3:
- --output;
- *output = (char)((input | BYTE_MARK) & BYTE_MASK);
- input >>= 6;
- case 2:
- --output;
- *output = (char)((input | BYTE_MARK) & BYTE_MASK);
- input >>= 6;
- case 1:
- --output;
- *output = (char)(input | FIRST_BYTE_MARK[*length]);
+ case 4:
+ --output;
+ *output = (char)((input | BYTE_MARK) & BYTE_MASK);
+ input >>= 6;
+ case 3:
+ --output;
+ *output = (char)((input | BYTE_MARK) & BYTE_MASK);
+ input >>= 6;
+ case 2:
+ --output;
+ *output = (char)((input | BYTE_MARK) & BYTE_MASK);
+ input >>= 6;
+ case 1:
+ --output;
+ *output = (char)(input | FIRST_BYTE_MARK[*length]);
}
}
@@ -136,17 +136,17 @@ void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* leng
// to figure out alhabetical vs. not across encoding. So take a very
// conservative approach.
-// if ( encoding == TIXML_ENCODING_UTF8 )
-// {
+ // if ( encoding == TIXML_ENCODING_UTF8 )
+ // {
if ( anyByte < 127 )
return isalpha( anyByte );
else
return 1; // What else to do? The unicode set is huge...get the english ones right.
-// }
-// else
-// {
-// return isalpha( anyByte );
-// }
+ // }
+ // else
+ // {
+ // return isalpha( anyByte );
+ // }
}
@@ -157,17 +157,17 @@ void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* leng
// to figure out alhabetical vs. not across encoding. So take a very
// conservative approach.
-// if ( encoding == TIXML_ENCODING_UTF8 )
-// {
+ // if ( encoding == TIXML_ENCODING_UTF8 )
+ // {
if ( anyByte < 127 )
return isalnum( anyByte );
else
return 1; // What else to do? The unicode set is huge...get the english ones right.
-// }
-// else
-// {
-// return isalnum( anyByte );
-// }
+ // }
+ // else
+ // {
+ // return isalnum( anyByte );
+ // }
}
@@ -223,95 +223,95 @@ void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding )
// Code contributed by Fletcher Dunn: (modified by lee)
switch (*pU)
{
- case 0:
- // We *should* never get here, but in case we do, don't
- // advance past the terminating null character, ever
- return;
-
- case '\r':
- // bump down to the next line
- ++row;
- col = 0;
- // Eat the character
- ++p;
+ case 0:
+ // We *should* never get here, but in case we do, don't
+ // advance past the terminating null character, ever
+ return;
- // Check for \r\n sequence, and treat this as a single character
- if (*p == '\n')
- {
+ case '\r':
+ // bump down to the next line
+ ++row;
+ col = 0;
+ // Eat the character
++p;
- }
- break;
- case '\n':
- // bump down to the next line
- ++row;
- col = 0;
+ // Check for \r\n sequence, and treat this as a single character
+ if (*p == '\n')
+ {
+ ++p;
+ }
+ break;
- // Eat the character
- ++p;
+ case '\n':
+ // bump down to the next line
+ ++row;
+ col = 0;
- // Check for \n\r sequence, and treat this as a single
- // character. (Yes, this bizarre thing does occur still
- // on some arcane platforms...)
- if (*p == '\r')
- {
+ // Eat the character
++p;
- }
- break;
- case '\t':
- // Eat the character
- ++p;
+ // Check for \n\r sequence, and treat this as a single
+ // character. (Yes, this bizarre thing does occur still
+ // on some arcane platforms...)
+ if (*p == '\r')
+ {
+ ++p;
+ }
+ break;
- // Skip to next tab stop
- col = (col / tabsize + 1) * tabsize;
- break;
+ case '\t':
+ // Eat the character
+ ++p;
- case TIXML_UTF_LEAD_0:
- if ( encoding == TIXML_ENCODING_UTF8 )
- {
- if ( *(p+1) && *(p+2) )
+ // Skip to next tab stop
+ col = (col / tabsize + 1) * tabsize;
+ break;
+
+ case TIXML_UTF_LEAD_0:
+ if ( encoding == TIXML_ENCODING_UTF8 )
{
- // In these cases, don't advance the column. These are
- // 0-width spaces.
- if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 )
- p += 3;
- else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU )
- p += 3;
- else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU )
- p += 3;
- else
+ if ( *(p+1) && *(p+2) )
{
- p +=3; // A normal character.
- ++col;
+ // In these cases, don't advance the column. These are
+ // 0-width spaces.
+ if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 )
+ p += 3;
+ else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU )
+ p += 3;
+ else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU )
+ p += 3;
+ else
+ {
+ p +=3; // A normal character.
+ ++col;
+ }
}
}
- }
- else
- {
- ++p;
- ++col;
- }
- break;
+ else
+ {
+ ++p;
+ ++col;
+ }
+ break;
- default:
- if ( encoding == TIXML_ENCODING_UTF8 )
- {
- // Eat the 1 to 4 byte utf8 character.
- int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)];
- if ( step == 0 )
- step = 1; // Error case from bad encoding, but handle gracefully.
- p += step;
-
- // Just advance one column, of course.
- ++col;
- }
- else
- {
- ++p;
- ++col;
- }
- break;
+ default:
+ if ( encoding == TIXML_ENCODING_UTF8 )
+ {
+ // Eat the 1 to 4 byte utf8 character.
+ int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)];
+ if ( step == 0 )
+ step = 1; // Error case from bad encoding, but handle gracefully.
+ p += step;
+
+ // Just advance one column, of course.
+ ++col;
+ }
+ else
+ {
+ ++p;
+ ++col;
+ }
+ break;
}
}
cursor.row = row;
@@ -374,7 +374,7 @@ const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding )
}
#ifdef TIXML_USE_STL
-/*static*/ bool TiXmlBase::StreamWhiteSpace( std::istream * in, TIXML_STRING * tag )
+/*static*/ bool TiXmlBase::StreamWhiteSpace( std::istream* in, TIXML_STRING* tag )
{
for( ;; )
{
@@ -389,7 +389,7 @@ const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding )
}
}
-/*static*/ bool TiXmlBase::StreamTo( std::istream * in, int character, TIXML_STRING * tag )
+/*static*/ bool TiXmlBase::StreamTo( std::istream* in, int character, TIXML_STRING* tag )
{
//assert( character > 0 && character < 128 ); // else it won't work in utf-8
while ( in->good() )
@@ -410,7 +410,7 @@ const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding )
// One of TinyXML's more performance demanding functions. Try to keep the memory overhead down. The
// "assign" optimization removes over 10% of the execution time.
//
-const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding )
+const char* TiXmlBase::ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding )
{
// Oddly, not supported on some comilers,
//name->clear();
@@ -425,8 +425,8 @@ const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncodi
// After that, they can be letters, underscores, numbers,
// hyphens, or colons. (Colons are valid ony for namespaces,
// but tinyxml can't tell namespaces from names.)
- if ( p && *p
- && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) )
+ if (p && *p
+ && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) )
{
const char* start = p;
while( p && *p
@@ -585,15 +585,15 @@ bool TiXmlBase::StringEqual( const char* p,
}
const char* TiXmlBase::ReadText( const char* p,
- TIXML_STRING * text,
+ TIXML_STRING* text,
bool trimWhiteSpace,
const char* endTag,
bool caseInsensitive,
TiXmlEncoding encoding )
{
*text = "";
- if ( !trimWhiteSpace // certain tags always keep whitespace
- || !condenseWhiteSpace ) // if true, whitespace is always kept
+ if (!trimWhiteSpace // certain tags always keep whitespace
+ || !condenseWhiteSpace ) // if true, whitespace is always kept
{
// Keep all the white space.
while ( p && *p
@@ -651,7 +651,7 @@ const char* TiXmlBase::ReadText( const char* p,
#ifdef TIXML_USE_STL
-void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag )
+void TiXmlDocument::StreamIn( std::istream* in, TIXML_STRING* tag )
{
// The basic issue with a document is that we don't know what we're
// streaming. Read something presumed to be a tag (and hope), then
@@ -778,8 +778,8 @@ const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiX
}
// Did we get encoding info?
- if ( encoding == TIXML_ENCODING_UNKNOWN
- && node->ToDeclaration() )
+ if (encoding == TIXML_ENCODING_UNKNOWN
+ && node->ToDeclaration() )
{
TiXmlDeclaration* dec = node->ToDeclaration();
const char* enc = dec->Encoding();
@@ -888,8 +888,8 @@ TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding )
#endif
returnNode = new TiXmlUnknown();
}
- else if ( IsAlpha( *(p+1), encoding )
- || *(p+1) == '_' )
+ else if (IsAlpha( *(p+1), encoding )
+ || *(p+1) == '_' )
{
#ifdef DEBUG_PARSER
TIXML_LOG( "XML parsing Element\n" );
@@ -914,7 +914,7 @@ TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding )
#ifdef TIXML_USE_STL
-void TiXmlElement::StreamIn (std::istream * in, TIXML_STRING * tag)
+void TiXmlElement::StreamIn (std::istream* in, TIXML_STRING* tag)
{
// We're called with some amount of pre-parsing. That is, some of "this"
// element is in "tag". Go ahead and stream to the closing ">"
@@ -939,8 +939,8 @@ void TiXmlElement::StreamIn (std::istream * in, TIXML_STRING * tag)
// Okay...if we are a "/>" tag, then we're done. We've read a complete tag.
// If not, identify and stream.
- if ( tag->at( tag->length() - 1 ) == '>'
- && tag->at( tag->length() - 2 ) == '/' )
+ if (tag->at( tag->length() - 1 ) == '>'
+ && tag->at( tag->length() - 2 ) == '/' )
{
// All good!
return;
@@ -1265,7 +1265,7 @@ const char* TiXmlElement::ReadValue( const char* p, TiXmlParsingData* data, TiXm
#ifdef TIXML_USE_STL
-void TiXmlUnknown::StreamIn( std::istream * in, TIXML_STRING * tag )
+void TiXmlUnknown::StreamIn( std::istream* in, TIXML_STRING* tag )
{
while ( in->good() )
{
@@ -1323,7 +1323,7 @@ const char* TiXmlUnknown::Parse( const char* p, TiXmlParsingData* data, TiXmlEnc
}
#ifdef TIXML_USE_STL
-void TiXmlComment::StreamIn( std::istream * in, TIXML_STRING * tag )
+void TiXmlComment::StreamIn( std::istream* in, TIXML_STRING* tag )
{
while ( in->good() )
{
@@ -1339,8 +1339,8 @@ void TiXmlComment::StreamIn( std::istream * in, TIXML_STRING * tag )
(*tag) += (char) c;
if ( c == '>'
- && tag->at( tag->length() - 2 ) == '-'
- && tag->at( tag->length() - 3 ) == '-' )
+ && tag->at( tag->length() - 2 ) == '-'
+ && tag->at( tag->length() - 3 ) == '-' )
{
// All is well.
return;
@@ -1479,7 +1479,7 @@ const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlE
}
#ifdef TIXML_USE_STL
-void TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag )
+void TiXmlText::StreamIn( std::istream* in, TIXML_STRING* tag )
{
while ( in->good() )
{
@@ -1563,7 +1563,7 @@ const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncodi
}
#ifdef TIXML_USE_STL
-void TiXmlDeclaration::StreamIn( std::istream * in, TIXML_STRING * tag )
+void TiXmlDeclaration::StreamIn( std::istream* in, TIXML_STRING* tag )
{
while ( in->good() )
{
diff --git a/shared/tinyxml/xmltest.cpp b/shared/tinyxml/xmltest.cpp
index 7cd6faca..b4d3551c 100644
--- a/shared/tinyxml/xmltest.cpp
+++ b/shared/tinyxml/xmltest.cpp
@@ -4,17 +4,17 @@
#ifdef TIXML_USE_STL
- #include <iostream>
- #include <sstream>
- using namespace std;
+#include <iostream>
+#include <sstream>
+using namespace std;
#else
- #include <stdio.h>
+#include <stdio.h>
#endif
#if defined( WIN32 ) && defined( TUNE )
- #include <crtdbg.h>
- _CrtMemState startMemState;
- _CrtMemState endMemState;
+#include <crtdbg.h>
+_CrtMemState startMemState;
+_CrtMemState endMemState;
#endif
#include "tinyxml.h"
@@ -29,43 +29,43 @@ static int gFail = 0;
bool XmlTest (const char* testString, const char* expected, const char* found, bool noEcho )
{
- bool pass = !strcmp( expected, found );
- if ( pass )
- printf ("[pass]");
- else
- printf ("[fail]");
-
- if ( noEcho )
- printf (" %s\n", testString);
- else
- printf (" %s [%s][%s]\n", testString, expected, found);
-
- if ( pass )
- ++gPass;
- else
- ++gFail;
- return pass;
+ bool pass = !strcmp( expected, found );
+ if ( pass )
+ printf ("[pass]");
+ else
+ printf ("[fail]");
+
+ if ( noEcho )
+ printf (" %s\n", testString);
+ else
+ printf (" %s [%s][%s]\n", testString, expected, found);
+
+ if ( pass )
+ ++gPass;
+ else
+ ++gFail;
+ return pass;
}
bool XmlTest( const char* testString, int expected, int found, bool noEcho )
{
- bool pass = ( expected == found );
- if ( pass )
- printf ("[pass]");
- else
- printf ("[fail]");
-
- if ( noEcho )
- printf (" %s\n", testString);
- else
- printf (" %s [%d][%d]\n", testString, expected, found);
-
- if ( pass )
- ++gPass;
- else
- ++gFail;
- return pass;
+ bool pass = ( expected == found );
+ if ( pass )
+ printf ("[pass]");
+ else
+ printf ("[fail]");
+
+ if ( noEcho )
+ printf (" %s\n", testString);
+ else
+ printf (" %s [%d][%d]\n", testString, expected, found);
+
+ if ( pass )
+ ++gPass;
+ else
+ ++gFail;
+ return pass;
}
@@ -79,910 +79,914 @@ bool XmlTest( const char* testString, int expected, int found, bool noEcho )
int main()
{
- //
- // We start with the 'demoStart' todo list. Process it. And
- // should hopefully end up with the todo list as illustrated.
- //
- const char* demoStart =
- "<?xml version=\"1.0\" standalone='no' >\n"
- "<!-- Our to do list data -->"
- "<ToDo>\n"
- "<!-- Do I need a secure PDA? -->\n"
- "<Item priority=\"1\" distance='close'> Go to the <bold>Toy store!</bold></Item>"
- "<Item priority=\"2\" distance='none'> Do bills </Item>"
- "<Item priority=\"2\" distance='far &amp; back'> Look for Evil Dinosaurs! </Item>"
- "</ToDo>";
-
- {
-
- #ifdef TIXML_USE_STL
- // What the todo list should look like after processing.
- // In stream (no formatting) representation.
- const char* demoEnd =
- "<?xml version=\"1.0\" standalone=\"no\" ?>"
- "<!-- Our to do list data -->"
- "<ToDo>"
- "<!-- Do I need a secure PDA? -->"
- "<Item priority=\"2\" distance=\"close\">Go to the"
- "<bold>Toy store!"
- "</bold>"
- "</Item>"
- "<Item priority=\"1\" distance=\"far\">Talk to:"
- "<Meeting where=\"School\">"
- "<Attendee name=\"Marple\" position=\"teacher\" />"
- "<Attendee name=\"Voel\" position=\"counselor\" />"
- "</Meeting>"
- "<Meeting where=\"Lunch\" />"
- "</Item>"
- "<Item priority=\"2\" distance=\"here\">Do bills"
- "</Item>"
- "</ToDo>";
- #endif
-
- // The example parses from the character string (above):
- #if defined( WIN32 ) && defined( TUNE )
- _CrtMemCheckpoint( &startMemState );
- #endif
-
- {
- // Write to a file and read it back, to check file I/O.
-
- TiXmlDocument doc( "demotest.xml" );
- doc.Parse( demoStart );
-
- if ( doc.Error() )
- {
- printf( "Error in %s: %s\n", doc.Value(), doc.ErrorDesc() );
- exit( 1 );
- }
- doc.SaveFile();
- }
-
- TiXmlDocument doc( "demotest.xml" );
- bool loadOkay = doc.LoadFile();
-
- if ( !loadOkay )
- {
- printf( "Could not load test file 'demotest.xml'. Error='%s'. Exiting.\n", doc.ErrorDesc() );
- exit( 1 );
- }
-
- printf( "** Demo doc read from disk: ** \n\n" );
- printf( "** Printing via doc.Print **\n" );
- doc.Print( stdout );
-
- {
- printf( "** Printing via TiXmlPrinter **\n" );
- TiXmlPrinter printer;
- doc.Accept( &printer );
- fprintf( stdout, "%s", printer.CStr() );
- }
- #ifdef TIXML_USE_STL
- {
- printf( "** Printing via operator<< **\n" );
- std::cout << doc;
- }
- #endif
- TiXmlNode* node = 0;
- TiXmlElement* todoElement = 0;
- TiXmlElement* itemElement = 0;
-
-
- // --------------------------------------------------------
- // An example of changing existing attributes, and removing
- // an element from the document.
- // --------------------------------------------------------
-
- // Get the "ToDo" element.
- // It is a child of the document, and can be selected by name.
- node = doc.FirstChild( "ToDo" );
- assert( node );
- todoElement = node->ToElement();
- assert( todoElement );
-
- // Going to the toy store is now our second priority...
- // So set the "priority" attribute of the first item in the list.
- node = todoElement->FirstChildElement(); // This skips the "PDA" comment.
- assert( node );
- itemElement = node->ToElement();
- assert( itemElement );
- itemElement->SetAttribute( "priority", 2 );
-
- // Change the distance to "doing bills" from
- // "none" to "here". It's the next sibling element.
- itemElement = itemElement->NextSiblingElement();
- assert( itemElement );
- itemElement->SetAttribute( "distance", "here" );
-
- // Remove the "Look for Evil Dinosaurs!" item.
- // It is 1 more sibling away. We ask the parent to remove
- // a particular child.
- itemElement = itemElement->NextSiblingElement();
- todoElement->RemoveChild( itemElement );
-
- itemElement = 0;
-
- // --------------------------------------------------------
- // What follows is an example of created elements and text
- // nodes and adding them to the document.
- // --------------------------------------------------------
-
- // Add some meetings.
- TiXmlElement item( "Item" );
- item.SetAttribute( "priority", "1" );
- item.SetAttribute( "distance", "far" );
-
- TiXmlText text( "Talk to:" );
-
- TiXmlElement meeting1( "Meeting" );
- meeting1.SetAttribute( "where", "School" );
-
- TiXmlElement meeting2( "Meeting" );
- meeting2.SetAttribute( "where", "Lunch" );
-
- TiXmlElement attendee1( "Attendee" );
- attendee1.SetAttribute( "name", "Marple" );
- attendee1.SetAttribute( "position", "teacher" );
-
- TiXmlElement attendee2( "Attendee" );
- attendee2.SetAttribute( "name", "Voel" );
- attendee2.SetAttribute( "position", "counselor" );
-
- // Assemble the nodes we've created:
- meeting1.InsertEndChild( attendee1 );
- meeting1.InsertEndChild( attendee2 );
-
- item.InsertEndChild( text );
- item.InsertEndChild( meeting1 );
- item.InsertEndChild( meeting2 );
-
- // And add the node to the existing list after the first child.
- node = todoElement->FirstChild( "Item" );
- assert( node );
- itemElement = node->ToElement();
- assert( itemElement );
-
- todoElement->InsertAfterChild( itemElement, item );
-
- printf( "\n** Demo doc processed: ** \n\n" );
- doc.Print( stdout );
-
-
- #ifdef TIXML_USE_STL
- printf( "** Demo doc processed to stream: ** \n\n" );
- cout << doc << endl << endl;
- #endif
-
- // --------------------------------------------------------
- // Different tests...do we have what we expect?
- // --------------------------------------------------------
-
- int count = 0;
- TiXmlElement* element;
-
- //////////////////////////////////////////////////////
-
- #ifdef TIXML_USE_STL
- cout << "** Basic structure. **\n";
- ostringstream outputStream( ostringstream::out );
- outputStream << doc;
- XmlTest( "Output stream correct.", string( demoEnd ).c_str(),
- outputStream.str().c_str(), true );
- #endif
-
- node = doc.RootElement();
- assert( node );
- XmlTest( "Root element exists.", true, ( node != 0 && node->ToElement() ) );
- XmlTest ( "Root element value is 'ToDo'.", "ToDo", node->Value());
-
- node = node->FirstChild();
- XmlTest( "First child exists & is a comment.", true, ( node != 0 && node->ToComment() ) );
- node = node->NextSibling();
- XmlTest( "Sibling element exists & is an element.", true, ( node != 0 && node->ToElement() ) );
- XmlTest ( "Value is 'Item'.", "Item", node->Value() );
-
- node = node->FirstChild();
- XmlTest ( "First child exists.", true, ( node != 0 && node->ToText() ) );
- XmlTest ( "Value is 'Go to the'.", "Go to the", node->Value() );
-
-
- //////////////////////////////////////////////////////
- printf ("\n** Iterators. **\n");
-
- // Walk all the top level nodes of the document.
- count = 0;
- for( node = doc.FirstChild();
- node;
- node = node->NextSibling() )
- {
- count++;
- }
- XmlTest( "Top level nodes, using First / Next.", 3, count );
-
- count = 0;
- for( node = doc.LastChild();
- node;
- node = node->PreviousSibling() )
- {
- count++;
- }
- XmlTest( "Top level nodes, using Last / Previous.", 3, count );
-
- // Walk all the top level nodes of the document,
- // using a different syntax.
- count = 0;
- for( node = doc.IterateChildren( 0 );
- node;
- node = doc.IterateChildren( node ) )
- {
- count++;
- }
- XmlTest( "Top level nodes, using IterateChildren.", 3, count );
-
- // Walk all the elements in a node.
- count = 0;
- for( element = todoElement->FirstChildElement();
- element;
- element = element->NextSiblingElement() )
- {
- count++;
- }
- XmlTest( "Children of the 'ToDo' element, using First / Next.",
- 3, count );
-
- // Walk all the elements in a node by value.
- count = 0;
- for( node = todoElement->FirstChild( "Item" );
- node;
- node = node->NextSibling( "Item" ) )
- {
- count++;
- }
- XmlTest( "'Item' children of the 'ToDo' element, using First/Next.", 3, count );
-
- count = 0;
- for( node = todoElement->LastChild( "Item" );
- node;
- node = node->PreviousSibling( "Item" ) )
- {
- count++;
- }
- XmlTest( "'Item' children of the 'ToDo' element, using Last/Previous.", 3, count );
-
- #ifdef TIXML_USE_STL
- {
- cout << "\n** Parsing. **\n";
- istringstream parse0( "<Element0 attribute0='foo0' attribute1= noquotes attribute2 = '&gt;' />" );
- TiXmlElement element0( "default" );
- parse0 >> element0;
-
- XmlTest ( "Element parsed, value is 'Element0'.", "Element0", element0.Value() );
- XmlTest ( "Reads attribute 'attribute0=\"foo0\"'.", "foo0", element0.Attribute( "attribute0" ));
- XmlTest ( "Reads incorrectly formatted 'attribute1=noquotes'.", "noquotes", element0.Attribute( "attribute1" ) );
- XmlTest ( "Read attribute with entity value '>'.", ">", element0.Attribute( "attribute2" ) );
- }
- #endif
-
- {
- const char* error = "<?xml version=\"1.0\" standalone=\"no\" ?>\n"
- "<passages count=\"006\" formatversion=\"20020620\">\n"
- " <wrong error>\n"
- "</passages>";
-
- TiXmlDocument docTest;
- docTest.Parse( error );
- XmlTest( "Error row", docTest.ErrorRow(), 3 );
- XmlTest( "Error column", docTest.ErrorCol(), 17 );
- //printf( "error=%d id='%s' row %d col%d\n", (int) doc.Error(), doc.ErrorDesc(), doc.ErrorRow()+1, doc.ErrorCol() + 1 );
-
- }
-
- #ifdef TIXML_USE_STL
- {
- //////////////////////////////////////////////////////
- cout << "\n** Streaming. **\n";
-
- // Round trip check: stream in, then stream back out to verify. The stream
- // out has already been checked, above. We use the output
-
- istringstream inputStringStream( outputStream.str() );
- TiXmlDocument document0;
-
- inputStringStream >> document0;
-
- ostringstream outputStream0( ostringstream::out );
- outputStream0 << document0;
-
- XmlTest( "Stream round trip correct.", string( demoEnd ).c_str(),
- outputStream0.str().c_str(), true );
-
- std::string str;
- str << document0;
-
- XmlTest( "String printing correct.", string( demoEnd ).c_str(),
- str.c_str(), true );
- }
- #endif
- }
-
- {
- const char* str = "<doc attr0='1' attr1='2.0' attr2='foo' />";
-
- TiXmlDocument doc;
- doc.Parse( str );
-
- TiXmlElement* ele = doc.FirstChildElement();
-
- int iVal, result;
- double dVal;
-
- result = ele->QueryDoubleAttribute( "attr0", &dVal );
- XmlTest( "Query attribute: int as double", result, TIXML_SUCCESS );
- XmlTest( "Query attribute: int as double", (int)dVal, 1 );
- result = ele->QueryDoubleAttribute( "attr1", &dVal );
- XmlTest( "Query attribute: double as double", (int)dVal, 2 );
- result = ele->QueryIntAttribute( "attr1", &iVal );
- XmlTest( "Query attribute: double as int", result, TIXML_SUCCESS );
- XmlTest( "Query attribute: double as int", iVal, 2 );
- result = ele->QueryIntAttribute( "attr2", &iVal );
- XmlTest( "Query attribute: not a number", result, TIXML_WRONG_TYPE );
- result = ele->QueryIntAttribute( "bar", &iVal );
- XmlTest( "Query attribute: does not exist", result, TIXML_NO_ATTRIBUTE );
- }
-
- {
- const char* str = "<doc/>";
-
- TiXmlDocument doc;
- doc.Parse( str );
-
- TiXmlElement* ele = doc.FirstChildElement();
-
- int iVal;
- double dVal;
-
- ele->SetAttribute( "str", "strValue" );
- ele->SetAttribute( "int", 1 );
- ele->SetDoubleAttribute( "double", -1.0 );
-
- const char* cStr = ele->Attribute( "str" );
- ele->QueryIntAttribute( "int", &iVal );
- ele->QueryDoubleAttribute( "double", &dVal );
-
- XmlTest( "Attribute round trip. c-string.", "strValue", cStr );
- XmlTest( "Attribute round trip. int.", 1, iVal );
- XmlTest( "Attribute round trip. double.", -1, (int)dVal );
- }
-
- {
- const char* str = "\t<?xml version=\"1.0\" standalone=\"no\" ?>\t<room doors='2'>\n"
- "</room>";
-
- TiXmlDocument doc;
- doc.SetTabSize( 8 );
- doc.Parse( str );
-
- TiXmlHandle docHandle( &doc );
- TiXmlHandle roomHandle = docHandle.FirstChildElement( "room" );
-
- assert( docHandle.Node() );
- assert( roomHandle.Element() );
-
- TiXmlElement* room = roomHandle.Element();
- assert( room );
- TiXmlAttribute* doors = room->FirstAttribute();
- assert( doors );
-
- XmlTest( "Location tracking: Tab 8: room row", room->Row(), 1 );
- XmlTest( "Location tracking: Tab 8: room col", room->Column(), 49 );
- XmlTest( "Location tracking: Tab 8: doors row", doors->Row(), 1 );
- XmlTest( "Location tracking: Tab 8: doors col", doors->Column(), 55 );
- }
-
- {
- const char* str = "\t<?xml version=\"1.0\" standalone=\"no\" ?>\t<room doors='2'>\n"
- " <!-- Silly example -->\n"
- " <door wall='north'>A great door!</door>\n"
- "\t<door wall='east'/>"
- "</room>";
-
- TiXmlDocument doc;
- doc.Parse( str );
-
- TiXmlHandle docHandle( &doc );
- TiXmlHandle roomHandle = docHandle.FirstChildElement( "room" );
- TiXmlHandle commentHandle = docHandle.FirstChildElement( "room" ).FirstChild();
- TiXmlHandle textHandle = docHandle.FirstChildElement( "room" ).ChildElement( "door", 0 ).FirstChild();
- TiXmlHandle door0Handle = docHandle.FirstChildElement( "room" ).ChildElement( 0 );
- TiXmlHandle door1Handle = docHandle.FirstChildElement( "room" ).ChildElement( 1 );
-
- assert( docHandle.Node() );
- assert( roomHandle.Element() );
- assert( commentHandle.Node() );
- assert( textHandle.Text() );
- assert( door0Handle.Element() );
- assert( door1Handle.Element() );
-
- TiXmlDeclaration* declaration = doc.FirstChild()->ToDeclaration();
- assert( declaration );
- TiXmlElement* room = roomHandle.Element();
- assert( room );
- TiXmlAttribute* doors = room->FirstAttribute();
- assert( doors );
- TiXmlText* text = textHandle.Text();
- TiXmlComment* comment = commentHandle.Node()->ToComment();
- assert( comment );
- TiXmlElement* door0 = door0Handle.Element();
- TiXmlElement* door1 = door1Handle.Element();
-
- XmlTest( "Location tracking: Declaration row", declaration->Row(), 1 );
- XmlTest( "Location tracking: Declaration col", declaration->Column(), 5 );
- XmlTest( "Location tracking: room row", room->Row(), 1 );
- XmlTest( "Location tracking: room col", room->Column(), 45 );
- XmlTest( "Location tracking: doors row", doors->Row(), 1 );
- XmlTest( "Location tracking: doors col", doors->Column(), 51 );
- XmlTest( "Location tracking: Comment row", comment->Row(), 2 );
- XmlTest( "Location tracking: Comment col", comment->Column(), 3 );
- XmlTest( "Location tracking: text row", text->Row(), 3 );
- XmlTest( "Location tracking: text col", text->Column(), 24 );
- XmlTest( "Location tracking: door0 row", door0->Row(), 3 );
- XmlTest( "Location tracking: door0 col", door0->Column(), 5 );
- XmlTest( "Location tracking: door1 row", door1->Row(), 4 );
- XmlTest( "Location tracking: door1 col", door1->Column(), 5 );
- }
-
-
- // --------------------------------------------------------
- // UTF-8 testing. It is important to test:
- // 1. Making sure name, value, and text read correctly
- // 2. Row, Col functionality
- // 3. Correct output
- // --------------------------------------------------------
- printf ("\n** UTF-8 **\n");
- {
- TiXmlDocument doc( "utf8test.xml" );
- doc.LoadFile();
- if ( doc.Error() && doc.ErrorId() == TiXmlBase::TIXML_ERROR_OPENING_FILE ) {
- printf( "WARNING: File 'utf8test.xml' not found.\n"
- "(Are you running the test from the wrong directory?)\n"
- "Could not test UTF-8 functionality.\n" );
- }
- else
- {
- TiXmlHandle docH( &doc );
- // Get the attribute "value" from the "Russian" element and check it.
- TiXmlElement* element = docH.FirstChildElement( "document" ).FirstChildElement( "Russian" ).Element();
- const unsigned char correctValue[] = { 0xd1U, 0x86U, 0xd0U, 0xb5U, 0xd0U, 0xbdU, 0xd0U, 0xbdU,
- 0xd0U, 0xbeU, 0xd1U, 0x81U, 0xd1U, 0x82U, 0xd1U, 0x8cU, 0 };
-
- XmlTest( "UTF-8: Russian value.", (const char*)correctValue, element->Attribute( "value" ), true );
- XmlTest( "UTF-8: Russian value row.", 4, element->Row() );
- XmlTest( "UTF-8: Russian value column.", 5, element->Column() );
-
- const unsigned char russianElementName[] = { 0xd0U, 0xa0U, 0xd1U, 0x83U,
- 0xd1U, 0x81U, 0xd1U, 0x81U,
- 0xd0U, 0xbaU, 0xd0U, 0xb8U,
- 0xd0U, 0xb9U, 0 };
- const char russianText[] = "<\xD0\xB8\xD0\xBC\xD0\xB5\xD0\xB5\xD1\x82>";
-
- TiXmlText* text = docH.FirstChildElement( "document" ).FirstChildElement( (const char*) russianElementName ).Child( 0 ).Text();
- XmlTest( "UTF-8: Browsing russian element name.",
- russianText,
- text->Value(),
- true );
- XmlTest( "UTF-8: Russian element name row.", 7, text->Row() );
- XmlTest( "UTF-8: Russian element name column.", 47, text->Column() );
-
- TiXmlDeclaration* dec = docH.Child( 0 ).Node()->ToDeclaration();
- XmlTest( "UTF-8: Declaration column.", 1, dec->Column() );
- XmlTest( "UTF-8: Document column.", 1, doc.Column() );
-
- // Now try for a round trip.
- doc.SaveFile( "utf8testout.xml" );
-
- // Check the round trip.
- char savedBuf[256];
- char verifyBuf[256];
- int okay = 1;
-
- FILE* saved = fopen( "utf8testout.xml", "r" );
- FILE* verify = fopen( "utf8testverify.xml", "r" );
- if ( saved && verify )
- {
- while ( fgets( verifyBuf, 256, verify ) )
- {
- fgets( savedBuf, 256, saved );
- if ( strcmp( verifyBuf, savedBuf ) )
- {
- okay = 0;
- break;
- }
- }
- fclose( saved );
- fclose( verify );
- }
- XmlTest( "UTF-8: Verified multi-language round trip.", 1, okay );
-
- // On most Western machines, this is an element that contains
- // the word "resume" with the correct accents, in a latin encoding.
- // It will be something else completely on non-wester machines,
- // which is why TinyXml is switching to UTF-8.
- const char latin[] = "<element>r\x82sum\x82</element>";
-
- TiXmlDocument latinDoc;
- latinDoc.Parse( latin, 0, TIXML_ENCODING_LEGACY );
-
- text = latinDoc.FirstChildElement()->FirstChild()->ToText();
- XmlTest( "Legacy encoding: Verify text element.", "r\x82sum\x82", text->Value() );
- }
- }
-
- //////////////////////
- // Copy and assignment
- //////////////////////
- printf ("\n** Copy and Assignment **\n");
- {
- TiXmlElement element( "foo" );
- element.Parse( "<element name='value' />", 0, TIXML_ENCODING_UNKNOWN );
-
- TiXmlElement elementCopy( element );
- TiXmlElement elementAssign( "foo" );
- elementAssign.Parse( "<incorrect foo='bar'/>", 0, TIXML_ENCODING_UNKNOWN );
- elementAssign = element;
-
- XmlTest( "Copy/Assign: element copy #1.", "element", elementCopy.Value() );
- XmlTest( "Copy/Assign: element copy #2.", "value", elementCopy.Attribute( "name" ) );
- XmlTest( "Copy/Assign: element assign #1.", "element", elementAssign.Value() );
- XmlTest( "Copy/Assign: element assign #2.", "value", elementAssign.Attribute( "name" ) );
- XmlTest( "Copy/Assign: element assign #3.", true, ( 0 == elementAssign.Attribute( "foo" )) );
-
- TiXmlComment comment;
- comment.Parse( "<!--comment-->", 0, TIXML_ENCODING_UNKNOWN );
- TiXmlComment commentCopy( comment );
- TiXmlComment commentAssign;
- commentAssign = commentCopy;
- XmlTest( "Copy/Assign: comment copy.", "comment", commentCopy.Value() );
- XmlTest( "Copy/Assign: comment assign.", "comment", commentAssign.Value() );
-
- TiXmlUnknown unknown;
- unknown.Parse( "<[unknown]>", 0, TIXML_ENCODING_UNKNOWN );
- TiXmlUnknown unknownCopy( unknown );
- TiXmlUnknown unknownAssign;
- unknownAssign.Parse( "incorrect", 0, TIXML_ENCODING_UNKNOWN );
- unknownAssign = unknownCopy;
- XmlTest( "Copy/Assign: unknown copy.", "[unknown]", unknownCopy.Value() );
- XmlTest( "Copy/Assign: unknown assign.", "[unknown]", unknownAssign.Value() );
-
- TiXmlText text( "TextNode" );
- TiXmlText textCopy( text );
- TiXmlText textAssign( "incorrect" );
- textAssign = text;
- XmlTest( "Copy/Assign: text copy.", "TextNode", textCopy.Value() );
- XmlTest( "Copy/Assign: text assign.", "TextNode", textAssign.Value() );
-
- TiXmlDeclaration dec;
- dec.Parse( "<?xml version='1.0' encoding='UTF-8'?>", 0, TIXML_ENCODING_UNKNOWN );
- TiXmlDeclaration decCopy( dec );
- TiXmlDeclaration decAssign;
- decAssign = dec;
-
- XmlTest( "Copy/Assign: declaration copy.", "UTF-8", decCopy.Encoding() );
- XmlTest( "Copy/Assign: text assign.", "UTF-8", decAssign.Encoding() );
-
- TiXmlDocument doc;
- elementCopy.InsertEndChild( textCopy );
- doc.InsertEndChild( decAssign );
- doc.InsertEndChild( elementCopy );
- doc.InsertEndChild( unknownAssign );
-
- TiXmlDocument docCopy( doc );
- TiXmlDocument docAssign;
- docAssign = docCopy;
-
- #ifdef TIXML_USE_STL
- std::string original, copy, assign;
- original << doc;
- copy << docCopy;
- assign << docAssign;
- XmlTest( "Copy/Assign: document copy.", original.c_str(), copy.c_str(), true );
- XmlTest( "Copy/Assign: document assign.", original.c_str(), assign.c_str(), true );
-
- #endif
- }
-
- //////////////////////////////////////////////////////
+ //
+ // We start with the 'demoStart' todo list. Process it. And
+ // should hopefully end up with the todo list as illustrated.
+ //
+ const char* demoStart =
+ "<?xml version=\"1.0\" standalone='no' >\n"
+ "<!-- Our to do list data -->"
+ "<ToDo>\n"
+ "<!-- Do I need a secure PDA? -->\n"
+ "<Item priority=\"1\" distance='close'> Go to the <bold>Toy store!</bold></Item>"
+ "<Item priority=\"2\" distance='none'> Do bills </Item>"
+ "<Item priority=\"2\" distance='far &amp; back'> Look for Evil Dinosaurs! </Item>"
+ "</ToDo>";
+
+ {
+
+#ifdef TIXML_USE_STL
+ // What the todo list should look like after processing.
+ // In stream (no formatting) representation.
+ const char* demoEnd =
+ "<?xml version=\"1.0\" standalone=\"no\" ?>"
+ "<!-- Our to do list data -->"
+ "<ToDo>"
+ "<!-- Do I need a secure PDA? -->"
+ "<Item priority=\"2\" distance=\"close\">Go to the"
+ "<bold>Toy store!"
+ "</bold>"
+ "</Item>"
+ "<Item priority=\"1\" distance=\"far\">Talk to:"
+ "<Meeting where=\"School\">"
+ "<Attendee name=\"Marple\" position=\"teacher\" />"
+ "<Attendee name=\"Voel\" position=\"counselor\" />"
+ "</Meeting>"
+ "<Meeting where=\"Lunch\" />"
+ "</Item>"
+ "<Item priority=\"2\" distance=\"here\">Do bills"
+ "</Item>"
+ "</ToDo>";
+#endif
+
+ // The example parses from the character string (above):
+#if defined( WIN32 ) && defined( TUNE )
+ _CrtMemCheckpoint( &startMemState );
+#endif
+
+ {
+ // Write to a file and read it back, to check file I/O.
+
+ TiXmlDocument doc( "demotest.xml" );
+ doc.Parse( demoStart );
+
+ if ( doc.Error() )
+ {
+ printf( "Error in %s: %s\n", doc.Value(), doc.ErrorDesc() );
+ exit( 1 );
+ }
+ doc.SaveFile();
+ }
+
+ TiXmlDocument doc( "demotest.xml" );
+ bool loadOkay = doc.LoadFile();
+
+ if ( !loadOkay )
+ {
+ printf( "Could not load test file 'demotest.xml'. Error='%s'. Exiting.\n", doc.ErrorDesc() );
+ exit( 1 );
+ }
+
+ printf( "** Demo doc read from disk: ** \n\n" );
+ printf( "** Printing via doc.Print **\n" );
+ doc.Print( stdout );
+
+ {
+ printf( "** Printing via TiXmlPrinter **\n" );
+ TiXmlPrinter printer;
+ doc.Accept( &printer );
+ fprintf( stdout, "%s", printer.CStr() );
+ }
#ifdef TIXML_USE_STL
- printf ("\n** Parsing, no Condense Whitespace **\n");
- TiXmlBase::SetCondenseWhiteSpace( false );
- {
- istringstream parse1( "<start>This is \ntext</start>" );
- TiXmlElement text1( "text" );
- parse1 >> text1;
-
- XmlTest ( "Condense white space OFF.", "This is \ntext",
- text1.FirstChild()->Value(),
- true );
- }
- TiXmlBase::SetCondenseWhiteSpace( true );
+ {
+ printf( "** Printing via operator<< **\n" );
+ std::cout << doc;
+ }
#endif
+ TiXmlNode* node = 0;
+ TiXmlElement* todoElement = 0;
+ TiXmlElement* itemElement = 0;
+
+
+ // --------------------------------------------------------
+ // An example of changing existing attributes, and removing
+ // an element from the document.
+ // --------------------------------------------------------
+
+ // Get the "ToDo" element.
+ // It is a child of the document, and can be selected by name.
+ node = doc.FirstChild( "ToDo" );
+ assert( node );
+ todoElement = node->ToElement();
+ assert( todoElement );
+
+ // Going to the toy store is now our second priority...
+ // So set the "priority" attribute of the first item in the list.
+ node = todoElement->FirstChildElement(); // This skips the "PDA" comment.
+ assert( node );
+ itemElement = node->ToElement();
+ assert( itemElement );
+ itemElement->SetAttribute( "priority", 2 );
+
+ // Change the distance to "doing bills" from
+ // "none" to "here". It's the next sibling element.
+ itemElement = itemElement->NextSiblingElement();
+ assert( itemElement );
+ itemElement->SetAttribute( "distance", "here" );
+
+ // Remove the "Look for Evil Dinosaurs!" item.
+ // It is 1 more sibling away. We ask the parent to remove
+ // a particular child.
+ itemElement = itemElement->NextSiblingElement();
+ todoElement->RemoveChild( itemElement );
+
+ itemElement = 0;
+
+ // --------------------------------------------------------
+ // What follows is an example of created elements and text
+ // nodes and adding them to the document.
+ // --------------------------------------------------------
+
+ // Add some meetings.
+ TiXmlElement item( "Item" );
+ item.SetAttribute( "priority", "1" );
+ item.SetAttribute( "distance", "far" );
+
+ TiXmlText text( "Talk to:" );
+
+ TiXmlElement meeting1( "Meeting" );
+ meeting1.SetAttribute( "where", "School" );
+
+ TiXmlElement meeting2( "Meeting" );
+ meeting2.SetAttribute( "where", "Lunch" );
+
+ TiXmlElement attendee1( "Attendee" );
+ attendee1.SetAttribute( "name", "Marple" );
+ attendee1.SetAttribute( "position", "teacher" );
+
+ TiXmlElement attendee2( "Attendee" );
+ attendee2.SetAttribute( "name", "Voel" );
+ attendee2.SetAttribute( "position", "counselor" );
+
+ // Assemble the nodes we've created:
+ meeting1.InsertEndChild( attendee1 );
+ meeting1.InsertEndChild( attendee2 );
+
+ item.InsertEndChild( text );
+ item.InsertEndChild( meeting1 );
+ item.InsertEndChild( meeting2 );
+
+ // And add the node to the existing list after the first child.
+ node = todoElement->FirstChild( "Item" );
+ assert( node );
+ itemElement = node->ToElement();
+ assert( itemElement );
+
+ todoElement->InsertAfterChild( itemElement, item );
+
+ printf( "\n** Demo doc processed: ** \n\n" );
+ doc.Print( stdout );
+
+
+#ifdef TIXML_USE_STL
+ printf( "** Demo doc processed to stream: ** \n\n" );
+ cout << doc << endl << endl;
+#endif
+
+ // --------------------------------------------------------
+ // Different tests...do we have what we expect?
+ // --------------------------------------------------------
- //////////////////////////////////////////////////////
- // GetText();
- {
- const char* str = "<foo>This is text</foo>";
- TiXmlDocument doc;
- doc.Parse( str );
- const TiXmlElement* element = doc.RootElement();
-
- XmlTest( "GetText() normal use.", "This is text", element->GetText() );
-
- str = "<foo><b>This is text</b></foo>";
- doc.Clear();
- doc.Parse( str );
- element = doc.RootElement();
-
- XmlTest( "GetText() contained element.", element->GetText() == 0, true );
-
- str = "<foo>This is <b>text</b></foo>";
- doc.Clear();
- TiXmlBase::SetCondenseWhiteSpace( false );
- doc.Parse( str );
- TiXmlBase::SetCondenseWhiteSpace( true );
- element = doc.RootElement();
-
- XmlTest( "GetText() partial.", "This is ", element->GetText() );
- }
-
-
- //////////////////////////////////////////////////////
- // CDATA
- {
- const char* str = "<xmlElement>"
- "<![CDATA["
- "I am > the rules!\n"
- "...since I make symbolic puns"
- "]]>"
- "</xmlElement>";
- TiXmlDocument doc;
- doc.Parse( str );
- doc.Print();
-
- XmlTest( "CDATA parse.", doc.FirstChildElement()->FirstChild()->Value(),
- "I am > the rules!\n...since I make symbolic puns",
- true );
-
- #ifdef TIXML_USE_STL
- //cout << doc << '\n';
-
- doc.Clear();
-
- istringstream parse0( str );
- parse0 >> doc;
- //cout << doc << '\n';
-
- XmlTest( "CDATA stream.", doc.FirstChildElement()->FirstChild()->Value(),
- "I am > the rules!\n...since I make symbolic puns",
- true );
- #endif
-
- TiXmlDocument doc1 = doc;
- //doc.Print();
-
- XmlTest( "CDATA copy.", doc1.FirstChildElement()->FirstChild()->Value(),
- "I am > the rules!\n...since I make symbolic puns",
- true );
- }
- {
- // [ 1482728 ] Wrong wide char parsing
- char buf[256];
- buf[255] = 0;
- for( int i=0; i<255; ++i ) {
- buf[i] = (char)((i>=32) ? i : 32);
- }
- TIXML_STRING str( "<xmlElement><![CDATA[" );
- str += buf;
- str += "]]></xmlElement>";
-
- TiXmlDocument doc;
- doc.Parse( str.c_str() );
-
- TiXmlPrinter printer;
- printer.SetStreamPrinting();
- doc.Accept( &printer );
-
- XmlTest( "CDATA with all bytes #1.", str.c_str(), printer.CStr(), true );
-
- #ifdef TIXML_USE_STL
- doc.Clear();
- istringstream iss( printer.Str() );
- iss >> doc;
- std::string out;
- out << doc;
- XmlTest( "CDATA with all bytes #2.", out.c_str(), printer.CStr(), true );
- #endif
- }
- {
- // [ 1480107 ] Bug-fix for STL-streaming of CDATA that contains tags
- // CDATA streaming had a couple of bugs, that this tests for.
- const char* str = "<xmlElement>"
- "<![CDATA["
- "<b>I am > the rules!</b>\n"
- "...since I make symbolic puns"
- "]]>"
- "</xmlElement>";
- TiXmlDocument doc;
- doc.Parse( str );
- doc.Print();
-
- XmlTest( "CDATA parse. [ 1480107 ]", doc.FirstChildElement()->FirstChild()->Value(),
- "<b>I am > the rules!</b>\n...since I make symbolic puns",
- true );
-
- #ifdef TIXML_USE_STL
-
- doc.Clear();
-
- istringstream parse0( str );
- parse0 >> doc;
-
- XmlTest( "CDATA stream. [ 1480107 ]", doc.FirstChildElement()->FirstChild()->Value(),
- "<b>I am > the rules!</b>\n...since I make symbolic puns",
- true );
- #endif
-
- TiXmlDocument doc1 = doc;
- //doc.Print();
-
- XmlTest( "CDATA copy. [ 1480107 ]", doc1.FirstChildElement()->FirstChild()->Value(),
- "<b>I am > the rules!</b>\n...since I make symbolic puns",
- true );
- }
- //////////////////////////////////////////////////////
- // Visit()
-
-
-
- //////////////////////////////////////////////////////
- printf( "\n** Fuzzing... **\n" );
-
- const int FUZZ_ITERATION = 300;
-
- // The only goal is not to crash on bad input.
- int len = (int) strlen( demoStart );
- for( int i=0; i<FUZZ_ITERATION; ++i )
- {
- char* demoCopy = new char[ len+1 ];
- strcpy( demoCopy, demoStart );
-
- demoCopy[ i%len ] = (char)((i+1)*3);
- demoCopy[ (i*7)%len ] = '>';
- demoCopy[ (i*11)%len ] = '<';
-
- TiXmlDocument xml;
- xml.Parse( demoCopy );
-
- delete [] demoCopy;
- }
- printf( "** Fuzzing Complete. **\n" );
-
- //////////////////////////////////////////////////////
- printf ("\n** Bug regression tests **\n");
-
- // InsertBeforeChild and InsertAfterChild causes crash.
- {
- TiXmlElement parent( "Parent" );
- TiXmlElement childText0( "childText0" );
- TiXmlElement childText1( "childText1" );
- TiXmlNode* childNode0 = parent.InsertEndChild( childText0 );
- TiXmlNode* childNode1 = parent.InsertBeforeChild( childNode0, childText1 );
-
- XmlTest( "Test InsertBeforeChild on empty node.", ( childNode1 == parent.FirstChild() ), true );
- }
-
- {
- // InsertBeforeChild and InsertAfterChild causes crash.
- TiXmlElement parent( "Parent" );
- TiXmlElement childText0( "childText0" );
- TiXmlElement childText1( "childText1" );
- TiXmlNode* childNode0 = parent.InsertEndChild( childText0 );
- TiXmlNode* childNode1 = parent.InsertAfterChild( childNode0, childText1 );
-
- XmlTest( "Test InsertAfterChild on empty node. ", ( childNode1 == parent.LastChild() ), true );
- }
-
- // Reports of missing constructors, irregular string problems.
- {
- // Missing constructor implementation. No test -- just compiles.
- TiXmlText text( "Missing" );
-
- #ifdef TIXML_USE_STL
- // Missing implementation:
- TiXmlDocument doc;
- string name = "missing";
- doc.LoadFile( name );
-
- TiXmlText textSTL( name );
- #else
- // verifying some basic string functions:
- TiXmlString a;
- TiXmlString b( "Hello" );
- TiXmlString c( "ooga" );
-
- c = " World!";
- a = b;
- a += c;
- a = a;
-
- XmlTest( "Basic TiXmlString test. ", "Hello World!", a.c_str() );
- #endif
- }
-
- // Long filenames crashing STL version
- {
- TiXmlDocument doc( "midsummerNightsDreamWithAVeryLongFilenameToConfuseTheStringHandlingRoutines.xml" );
- bool loadOkay = doc.LoadFile();
- loadOkay = true; // get rid of compiler warning.
- // Won't pass on non-dev systems. Just a "no crash" check.
- //XmlTest( "Long filename. ", true, loadOkay );
- }
-
- {
- // Entities not being written correctly.
- // From Lynn Allen
-
- const char* passages =
- "<?xml version=\"1.0\" standalone=\"no\" ?>"
- "<passages count=\"006\" formatversion=\"20020620\">"
- "<psg context=\"Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
- " It also has &lt;, &gt;, and &amp;, as well as a fake copyright &#xA9;.\"> </psg>"
- "</passages>";
-
- TiXmlDocument doc( "passages.xml" );
- doc.Parse( passages );
- TiXmlElement* psg = doc.RootElement()->FirstChildElement();
- const char* context = psg->Attribute( "context" );
- const char* expected = "Line 5 has \"quotation marks\" and 'apostrophe marks'. It also has <, >, and &, as well as a fake copyright \xC2\xA9.";
-
- XmlTest( "Entity transformation: read. ", expected, context, true );
-
- FILE* textfile = fopen( "textfile.txt", "w" );
- if ( textfile )
- {
- psg->Print( textfile, 0 );
- fclose( textfile );
- }
- textfile = fopen( "textfile.txt", "r" );
- assert( textfile );
- if ( textfile )
- {
- char buf[ 1024 ];
- fgets( buf, 1024, textfile );
- XmlTest( "Entity transformation: write. ",
- "<psg context=\'Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
- " It also has &lt;, &gt;, and &amp;, as well as a fake copyright \xC2\xA9.' />",
- buf,
- true );
- }
- fclose( textfile );
- }
+ int count = 0;
+ TiXmlElement* element;
+
+ //////////////////////////////////////////////////////
+
+#ifdef TIXML_USE_STL
+ cout << "** Basic structure. **\n";
+ ostringstream outputStream( ostringstream::out );
+ outputStream << doc;
+ XmlTest( "Output stream correct.", string( demoEnd ).c_str(),
+ outputStream.str().c_str(), true );
+#endif
+
+ node = doc.RootElement();
+ assert( node );
+ XmlTest( "Root element exists.", true, ( node != 0 && node->ToElement() ) );
+ XmlTest ( "Root element value is 'ToDo'.", "ToDo", node->Value());
+
+ node = node->FirstChild();
+ XmlTest( "First child exists & is a comment.", true, ( node != 0 && node->ToComment() ) );
+ node = node->NextSibling();
+ XmlTest( "Sibling element exists & is an element.", true, ( node != 0 && node->ToElement() ) );
+ XmlTest ( "Value is 'Item'.", "Item", node->Value() );
+
+ node = node->FirstChild();
+ XmlTest ( "First child exists.", true, ( node != 0 && node->ToText() ) );
+ XmlTest ( "Value is 'Go to the'.", "Go to the", node->Value() );
+
+
+ //////////////////////////////////////////////////////
+ printf ("\n** Iterators. **\n");
+
+ // Walk all the top level nodes of the document.
+ count = 0;
+ for( node = doc.FirstChild();
+ node;
+ node = node->NextSibling() )
+ {
+ count++;
+ }
+ XmlTest( "Top level nodes, using First / Next.", 3, count );
+
+ count = 0;
+ for( node = doc.LastChild();
+ node;
+ node = node->PreviousSibling() )
+ {
+ count++;
+ }
+ XmlTest( "Top level nodes, using Last / Previous.", 3, count );
+
+ // Walk all the top level nodes of the document,
+ // using a different syntax.
+ count = 0;
+ for( node = doc.IterateChildren( 0 );
+ node;
+ node = doc.IterateChildren( node ) )
+ {
+ count++;
+ }
+ XmlTest( "Top level nodes, using IterateChildren.", 3, count );
+
+ // Walk all the elements in a node.
+ count = 0;
+ for( element = todoElement->FirstChildElement();
+ element;
+ element = element->NextSiblingElement() )
+ {
+ count++;
+ }
+ XmlTest( "Children of the 'ToDo' element, using First / Next.",
+ 3, count );
+
+ // Walk all the elements in a node by value.
+ count = 0;
+ for( node = todoElement->FirstChild( "Item" );
+ node;
+ node = node->NextSibling( "Item" ) )
+ {
+ count++;
+ }
+ XmlTest( "'Item' children of the 'ToDo' element, using First/Next.", 3, count );
+
+ count = 0;
+ for( node = todoElement->LastChild( "Item" );
+ node;
+ node = node->PreviousSibling( "Item" ) )
+ {
+ count++;
+ }
+ XmlTest( "'Item' children of the 'ToDo' element, using Last/Previous.", 3, count );
+
+#ifdef TIXML_USE_STL
+ {
+ cout << "\n** Parsing. **\n";
+ istringstream parse0( "<Element0 attribute0='foo0' attribute1= noquotes attribute2 = '&gt;' />" );
+ TiXmlElement element0( "default" );
+ parse0 >> element0;
+
+ XmlTest ( "Element parsed, value is 'Element0'.", "Element0", element0.Value() );
+ XmlTest ( "Reads attribute 'attribute0=\"foo0\"'.", "foo0", element0.Attribute( "attribute0" ));
+ XmlTest ( "Reads incorrectly formatted 'attribute1=noquotes'.", "noquotes", element0.Attribute( "attribute1" ) );
+ XmlTest ( "Read attribute with entity value '>'.", ">", element0.Attribute( "attribute2" ) );
+ }
+#endif
+
+ {
+ const char* error = "<?xml version=\"1.0\" standalone=\"no\" ?>\n"
+ "<passages count=\"006\" formatversion=\"20020620\">\n"
+ " <wrong error>\n"
+ "</passages>";
+
+ TiXmlDocument docTest;
+ docTest.Parse( error );
+ XmlTest( "Error row", docTest.ErrorRow(), 3 );
+ XmlTest( "Error column", docTest.ErrorCol(), 17 );
+ //printf( "error=%d id='%s' row %d col%d\n", (int) doc.Error(), doc.ErrorDesc(), doc.ErrorRow()+1, doc.ErrorCol() + 1 );
+
+ }
+
+#ifdef TIXML_USE_STL
+ {
+ //////////////////////////////////////////////////////
+ cout << "\n** Streaming. **\n";
+
+ // Round trip check: stream in, then stream back out to verify. The stream
+ // out has already been checked, above. We use the output
+
+ istringstream inputStringStream( outputStream.str() );
+ TiXmlDocument document0;
+
+ inputStringStream >> document0;
+
+ ostringstream outputStream0( ostringstream::out );
+ outputStream0 << document0;
+
+ XmlTest( "Stream round trip correct.", string( demoEnd ).c_str(),
+ outputStream0.str().c_str(), true );
+
+ std::string str;
+ str << document0;
+
+ XmlTest( "String printing correct.", string( demoEnd ).c_str(),
+ str.c_str(), true );
+ }
+#endif
+ }
+
+ {
+ const char* str = "<doc attr0='1' attr1='2.0' attr2='foo' />";
+
+ TiXmlDocument doc;
+ doc.Parse( str );
+
+ TiXmlElement* ele = doc.FirstChildElement();
+
+ int iVal, result;
+ double dVal;
+
+ result = ele->QueryDoubleAttribute( "attr0", &dVal );
+ XmlTest( "Query attribute: int as double", result, TIXML_SUCCESS );
+ XmlTest( "Query attribute: int as double", (int)dVal, 1 );
+ result = ele->QueryDoubleAttribute( "attr1", &dVal );
+ XmlTest( "Query attribute: double as double", (int)dVal, 2 );
+ result = ele->QueryIntAttribute( "attr1", &iVal );
+ XmlTest( "Query attribute: double as int", result, TIXML_SUCCESS );
+ XmlTest( "Query attribute: double as int", iVal, 2 );
+ result = ele->QueryIntAttribute( "attr2", &iVal );
+ XmlTest( "Query attribute: not a number", result, TIXML_WRONG_TYPE );
+ result = ele->QueryIntAttribute( "bar", &iVal );
+ XmlTest( "Query attribute: does not exist", result, TIXML_NO_ATTRIBUTE );
+ }
{
- FILE* textfile = fopen( "test5.xml", "w" );
- if ( textfile )
- {
+ const char* str = "<doc/>";
+
+ TiXmlDocument doc;
+ doc.Parse( str );
+
+ TiXmlElement* ele = doc.FirstChildElement();
+
+ int iVal;
+ double dVal;
+
+ ele->SetAttribute( "str", "strValue" );
+ ele->SetAttribute( "int", 1 );
+ ele->SetDoubleAttribute( "double", -1.0 );
+
+ const char* cStr = ele->Attribute( "str" );
+ ele->QueryIntAttribute( "int", &iVal );
+ ele->QueryDoubleAttribute( "double", &dVal );
+
+ XmlTest( "Attribute round trip. c-string.", "strValue", cStr );
+ XmlTest( "Attribute round trip. int.", 1, iVal );
+ XmlTest( "Attribute round trip. double.", -1, (int)dVal );
+ }
+
+ {
+ const char* str = "\t<?xml version=\"1.0\" standalone=\"no\" ?>\t<room doors='2'>\n"
+ "</room>";
+
+ TiXmlDocument doc;
+ doc.SetTabSize( 8 );
+ doc.Parse( str );
+
+ TiXmlHandle docHandle( &doc );
+ TiXmlHandle roomHandle = docHandle.FirstChildElement( "room" );
+
+ assert( docHandle.Node() );
+ assert( roomHandle.Element() );
+
+ TiXmlElement* room = roomHandle.Element();
+ assert( room );
+ TiXmlAttribute* doors = room->FirstAttribute();
+ assert( doors );
+
+ XmlTest( "Location tracking: Tab 8: room row", room->Row(), 1 );
+ XmlTest( "Location tracking: Tab 8: room col", room->Column(), 49 );
+ XmlTest( "Location tracking: Tab 8: doors row", doors->Row(), 1 );
+ XmlTest( "Location tracking: Tab 8: doors col", doors->Column(), 55 );
+ }
+
+ {
+ const char* str = "\t<?xml version=\"1.0\" standalone=\"no\" ?>\t<room doors='2'>\n"
+ " <!-- Silly example -->\n"
+ " <door wall='north'>A great door!</door>\n"
+ "\t<door wall='east'/>"
+ "</room>";
+
+ TiXmlDocument doc;
+ doc.Parse( str );
+
+ TiXmlHandle docHandle( &doc );
+ TiXmlHandle roomHandle = docHandle.FirstChildElement( "room" );
+ TiXmlHandle commentHandle = docHandle.FirstChildElement( "room" ).FirstChild();
+ TiXmlHandle textHandle = docHandle.FirstChildElement( "room" ).ChildElement( "door", 0 ).FirstChild();
+ TiXmlHandle door0Handle = docHandle.FirstChildElement( "room" ).ChildElement( 0 );
+ TiXmlHandle door1Handle = docHandle.FirstChildElement( "room" ).ChildElement( 1 );
+
+ assert( docHandle.Node() );
+ assert( roomHandle.Element() );
+ assert( commentHandle.Node() );
+ assert( textHandle.Text() );
+ assert( door0Handle.Element() );
+ assert( door1Handle.Element() );
+
+ TiXmlDeclaration* declaration = doc.FirstChild()->ToDeclaration();
+ assert( declaration );
+ TiXmlElement* room = roomHandle.Element();
+ assert( room );
+ TiXmlAttribute* doors = room->FirstAttribute();
+ assert( doors );
+ TiXmlText* text = textHandle.Text();
+ TiXmlComment* comment = commentHandle.Node()->ToComment();
+ assert( comment );
+ TiXmlElement* door0 = door0Handle.Element();
+ TiXmlElement* door1 = door1Handle.Element();
+
+ XmlTest( "Location tracking: Declaration row", declaration->Row(), 1 );
+ XmlTest( "Location tracking: Declaration col", declaration->Column(), 5 );
+ XmlTest( "Location tracking: room row", room->Row(), 1 );
+ XmlTest( "Location tracking: room col", room->Column(), 45 );
+ XmlTest( "Location tracking: doors row", doors->Row(), 1 );
+ XmlTest( "Location tracking: doors col", doors->Column(), 51 );
+ XmlTest( "Location tracking: Comment row", comment->Row(), 2 );
+ XmlTest( "Location tracking: Comment col", comment->Column(), 3 );
+ XmlTest( "Location tracking: text row", text->Row(), 3 );
+ XmlTest( "Location tracking: text col", text->Column(), 24 );
+ XmlTest( "Location tracking: door0 row", door0->Row(), 3 );
+ XmlTest( "Location tracking: door0 col", door0->Column(), 5 );
+ XmlTest( "Location tracking: door1 row", door1->Row(), 4 );
+ XmlTest( "Location tracking: door1 col", door1->Column(), 5 );
+ }
+
+
+ // --------------------------------------------------------
+ // UTF-8 testing. It is important to test:
+ // 1. Making sure name, value, and text read correctly
+ // 2. Row, Col functionality
+ // 3. Correct output
+ // --------------------------------------------------------
+ printf ("\n** UTF-8 **\n");
+ {
+ TiXmlDocument doc( "utf8test.xml" );
+ doc.LoadFile();
+ if ( doc.Error() && doc.ErrorId() == TiXmlBase::TIXML_ERROR_OPENING_FILE )
+ {
+ printf( "WARNING: File 'utf8test.xml' not found.\n"
+ "(Are you running the test from the wrong directory?)\n"
+ "Could not test UTF-8 functionality.\n" );
+ }
+ else
+ {
+ TiXmlHandle docH( &doc );
+ // Get the attribute "value" from the "Russian" element and check it.
+ TiXmlElement* element = docH.FirstChildElement( "document" ).FirstChildElement( "Russian" ).Element();
+ const unsigned char correctValue[] = { 0xd1U, 0x86U, 0xd0U, 0xb5U, 0xd0U, 0xbdU, 0xd0U, 0xbdU,
+ 0xd0U, 0xbeU, 0xd1U, 0x81U, 0xd1U, 0x82U, 0xd1U, 0x8cU, 0
+ };
+
+ XmlTest( "UTF-8: Russian value.", (const char*)correctValue, element->Attribute( "value" ), true );
+ XmlTest( "UTF-8: Russian value row.", 4, element->Row() );
+ XmlTest( "UTF-8: Russian value column.", 5, element->Column() );
+
+ const unsigned char russianElementName[] = { 0xd0U, 0xa0U, 0xd1U, 0x83U,
+ 0xd1U, 0x81U, 0xd1U, 0x81U,
+ 0xd0U, 0xbaU, 0xd0U, 0xb8U,
+ 0xd0U, 0xb9U, 0
+ };
+ const char russianText[] = "<\xD0\xB8\xD0\xBC\xD0\xB5\xD0\xB5\xD1\x82>";
+
+ TiXmlText* text = docH.FirstChildElement( "document" ).FirstChildElement( (const char*) russianElementName ).Child( 0 ).Text();
+ XmlTest( "UTF-8: Browsing russian element name.",
+ russianText,
+ text->Value(),
+ true );
+ XmlTest( "UTF-8: Russian element name row.", 7, text->Row() );
+ XmlTest( "UTF-8: Russian element name column.", 47, text->Column() );
+
+ TiXmlDeclaration* dec = docH.Child( 0 ).Node()->ToDeclaration();
+ XmlTest( "UTF-8: Declaration column.", 1, dec->Column() );
+ XmlTest( "UTF-8: Document column.", 1, doc.Column() );
+
+ // Now try for a round trip.
+ doc.SaveFile( "utf8testout.xml" );
+
+ // Check the round trip.
+ char savedBuf[256];
+ char verifyBuf[256];
+ int okay = 1;
+
+ FILE* saved = fopen( "utf8testout.xml", "r" );
+ FILE* verify = fopen( "utf8testverify.xml", "r" );
+ if ( saved && verify )
+ {
+ while ( fgets( verifyBuf, 256, verify ) )
+ {
+ fgets( savedBuf, 256, saved );
+ if ( strcmp( verifyBuf, savedBuf ) )
+ {
+ okay = 0;
+ break;
+ }
+ }
+ fclose( saved );
+ fclose( verify );
+ }
+ XmlTest( "UTF-8: Verified multi-language round trip.", 1, okay );
+
+ // On most Western machines, this is an element that contains
+ // the word "resume" with the correct accents, in a latin encoding.
+ // It will be something else completely on non-wester machines,
+ // which is why TinyXml is switching to UTF-8.
+ const char latin[] = "<element>r\x82sum\x82</element>";
+
+ TiXmlDocument latinDoc;
+ latinDoc.Parse( latin, 0, TIXML_ENCODING_LEGACY );
+
+ text = latinDoc.FirstChildElement()->FirstChild()->ToText();
+ XmlTest( "Legacy encoding: Verify text element.", "r\x82sum\x82", text->Value() );
+ }
+ }
+
+ //////////////////////
+ // Copy and assignment
+ //////////////////////
+ printf ("\n** Copy and Assignment **\n");
+ {
+ TiXmlElement element( "foo" );
+ element.Parse( "<element name='value' />", 0, TIXML_ENCODING_UNKNOWN );
+
+ TiXmlElement elementCopy( element );
+ TiXmlElement elementAssign( "foo" );
+ elementAssign.Parse( "<incorrect foo='bar'/>", 0, TIXML_ENCODING_UNKNOWN );
+ elementAssign = element;
+
+ XmlTest( "Copy/Assign: element copy #1.", "element", elementCopy.Value() );
+ XmlTest( "Copy/Assign: element copy #2.", "value", elementCopy.Attribute( "name" ) );
+ XmlTest( "Copy/Assign: element assign #1.", "element", elementAssign.Value() );
+ XmlTest( "Copy/Assign: element assign #2.", "value", elementAssign.Attribute( "name" ) );
+ XmlTest( "Copy/Assign: element assign #3.", true, ( 0 == elementAssign.Attribute( "foo" )) );
+
+ TiXmlComment comment;
+ comment.Parse( "<!--comment-->", 0, TIXML_ENCODING_UNKNOWN );
+ TiXmlComment commentCopy( comment );
+ TiXmlComment commentAssign;
+ commentAssign = commentCopy;
+ XmlTest( "Copy/Assign: comment copy.", "comment", commentCopy.Value() );
+ XmlTest( "Copy/Assign: comment assign.", "comment", commentAssign.Value() );
+
+ TiXmlUnknown unknown;
+ unknown.Parse( "<[unknown]>", 0, TIXML_ENCODING_UNKNOWN );
+ TiXmlUnknown unknownCopy( unknown );
+ TiXmlUnknown unknownAssign;
+ unknownAssign.Parse( "incorrect", 0, TIXML_ENCODING_UNKNOWN );
+ unknownAssign = unknownCopy;
+ XmlTest( "Copy/Assign: unknown copy.", "[unknown]", unknownCopy.Value() );
+ XmlTest( "Copy/Assign: unknown assign.", "[unknown]", unknownAssign.Value() );
+
+ TiXmlText text( "TextNode" );
+ TiXmlText textCopy( text );
+ TiXmlText textAssign( "incorrect" );
+ textAssign = text;
+ XmlTest( "Copy/Assign: text copy.", "TextNode", textCopy.Value() );
+ XmlTest( "Copy/Assign: text assign.", "TextNode", textAssign.Value() );
+
+ TiXmlDeclaration dec;
+ dec.Parse( "<?xml version='1.0' encoding='UTF-8'?>", 0, TIXML_ENCODING_UNKNOWN );
+ TiXmlDeclaration decCopy( dec );
+ TiXmlDeclaration decAssign;
+ decAssign = dec;
+
+ XmlTest( "Copy/Assign: declaration copy.", "UTF-8", decCopy.Encoding() );
+ XmlTest( "Copy/Assign: text assign.", "UTF-8", decAssign.Encoding() );
+
+ TiXmlDocument doc;
+ elementCopy.InsertEndChild( textCopy );
+ doc.InsertEndChild( decAssign );
+ doc.InsertEndChild( elementCopy );
+ doc.InsertEndChild( unknownAssign );
+
+ TiXmlDocument docCopy( doc );
+ TiXmlDocument docAssign;
+ docAssign = docCopy;
+
+#ifdef TIXML_USE_STL
+ std::string original, copy, assign;
+ original << doc;
+ copy << docCopy;
+ assign << docAssign;
+ XmlTest( "Copy/Assign: document copy.", original.c_str(), copy.c_str(), true );
+ XmlTest( "Copy/Assign: document assign.", original.c_str(), assign.c_str(), true );
+
+#endif
+ }
+
+ //////////////////////////////////////////////////////
+#ifdef TIXML_USE_STL
+ printf ("\n** Parsing, no Condense Whitespace **\n");
+ TiXmlBase::SetCondenseWhiteSpace( false );
+ {
+ istringstream parse1( "<start>This is \ntext</start>" );
+ TiXmlElement text1( "text" );
+ parse1 >> text1;
+
+ XmlTest ( "Condense white space OFF.", "This is \ntext",
+ text1.FirstChild()->Value(),
+ true );
+ }
+ TiXmlBase::SetCondenseWhiteSpace( true );
+#endif
+
+ //////////////////////////////////////////////////////
+ // GetText();
+ {
+ const char* str = "<foo>This is text</foo>";
+ TiXmlDocument doc;
+ doc.Parse( str );
+ const TiXmlElement* element = doc.RootElement();
+
+ XmlTest( "GetText() normal use.", "This is text", element->GetText() );
+
+ str = "<foo><b>This is text</b></foo>";
+ doc.Clear();
+ doc.Parse( str );
+ element = doc.RootElement();
+
+ XmlTest( "GetText() contained element.", element->GetText() == 0, true );
+
+ str = "<foo>This is <b>text</b></foo>";
+ doc.Clear();
+ TiXmlBase::SetCondenseWhiteSpace( false );
+ doc.Parse( str );
+ TiXmlBase::SetCondenseWhiteSpace( true );
+ element = doc.RootElement();
+
+ XmlTest( "GetText() partial.", "This is ", element->GetText() );
+ }
+
+
+ //////////////////////////////////////////////////////
+ // CDATA
+ {
+ const char* str = "<xmlElement>"
+ "<![CDATA["
+ "I am > the rules!\n"
+ "...since I make symbolic puns"
+ "]]>"
+ "</xmlElement>";
+ TiXmlDocument doc;
+ doc.Parse( str );
+ doc.Print();
+
+ XmlTest( "CDATA parse.", doc.FirstChildElement()->FirstChild()->Value(),
+ "I am > the rules!\n...since I make symbolic puns",
+ true );
+
+#ifdef TIXML_USE_STL
+ //cout << doc << '\n';
+
+ doc.Clear();
+
+ istringstream parse0( str );
+ parse0 >> doc;
+ //cout << doc << '\n';
+
+ XmlTest( "CDATA stream.", doc.FirstChildElement()->FirstChild()->Value(),
+ "I am > the rules!\n...since I make symbolic puns",
+ true );
+#endif
+
+ TiXmlDocument doc1 = doc;
+ //doc.Print();
+
+ XmlTest( "CDATA copy.", doc1.FirstChildElement()->FirstChild()->Value(),
+ "I am > the rules!\n...since I make symbolic puns",
+ true );
+ }
+ {
+ // [ 1482728 ] Wrong wide char parsing
+ char buf[256];
+ buf[255] = 0;
+ for( int i=0; i<255; ++i )
+ {
+ buf[i] = (char)((i>=32) ? i : 32);
+ }
+ TIXML_STRING str( "<xmlElement><![CDATA[" );
+ str += buf;
+ str += "]]></xmlElement>";
+
+ TiXmlDocument doc;
+ doc.Parse( str.c_str() );
+
+ TiXmlPrinter printer;
+ printer.SetStreamPrinting();
+ doc.Accept( &printer );
+
+ XmlTest( "CDATA with all bytes #1.", str.c_str(), printer.CStr(), true );
+
+#ifdef TIXML_USE_STL
+ doc.Clear();
+ istringstream iss( printer.Str() );
+ iss >> doc;
+ std::string out;
+ out << doc;
+ XmlTest( "CDATA with all bytes #2.", out.c_str(), printer.CStr(), true );
+#endif
+ }
+ {
+ // [ 1480107 ] Bug-fix for STL-streaming of CDATA that contains tags
+ // CDATA streaming had a couple of bugs, that this tests for.
+ const char* str = "<xmlElement>"
+ "<![CDATA["
+ "<b>I am > the rules!</b>\n"
+ "...since I make symbolic puns"
+ "]]>"
+ "</xmlElement>";
+ TiXmlDocument doc;
+ doc.Parse( str );
+ doc.Print();
+
+ XmlTest( "CDATA parse. [ 1480107 ]", doc.FirstChildElement()->FirstChild()->Value(),
+ "<b>I am > the rules!</b>\n...since I make symbolic puns",
+ true );
+
+#ifdef TIXML_USE_STL
+
+ doc.Clear();
+
+ istringstream parse0( str );
+ parse0 >> doc;
+
+ XmlTest( "CDATA stream. [ 1480107 ]", doc.FirstChildElement()->FirstChild()->Value(),
+ "<b>I am > the rules!</b>\n...since I make symbolic puns",
+ true );
+#endif
+
+ TiXmlDocument doc1 = doc;
+ //doc.Print();
+
+ XmlTest( "CDATA copy. [ 1480107 ]", doc1.FirstChildElement()->FirstChild()->Value(),
+ "<b>I am > the rules!</b>\n...since I make symbolic puns",
+ true );
+ }
+ //////////////////////////////////////////////////////
+ // Visit()
+
+
+
+ //////////////////////////////////////////////////////
+ printf( "\n** Fuzzing... **\n" );
+
+ const int FUZZ_ITERATION = 300;
+
+ // The only goal is not to crash on bad input.
+ int len = (int) strlen( demoStart );
+ for( int i=0; i<FUZZ_ITERATION; ++i )
+ {
+ char* demoCopy = new char[ len+1 ];
+ strcpy( demoCopy, demoStart );
+
+ demoCopy[ i%len ] = (char)((i+1)*3);
+ demoCopy[ (i*7)%len ] = '>';
+ demoCopy[ (i*11)%len ] = '<';
+
+ TiXmlDocument xml;
+ xml.Parse( demoCopy );
+
+ delete [] demoCopy;
+ }
+ printf( "** Fuzzing Complete. **\n" );
+
+ //////////////////////////////////////////////////////
+ printf ("\n** Bug regression tests **\n");
+
+ // InsertBeforeChild and InsertAfterChild causes crash.
+ {
+ TiXmlElement parent( "Parent" );
+ TiXmlElement childText0( "childText0" );
+ TiXmlElement childText1( "childText1" );
+ TiXmlNode* childNode0 = parent.InsertEndChild( childText0 );
+ TiXmlNode* childNode1 = parent.InsertBeforeChild( childNode0, childText1 );
+
+ XmlTest( "Test InsertBeforeChild on empty node.", ( childNode1 == parent.FirstChild() ), true );
+ }
+
+ {
+ // InsertBeforeChild and InsertAfterChild causes crash.
+ TiXmlElement parent( "Parent" );
+ TiXmlElement childText0( "childText0" );
+ TiXmlElement childText1( "childText1" );
+ TiXmlNode* childNode0 = parent.InsertEndChild( childText0 );
+ TiXmlNode* childNode1 = parent.InsertAfterChild( childNode0, childText1 );
+
+ XmlTest( "Test InsertAfterChild on empty node. ", ( childNode1 == parent.LastChild() ), true );
+ }
+
+ // Reports of missing constructors, irregular string problems.
+ {
+ // Missing constructor implementation. No test -- just compiles.
+ TiXmlText text( "Missing" );
+
+#ifdef TIXML_USE_STL
+ // Missing implementation:
+ TiXmlDocument doc;
+ string name = "missing";
+ doc.LoadFile( name );
+
+ TiXmlText textSTL( name );
+#else
+ // verifying some basic string functions:
+ TiXmlString a;
+ TiXmlString b( "Hello" );
+ TiXmlString c( "ooga" );
+
+ c = " World!";
+ a = b;
+ a += c;
+ a = a;
+
+ XmlTest( "Basic TiXmlString test. ", "Hello World!", a.c_str() );
+#endif
+ }
+
+ // Long filenames crashing STL version
+ {
+ TiXmlDocument doc( "midsummerNightsDreamWithAVeryLongFilenameToConfuseTheStringHandlingRoutines.xml" );
+ bool loadOkay = doc.LoadFile();
+ loadOkay = true; // get rid of compiler warning.
+ // Won't pass on non-dev systems. Just a "no crash" check.
+ //XmlTest( "Long filename. ", true, loadOkay );
+ }
+
+ {
+ // Entities not being written correctly.
+ // From Lynn Allen
+
+ const char* passages =
+ "<?xml version=\"1.0\" standalone=\"no\" ?>"
+ "<passages count=\"006\" formatversion=\"20020620\">"
+ "<psg context=\"Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
+ " It also has &lt;, &gt;, and &amp;, as well as a fake copyright &#xA9;.\"> </psg>"
+ "</passages>";
+
+ TiXmlDocument doc( "passages.xml" );
+ doc.Parse( passages );
+ TiXmlElement* psg = doc.RootElement()->FirstChildElement();
+ const char* context = psg->Attribute( "context" );
+ const char* expected = "Line 5 has \"quotation marks\" and 'apostrophe marks'. It also has <, >, and &, as well as a fake copyright \xC2\xA9.";
+
+ XmlTest( "Entity transformation: read. ", expected, context, true );
+
+ FILE* textfile = fopen( "textfile.txt", "w" );
+ if ( textfile )
+ {
+ psg->Print( textfile, 0 );
+ fclose( textfile );
+ }
+ textfile = fopen( "textfile.txt", "r" );
+ assert( textfile );
+ if ( textfile )
+ {
+ char buf[ 1024 ];
+ fgets( buf, 1024, textfile );
+ XmlTest( "Entity transformation: write. ",
+ "<psg context=\'Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
+ " It also has &lt;, &gt;, and &amp;, as well as a fake copyright \xC2\xA9.' />",
+ buf,
+ true );
+ }
+ fclose( textfile );
+ }
+
+ {
+ FILE* textfile = fopen( "test5.xml", "w" );
+ if ( textfile )
+ {
fputs("<?xml version='1.0'?><a.elem xmi.version='2.0'/>", textfile);
fclose(textfile);
- TiXmlDocument doc;
+ TiXmlDocument doc;
doc.LoadFile( "test5.xml" );
XmlTest( "dot in element attributes and names", doc.Error(), 0);
- }
+ }
}
- {
- FILE* textfile = fopen( "test6.xml", "w" );
- if ( textfile )
- {
+ {
+ FILE* textfile = fopen( "test6.xml", "w" );
+ if ( textfile )
+ {
fputs("<element><Name>1.1 Start easy ignore fin thickness&#xA;</Name></element>", textfile );
fclose(textfile);
@@ -990,375 +994,376 @@ int main()
bool result = doc.LoadFile( "test6.xml" );
XmlTest( "Entity with one digit.", result, true );
- TiXmlText* text = doc.FirstChildElement()->FirstChildElement()->FirstChild()->ToText();
- XmlTest( "Entity with one digit.",
- text->Value(), "1.1 Start easy ignore fin thickness\n" );
- }
+ TiXmlText* text = doc.FirstChildElement()->FirstChildElement()->FirstChild()->ToText();
+ XmlTest( "Entity with one digit.",
+ text->Value(), "1.1 Start easy ignore fin thickness\n" );
+ }
}
- {
- // DOCTYPE not preserved (950171)
- //
- const char* doctype =
- "<?xml version=\"1.0\" ?>"
- "<!DOCTYPE PLAY SYSTEM 'play.dtd'>"
- "<!ELEMENT title (#PCDATA)>"
- "<!ELEMENT books (title,authors)>"
- "<element />";
-
- TiXmlDocument doc;
- doc.Parse( doctype );
- doc.SaveFile( "test7.xml" );
- doc.Clear();
- doc.LoadFile( "test7.xml" );
-
- TiXmlHandle docH( &doc );
- TiXmlUnknown* unknown = docH.Child( 1 ).Unknown();
- XmlTest( "Correct value of unknown.", "!DOCTYPE PLAY SYSTEM 'play.dtd'", unknown->Value() );
- #ifdef TIXML_USE_STL
- TiXmlNode* node = docH.Child( 2 ).Node();
- std::string str;
- str << (*node);
- XmlTest( "Correct streaming of unknown.", "<!ELEMENT title (#PCDATA)>", str.c_str() );
- #endif
- }
-
- {
- // [ 791411 ] Formatting bug
- // Comments do not stream out correctly.
- const char* doctype =
- "<!-- Somewhat<evil> -->";
- TiXmlDocument doc;
- doc.Parse( doctype );
-
- TiXmlHandle docH( &doc );
- TiXmlComment* comment = docH.Child( 0 ).Node()->ToComment();
-
- XmlTest( "Comment formatting.", " Somewhat<evil> ", comment->Value() );
- #ifdef TIXML_USE_STL
- std::string str;
- str << (*comment);
- XmlTest( "Comment streaming.", "<!-- Somewhat<evil> -->", str.c_str() );
- #endif
- }
-
- {
- // [ 870502 ] White space issues
- TiXmlDocument doc;
- TiXmlText* text;
- TiXmlHandle docH( &doc );
-
- const char* doctype0 = "<element> This has leading and trailing space </element>";
- const char* doctype1 = "<element>This has internal space</element>";
- const char* doctype2 = "<element> This has leading, trailing, and internal space </element>";
-
- TiXmlBase::SetCondenseWhiteSpace( false );
- doc.Clear();
- doc.Parse( doctype0 );
- text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
- XmlTest( "White space kept.", " This has leading and trailing space ", text->Value() );
-
- doc.Clear();
- doc.Parse( doctype1 );
- text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
- XmlTest( "White space kept.", "This has internal space", text->Value() );
-
- doc.Clear();
- doc.Parse( doctype2 );
- text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
- XmlTest( "White space kept.", " This has leading, trailing, and internal space ", text->Value() );
-
- TiXmlBase::SetCondenseWhiteSpace( true );
- doc.Clear();
- doc.Parse( doctype0 );
- text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
- XmlTest( "White space condensed.", "This has leading and trailing space", text->Value() );
-
- doc.Clear();
- doc.Parse( doctype1 );
- text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
- XmlTest( "White space condensed.", "This has internal space", text->Value() );
-
- doc.Clear();
- doc.Parse( doctype2 );
- text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
- XmlTest( "White space condensed.", "This has leading, trailing, and internal space", text->Value() );
- }
-
- {
- // Double attributes
- const char* doctype = "<element attr='red' attr='blue' />";
-
- TiXmlDocument doc;
- doc.Parse( doctype );
-
- XmlTest( "Parsing repeated attributes.", true, doc.Error() ); // is an error to tinyxml (didn't use to be, but caused issues)
- //XmlTest( "Parsing repeated attributes.", "blue", doc.FirstChildElement( "element" )->Attribute( "attr" ) );
- }
-
- {
- // Embedded null in stream.
- const char* doctype = "<element att\0r='red' attr='blue' />";
-
- TiXmlDocument doc;
- doc.Parse( doctype );
- XmlTest( "Embedded null throws error.", true, doc.Error() );
-
- #ifdef TIXML_USE_STL
- istringstream strm( doctype );
- doc.Clear();
- doc.ClearError();
- strm >> doc;
- XmlTest( "Embedded null throws error.", true, doc.Error() );
- #endif
- }
+ {
+ // DOCTYPE not preserved (950171)
+ //
+ const char* doctype =
+ "<?xml version=\"1.0\" ?>"
+ "<!DOCTYPE PLAY SYSTEM 'play.dtd'>"
+ "<!ELEMENT title (#PCDATA)>"
+ "<!ELEMENT books (title,authors)>"
+ "<element />";
+
+ TiXmlDocument doc;
+ doc.Parse( doctype );
+ doc.SaveFile( "test7.xml" );
+ doc.Clear();
+ doc.LoadFile( "test7.xml" );
+
+ TiXmlHandle docH( &doc );
+ TiXmlUnknown* unknown = docH.Child( 1 ).Unknown();
+ XmlTest( "Correct value of unknown.", "!DOCTYPE PLAY SYSTEM 'play.dtd'", unknown->Value() );
+#ifdef TIXML_USE_STL
+ TiXmlNode* node = docH.Child( 2 ).Node();
+ std::string str;
+ str << (*node);
+ XmlTest( "Correct streaming of unknown.", "<!ELEMENT title (#PCDATA)>", str.c_str() );
+#endif
+ }
{
- // Legacy mode test. (This test may only pass on a western system)
- const char* str =
- "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"
- "<ä>"
- "CöntäntßäöüÄÖÜ"
- "</ä>";
+ // [ 791411 ] Formatting bug
+ // Comments do not stream out correctly.
+ const char* doctype =
+ "<!-- Somewhat<evil> -->";
+ TiXmlDocument doc;
+ doc.Parse( doctype );
- TiXmlDocument doc;
- doc.Parse( str );
-
- TiXmlHandle docHandle( &doc );
- TiXmlHandle aHandle = docHandle.FirstChildElement( "ä" );
- TiXmlHandle tHandle = aHandle.Child( 0 );
- assert( aHandle.Element() );
- assert( tHandle.Text() );
- XmlTest( "ISO-8859-1 Parsing.", "CöntäntßäöüÄÖÜ", tHandle.Text()->Value() );
+ TiXmlHandle docH( &doc );
+ TiXmlComment* comment = docH.Child( 0 ).Node()->ToComment();
+
+ XmlTest( "Comment formatting.", " Somewhat<evil> ", comment->Value() );
+#ifdef TIXML_USE_STL
+ std::string str;
+ str << (*comment);
+ XmlTest( "Comment streaming.", "<!-- Somewhat<evil> -->", str.c_str() );
+#endif
+ }
+
+ {
+ // [ 870502 ] White space issues
+ TiXmlDocument doc;
+ TiXmlText* text;
+ TiXmlHandle docH( &doc );
+
+ const char* doctype0 = "<element> This has leading and trailing space </element>";
+ const char* doctype1 = "<element>This has internal space</element>";
+ const char* doctype2 = "<element> This has leading, trailing, and internal space </element>";
+
+ TiXmlBase::SetCondenseWhiteSpace( false );
+ doc.Clear();
+ doc.Parse( doctype0 );
+ text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
+ XmlTest( "White space kept.", " This has leading and trailing space ", text->Value() );
+
+ doc.Clear();
+ doc.Parse( doctype1 );
+ text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
+ XmlTest( "White space kept.", "This has internal space", text->Value() );
+
+ doc.Clear();
+ doc.Parse( doctype2 );
+ text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
+ XmlTest( "White space kept.", " This has leading, trailing, and internal space ", text->Value() );
+
+ TiXmlBase::SetCondenseWhiteSpace( true );
+ doc.Clear();
+ doc.Parse( doctype0 );
+ text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
+ XmlTest( "White space condensed.", "This has leading and trailing space", text->Value() );
+
+ doc.Clear();
+ doc.Parse( doctype1 );
+ text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
+ XmlTest( "White space condensed.", "This has internal space", text->Value() );
+
+ doc.Clear();
+ doc.Parse( doctype2 );
+ text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
+ XmlTest( "White space condensed.", "This has leading, trailing, and internal space", text->Value() );
+ }
+
+ {
+ // Double attributes
+ const char* doctype = "<element attr='red' attr='blue' />";
+
+ TiXmlDocument doc;
+ doc.Parse( doctype );
+
+ XmlTest( "Parsing repeated attributes.", true, doc.Error() ); // is an error to tinyxml (didn't use to be, but caused issues)
+ //XmlTest( "Parsing repeated attributes.", "blue", doc.FirstChildElement( "element" )->Attribute( "attr" ) );
+ }
+
+ {
+ // Embedded null in stream.
+ const char* doctype = "<element att\0r='red' attr='blue' />";
+
+ TiXmlDocument doc;
+ doc.Parse( doctype );
+ XmlTest( "Embedded null throws error.", true, doc.Error() );
+
+#ifdef TIXML_USE_STL
+ istringstream strm( doctype );
+ doc.Clear();
+ doc.ClearError();
+ strm >> doc;
+ XmlTest( "Embedded null throws error.", true, doc.Error() );
+#endif
+ }
+
+ {
+ // Legacy mode test. (This test may only pass on a western system)
+ const char* str =
+ "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"
+ "<ä>"
+ "CöntäntßäöüÄÖÜ"
+ "</ä>";
+
+ TiXmlDocument doc;
+ doc.Parse( str );
+
+ TiXmlHandle docHandle( &doc );
+ TiXmlHandle aHandle = docHandle.FirstChildElement( "ä" );
+ TiXmlHandle tHandle = aHandle.Child( 0 );
+ assert( aHandle.Element() );
+ assert( tHandle.Text() );
+ XmlTest( "ISO-8859-1 Parsing.", "CöntäntßäöüÄÖÜ", tHandle.Text()->Value() );
+ }
+
+ {
+ // Empty documents should return TIXML_ERROR_PARSING_EMPTY, bug 1070717
+ const char* str = " ";
+ TiXmlDocument doc;
+ doc.Parse( str );
+ XmlTest( "Empty document error TIXML_ERROR_DOCUMENT_EMPTY", TiXmlBase::TIXML_ERROR_DOCUMENT_EMPTY, doc.ErrorId() );
+ }
+#ifndef TIXML_USE_STL
+ {
+ // String equality. [ 1006409 ] string operator==/!= no worky in all cases
+ TiXmlString temp;
+ XmlTest( "Empty tinyxml string compare equal", ( temp == "" ), true );
+
+ TiXmlString foo;
+ TiXmlString bar( "" );
+ XmlTest( "Empty tinyxml string compare equal", ( foo == bar ), true );
+ }
+
+#endif
+ {
+ // Bug [ 1195696 ] from marlonism
+ TiXmlBase::SetCondenseWhiteSpace(false);
+ TiXmlDocument xml;
+ xml.Parse("<text><break/>This hangs</text>");
+ XmlTest( "Test safe error return.", xml.Error(), false );
+ }
+
+ {
+ // Bug [ 1243992 ] - another infinite loop
+ TiXmlDocument doc;
+ doc.SetCondenseWhiteSpace(false);
+ doc.Parse("<p><pb></pb>test</p>");
+ }
+ {
+ // Low entities
+ TiXmlDocument xml;
+ xml.Parse( "<test>&#x0e;</test>" );
+ const char result[] = { 0x0e, 0 };
+ XmlTest( "Low entities.", xml.FirstChildElement()->GetText(), result );
+ xml.Print();
+ }
+ {
+ // Bug [ 1451649 ] Attribute values with trailing quotes not handled correctly
+ TiXmlDocument xml;
+ xml.Parse( "<foo attribute=bar\" />" );
+ XmlTest( "Throw error with bad end quotes.", xml.Error(), true );
+ }
+#ifdef TIXML_USE_STL
+ {
+ // Bug [ 1449463 ] Consider generic query
+ TiXmlDocument xml;
+ xml.Parse( "<foo bar='3' barStr='a string'/>" );
+
+ TiXmlElement* ele = xml.FirstChildElement();
+ double d;
+ int i;
+ float f;
+ bool b;
+ std::string str;
+
+ XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &d ), TIXML_SUCCESS );
+ XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &i ), TIXML_SUCCESS );
+ XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &f ), TIXML_SUCCESS );
+ XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &b ), TIXML_WRONG_TYPE );
+ XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "nobar", &b ), TIXML_NO_ATTRIBUTE );
+ XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "barStr", &str ), TIXML_SUCCESS );
+
+ XmlTest( "QueryValueAttribute", (d==3.0), true );
+ XmlTest( "QueryValueAttribute", (i==3), true );
+ XmlTest( "QueryValueAttribute", (f==3.0f), true );
+ XmlTest( "QueryValueAttribute", (str==std::string( "a string" )), true );
+ }
+#endif
+
+#ifdef TIXML_USE_STL
+ {
+ // [ 1505267 ] redundant malloc in TiXmlElement::Attribute
+ TiXmlDocument xml;
+ xml.Parse( "<foo bar='3' />" );
+ TiXmlElement* ele = xml.FirstChildElement();
+ double d;
+ int i;
+
+ std::string bar = "bar";
+
+ const std::string* atrrib = ele->Attribute( bar );
+ ele->Attribute( bar, &d );
+ ele->Attribute( bar, &i );
+
+ XmlTest( "Attribute", atrrib->empty(), false );
+ XmlTest( "Attribute", (d==3.0), true );
+ XmlTest( "Attribute", (i==3), true );
+ }
+#endif
+
+ {
+ // [ 1356059 ] Allow TiXMLDocument to only be at the top level
+ TiXmlDocument xml, xml2;
+ xml.InsertEndChild( xml2 );
+ XmlTest( "Document only at top level.", xml.Error(), true );
+ XmlTest( "Document only at top level.", xml.ErrorId(), TiXmlBase::TIXML_ERROR_DOCUMENT_TOP_ONLY );
+ }
+
+ {
+ // [ 1663758 ] Failure to report error on bad XML
+ TiXmlDocument xml;
+ xml.Parse("<x>");
+ XmlTest("Missing end tag at end of input", xml.Error(), true);
+ xml.Parse("<x> ");
+ XmlTest("Missing end tag with trailing whitespace", xml.Error(), true);
+ }
+
+ {
+ // [ 1635701 ] fail to parse files with a tag separated into two lines
+ // I'm not sure this is a bug. Marked 'pending' for feedback.
+ TiXmlDocument xml;
+ xml.Parse( "<title><p>text</p\n><title>" );
+ //xml.Print();
+ //XmlTest( "Tag split by newline", xml.Error(), false );
+ }
+
+#ifdef TIXML_USE_STL
+ {
+ // [ 1475201 ] TinyXML parses entities in comments
+ TiXmlDocument xml;
+ istringstream parse1( "<!-- declarations for <head> & <body> -->"
+ "<!-- far &amp; away -->" );
+ parse1 >> xml;
+
+ TiXmlNode* e0 = xml.FirstChild();
+ TiXmlNode* e1 = e0->NextSibling();
+ TiXmlComment* c0 = e0->ToComment();
+ TiXmlComment* c1 = e1->ToComment();
+
+ XmlTest( "Comments ignore entities.", " declarations for <head> & <body> ", c0->Value(), true );
+ XmlTest( "Comments ignore entities.", " far &amp; away ", c1->Value(), true );
+ }
+#endif
+
+ {
+ // [ 1475201 ] TinyXML parses entities in comments
+ TiXmlDocument xml;
+ xml.Parse("<!-- declarations for <head> & <body> -->"
+ "<!-- far &amp; away -->" );
+
+ TiXmlNode* e0 = xml.FirstChild();
+ TiXmlNode* e1 = e0->NextSibling();
+ TiXmlComment* c0 = e0->ToComment();
+ TiXmlComment* c1 = e1->ToComment();
+
+ XmlTest( "Comments ignore entities.", " declarations for <head> & <body> ", c0->Value(), true );
+ XmlTest( "Comments ignore entities.", " far &amp; away ", c1->Value(), true );
+ }
+
+ {
+ TiXmlDocument xml;
+ xml.Parse( "<Parent>"
+ "<child1 att=''/>"
+ "<!-- With this comment, child2 will not be parsed! -->"
+ "<child2 att=''/>"
+ "</Parent>" );
+ int count = 0;
+
+ TiXmlNode* ele = 0;
+ while ( (ele = xml.FirstChildElement( "Parent" )->IterateChildren( ele ) ) != 0 )
+ {
+ ++count;
+ }
+ XmlTest( "Comments iterate correctly.", 3, count );
+ }
+
+ {
+ // trying to repro ]1874301]. If it doesn't go into an infinite loop, all is well.
+ unsigned char buf[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?><feed><![CDATA[Test XMLblablablalblbl";
+ buf[60] = 239;
+ buf[61] = 0;
+
+ TiXmlDocument doc;
+ doc.Parse( (const char*)buf);
+ }
+
+
+ {
+ // bug 1827248 Error while parsing a little bit malformed file
+ // Actually not malformed - should work.
+ TiXmlDocument xml;
+ xml.Parse( "<attributelist> </attributelist >" );
+ XmlTest( "Handle end tag whitespace", false, xml.Error() );
+ }
+
+ {
+ // 1709904 - can not repro the crash
+ {
+ TiXmlDocument xml;
+ xml.Parse( "<tag>/</tag>" );
+ XmlTest( "Odd XML parsing.", xml.FirstChild()->Value(), "tag" );
+ }
+ /* Could not repro. {
+ TiXmlDocument xml;
+ xml.LoadFile( "EQUI_Inventory.xml" );
+ //XmlTest( "Odd XML parsing.", xml.FirstChildElement()->Value(), "XML" );
+ TiXmlPrinter printer;
+ xml.Accept( &printer );
+ fprintf( stdout, "%s", printer.CStr() );
+ }*/
}
- {
- // Empty documents should return TIXML_ERROR_PARSING_EMPTY, bug 1070717
- const char* str = " ";
- TiXmlDocument doc;
- doc.Parse( str );
- XmlTest( "Empty document error TIXML_ERROR_DOCUMENT_EMPTY", TiXmlBase::TIXML_ERROR_DOCUMENT_EMPTY, doc.ErrorId() );
- }
- #ifndef TIXML_USE_STL
- {
- // String equality. [ 1006409 ] string operator==/!= no worky in all cases
- TiXmlString temp;
- XmlTest( "Empty tinyxml string compare equal", ( temp == "" ), true );
-
- TiXmlString foo;
- TiXmlString bar( "" );
- XmlTest( "Empty tinyxml string compare equal", ( foo == bar ), true );
- }
-
- #endif
- {
- // Bug [ 1195696 ] from marlonism
- TiXmlBase::SetCondenseWhiteSpace(false);
- TiXmlDocument xml;
- xml.Parse("<text><break/>This hangs</text>");
- XmlTest( "Test safe error return.", xml.Error(), false );
- }
-
- {
- // Bug [ 1243992 ] - another infinite loop
- TiXmlDocument doc;
- doc.SetCondenseWhiteSpace(false);
- doc.Parse("<p><pb></pb>test</p>");
- }
- {
- // Low entities
- TiXmlDocument xml;
- xml.Parse( "<test>&#x0e;</test>" );
- const char result[] = { 0x0e, 0 };
- XmlTest( "Low entities.", xml.FirstChildElement()->GetText(), result );
- xml.Print();
- }
- {
- // Bug [ 1451649 ] Attribute values with trailing quotes not handled correctly
- TiXmlDocument xml;
- xml.Parse( "<foo attribute=bar\" />" );
- XmlTest( "Throw error with bad end quotes.", xml.Error(), true );
- }
- #ifdef TIXML_USE_STL
- {
- // Bug [ 1449463 ] Consider generic query
- TiXmlDocument xml;
- xml.Parse( "<foo bar='3' barStr='a string'/>" );
-
- TiXmlElement* ele = xml.FirstChildElement();
- double d;
- int i;
- float f;
- bool b;
- std::string str;
-
- XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &d ), TIXML_SUCCESS );
- XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &i ), TIXML_SUCCESS );
- XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &f ), TIXML_SUCCESS );
- XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &b ), TIXML_WRONG_TYPE );
- XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "nobar", &b ), TIXML_NO_ATTRIBUTE );
- XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "barStr", &str ), TIXML_SUCCESS );
-
- XmlTest( "QueryValueAttribute", (d==3.0), true );
- XmlTest( "QueryValueAttribute", (i==3), true );
- XmlTest( "QueryValueAttribute", (f==3.0f), true );
- XmlTest( "QueryValueAttribute", (str==std::string( "a string" )), true );
- }
- #endif
-
- #ifdef TIXML_USE_STL
- {
- // [ 1505267 ] redundant malloc in TiXmlElement::Attribute
- TiXmlDocument xml;
- xml.Parse( "<foo bar='3' />" );
- TiXmlElement* ele = xml.FirstChildElement();
- double d;
- int i;
-
- std::string bar = "bar";
-
- const std::string* atrrib = ele->Attribute( bar );
- ele->Attribute( bar, &d );
- ele->Attribute( bar, &i );
-
- XmlTest( "Attribute", atrrib->empty(), false );
- XmlTest( "Attribute", (d==3.0), true );
- XmlTest( "Attribute", (i==3), true );
- }
- #endif
-
- {
- // [ 1356059 ] Allow TiXMLDocument to only be at the top level
- TiXmlDocument xml, xml2;
- xml.InsertEndChild( xml2 );
- XmlTest( "Document only at top level.", xml.Error(), true );
- XmlTest( "Document only at top level.", xml.ErrorId(), TiXmlBase::TIXML_ERROR_DOCUMENT_TOP_ONLY );
- }
-
- {
- // [ 1663758 ] Failure to report error on bad XML
- TiXmlDocument xml;
- xml.Parse("<x>");
- XmlTest("Missing end tag at end of input", xml.Error(), true);
- xml.Parse("<x> ");
- XmlTest("Missing end tag with trailing whitespace", xml.Error(), true);
- }
-
- {
- // [ 1635701 ] fail to parse files with a tag separated into two lines
- // I'm not sure this is a bug. Marked 'pending' for feedback.
- TiXmlDocument xml;
- xml.Parse( "<title><p>text</p\n><title>" );
- //xml.Print();
- //XmlTest( "Tag split by newline", xml.Error(), false );
- }
-
- #ifdef TIXML_USE_STL
- {
- // [ 1475201 ] TinyXML parses entities in comments
- TiXmlDocument xml;
- istringstream parse1( "<!-- declarations for <head> & <body> -->"
- "<!-- far &amp; away -->" );
- parse1 >> xml;
-
- TiXmlNode* e0 = xml.FirstChild();
- TiXmlNode* e1 = e0->NextSibling();
- TiXmlComment* c0 = e0->ToComment();
- TiXmlComment* c1 = e1->ToComment();
-
- XmlTest( "Comments ignore entities.", " declarations for <head> & <body> ", c0->Value(), true );
- XmlTest( "Comments ignore entities.", " far &amp; away ", c1->Value(), true );
- }
- #endif
-
- {
- // [ 1475201 ] TinyXML parses entities in comments
- TiXmlDocument xml;
- xml.Parse("<!-- declarations for <head> & <body> -->"
- "<!-- far &amp; away -->" );
-
- TiXmlNode* e0 = xml.FirstChild();
- TiXmlNode* e1 = e0->NextSibling();
- TiXmlComment* c0 = e0->ToComment();
- TiXmlComment* c1 = e1->ToComment();
-
- XmlTest( "Comments ignore entities.", " declarations for <head> & <body> ", c0->Value(), true );
- XmlTest( "Comments ignore entities.", " far &amp; away ", c1->Value(), true );
- }
-
- {
- TiXmlDocument xml;
- xml.Parse( "<Parent>"
- "<child1 att=''/>"
- "<!-- With this comment, child2 will not be parsed! -->"
- "<child2 att=''/>"
- "</Parent>" );
- int count = 0;
-
- TiXmlNode* ele = 0;
- while ( (ele = xml.FirstChildElement( "Parent" )->IterateChildren( ele ) ) != 0 ) {
- ++count;
- }
- XmlTest( "Comments iterate correctly.", 3, count );
- }
-
- {
- // trying to repro ]1874301]. If it doesn't go into an infinite loop, all is well.
- unsigned char buf[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?><feed><![CDATA[Test XMLblablablalblbl";
- buf[60] = 239;
- buf[61] = 0;
-
- TiXmlDocument doc;
- doc.Parse( (const char*)buf);
- }
-
-
- {
- // bug 1827248 Error while parsing a little bit malformed file
- // Actually not malformed - should work.
- TiXmlDocument xml;
- xml.Parse( "<attributelist> </attributelist >" );
- XmlTest( "Handle end tag whitespace", false, xml.Error() );
- }
-
- {
- // 1709904 - can not repro the crash
- {
- TiXmlDocument xml;
- xml.Parse( "<tag>/</tag>" );
- XmlTest( "Odd XML parsing.", xml.FirstChild()->Value(), "tag" );
- }
- /* Could not repro. {
- TiXmlDocument xml;
- xml.LoadFile( "EQUI_Inventory.xml" );
- //XmlTest( "Odd XML parsing.", xml.FirstChildElement()->Value(), "XML" );
- TiXmlPrinter printer;
- xml.Accept( &printer );
- fprintf( stdout, "%s", printer.CStr() );
- }*/
- }
-
- /* 1417717 experiment
- {
- TiXmlDocument xml;
- xml.Parse("<text>Dan & Tracie</text>");
- xml.Print(stdout);
- }
- {
- TiXmlDocument xml;
- xml.Parse("<text>Dan &foo; Tracie</text>");
- xml.Print(stdout);
- }
- */
- #if defined( WIN32 ) && defined( TUNE )
- _CrtMemCheckpoint( &endMemState );
- //_CrtMemDumpStatistics( &endMemState );
-
- _CrtMemState diffMemState;
- _CrtMemDifference( &diffMemState, &startMemState, &endMemState );
- _CrtMemDumpStatistics( &diffMemState );
- #endif
-
- printf ("\nPass %d, Fail %d\n", gPass, gFail);
- return gFail;
+ /* 1417717 experiment
+ {
+ TiXmlDocument xml;
+ xml.Parse("<text>Dan & Tracie</text>");
+ xml.Print(stdout);
+ }
+ {
+ TiXmlDocument xml;
+ xml.Parse("<text>Dan &foo; Tracie</text>");
+ xml.Print(stdout);
+ }
+ */
+#if defined( WIN32 ) && defined( TUNE )
+ _CrtMemCheckpoint( &endMemState );
+ //_CrtMemDumpStatistics( &endMemState );
+
+ _CrtMemState diffMemState;
+ _CrtMemDifference( &diffMemState, &startMemState, &endMemState );
+ _CrtMemDumpStatistics( &diffMemState );
+#endif
+
+ printf ("\nPass %d, Fail %d\n", gPass, gFail);
+ return gFail;
}
diff --git a/shared/util.cpp b/shared/util.cpp
index f115f8dc..2af7dc5b 100644
--- a/shared/util.cpp
+++ b/shared/util.cpp
@@ -175,16 +175,16 @@ wxString ffs3::utcTimeToLocalString(const wxLongLong& utcTime)
SYSTEMTIME systemTimeUtc = {};
if (!::FileTimeToSystemTime(
- &lastWriteTimeUtc, //__in const FILETIME *lpFileTime,
- &systemTimeUtc)) //__out LPSYSTEMTIME lpSystemTime
+ &lastWriteTimeUtc, //__in const FILETIME *lpFileTime,
+ &systemTimeUtc)) //__out LPSYSTEMTIME lpSystemTime
throw std::runtime_error(std::string((wxString(_("Conversion error:")) + wxT(" FILETIME -> SYSTEMTIME: ") +
wxT("(") + wxULongLong(lastWriteTimeUtc.dwHighDateTime, lastWriteTimeUtc.dwLowDateTime).ToString() + wxT(") ") +
wxT("\n\n") + getLastErrorFormatted()).ToAscii()));
if (!::SystemTimeToTzSpecificLocalTime(
- NULL, //__in_opt LPTIME_ZONE_INFORMATION lpTimeZone,
- &systemTimeUtc, //__in LPSYSTEMTIME lpUniversalTime,
- &systemTimeLocal)) //__out LPSYSTEMTIME lpLocalTime
+ NULL, //__in_opt LPTIME_ZONE_INFORMATION lpTimeZone,
+ &systemTimeUtc, //__in LPSYSTEMTIME lpUniversalTime,
+ &systemTimeLocal)) //__out LPSYSTEMTIME lpLocalTime
throw std::runtime_error(std::string((wxString(_("Conversion error:")) + wxT(" SYSTEMTIME -> local SYSTEMTIME: ") +
wxT("(") + wxULongLong(lastWriteTimeUtc.dwHighDateTime, lastWriteTimeUtc.dwLowDateTime).ToString() + wxT(") ") +
wxT("\n\n") + getLastErrorFormatted()).ToAscii()));
@@ -193,8 +193,8 @@ wxString ffs3::utcTimeToLocalString(const wxLongLong& utcTime)
{
FILETIME fileTimeLocal = {};
if (!::FileTimeToLocalFileTime( //convert to local time
- &lastWriteTimeUtc, //pointer to UTC file time to convert
- &fileTimeLocal)) //pointer to converted file time
+ &lastWriteTimeUtc, //pointer to UTC file time to convert
+ &fileTimeLocal)) //pointer to converted file time
throw std::runtime_error(std::string((wxString(_("Conversion error:")) + wxT(" FILETIME -> local FILETIME: ") +
wxT("(") + wxULongLong(lastWriteTimeUtc.dwHighDateTime, lastWriteTimeUtc.dwLowDateTime).ToString() + wxT(") ") +
wxT("\n\n") + getLastErrorFormatted()).ToAscii()));
@@ -205,8 +205,8 @@ wxString ffs3::utcTimeToLocalString(const wxLongLong& utcTime)
// dateLow = 4294967295
if (!::FileTimeToSystemTime(
- &fileTimeLocal, //pointer to file time to convert
- &systemTimeLocal)) //pointer to structure to receive system time
+ &fileTimeLocal, //pointer to file time to convert
+ &systemTimeLocal)) //pointer to structure to receive system time
throw std::runtime_error(std::string((wxString(_("Conversion error:")) + wxT(" local FILETIME -> local SYSTEMTIME: ") +
wxT("(") + wxULongLong(fileTimeLocal.dwHighDateTime, fileTimeLocal.dwLowDateTime).ToString() + wxT(") ") +
wxT("\n\n") + getLastErrorFormatted()).ToAscii()));
diff --git a/shared/xml_base.cpp b/shared/xml_base.cpp
index 99d4d3ca..c3d04364 100644
--- a/shared/xml_base.cpp
+++ b/shared/xml_base.cpp
@@ -19,16 +19,16 @@ std::string getTypeName(xmlAccess::XmlType type)
{
switch (type)
{
- case xmlAccess::XML_GUI_CONFIG:
- return "GUI";
- case xmlAccess::XML_BATCH_CONFIG:
- return "BATCH";
- case xmlAccess::XML_GLOBAL_SETTINGS:
- return "GLOBAL";
- case xmlAccess::XML_REAL_CONFIG:
- return "REAL";
- case xmlAccess::XML_OTHER:
- break;
+ case xmlAccess::XML_GUI_CONFIG:
+ return "GUI";
+ case xmlAccess::XML_BATCH_CONFIG:
+ return "BATCH";
+ case xmlAccess::XML_GLOBAL_SETTINGS:
+ return "GLOBAL";
+ case xmlAccess::XML_REAL_CONFIG:
+ return "REAL";
+ case xmlAccess::XML_OTHER:
+ break;
}
assert(false);
return "OTHER";
@@ -44,13 +44,13 @@ void normalize(std::vector<char>& stream)
for (std::vector<char>::const_iterator i = stream.begin(); i != stream.end(); ++i)
switch (*i)
{
- case 0xD:
- tmp.push_back(0xA);
- if (i + 1 != stream.end() && *(i + 1) == 0xA)
- ++i;
- break;
- default:
- tmp.push_back(*i);
+ case 0xD:
+ tmp.push_back(0xA);
+ if (i + 1 != stream.end() && *(i + 1) == 0xA)
+ ++i;
+ break;
+ default:
+ tmp.push_back(*i);
}
stream.swap(tmp);
@@ -131,6 +131,8 @@ xmlAccess::XmlType xmlAccess::getXmlType(const wxString& filename) //throw()
void xmlAccess::loadXmlDocument(const wxString& filename, const xmlAccess::XmlType type, TiXmlDocument& document) //throw XmlError()
{
+ TiXmlBase::SetCondenseWhiteSpace(false); //do not condense whitespace characters
+
::loadRawXmlDocument(filename, document); //throw XmlError()
TiXmlElement* root = document.RootElement();
diff --git a/shared/zbase.h b/shared/zbase.h
index c3d539a1..a0322de0 100644
--- a/shared/zbase.h
+++ b/shared/zbase.h
@@ -225,7 +225,7 @@ public:
Zbase(const Zbase& source);
~Zbase();
- operator const T*() const; //implicit conversion to C-string
+ operator const T* () const; //implicit conversion to C-string
//STL accessors
const T* begin() const;
@@ -417,7 +417,7 @@ Zbase<T, SP, AP>::~Zbase()
template <class T, template <class, class> class SP, class AP>
inline
-Zbase<T, SP, AP>::operator const T*() const
+Zbase<T, SP, AP>::operator const T* () const
{
return rawStr;
}
diff --git a/shared/zstring.cpp b/shared/zstring.cpp
index 40590a90..6440c9af 100644
--- a/shared/zstring.cpp
+++ b/shared/zstring.cpp
@@ -31,8 +31,8 @@ LeakChecker::~LeakChecker()
std::string leakingStrings;
for (VoidPtrSizeMap::const_iterator i = activeStrings.begin();
- i != activeStrings.end() && ++rowCount <= 20;
- ++i)
+ i != activeStrings.end() && ++rowCount <= 20;
+ ++i)
leakingStrings += "\"" + rawMemToString(i->first, i->second) + "\"\n";
const std::string message = std::string("Memory leak detected!") + "\n\n"
@@ -130,8 +130,8 @@ int z_impl::compareFilenamesWin(const wchar_t* a, const wchar_t* b, size_t sizeA
}
else //fallback
{
-//do NOT use "CompareString"; this function is NOT accurate (even with LOCALE_INVARIANT and SORT_STRINGSORT): for example "weiß" == "weiss"!!!
-//the only reliable way to compare filenames (with XP) is to call "CharUpper" or "LCMapString":
+ //do NOT use "CompareString"; this function is NOT accurate (even with LOCALE_INVARIANT and SORT_STRINGSORT): for example "weiß" == "weiss"!!!
+ //the only reliable way to compare filenames (with XP) is to call "CharUpper" or "LCMapString":
const size_t minSize = std::min(sizeA, sizeB);
@@ -145,13 +145,13 @@ int z_impl::compareFilenamesWin(const wchar_t* a, const wchar_t* b, size_t sizeA
wchar_t bufferB[5000];
if (::LCMapString( //faster than CharUpperBuff + wmemcpy or CharUpper + wmemcpy and same speed like ::CompareString()
- ZSTRING_INVARIANT_LOCALE, //__in LCID Locale,
- LCMAP_UPPERCASE, //__in DWORD dwMapFlags,
- a, //__in LPCTSTR lpSrcStr,
- static_cast<int>(minSize), //__in int cchSrc,
- bufferA, //__out LPTSTR lpDestStr,
- 5000 //__in int cchDest
- ) == 0)
+ ZSTRING_INVARIANT_LOCALE, //__in LCID Locale,
+ LCMAP_UPPERCASE, //__in DWORD dwMapFlags,
+ a, //__in LPCTSTR lpSrcStr,
+ static_cast<int>(minSize), //__in int cchSrc,
+ bufferA, //__out LPTSTR lpDestStr,
+ 5000 //__in int cchDest
+ ) == 0)
throw std::runtime_error("Error comparing strings! (LCMapString)");
if (::LCMapString(ZSTRING_INVARIANT_LOCALE, LCMAP_UPPERCASE, b, static_cast<int>(minSize), bufferB, 5000) == 0)
@@ -178,18 +178,18 @@ int z_impl::compareFilenamesWin(const wchar_t* a, const wchar_t* b, size_t sizeA
rv;
}
-// const int rv = CompareString(
-// invariantLocale, //locale independent
-// NORM_IGNORECASE | SORT_STRINGSORT, //comparison-style options
-// a, //pointer to first string
-// aCount, //size, in bytes or characters, of first string
-// b, //pointer to second string
-// bCount); //size, in bytes or characters, of second string
-//
-// if (rv == 0)
-// throw std::runtime_error("Error comparing strings!");
-// else
-// return rv - 2; //convert to C-style string compare result
+ // const int rv = CompareString(
+ // invariantLocale, //locale independent
+ // NORM_IGNORECASE | SORT_STRINGSORT, //comparison-style options
+ // a, //pointer to first string
+ // aCount, //size, in bytes or characters, of first string
+ // b, //pointer to second string
+ // bCount); //size, in bytes or characters, of second string
+ //
+ // if (rv == 0)
+ // throw std::runtime_error("Error comparing strings!");
+ // else
+ // return rv - 2; //convert to C-style string compare result
}
bgstack15